stm322xg_eval_sd.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /**
  2. ******************************************************************************
  3. * @file stm322xg_eval_sd.c
  4. * @author MCD Application Team
  5. * @brief This file includes the uSD card driver mounted on STM322xG-EVAL
  6. * evaluation board.
  7. ******************************************************************************
  8. * @attention
  9. *
  10. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  11. *
  12. * Redistribution and use in source and binary forms, with or without modification,
  13. * are permitted provided that the following conditions are met:
  14. * 1. Redistributions of source code must retain the above copyright notice,
  15. * this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright notice,
  17. * this list of conditions and the following disclaimer in the documentation
  18. * and/or other materials provided with the distribution.
  19. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  20. * may be used to endorse or promote products derived from this software
  21. * without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  27. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  29. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  30. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  31. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  32. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ******************************************************************************
  35. */
  36. /* File Info : -----------------------------------------------------------------
  37. User NOTES
  38. 1. How To use this driver:
  39. --------------------------
  40. - This driver is used to drive the micro SD external card mounted on STM322xG-EVAL
  41. evaluation board.
  42. - This driver does not need a specific component driver for the micro SD device
  43. to be included with.
  44. 2. Driver description:
  45. ---------------------
  46. + Initialization steps:
  47. o Initialize the micro SD card using the BSP_SD_Init() function. This
  48. function includes the MSP layer hardware resources initialization and the
  49. SDIO interface configuration to interface with the external micro SD. It
  50. also includes the micro SD initialization sequence.
  51. o To check the SD card presence you can use the function BSP_SD_IsDetected() which
  52. returns the detection status
  53. o If SD presence detection interrupt mode is desired, you must configure the
  54. SD detection interrupt mode by calling the function BSP_SD_ITConfig(). The interrupt
  55. is generated as an external interrupt whenever the micro SD card is
  56. plugged/unplugged in/from the evaluation board. The SD detection interrupt
  57. is handeled by calling the function BSP_SD_DetectIT() which is called in the IRQ
  58. handler file, the user callback is implemented in the function BSP_SD_DetectCallback().
  59. o The function BSP_SD_GetCardInfo() is used to get the micro SD card information
  60. which is stored in the structure "HAL_SD_CardInfoTypedef".
  61. + Micro SD card operations
  62. o The micro SD card can be accessed with read/write block(s) operations once
  63. it is ready for access. The access can be performed whether using the polling
  64. mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(), or by DMA
  65. transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA()
  66. o The DMA transfer complete is used with interrupt mode. Once the SD transfer
  67. is complete, the SD interrupt is handled using the function BSP_SD_IRQHandler(),
  68. the DMA Tx/Rx transfer complete are handled using the functions
  69. BSP_SD_DMA_Tx_IRQHandler()/BSP_SD_DMA_Rx_IRQHandler(). The corresponding user callbacks
  70. are implemented by the user at application level.
  71. o The SD erase block(s) is performed using the function BSP_SD_Erase() with specifying
  72. the number of blocks to erase.
  73. o The SD runtime status is returned when calling the function BSP_SD_GetCardState().
  74. ------------------------------------------------------------------------------*/
  75. /* Includes ------------------------------------------------------------------*/
  76. #include "stm322xg_eval_sd.h"
  77. /** @addtogroup BSP
  78. * @{
  79. */
  80. /** @addtogroup STM322xG_EVAL
  81. * @{
  82. */
  83. /** @defgroup STM322xG_EVAL_SD STM322xG EVAL SD
  84. * @{
  85. */
  86. /** @defgroup STM322xG_EVAL_SD_Private_Variables STM322xG EVAL SD Private Variables
  87. * @{
  88. */
  89. SD_HandleTypeDef uSdHandle;
  90. /**
  91. * @}
  92. */
  93. /** @defgroup STM322xG_EVAL_SD_Private_Functions STM322xG EVAL SD Private Functions
  94. * @{
  95. */
  96. /**
  97. * @brief Initializes the SD card device.
  98. * @retval SD status.
  99. */
  100. uint8_t BSP_SD_Init(void)
  101. {
  102. uint8_t SD_state = MSD_OK;
  103. /* uSD device interface configuration */
  104. uSdHandle.Instance = SDIO;
  105. uSdHandle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
  106. uSdHandle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
  107. uSdHandle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
  108. uSdHandle.Init.BusWide = SDIO_BUS_WIDE_1B;
  109. uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
  110. uSdHandle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV;
  111. /* Check if the SD card is plugged in the slot */
  112. if(BSP_SD_IsDetected() != SD_PRESENT)
  113. {
  114. return MSD_ERROR;
  115. }
  116. /* Msp SD initialization */
  117. BSP_SD_MspInit(&uSdHandle, NULL);
  118. if(HAL_SD_Init(&uSdHandle) != HAL_OK)
  119. {
  120. SD_state = MSD_ERROR;
  121. }
  122. /* Configure SD Bus width */
  123. if(SD_state == MSD_OK)
  124. {
  125. /* Enable wide operation */
  126. if(HAL_SD_ConfigWideBusOperation(&uSdHandle, SDIO_BUS_WIDE_4B) != HAL_OK)
  127. {
  128. SD_state = MSD_ERROR;
  129. }
  130. else
  131. {
  132. SD_state = MSD_OK;
  133. }
  134. }
  135. return SD_state;
  136. }
  137. /**
  138. * @brief Configures Interrupt mode for SD detection pin.
  139. * @retval Returns 0
  140. */
  141. uint8_t BSP_SD_ITConfig(void)
  142. {
  143. GPIO_InitTypeDef GPIO_Init_Structure;
  144. /* Configure Interrupt mode for SD detection pin */
  145. GPIO_Init_Structure.Mode = GPIO_MODE_IT_RISING_FALLING;
  146. GPIO_Init_Structure.Pull = GPIO_PULLUP;
  147. GPIO_Init_Structure.Speed = GPIO_SPEED_HIGH;
  148. GPIO_Init_Structure.Pin = SD_DETECT_PIN;
  149. HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_Init_Structure);
  150. /* NVIC configuration for SDIO interrupts */
  151. HAL_NVIC_SetPriority(SD_DETECT_IRQn, 0x0E, 0);
  152. HAL_NVIC_EnableIRQ(SD_DETECT_IRQn);
  153. return 0;
  154. }
  155. /**
  156. * @brief Detects if SD card is correctly plugged in the memory slot or not.
  157. * @retval Returns if SD is detected or not
  158. */
  159. uint8_t BSP_SD_IsDetected(void)
  160. {
  161. __IO uint8_t status = SD_PRESENT;
  162. /* Check SD card detect pin */
  163. if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != GPIO_PIN_RESET)
  164. {
  165. status = SD_NOT_PRESENT;
  166. }
  167. return status;
  168. }
  169. /**
  170. * @brief SD detect IT treatment
  171. */
  172. void BSP_SD_DetectIT(void)
  173. {
  174. /* SD detect IT callback */
  175. BSP_SD_DetectCallback();
  176. }
  177. /**
  178. * @brief SD detect IT detection callback
  179. */
  180. __weak void BSP_SD_DetectCallback(void)
  181. {
  182. /* NOTE: This function Should not be modified, when the callback is needed,
  183. the BSP_SD_DetectCallback could be implemented in the user file
  184. */
  185. }
  186. /**
  187. * @brief Reads block(s) from a specified address in an SD card, in polling mode.
  188. * @param pData: Pointer to the buffer that will contain the data to transmit
  189. * @param ReadAddr: Address from where data is to be read
  190. * @param NumOfBlocks: Number of SD blocks to read
  191. * @param Timeout: Timeout for read operation
  192. * @retval SD status
  193. */
  194. uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
  195. {
  196. if(HAL_SD_ReadBlocks(&uSdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout) != HAL_OK)
  197. {
  198. return MSD_ERROR;
  199. }
  200. else
  201. {
  202. return MSD_OK;
  203. }
  204. }
  205. /**
  206. * @brief Writes block(s) to a specified address in an SD card, in polling mode.
  207. * @param pData: Pointer to the buffer that will contain the data to transmit
  208. * @param WriteAddr: Address from where data is to be written
  209. * @param NumOfBlocks: Number of SD blocks to write
  210. * @param Timeout: Timeout for write operation
  211. * @retval SD status
  212. */
  213. uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
  214. {
  215. if(HAL_SD_WriteBlocks(&uSdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout) != HAL_OK)
  216. {
  217. return MSD_ERROR;
  218. }
  219. else
  220. {
  221. return MSD_OK;
  222. }
  223. }
  224. /**
  225. * @brief Reads block(s) from a specified address in an SD card, in DMA mode.
  226. * @param pData: Pointer to the buffer that will contain the data to transmit
  227. * @param ReadAddr: Address from where data is to be read
  228. * @param NumOfBlocks: Number of SD blocks to read
  229. * @retval SD status
  230. */
  231. uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
  232. {
  233. /* Read block(s) in DMA transfer mode */
  234. if(HAL_SD_ReadBlocks_DMA(&uSdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks) != HAL_OK)
  235. {
  236. return MSD_ERROR;
  237. }
  238. else
  239. {
  240. return MSD_OK;
  241. }
  242. }
  243. /**
  244. * @brief Writes block(s) to a specified address in an SD card, in DMA mode.
  245. * @param pData: Pointer to the buffer that will contain the data to transmit
  246. * @param WriteAddr: Address from where data is to be written
  247. * @param NumOfBlocks: Number of SD blocks to write
  248. * @retval SD status
  249. */
  250. uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
  251. {
  252. /* Write block(s) in DMA transfer mode */
  253. if(HAL_SD_WriteBlocks_DMA(&uSdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks) != HAL_OK)
  254. {
  255. return MSD_ERROR;
  256. }
  257. else
  258. {
  259. return MSD_OK;
  260. }
  261. }
  262. /**
  263. * @brief Erases the specified memory area of the given SD card.
  264. * @param StartAddr: Start byte address
  265. * @param EndAddr: End byte address
  266. * @retval SD status
  267. */
  268. uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr)
  269. {
  270. if(HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr) != HAL_OK)
  271. {
  272. return MSD_ERROR;
  273. }
  274. else
  275. {
  276. return MSD_OK;
  277. }
  278. }
  279. /**
  280. * @brief Initializes the SD MSP.
  281. * @param hsd: SD handle
  282. * @param Params : pointer on additional configuration parameters, can be NULL.
  283. */
  284. __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params)
  285. {
  286. static DMA_HandleTypeDef dmaRxHandle;
  287. static DMA_HandleTypeDef dmaTxHandle;
  288. GPIO_InitTypeDef GPIO_Init_Structure;
  289. /* Enable SDIO clock */
  290. __HAL_RCC_SDIO_CLK_ENABLE();
  291. /* Enable DMA2 clocks */
  292. __DMAx_TxRx_CLK_ENABLE();
  293. /* Enable GPIOs clock */
  294. __HAL_RCC_GPIOC_CLK_ENABLE();
  295. __HAL_RCC_GPIOD_CLK_ENABLE();
  296. __SD_DETECT_GPIO_CLK_ENABLE();
  297. /* Common GPIO configuration */
  298. GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP;
  299. GPIO_Init_Structure.Pull = GPIO_PULLUP;
  300. GPIO_Init_Structure.Speed = GPIO_SPEED_HIGH;
  301. GPIO_Init_Structure.Alternate = GPIO_AF12_SDIO;
  302. /* GPIOC configuration */
  303. GPIO_Init_Structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
  304. HAL_GPIO_Init(GPIOC, &GPIO_Init_Structure);
  305. /* GPIOD configuration */
  306. GPIO_Init_Structure.Pin = GPIO_PIN_2;
  307. HAL_GPIO_Init(GPIOD, &GPIO_Init_Structure);
  308. /* SD Card detect pin configuration */
  309. GPIO_Init_Structure.Mode = GPIO_MODE_INPUT;
  310. GPIO_Init_Structure.Pull = GPIO_PULLUP;
  311. GPIO_Init_Structure.Speed = GPIO_SPEED_HIGH;
  312. GPIO_Init_Structure.Pin = SD_DETECT_PIN;
  313. HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_Init_Structure);
  314. /* NVIC configuration for SDIO interrupts */
  315. HAL_NVIC_SetPriority(SDIO_IRQn, 0x0E, 0);
  316. HAL_NVIC_EnableIRQ(SDIO_IRQn);
  317. /* Configure DMA Rx parameters */
  318. dmaRxHandle.Init.Channel = SD_DMAx_Rx_CHANNEL;
  319. dmaRxHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
  320. dmaRxHandle.Init.PeriphInc = DMA_PINC_DISABLE;
  321. dmaRxHandle.Init.MemInc = DMA_MINC_ENABLE;
  322. dmaRxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  323. dmaRxHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  324. dmaRxHandle.Init.Mode = DMA_PFCTRL;
  325. dmaRxHandle.Init.Priority = DMA_PRIORITY_VERY_HIGH;
  326. dmaRxHandle.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  327. dmaRxHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  328. dmaRxHandle.Init.MemBurst = DMA_MBURST_INC4;
  329. dmaRxHandle.Init.PeriphBurst = DMA_PBURST_INC4;
  330. dmaRxHandle.Instance = SD_DMAx_Rx_STREAM;
  331. /* Associate the DMA handle */
  332. __HAL_LINKDMA(hsd, hdmarx, dmaRxHandle);
  333. /* Deinitialize the stream for new transfer */
  334. HAL_DMA_DeInit(&dmaRxHandle);
  335. /* Configure the DMA stream */
  336. HAL_DMA_Init(&dmaRxHandle);
  337. /* Configure DMA Tx parameters */
  338. dmaTxHandle.Init.Channel = SD_DMAx_Tx_CHANNEL;
  339. dmaTxHandle.Init.Direction = DMA_MEMORY_TO_PERIPH;
  340. dmaTxHandle.Init.PeriphInc = DMA_PINC_DISABLE;
  341. dmaTxHandle.Init.MemInc = DMA_MINC_ENABLE;
  342. dmaTxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  343. dmaTxHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  344. dmaTxHandle.Init.Mode = DMA_PFCTRL;
  345. dmaTxHandle.Init.Priority = DMA_PRIORITY_VERY_HIGH;
  346. dmaTxHandle.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  347. dmaTxHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  348. dmaTxHandle.Init.MemBurst = DMA_MBURST_INC4;
  349. dmaTxHandle.Init.PeriphBurst = DMA_PBURST_INC4;
  350. dmaTxHandle.Instance = SD_DMAx_Tx_STREAM;
  351. /* Associate the DMA handle */
  352. __HAL_LINKDMA(hsd, hdmatx, dmaTxHandle);
  353. /* Deinitialize the stream for new transfer */
  354. HAL_DMA_DeInit(&dmaTxHandle);
  355. /* Configure the DMA stream */
  356. HAL_DMA_Init(&dmaTxHandle);
  357. /* NVIC configuration for DMA transfer complete interrupt */
  358. HAL_NVIC_SetPriority(SD_DMAx_Rx_IRQn, 0x0F, 0);
  359. HAL_NVIC_EnableIRQ(SD_DMAx_Rx_IRQn);
  360. /* NVIC configuration for DMA transfer complete interrupt */
  361. HAL_NVIC_SetPriority(SD_DMAx_Tx_IRQn, 0x0F, 0);
  362. HAL_NVIC_EnableIRQ(SD_DMAx_Tx_IRQn);
  363. }
  364. /**
  365. * @brief Gets the current SD card data status.
  366. * @retval Data transfer state.
  367. * This value can be one of the following values:
  368. * @arg SD_TRANSFER_OK: No data transfer is acting
  369. * @arg SD_TRANSFER_BUSY: Data transfer is acting
  370. */
  371. uint8_t BSP_SD_GetCardState(void)
  372. {
  373. return((HAL_SD_GetCardState(&uSdHandle) == HAL_SD_CARD_TRANSFER ) ? SD_TRANSFER_OK : SD_TRANSFER_BUSY);
  374. }
  375. /**
  376. * @brief Get SD information about specific SD card.
  377. * @param CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
  378. * @retval None
  379. */
  380. void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypeDef *CardInfo)
  381. {
  382. /* Get SD card Information */
  383. HAL_SD_GetCardInfo(&uSdHandle, CardInfo);
  384. }
  385. /**
  386. * @brief SD Abort callbacks
  387. * @param hsd: SD handle
  388. * @retval None
  389. */
  390. void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
  391. {
  392. BSP_SD_AbortCallback();
  393. }
  394. /**
  395. * @brief Tx Transfer completed callbacks
  396. * @param hsd: SD handle
  397. * @retval None
  398. */
  399. void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
  400. {
  401. BSP_SD_WriteCpltCallback();
  402. }
  403. /**
  404. * @brief Rx Transfer completed callbacks
  405. * @param hsd: SD handle
  406. * @retval None
  407. */
  408. void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
  409. {
  410. BSP_SD_ReadCpltCallback();
  411. }
  412. /**
  413. * @brief BSP SD Abort callbacks
  414. * @retval None
  415. */
  416. __weak void BSP_SD_AbortCallback(void)
  417. {
  418. }
  419. /**
  420. * @brief BSP Tx Transfer completed callbacks
  421. * @retval None
  422. */
  423. __weak void BSP_SD_WriteCpltCallback(void)
  424. {
  425. }
  426. /**
  427. * @brief BSP Rx Transfer completed callbacks
  428. * @retval None
  429. */
  430. __weak void BSP_SD_ReadCpltCallback(void)
  431. {
  432. }
  433. /**
  434. * @}
  435. */
  436. /**
  437. * @}
  438. */
  439. /**
  440. * @}
  441. */
  442. /**
  443. * @}
  444. */
  445. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/