You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
6.4 KiB

3 months ago
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file usbh_diskio.c (based on usbh_diskio_template.c v2.0.2)
  5. * @brief USB Host Disk I/O driver
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2024 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* USER CODE BEGIN firstSection */
  20. /* can be used to modify / undefine following code or add new definitions */
  21. /* USER CODE END firstSection */
  22. /* Includes ------------------------------------------------------------------*/
  23. #include "ff_gen_drv.h"
  24. #include "usbh_diskio.h"
  25. /* Private typedef -----------------------------------------------------------*/
  26. /* Private define ------------------------------------------------------------*/
  27. #define USB_DEFAULT_BLOCK_SIZE 512
  28. /* Private variables ---------------------------------------------------------*/
  29. extern USBH_HandleTypeDef hUSB_Host;
  30. /* Private function prototypes -----------------------------------------------*/
  31. DSTATUS USBH_initialize (BYTE);
  32. DSTATUS USBH_status (BYTE);
  33. DRESULT USBH_read (BYTE, BYTE*, DWORD, UINT);
  34. #if _USE_WRITE == 1
  35. DRESULT USBH_write (BYTE, const BYTE*, DWORD, UINT);
  36. #endif /* _USE_WRITE == 1 */
  37. #if _USE_IOCTL == 1
  38. DRESULT USBH_ioctl (BYTE, BYTE, void*);
  39. #endif /* _USE_IOCTL == 1 */
  40. const Diskio_drvTypeDef USBH_Driver =
  41. {
  42. USBH_initialize,
  43. USBH_status,
  44. USBH_read,
  45. #if _USE_WRITE == 1
  46. USBH_write,
  47. #endif /* _USE_WRITE == 1 */
  48. #if _USE_IOCTL == 1
  49. USBH_ioctl,
  50. #endif /* _USE_IOCTL == 1 */
  51. };
  52. /* USER CODE BEGIN beforeFunctionSection */
  53. /* can be used to modify / undefine following code or add new code */
  54. /* USER CODE END beforeFunctionSection */
  55. /* Private functions ---------------------------------------------------------*/
  56. /**
  57. * @brief Initializes a Drive
  58. * @param lun : lun id
  59. * @retval DSTATUS: Operation status
  60. */
  61. DSTATUS USBH_initialize(BYTE lun)
  62. {
  63. /* CAUTION : USB Host library has to be initialized in the application */
  64. return RES_OK;
  65. }
  66. /**
  67. * @brief Gets Disk Status
  68. * @param lun : lun id
  69. * @retval DSTATUS: Operation status
  70. */
  71. DSTATUS USBH_status(BYTE lun)
  72. {
  73. DRESULT res = RES_ERROR;
  74. if(USBH_MSC_UnitIsReady(&hUSB_Host, lun))
  75. {
  76. res = RES_OK;
  77. }
  78. else
  79. {
  80. res = RES_ERROR;
  81. }
  82. return res;
  83. }
  84. /* USER CODE BEGIN beforeReadSection */
  85. /* can be used to modify previous code / undefine following code / add new code */
  86. /* USER CODE END beforeReadSection */
  87. /**
  88. * @brief Reads Sector(s)
  89. * @param lun : lun id
  90. * @param *buff: Data buffer to store read data
  91. * @param sector: Sector address (LBA)
  92. * @param count: Number of sectors to read (1..128)
  93. * @retval DRESULT: Operation result
  94. */
  95. DRESULT USBH_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
  96. {
  97. DRESULT res = RES_ERROR;
  98. MSC_LUNTypeDef info;
  99. if(USBH_MSC_Read(&hUSB_Host, lun, sector, buff, count) == USBH_OK)
  100. {
  101. res = RES_OK;
  102. }
  103. else
  104. {
  105. USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info);
  106. switch (info.sense.asc)
  107. {
  108. case SCSI_ASC_LOGICAL_UNIT_NOT_READY:
  109. case SCSI_ASC_MEDIUM_NOT_PRESENT:
  110. case SCSI_ASC_NOT_READY_TO_READY_CHANGE:
  111. USBH_ErrLog ("USB Disk is not ready!");
  112. res = RES_NOTRDY;
  113. break;
  114. default:
  115. res = RES_ERROR;
  116. break;
  117. }
  118. }
  119. return res;
  120. }
  121. /* USER CODE BEGIN beforeWriteSection */
  122. /* can be used to modify previous code / undefine following code / add new code */
  123. /* USER CODE END beforeWriteSection */
  124. /**
  125. * @brief Writes Sector(s)
  126. * @param lun : lun id
  127. * @param *buff: Data to be written
  128. * @param sector: Sector address (LBA)
  129. * @param count: Number of sectors to write (1..128)
  130. * @retval DRESULT: Operation result
  131. */
  132. #if _USE_WRITE == 1
  133. DRESULT USBH_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
  134. {
  135. DRESULT res = RES_ERROR;
  136. MSC_LUNTypeDef info;
  137. if(USBH_MSC_Write(&hUSB_Host, lun, sector, (BYTE *)buff, count) == USBH_OK)
  138. {
  139. res = RES_OK;
  140. }
  141. else
  142. {
  143. USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info);
  144. switch (info.sense.asc)
  145. {
  146. case SCSI_ASC_WRITE_PROTECTED:
  147. USBH_ErrLog("USB Disk is Write protected!");
  148. res = RES_WRPRT;
  149. break;
  150. case SCSI_ASC_LOGICAL_UNIT_NOT_READY:
  151. case SCSI_ASC_MEDIUM_NOT_PRESENT:
  152. case SCSI_ASC_NOT_READY_TO_READY_CHANGE:
  153. USBH_ErrLog("USB Disk is not ready!");
  154. res = RES_NOTRDY;
  155. break;
  156. default:
  157. res = RES_ERROR;
  158. break;
  159. }
  160. }
  161. return res;
  162. }
  163. #endif /* _USE_WRITE == 1 */
  164. /* USER CODE BEGIN beforeIoctlSection */
  165. /* can be used to modify previous code / undefine following code / add new code */
  166. /* USER CODE END beforeIoctlSection */
  167. /**
  168. * @brief I/O control operation
  169. * @param lun : lun id
  170. * @param cmd: Control code
  171. * @param *buff: Buffer to send/receive control data
  172. * @retval DRESULT: Operation result
  173. */
  174. #if _USE_IOCTL == 1
  175. DRESULT USBH_ioctl(BYTE lun, BYTE cmd, void *buff)
  176. {
  177. DRESULT res = RES_ERROR;
  178. MSC_LUNTypeDef info;
  179. switch (cmd)
  180. {
  181. /* Make sure that no pending write process */
  182. case CTRL_SYNC:
  183. res = RES_OK;
  184. break;
  185. /* Get number of sectors on the disk (DWORD) */
  186. case GET_SECTOR_COUNT :
  187. if(USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info) == USBH_OK)
  188. {
  189. *(DWORD*)buff = info.capacity.block_nbr;
  190. res = RES_OK;
  191. }
  192. else
  193. {
  194. res = RES_ERROR;
  195. }
  196. break;
  197. /* Get R/W sector size (WORD) */
  198. case GET_SECTOR_SIZE :
  199. if(USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info) == USBH_OK)
  200. {
  201. *(DWORD*)buff = info.capacity.block_size;
  202. res = RES_OK;
  203. }
  204. else
  205. {
  206. res = RES_ERROR;
  207. }
  208. break;
  209. /* Get erase block size in unit of sector (DWORD) */
  210. case GET_BLOCK_SIZE :
  211. if(USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info) == USBH_OK)
  212. {
  213. *(DWORD*)buff = info.capacity.block_size / USB_DEFAULT_BLOCK_SIZE;
  214. res = RES_OK;
  215. }
  216. else
  217. {
  218. res = RES_ERROR;
  219. }
  220. break;
  221. default:
  222. res = RES_PARERR;
  223. }
  224. return res;
  225. }
  226. #endif /* _USE_IOCTL == 1 */
  227. /* USER CODE BEGIN lastSection */
  228. /* can be used to modify / undefine previous code or add new code */
  229. /* USER CODE END lastSection */