fatfs_diskio.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*-----------------------------------------------------------------------*/
  2. /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
  3. /*-----------------------------------------------------------------------*/
  4. /* This is a stub disk I/O module that acts as front end of the existing */
  5. /* disk I/O modules and attach it to FatFs module with common interface. */
  6. /*-----------------------------------------------------------------------*/
  7. #include "hal.h"
  8. #include "ffconf.h"
  9. #include "diskio.h"
  10. #if HAL_USE_MMC_SPI && HAL_USE_SDC
  11. #error "cannot specify both MMC_SPI and SDC drivers"
  12. #endif
  13. #if !defined(FATFS_HAL_DEVICE)
  14. #if HAL_USE_MMC_SPI
  15. #define FATFS_HAL_DEVICE MMCD1
  16. #else
  17. #define FATFS_HAL_DEVICE SDCD1
  18. #endif
  19. #endif
  20. #if HAL_USE_MMC_SPI
  21. extern MMCDriver FATFS_HAL_DEVICE;
  22. #elif HAL_USE_SDC
  23. extern SDCDriver FATFS_HAL_DEVICE;
  24. #else
  25. #error "MMC_SPI or SDC driver must be specified"
  26. #endif
  27. #if HAL_USE_RTC
  28. extern RTCDriver RTCD1;
  29. #endif
  30. /*-----------------------------------------------------------------------*/
  31. /* Correspondence between physical drive number and physical drive. */
  32. #define MMC 0
  33. #define SDC 0
  34. /*
  35. retry all disk operations up to 5 times to reduce the impact of poor
  36. hardware
  37. */
  38. #define FATFS_NUM_RETRIES 5
  39. #define FATFS_RETRY(x) do { uint8_t ii; for (ii=0; ii<FATFS_NUM_RETRIES; ii++) {if ((x)==0) break; else if (ii==FATFS_NUM_RETRIES-1) return RES_ERROR;}} while(0)
  40. /*-----------------------------------------------------------------------*/
  41. /* Inidialize a Drive */
  42. DSTATUS disk_initialize (
  43. BYTE pdrv /* Physical drive number (0..) */
  44. )
  45. {
  46. DSTATUS stat;
  47. switch (pdrv) {
  48. #if HAL_USE_MMC_SPI
  49. case MMC:
  50. stat = 0;
  51. /* It is initialized externally, just reads the status.*/
  52. if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
  53. stat |= STA_NOINIT;
  54. if (mmcIsWriteProtected(&FATFS_HAL_DEVICE))
  55. stat |= STA_PROTECT;
  56. return stat;
  57. #else
  58. case SDC:
  59. stat = 0;
  60. /* It is initialized externally, just reads the status.*/
  61. if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
  62. stat |= STA_NOINIT;
  63. if (sdcIsWriteProtected(&FATFS_HAL_DEVICE))
  64. stat |= STA_PROTECT;
  65. return stat;
  66. #endif
  67. }
  68. return STA_NOINIT;
  69. }
  70. /*-----------------------------------------------------------------------*/
  71. /* Return Disk Status */
  72. DSTATUS disk_status (
  73. BYTE pdrv /* Physical drive number (0..) */
  74. )
  75. {
  76. DSTATUS stat;
  77. switch (pdrv) {
  78. #if HAL_USE_MMC_SPI
  79. case MMC:
  80. stat = 0;
  81. /* It is initialized externally, just reads the status.*/
  82. if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
  83. stat |= STA_NOINIT;
  84. if (mmcIsWriteProtected(&FATFS_HAL_DEVICE))
  85. stat |= STA_PROTECT;
  86. return stat;
  87. #else
  88. case SDC:
  89. stat = 0;
  90. /* It is initialized externally, just reads the status.*/
  91. if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
  92. stat |= STA_NOINIT;
  93. if (sdcIsWriteProtected(&FATFS_HAL_DEVICE))
  94. stat |= STA_PROTECT;
  95. return stat;
  96. #endif
  97. }
  98. return STA_NOINIT;
  99. }
  100. /*-----------------------------------------------------------------------*/
  101. /* Read Sector(s) */
  102. DRESULT disk_read (
  103. BYTE pdrv, /* Physical drive number (0..) */
  104. BYTE *buff, /* Data buffer to store read data */
  105. DWORD sector, /* Sector address (LBA) */
  106. UINT count /* Number of sectors to read (1..255) */
  107. )
  108. {
  109. switch (pdrv) {
  110. #if HAL_USE_MMC_SPI
  111. case MMC:
  112. if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
  113. return RES_NOTRDY;
  114. FATFS_RETRY(mmcStartSequentialRead(&FATFS_HAL_DEVICE, sector));
  115. while (count > 0) {
  116. FATFS_RETRY(mmcSequentialRead(&FATFS_HAL_DEVICE, buff));
  117. buff += MMCSD_BLOCK_SIZE;
  118. count--;
  119. }
  120. FATFS_RETRY(mmcStopSequentialRead(&FATFS_HAL_DEVICE));
  121. return RES_OK;
  122. #else
  123. case SDC:
  124. if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
  125. return RES_NOTRDY;
  126. FATFS_RETRY(sdcRead(&FATFS_HAL_DEVICE, sector, buff, count));
  127. return RES_OK;
  128. #endif
  129. }
  130. return RES_PARERR;
  131. }
  132. /*-----------------------------------------------------------------------*/
  133. /* Write Sector(s) */
  134. #if !FF_FS_READONLY
  135. DRESULT disk_write (
  136. BYTE pdrv, /* Physical drive number (0..) */
  137. const BYTE *buff, /* Data to be written */
  138. DWORD sector, /* Sector address (LBA) */
  139. UINT count /* Number of sectors to write (1..255) */
  140. )
  141. {
  142. switch (pdrv) {
  143. #if HAL_USE_MMC_SPI
  144. case MMC:
  145. if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
  146. return RES_NOTRDY;
  147. if (mmcIsWriteProtected(&FATFS_HAL_DEVICE))
  148. return RES_WRPRT;
  149. FATFS_RETRY(mmcStartSequentialWrite(&FATFS_HAL_DEVICE, sector));
  150. while (count > 0) {
  151. FATFS_RETRY(mmcSequentialWrite(&FATFS_HAL_DEVICE, buff));
  152. buff += MMCSD_BLOCK_SIZE;
  153. count--;
  154. }
  155. FATFS_RETRY(mmcStopSequentialWrite(&FATFS_HAL_DEVICE));
  156. return RES_OK;
  157. #else
  158. case SDC:
  159. if (blkGetDriverState(&FATFS_HAL_DEVICE) != BLK_READY)
  160. return RES_NOTRDY;
  161. FATFS_RETRY(sdcWrite(&FATFS_HAL_DEVICE, sector, buff, count));
  162. return RES_OK;
  163. #endif
  164. }
  165. return RES_PARERR;
  166. }
  167. #endif /* _FS_READONLY */
  168. /*-----------------------------------------------------------------------*/
  169. /* Miscellaneous Functions */
  170. DRESULT disk_ioctl (
  171. BYTE pdrv, /* Physical drive number (0..) */
  172. BYTE cmd, /* Control code */
  173. void *buff /* Buffer to send/receive control data */
  174. )
  175. {
  176. (void)buff;
  177. switch (pdrv) {
  178. #if HAL_USE_MMC_SPI
  179. case MMC:
  180. switch (cmd) {
  181. case CTRL_SYNC:
  182. return RES_OK;
  183. #if FF_MAX_SS > FF_MIN_SS
  184. case GET_SECTOR_SIZE:
  185. *((WORD *)buff) = MMCSD_BLOCK_SIZE;
  186. return RES_OK;
  187. #endif
  188. #if FF_USE_TRIM
  189. case CTRL_TRIM:
  190. mmcErase(&FATFS_HAL_DEVICE, *((DWORD *)buff), *((DWORD *)buff + 1));
  191. return RES_OK;
  192. #endif
  193. default:
  194. return RES_PARERR;
  195. }
  196. #else
  197. case SDC:
  198. switch (cmd) {
  199. case CTRL_SYNC:
  200. return RES_OK;
  201. case GET_SECTOR_COUNT:
  202. *((DWORD *)buff) = mmcsdGetCardCapacity(&FATFS_HAL_DEVICE);
  203. return RES_OK;
  204. #if FF_MAX_SS > FF_MIN_SS
  205. case GET_SECTOR_SIZE:
  206. *((WORD *)buff) = MMCSD_BLOCK_SIZE;
  207. return RES_OK;
  208. #endif
  209. case GET_BLOCK_SIZE:
  210. *((DWORD *)buff) = 256; /* 512b blocks in one erase block */
  211. return RES_OK;
  212. #if FF_USE_TRIM
  213. case CTRL_TRIM:
  214. sdcErase(&FATFS_HAL_DEVICE, *((DWORD *)buff), *((DWORD *)buff + 1));
  215. return RES_OK;
  216. #endif
  217. default:
  218. return RES_PARERR;
  219. }
  220. #endif
  221. }
  222. return RES_PARERR;
  223. }
  224. #ifndef _ARDUPILOT_
  225. DWORD get_fattime(void) {
  226. #if HAL_USE_RTC
  227. RTCDateTime timespec;
  228. rtcGetTime(&RTCD1, &timespec);
  229. return rtcConvertDateTimeToFAT(&timespec);
  230. #else
  231. return ((uint32_t)0 | (1 << 16)) | (1 << 21); /* wrong but valid time */
  232. #endif
  233. }
  234. #endif // _ARDUPILOT_