image/svg+xml
Brteve's API for EveApps
Version 0.0.1
The reference document for common folder of EveApps project.
 
Loading...
Searching...
No Matches
diskio_rp2040.c
Go to the documentation of this file.
1
32#if defined(PICO_BUILD)
33
34#include "pico.h"
35#include "pico/stdlib.h"
36#include "hardware/clocks.h"
37#include "hardware/spi.h"
38#include "hardware/gpio.h"
39
40#include "ff.h"
41#include "diskio.h"
42
43#include "hardware/spi.h"
44
45/* SPI pin assignment */
46#define SPI_ACTIVE spi1
47#define PIN_SPI0_SCK 10
48#define PIN_SPI0_MOSI 11
49#define PIN_SPI0_MISO 12
50#define PIN_SPI0_CS 13
51
52// #define SPI_ACTIVE spi0
53// #define PIN_SPI0_SCK 6
54// #define PIN_SPI0_MOSI 7
55// #define PIN_SPI0_MISO 8
56// #define PIN_SPI0_CS 9
57
58/*--------------------------------------------------------------------------
59
60 Module Private Functions
61
62---------------------------------------------------------------------------*/
63
64/* MMC/SD command */
65#define CMD0 (0) /* GO_IDLE_STATE */
66#define CMD1 (1) /* SEND_OP_COND (MMC) */
67#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
68#define CMD8 (8) /* SEND_IF_COND */
69#define CMD9 (9) /* SEND_CSD */
70#define CMD10 (10) /* SEND_CID */
71#define CMD12 (12) /* STOP_TRANSMISSION */
72#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
73#define CMD16 (16) /* SET_BLOCKLEN */
74#define CMD17 (17) /* READ_SINGLE_BLOCK */
75#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
76#define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */
77#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
78#define CMD24 (24) /* WRITE_BLOCK */
79#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
80#define CMD32 (32) /* ERASE_ER_BLK_START */
81#define CMD33 (33) /* ERASE_ER_BLK_END */
82#define CMD38 (38) /* ERASE */
83#define CMD55 (55) /* APP_CMD */
84#define CMD58 (58) /* READ_OCR */
85
86/* MMC card type flags (MMC_GET_TYPE) */
87#define CT_MMC 0x01 /* MMC ver 3 */
88#define CT_SD1 0x02 /* SD ver 1 */
89#define CT_SD2 0x04 /* SD ver 2 */
90#define CT_SDC (CT_SD1|CT_SD2) /* SD */
91#define CT_BLOCK 0x08 /* Block addressing */
92
93#define CLK_SLOW (100 * KHZ)
94#define CLK_FAST (50 * MHZ)
95
96static volatile
97DSTATUS Stat = STA_NOINIT; /* Physical drive status */
98
99static
100BYTE CardType; /* Card type flags */
101
102static inline uint32_t _millis(void)
103{
104 return to_ms_since_boot(get_absolute_time());
105}
106
107/*-----------------------------------------------------------------------*/
108/* SPI controls (Platform dependent) */
109/*-----------------------------------------------------------------------*/
110
111static inline void cs_select(uint cs_pin) {
112 asm volatile("nop \n nop \n nop"); // FIXME
113 gpio_put(cs_pin, 0);
114 asm volatile("nop \n nop \n nop"); // FIXME
115}
116
117static inline void cs_deselect(uint cs_pin) {
118 asm volatile("nop \n nop \n nop"); // FIXME
119 gpio_put(cs_pin, 1);
120 asm volatile("nop \n nop \n nop"); // FIXME
121}
122
123static void FCLK_SLOW(void)
124{
125 spi_set_baudrate(SPI_ACTIVE, CLK_SLOW);
126}
127
128static void FCLK_FAST(void)
129{
130 spi_set_baudrate(SPI_ACTIVE, CLK_FAST);
131}
132
133static void CS_HIGH(void)
134{
135 cs_deselect(PIN_SPI0_CS);
136}
137
138static void CS_LOW(void)
139{
140 cs_select(PIN_SPI0_CS);
141}
142
143/* Initialize MMC interface */
144static
145void init_spi(void)
146{
147 /* GPIO pin configuration */
148 /* pull up of MISO is MUST (10Kohm external pull up is recommended) */
149 /* Set drive strength and slew rate if needed to meet wire condition */
150 gpio_init(PIN_SPI0_SCK);
151 gpio_pull_up(PIN_SPI0_SCK);
152 gpio_set_drive_strength(PIN_SPI0_SCK, PADS_BANK0_GPIO0_DRIVE_VALUE_4MA); // 2mA, 4mA (default), 8mA, 12mA
153 gpio_set_slew_rate(PIN_SPI0_SCK, 0); // 0: SLOW (default), 1: FAST
154 gpio_set_function(PIN_SPI0_SCK, GPIO_FUNC_SPI);
155
156 gpio_init(PIN_SPI0_MISO);
157 gpio_pull_up(PIN_SPI0_MISO);
158 gpio_set_input_hysteresis_enabled(PIN_SPI0_MISO, 1); // 0: Off, 1: On (default)
159 gpio_set_function(PIN_SPI0_MISO, GPIO_FUNC_SPI);
160
161 gpio_init(PIN_SPI0_MOSI);
162 gpio_pull_up(PIN_SPI0_MOSI);
163 gpio_set_drive_strength(PIN_SPI0_MOSI, PADS_BANK0_GPIO0_DRIVE_VALUE_4MA); // 2mA, 4mA (default), 8mA, 12mA
164 gpio_set_slew_rate(PIN_SPI0_MOSI, 0); // 0: SLOW (default), 1: FAST
165 gpio_set_function(PIN_SPI0_MOSI, GPIO_FUNC_SPI);
166
167 gpio_init(PIN_SPI0_CS);
168 gpio_pull_up(PIN_SPI0_CS);
169 gpio_set_drive_strength(PIN_SPI0_CS, PADS_BANK0_GPIO0_DRIVE_VALUE_4MA); // 2mA, 4mA (default), 8mA, 12mA
170 gpio_set_slew_rate(PIN_SPI0_CS, 0); // 0: SLOW (default), 1: FAST
171 gpio_set_dir(PIN_SPI0_CS, GPIO_OUT);
172
173 /* chip _select invalid*/
174 CS_HIGH();
175
176 spi_init(SPI_ACTIVE, CLK_SLOW);
177
178 /* SPI0 parameter config */
179 spi_set_format(SPI_ACTIVE,
180 8, /* data_bits */
181 SPI_CPOL_0, /* cpol */
182 SPI_CPHA_0, /* cpha */
183 SPI_MSB_FIRST /* order */
184 );
185}
186
187/* Exchange a byte */
188static
189BYTE xchg_spi (
190 BYTE dat /* Data to send */
191)
192{
193 uint8_t *buff = (uint8_t *) &dat;
194 spi_write_read_blocking(SPI_ACTIVE, buff, buff, 1);
195 return (BYTE) *buff;
196}
197
198
199/* Receive multiple byte */
200static
201void rcvr_spi_multi (
202 BYTE *buff, /* Pointer to data buffer */
203 UINT btr /* Number of bytes to receive (even number) */
204)
205{
206 uint8_t *b = (uint8_t *) buff;
207 spi_read_blocking(SPI_ACTIVE, 0xff, b, btr);
208}
209
210
211/*-----------------------------------------------------------------------*/
212/* Wait for card ready */
213/*-----------------------------------------------------------------------*/
214
215static
216int wait_ready ( /* 1:Ready, 0:Timeout */
217 UINT wt /* Timeout [ms] */
218)
219{
220 BYTE d;
221
222 uint32_t t = _millis();
223 do {
224 d = xchg_spi(0xFF);
225 /* This loop takes a time. Insert rot_rdq() here for multitask envilonment. */
226 } while (d != 0xFF && _millis() < t + wt); /* Wait for card goes ready or timeout */
227
228 return (d == 0xFF) ? 1 : 0;
229}
230
231
232
233/*-----------------------------------------------------------------------*/
234/* Deselect card and release SPI */
235/*-----------------------------------------------------------------------*/
236
237static
238void deselect (void)
239{
240 CS_HIGH(); /* Set CS# high */
241 xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */
242}
243
244
245
246/*-----------------------------------------------------------------------*/
247/* Select card and wait for ready */
248/*-----------------------------------------------------------------------*/
249
250static
251int _select (void) /* 1:OK, 0:Timeout */
252{
253 CS_LOW(); /* Set CS# low */
254 xchg_spi(0xFF); /* Dummy clock (force DO enabled) */
255 if (wait_ready(500)) return 1; /* Wait for card ready */
256
257 deselect();
258 return 0; /* Timeout */
259}
260
261
262
263/*-----------------------------------------------------------------------*/
264/* Receive a data packet from the MMC */
265/*-----------------------------------------------------------------------*/
266
267static
268int rcvr_datablock ( /* 1:OK, 0:Error */
269 BYTE *buff, /* Data buffer */
270 UINT btr /* Data block length (byte) */
271)
272{
273 BYTE token;
274
275 const uint32_t timeout = 200;
276 uint32_t t = _millis();
277 do { /* Wait for DataStart token in timeout of 200ms */
278 token = xchg_spi(0xFF);
279 /* This loop will take a time. Insert rot_rdq() here for multitask envilonment. */
280 } while (token == 0xFF && _millis() < t + timeout);
281 if(token != 0xFE) return 0; /* Function fails if invalid DataStart token or timeout */
282
283 rcvr_spi_multi(buff, btr); /* Store trailing data to the buffer */
284 xchg_spi(0xFF); xchg_spi(0xFF); /* Discard CRC */
285
286 return 1; /* Function succeeded */
287}
288
289
290/*-----------------------------------------------------------------------*/
291/* Send a command packet to the MMC */
292/*-----------------------------------------------------------------------*/
293
294static
295BYTE send_cmd ( /* Return value: R1 resp (bit7==1:Failed to send) */
296 BYTE cmd, /* Command index */
297 DWORD arg /* Argument */
298)
299{
300 BYTE n, res;
301
302
303 if (cmd & 0x80) { /* Send a CMD55 prior to ACMD<n> */
304 cmd &= 0x7F;
305 res = send_cmd(CMD55, 0);
306 if (res > 1) return res;
307 }
308
309 /* Select the card and wait for ready except to stop multiple block read */
310 if (cmd != CMD12) {
311 deselect();
312 if (!_select()) return 0xFF;
313 }
314
315 /* Send command packet */
316 xchg_spi(0x40 | cmd); /* Start + command index */
317 xchg_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
318 xchg_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
319 xchg_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
320 xchg_spi((BYTE)arg); /* Argument[7..0] */
321 n = 0x01; /* Dummy CRC + Stop */
322 if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
323 if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
324 xchg_spi(n);
325
326 /* Receive command resp */
327 if (cmd == CMD12) xchg_spi(0xFF); /* Diacard following one byte when CMD12 */
328 n = 10; /* Wait for response (10 bytes max) */
329 do {
330 res = xchg_spi(0xFF);
331 } while ((res & 0x80) && --n);
332
333 return res; /* Return received response */
334}
335
336/*--------------------------------------------------------------------------
337
338 Public Functions
339
340---------------------------------------------------------------------------*/
341
342
343/*-----------------------------------------------------------------------*/
344/* Initialize disk drive */
345/*-----------------------------------------------------------------------*/
346
348 BYTE drv /* Physical drive number (0) */
349)
350{
351 BYTE n, cmd, ty, ocr[4];
352 const uint32_t timeout = 1000; /* Initialization timeout = 1 sec */
353 uint32_t t;
354
355
356 if (drv) return STA_NOINIT; /* Supports only drive 0 */
357 init_spi(); /* Initialize SPI */
358 sleep_ms(10);
359
360 if (Stat & STA_NODISK) return Stat; /* Is card existing in the soket? */
361
362 FCLK_SLOW();
363 CS_LOW();
364 for (n = 10; n; n--) xchg_spi(0xFF); /* Send 80 dummy clocks */
365
366 ty = 0;
367 if (send_cmd(CMD0, 0) == 1) { /* Put the card SPI/Idle state */
368 t = _millis();
369 if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */
370 for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); /* Get 32 bit return value of R7 resp */
371 if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* Is the card supports vcc of 2.7-3.6V? */
372 while (_millis() < t + timeout && send_cmd(ACMD41, 1UL << 30)) ; /* Wait for end of initialization with ACMD41(HCS) */
373 if (_millis() < t + timeout && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
374 for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
375 ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* Card id SDv2 */
376 }
377 }
378 } else { /* Not SDv2 card */
379 if (send_cmd(ACMD41, 0) <= 1) { /* SDv1 or MMC? */
380 ty = CT_SD1; cmd = ACMD41; /* SDv1 (ACMD41(0)) */
381 } else {
382 ty = CT_MMC; cmd = CMD1; /* MMCv3 (CMD1(0)) */
383 }
384 while (_millis() < t + timeout && send_cmd(cmd, 0)) ; /* Wait for end of initialization */
385 if (_millis() >= t + timeout || send_cmd(CMD16, 512) != 0) /* Set block length: 512 */
386 ty = 0;
387 }
388 }
389 CardType = ty; /* Card type */
390 deselect();
391
392 if (ty) { /* OK */
393 FCLK_FAST(); /* Set fast clock */
394 Stat &= ~STA_NOINIT; /* Clear STA_NOINIT flag */
395 } else { /* Failed */
396 Stat = STA_NOINIT;
397 }
398
399 return Stat;
400}
401
402
403
404/*-----------------------------------------------------------------------*/
405/* Get disk status */
406/*-----------------------------------------------------------------------*/
407
409 BYTE drv /* Physical drive number (0) */
410)
411{
412 if (drv) return STA_NOINIT; /* Supports only drive 0 */
413
414 return Stat; /* Return disk status */
415}
416
417
418
419/*-----------------------------------------------------------------------*/
420/* Read sector(s) */
421/*-----------------------------------------------------------------------*/
422
424 BYTE drv, /* Physical drive number (0) */
425 BYTE *buff, /* Pointer to the data buffer to store read data */
426 LBA_t sector, /* Start sector number (LBA) */
427 UINT count /* Number of sectors to read (1..128) */
428)
429{
430 if (drv || !count) return RES_PARERR; /* Check parameter */
431 if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
432
433 if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ot BA conversion (byte addressing cards) */
434
435 if (count == 1) { /* Single sector read */
436 if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
437 && rcvr_datablock(buff, 512)) {
438 count = 0;
439 }
440 }
441 else { /* Multiple sector read */
442 if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
443 do {
444 if (!rcvr_datablock(buff, 512)) break;
445 buff += 512;
446 } while (--count);
447 send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
448 }
449 }
450 deselect();
451
452 return count ? RES_ERROR : RES_OK; /* Return result */
453}
454
455
456
457#if !FF_FS_READONLY && !FF_FS_NORTC
458/* get the current time */
459DWORD get_fattime (void)
460{
461 return 0;
462}
463#endif
464
465#if FF_FS_READONLY == 0
466/* Transmit multiple byte */
467static
468void xmit_spi_multi (
469 const BYTE *buff, /* Pointer to data buffer */
470 UINT btx /* Number of bytes to transmit (even number) */
471)
472{
473 const uint8_t *b = (const uint8_t *) buff;
474 spi_write_blocking(SPI_ACTIVE, b, btx);
475}
476
477/*-----------------------------------------------------------------------*/
478/* Transmit a data packet to the MMC */
479/*-----------------------------------------------------------------------*/
480
481static
482int xmit_datablock ( /* 1:OK, 0:Error */
483 const BYTE *buff, /* 512 byte data block to be transmitted */
484 BYTE token /* Data/Stop token */
485)
486{
487 BYTE resp;
488 if (!wait_ready(500)) return 0;
489 xchg_spi(token); /* Xmit data token */
490 if (token != 0xFD) { /* Is data token */
491 xmit_spi_multi(buff, 512); /* Xmit the data block to the MMC */
492 xchg_spi(0xFF); /* CRC (Dummy) */
493 xchg_spi(0xFF);
494 resp = xchg_spi(0xFF); /* Reveive data response */
495 if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
496 return 0;
497 }
498 return 1;
499}
500
501/*-----------------------------------------------------------------------*/
502/* Write sector(s) */
503/*-----------------------------------------------------------------------*/
504
506 BYTE drv, /* Physical drive number (0) */
507 const BYTE *buff, /* Ponter to the data to write */
508 LBA_t sector, /* Start sector number (LBA) */
509 UINT count /* Number of sectors to write (1..128) */
510)
511{
512 if (drv || !count) return RES_PARERR; /* Check parameter */
513 if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */
514 if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protect */
515
516 if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ==> BA conversion (byte addressing cards) */
517
518 if (!_select()) return RES_NOTRDY;
519
520 if (count == 1) { /* Single sector write */
521 if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
522 && xmit_datablock(buff, 0xFE)) {
523 count = 0;
524 }
525 }
526 else { /* Multiple sector write */
527 if (CardType & CT_SDC) send_cmd(ACMD23, count); /* Predefine number of sectors */
528 if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
529 do {
530 if (!xmit_datablock(buff, 0xFC)) break;
531 buff += 512;
532 } while (--count);
533 if (!xmit_datablock(0, 0xFD)) count = 1; /* STOP_TRAN token */
534 }
535 }
536 deselect();
537
538 return count ? RES_ERROR : RES_OK; /* Return result */
539}
540#endif
541
542
543/*-----------------------------------------------------------------------*/
544/* Miscellaneous drive controls other than data read/write */
545/*-----------------------------------------------------------------------*/
546
548 BYTE drv, /* Physical drive number (0) */
549 BYTE cmd, /* Control command code */
550 void *buff /* Pointer to the conrtol data */
551)
552{
553 DRESULT res;
554 BYTE n, csd[16];
555 DWORD *dp, st, ed, csize;
556
557
558 if (drv) return RES_PARERR; /* Check parameter */
559 if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
560
561 res = RES_ERROR;
562
563 switch (cmd) {
564 case CTRL_SYNC : /* Wait for end of internal write process of the drive */
565 if (_select()) res = RES_OK;
566 break;
567
568 case GET_SECTOR_COUNT : /* Get drive capacity in unit of sector (DWORD) */
569 if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
570 if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
571 csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
572 *(DWORD*)buff = csize << 10;
573 } else { /* SDC ver 1.XX or MMC ver 3 */
574 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
575 csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
576 *(DWORD*)buff = csize << (n - 9);
577 }
578 res = RES_OK;
579 }
580 break;
581
582 case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
583 if (CardType & CT_SD2) { /* SDC ver 2.00 */
584 if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
585 xchg_spi(0xFF);
586 if (rcvr_datablock(csd, 16)) { /* Read partial block */
587 for (n = 64 - 16; n; n--) xchg_spi(0xFF); /* Purge trailing data */
588 *(DWORD*)buff = 16UL << (csd[10] >> 4);
589 res = RES_OK;
590 }
591 }
592 } else { /* SDC ver 1.XX or MMC */
593 if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
594 if (CardType & CT_SD1) { /* SDC ver 1.XX */
595 *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
596 } else { /* MMC */
597 *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
598 }
599 res = RES_OK;
600 }
601 }
602 break;
603
604 case CTRL_TRIM : /* Erase a block of sectors (used when _USE_ERASE == 1) */
605 if (!(CardType & CT_SDC)) break; /* Check if the card is SDC */
606 if (disk_ioctl(drv, MMC_GET_CSD, csd)) break; /* Get CSD */
607 if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; /* Check if sector erase can be applied to the card */
608 dp = buff; st = dp[0]; ed = dp[1]; /* Load sector block */
609 if (!(CardType & CT_BLOCK)) {
610 st *= 512; ed *= 512;
611 }
612 if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) { /* Erase sector block */
613 res = RES_OK; /* FatFs does not check result of this command */
614 }
615 break;
616
617 default:
618 res = RES_PARERR;
619 }
620
621 deselect();
622
623 return res;
624}
625#endif
static uint32_t b
Definition Common.c:37
static uint32_t d
Definition Common.c:39
unsigned int uint32_t
unsigned char uint8_t
static ft_void_t ft_uint32_t * cmd
Definition FT_Gpu_Hal.h:184
DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count)
DSTATUS disk_initialize(BYTE pdrv)
#define CTRL_SYNC
Definition diskio.h:46
#define GET_SECTOR_COUNT
Definition diskio.h:47
DSTATUS disk_status(BYTE pdrv)
#define STA_PROTECT
Definition diskio.h:40
DRESULT
Definition diskio.h:16
@ RES_OK
Definition diskio.h:17
@ RES_WRPRT
Definition diskio.h:19
@ RES_ERROR
Definition diskio.h:18
@ RES_NOTRDY
Definition diskio.h:20
@ RES_PARERR
Definition diskio.h:21
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
#define STA_NOINIT
Definition diskio.h:38
DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count)
BYTE DSTATUS
Definition diskio.h:13
#define MMC_GET_CSD
Definition diskio.h:60
#define GET_BLOCK_SIZE
Definition diskio.h:49
#define STA_NODISK
Definition diskio.h:39
#define CTRL_TRIM
Definition diskio.h:50
unsigned short WORD
Definition ff.h:60
DWORD LBA_t
Definition ff.h:83
unsigned int UINT
Definition ff.h:58
unsigned char BYTE
Definition ff.h:59
unsigned long DWORD
Definition ff.h:61