user_diskio.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file user_diskio.c
  5. * @brief This file includes a diskio driver skeleton to be completed by the user.
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under Ultimate Liberty license
  13. * SLA0044, the "License"; You may not use this file except in compliance with
  14. * the License. You may obtain a copy of the License at:
  15. * www.st.com/SLA0044
  16. *
  17. ******************************************************************************
  18. */
  19. /* USER CODE END Header */
  20. #ifdef USE_OBSOLETE_USER_CODE_SECTION_0
  21. /*
  22. * Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0)
  23. * To be suppressed in the future.
  24. * Kept to ensure backward compatibility with previous CubeMx versions when
  25. * migrating projects.
  26. * User code previously added there should be copied in the new user sections before
  27. * the section contents can be deleted.
  28. */
  29. /* USER CODE BEGIN 0 */
  30. /* USER CODE END 0 */
  31. #endif
  32. /* USER CODE BEGIN DECL */
  33. /* Includes ------------------------------------------------------------------*/
  34. #include "user_diskio.h"
  35. #include "furi-hal-spi.h"
  36. /* Private typedef -----------------------------------------------------------*/
  37. /* Private define ------------------------------------------------------------*/
  38. /* Private variables ---------------------------------------------------------*/
  39. /* Disk status */
  40. static volatile DSTATUS Stat = STA_NOINIT;
  41. static DSTATUS User_CheckStatus(BYTE lun) {
  42. Stat = STA_NOINIT;
  43. if(BSP_SD_GetCardState() == MSD_OK) {
  44. Stat &= ~STA_NOINIT;
  45. }
  46. return Stat;
  47. }
  48. /* USER CODE END DECL */
  49. /* Private function prototypes -----------------------------------------------*/
  50. DSTATUS USER_initialize(BYTE pdrv);
  51. DSTATUS USER_status(BYTE pdrv);
  52. DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
  53. #if _USE_WRITE == 1
  54. DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
  55. #endif /* _USE_WRITE == 1 */
  56. #if _USE_IOCTL == 1
  57. DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff);
  58. #endif /* _USE_IOCTL == 1 */
  59. Diskio_drvTypeDef USER_Driver = {
  60. USER_initialize,
  61. USER_status,
  62. USER_read,
  63. #if _USE_WRITE
  64. USER_write,
  65. #endif /* _USE_WRITE == 1 */
  66. #if _USE_IOCTL == 1
  67. USER_ioctl,
  68. #endif /* _USE_IOCTL == 1 */
  69. };
  70. /* Private functions ---------------------------------------------------------*/
  71. /**
  72. * @brief Initializes a Drive
  73. * @param pdrv: Physical drive number (0..)
  74. * @retval DSTATUS: Operation status
  75. */
  76. DSTATUS USER_initialize(BYTE pdrv) {
  77. /* USER CODE BEGIN INIT */
  78. const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast);
  79. DSTATUS status = User_CheckStatus(pdrv);
  80. furi_hal_spi_device_return(sd_spi_fast_dev);
  81. return status;
  82. /* USER CODE END INIT */
  83. }
  84. /**
  85. * @brief Gets Disk Status
  86. * @param pdrv: Physical drive number (0..)
  87. * @retval DSTATUS: Operation status
  88. */
  89. DSTATUS USER_status(BYTE pdrv) {
  90. /* USER CODE BEGIN STATUS */
  91. return Stat;
  92. /* USER CODE END STATUS */
  93. }
  94. /**
  95. * @brief Reads Sector(s)
  96. * @param pdrv: Physical drive number (0..)
  97. * @param *buff: Data buffer to store read data
  98. * @param sector: Sector address (LBA)
  99. * @param count: Number of sectors to read (1..128)
  100. * @retval DRESULT: Operation result
  101. */
  102. DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
  103. /* USER CODE BEGIN READ */
  104. DRESULT res = RES_ERROR;
  105. const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast);
  106. if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) {
  107. /* wait until the read operation is finished */
  108. while(BSP_SD_GetCardState() != MSD_OK) {
  109. }
  110. res = RES_OK;
  111. }
  112. furi_hal_spi_device_return(sd_spi_fast_dev);
  113. return res;
  114. /* USER CODE END READ */
  115. }
  116. /**
  117. * @brief Writes Sector(s)
  118. * @param pdrv: Physical drive number (0..)
  119. * @param *buff: Data to be written
  120. * @param sector: Sector address (LBA)
  121. * @param count: Number of sectors to write (1..128)
  122. * @retval DRESULT: Operation result
  123. */
  124. #if _USE_WRITE == 1
  125. DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
  126. /* USER CODE BEGIN WRITE */
  127. /* USER CODE HERE */
  128. DRESULT res = RES_ERROR;
  129. const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast);
  130. if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) {
  131. /* wait until the Write operation is finished */
  132. while(BSP_SD_GetCardState() != MSD_OK) {
  133. }
  134. res = RES_OK;
  135. }
  136. furi_hal_spi_device_return(sd_spi_fast_dev);
  137. return res;
  138. /* USER CODE END WRITE */
  139. }
  140. #endif /* _USE_WRITE == 1 */
  141. /**
  142. * @brief I/O control operation
  143. * @param pdrv: Physical drive number (0..)
  144. * @param cmd: Control code
  145. * @param *buff: Buffer to send/receive control data
  146. * @retval DRESULT: Operation result
  147. */
  148. #if _USE_IOCTL == 1
  149. DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) {
  150. /* USER CODE BEGIN IOCTL */
  151. DRESULT res = RES_ERROR;
  152. BSP_SD_CardInfo CardInfo;
  153. if(Stat & STA_NOINIT) return RES_NOTRDY;
  154. const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast);
  155. switch(cmd) {
  156. /* Make sure that no pending write process */
  157. case CTRL_SYNC:
  158. res = RES_OK;
  159. break;
  160. /* Get number of sectors on the disk (DWORD) */
  161. case GET_SECTOR_COUNT:
  162. BSP_SD_GetCardInfo(&CardInfo);
  163. *(DWORD*)buff = CardInfo.LogBlockNbr;
  164. res = RES_OK;
  165. break;
  166. /* Get R/W sector size (WORD) */
  167. case GET_SECTOR_SIZE:
  168. BSP_SD_GetCardInfo(&CardInfo);
  169. *(WORD*)buff = CardInfo.LogBlockSize;
  170. res = RES_OK;
  171. break;
  172. /* Get erase block size in unit of sector (DWORD) */
  173. case GET_BLOCK_SIZE:
  174. BSP_SD_GetCardInfo(&CardInfo);
  175. *(DWORD*)buff = CardInfo.LogBlockSize;
  176. res = RES_OK;
  177. break;
  178. default:
  179. res = RES_PARERR;
  180. }
  181. furi_hal_spi_device_return(sd_spi_fast_dev);
  182. return res;
  183. /* USER CODE END IOCTL */
  184. }
  185. #endif /* _USE_IOCTL == 1 */
  186. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/