2 ******************************************************************************
3 * @file bsp_driver_sd.c (based on stm324x9i_eval_sd.c)
4 * @brief This file includes a generic uSD card driver.
5 ******************************************************************************
7 * COPYRIGHT(c) 2016 STMicroelectronics
9 * Redistribution and use in source and binary forms, with or without modification,
10 * are permitted provided that the following conditions are met:
11 * 1. Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 * 3. Neither the name of STMicroelectronics nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ******************************************************************************
34 /* USER CODE BEGIN 0 */
35 /* Includes ------------------------------------------------------------------*/
36 #include "bsp_driver_sd.h"
38 /* Extern variables ---------------------------------------------------------*/
40 extern SD_HandleTypeDef hsd;
43 * @brief Initializes the SD card device.
47 uint8_t BSP_SD_Init(void)
49 uint8_t SD_state = MSD_OK;
50 /* Check if the SD card is plugged in the slot */
51 if (BSP_SD_IsDetected() != SD_PRESENT)
55 SD_state = HAL_SD_Init(&hsd);
57 if (SD_state == MSD_OK)
59 if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
67 // Clock bypass mode is broken on STM32F205
68 // This just corrupts data for now.
71 uint8_t SD_hs[64] = {0};
72 //uint32_t SD_scr[2] = {0, 0};
73 //uint32_t SD_SPEC = 0 ;
75 uint32_t *tempbuff = (uint32_t *)SD_hs;
77 // Prepare to read 64 bytes training data
78 SDIO_DataInitTypeDef config;
79 config.DataTimeOut = SDMMC_DATATIMEOUT;
80 config.DataLength = 64;
81 config.DataBlockSize = SDIO_DATABLOCK_SIZE_64B;
82 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
83 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
84 config.DPSM = SDIO_DPSM_ENABLE;
85 (void)SDIO_ConfigData(hsd.Instance, &config);
88 // SDR25 (25MB/s) mode 0x80FFFF01
89 // Which is the max without going to 1.8v
90 uint32_t errorstate = SDMMC_CmdSwitch(hsd.Instance, 0x80FFFF01);
92 // Low-level init for the bypass. Changes registers only
93 hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_ENABLE;
94 SDIO_Init(hsd.Instance, hsd.Init);
96 // Now we read some training data
98 if (errorstate == HAL_SD_ERROR_NONE)
100 while(!__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND/* | SDIO_FLAG_STBITERR*/))
102 if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_RXFIFOHF))
104 for (count = 0; count < 8; count++)
106 *(tempbuff + count) = SDIO_ReadFIFO(hsd.Instance);
113 if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_DTIMEOUT))
115 __HAL_SD_CLEAR_FLAG(&hsd, SDIO_FLAG_DTIMEOUT);
116 SD_state = MSD_ERROR;
118 else if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_DCRCFAIL))
120 __HAL_SD_CLEAR_FLAG(&hsd, SDIO_FLAG_DCRCFAIL);
121 SD_state = MSD_ERROR;
123 else if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_RXOVERR))
125 __HAL_SD_CLEAR_FLAG(&hsd, SDIO_FLAG_RXOVERR);
126 SD_state = MSD_ERROR;
128 /*else if (__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_STBITERR))
130 __HAL_SD_CLEAR_FLAG(&hsd, SDIO_FLAG_STBITERR);
131 SD_state = MSD_ERROR;
135 count = SD_DATATIMEOUT;
137 while ((__HAL_SD_GET_FLAG(&hsd, SDIO_FLAG_RXDAVL)) && (count > 0))
139 *tempbuff = SDIO_ReadFIFO(hsd.Instance);
144 /* Clear all the static flags */
145 __HAL_SD_CLEAR_FLAG(&hsd, SDIO_STATIC_FLAGS);
156 * @brief Configures Interrupt mode for SD detection pin.
158 * @retval Returns 0 in success otherwise 1.
160 uint8_t BSP_SD_ITConfig(void)
162 /* TBI: add user code here depending on the hardware configuration used */
167 /** @brief SD detect IT treatment
171 void BSP_SD_DetectIT(void)
173 /* TBI: add user code here depending on the hardware configuration used */
176 /** @brief SD detect IT detection callback
180 __weak void BSP_SD_DetectCallback(void)
182 /* NOTE: This function Should not be modified, when the callback is needed,
183 the SD_DetectCallback could be implemented in the user file
189 * @brief Reads block(s) from a specified address in an SD card, in polling mode.
190 * @param pData: Pointer to the buffer that will contain the data to transmit
191 * @param BlockAddr: Address from where data is to be read
192 * @param NumOfBlocks: Number of SD blocks to read
196 uint8_t BSP_SD_ReadBlocks(uint8_t *pData, uint64_t BlockAddr, uint32_t NumOfBlocks)
198 if(HAL_SD_ReadBlocks_DMA(&hsd, pData, BlockAddr, NumOfBlocks) != HAL_OK)
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 BlockAddr: Address from where data is to be written
209 * @param NumOfBlocks: Number of SD blocks to write
212 /*uint8_t BSP_SD_WriteBlocks(uint8_t *pData, uint64_t BlockAddr, uint32_t NumOfBlocks)
214 if(HAL_SD_WriteBlocks_DMA(&hsd, pData, BlockAddr, NumOfBlocks) != HAL_OK)
222 * @brief Reads block(s) from a specified address in an SD card, in DMA mode.
223 * @param pData: Pointer to the buffer that will contain the data to transmit
224 * @param BlockAddr: Address from where data is to be read
225 * @param NumOfBlocks: Number of SD blocks to read
228 uint8_t BSP_SD_ReadBlocks_DMA(uint8_t *pData, uint64_t BlockAddr, uint32_t NumOfBlocks)
230 uint8_t SD_state = MSD_OK;
232 /* Read block(s) in DMA transfer mode */
233 if(HAL_SD_ReadBlocks_DMA(&hsd, pData, BlockAddr, NumOfBlocks) != HAL_OK)
235 SD_state = MSD_ERROR;
238 /* Wait until transfer is complete */
239 if(SD_state == MSD_OK)
241 while (HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY) {}
243 if(HAL_SD_GetState(&hsd) == HAL_SD_STATE_ERROR)
245 SD_state = MSD_ERROR;
257 * @brief Writes block(s) to a specified address in an SD card, in DMA mode.
258 * @param pData: Pointer to the buffer that will contain the data to transmit
259 * @param BlockAddr: Address from where data is to be written
260 * @param NumOfBlocks: Number of SD blocks to write
263 uint8_t BSP_SD_WriteBlocks_DMA(uint8_t *pData, uint64_t BlockAddr, uint32_t NumOfBlocks)
265 uint8_t SD_state = MSD_OK;
267 /* Write block(s) in DMA transfer mode */
268 if(HAL_SD_WriteBlocks_DMA(&hsd, pData, BlockAddr, NumOfBlocks) != HAL_OK)
270 SD_state = MSD_ERROR;
273 /* Wait until transfer is complete */
274 if(SD_state == MSD_OK)
276 while (HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY) {}
278 if(HAL_SD_GetState(&hsd) == HAL_SD_STATE_ERROR)
280 SD_state = MSD_ERROR;
287 HAL_SD_CardStateTypeDef cardState = HAL_SD_GetCardState(&hsd);
288 while (cardState == HAL_SD_CARD_PROGRAMMING || cardState == HAL_SD_CARD_RECEIVING)
290 // Wait while the SD card is writing buffer to flash
291 // The card may remain in the RECEIVING state (even though it's programming) if
292 // it has buffer space to receive more data available.
294 cardState = HAL_SD_GetCardState(&hsd);
303 * @brief Erases the specified memory area of the given SD card.
304 * @param StartAddr: Start byte address
305 * @param EndAddr: End byte address
309 uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr)
311 if(HAL_SD_Erase(&hsd, StartAddr, EndAddr) != SD_OK)
321 * @brief Handles SD card interrupt request.
325 /*void BSP_SD_IRQHandler(void)
327 HAL_SD_IRQHandler(&hsd);
331 * @brief Handles SD DMA Tx transfer interrupt request.
335 /*void BSP_SD_DMA_Tx_IRQHandler(void)
337 HAL_DMA_IRQHandler(hsd.hdmatx);
341 * @brief Handles SD DMA Rx transfer interrupt request.
346 void BSP_SD_DMA_Rx_IRQHandler(void)
348 HAL_DMA_IRQHandler(hsd.hdmarx);
352 * @brief Gets the current SD card data status.
354 * @retval Data transfer state.
355 * This value can be one of the following values:
356 * @arg SD_TRANSFER_OK: No data transfer is acting
357 * @arg SD_TRANSFER_BUSY: Data transfer is acting
358 * @arg SD_TRANSFER_ERROR: Data transfer error
360 HAL_SD_CardStateTypeDef BSP_SD_GetStatus(void)
362 return(HAL_SD_GetState(&hsd));
366 * @brief Get SD information about specific SD card.
367 * @param CardInfo: Pointer to HAL_SD_CardInfoTypeDef structure
370 void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypeDef* CardInfo)
372 /* Get SD card Information */
373 HAL_SD_GetCardInfo(&hsd, CardInfo);
375 /* USER CODE END 0 */
378 * @brief Detects if SD card is correctly plugged in the memory slot or not.
380 * @retval Returns if SD is detected or not
382 uint8_t BSP_SD_IsDetected(void)
384 __IO uint8_t status = SD_PRESENT;
386 /* USER CODE BEGIN 1 */
387 /* user code can be inserted here */
388 /* USER CODE END 1 */
393 /* USER CODE BEGIN AdditionalCode */
394 /* user code can be inserted here */
395 /* USER CODE END AdditionalCode */
397 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/