/*-----------------------------------------------------------------------*/ /* Low level disk I/O module for FatFs with SD card support */ /*-----------------------------------------------------------------------*/ #include "ff.h" #include "diskio.h" #include "sd_card.h" #include #include #include /* Definitions of physical drive number for each drive */ #define DEV_SD 0 /* SD card */ /*-----------------------------------------------------------------------*/ /* Get Drive Status */ /*-----------------------------------------------------------------------*/ DSTATUS disk_status ( BYTE pdrv /* Physical drive number to identify the drive */ ) { if (pdrv != DEV_SD) return STA_NOINIT; // Assume SD card is always initialized after sd_card_init() is called return 0; // OK - not write protected, not removed } /*-----------------------------------------------------------------------*/ /* Initialize a Drive */ /*-----------------------------------------------------------------------*/ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive number to identify the drive */ ) { if (pdrv != DEV_SD) return STA_NOINIT; // SD card should already be initialized via sd_card_init() return 0; // OK } /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ DRESULT disk_read ( BYTE pdrv, /* Physical drive number to identify the drive */ BYTE *buff, /* Data buffer to store read data */ LBA_t sector, /* Start sector in LBA */ UINT count /* Number of sectors to read */ ) { if (pdrv != DEV_SD) return RES_PARERR; for (UINT i = 0; i < count; i++) { if (!sd_card_read_block(sector + i, buff + (i * 512))) { return RES_ERROR; } } return RES_OK; } /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ #if FF_FS_READONLY == 0 DRESULT disk_write ( BYTE pdrv, /* Physical drive number to identify the drive */ const BYTE *buff, /* Data to be written */ LBA_t sector, /* Start sector in LBA */ UINT count /* Number of sectors to write */ ) { if (pdrv != DEV_SD) return RES_PARERR; for (UINT i = 0; i < count; i++) { bool result = sd_card_write_block(sector + i, (uint8_t*)(buff + (i * 512))); if (!result) { printf("ERROR disk_write failed at sector %lu\n", (unsigned long)(sector + i)); return RES_ERROR; } } return RES_OK; } #endif /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ DRESULT disk_ioctl ( BYTE pdrv, /* Physical drive number (0..) */ BYTE cmd, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { if (pdrv != DEV_SD) return RES_PARERR; DRESULT res = RES_ERROR; switch (cmd) { case CTRL_SYNC: // Complete pending write process (if needed) res = RES_OK; break; case GET_SECTOR_COUNT: // Get number of sectors on the disk (DWORD) { sd_card_info_t info; if (sd_card_get_info(&info)) { // Calculate total sectors from capacity // capacity_mb * 1024 * 1024 / 512 = capacity_mb * 2048 *(LBA_t*)buff = (LBA_t)info.capacity_mb * 2048; res = RES_OK; } } break; case GET_SECTOR_SIZE: // Get sector size (WORD) *(WORD*)buff = 512; res = RES_OK; break; case GET_BLOCK_SIZE: // Get erase block size in unit of sector (DWORD) *(DWORD*)buff = 1; // Single sector erase res = RES_OK; break; case CTRL_TRIM: // Inform device that data on the block of sectors is no longer used (optional) res = RES_OK; break; default: res = RES_PARERR; } return res; }