STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
stm32f769i_discovery_sd.c
Go to the documentation of this file.
1 
39 /* File Info : -----------------------------------------------------------------
40  User NOTES
41 1. How To use this driver:
42 --------------------------
43  - This driver is used to drive the micro SD external card mounted on STM32F769I-Discovery
44  board.
45  - This driver does not need a specific component driver for the micro SD device
46  to be included with.
47 
48 2. Driver description:
49 ---------------------
50  + Initialization steps:
51  o Initialize the micro SD card using the BSP_SD_Init() function. This
52  function includes the MSP layer hardware resources initialization and the
53  SDIO interface configuration to interface with the external micro SD. It
54  also includes the micro SD initialization sequence.
55  o To check the SD card presence you can use the function BSP_SD_IsDetected() which
56  returns the detection status
57  o If SD presence detection interrupt mode is desired, you must configure the
58  SD detection interrupt mode by calling the function BSP_SD_ITConfig(). The interrupt
59  is generated as an external interrupt whenever the micro SD card is
60  plugged/unplugged in/from the discovery board. The SD detection interrupt
61  is handled by calling the function BSP_SD_DetectIT() which is called in the IRQ
62  handler file, the user callback is implemented in the function BSP_SD_DetectCallback().
63  o The function BSP_SD_GetCardInfo() is used to get the micro SD card information
64  which is stored in the structure "HAL_SD_CardInfoTypedef".
65 
66  + Micro SD card operations
67  o The micro SD card can be accessed with read/write block(s) operations once
68  it is reay for access. The access cand be performed whether using the polling
69  mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(), or by DMA
70  transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA()
71  o The DMA transfer complete is used with interrupt mode. Once the SD transfer
72  is complete, the SD interrupt is handeled using the function BSP_SD_IRQHandler(),
73  the DMA Tx/Rx transfer complete are handeled using the functions
74  BSP_SD_DMA_Tx_IRQHandler()/BSP_SD_DMA_Rx_IRQHandler(). The corresponding user callbacks
75  are implemented by the user at application level.
76  o The SD erase block(s) is performed using the function BSP_SD_Erase() with specifying
77  the number of blocks to erase.
78  o The SD runtime status is returned when calling the function BSP_SD_GetStatus().
79 
80 ------------------------------------------------------------------------------*/
81 
82 /* Includes ------------------------------------------------------------------*/
84 
123 static SD_CardInfo uSdCardInfo;
124 
144 uint8_t BSP_SD_Init(void)
145 {
146  uint8_t sd_state = MSD_OK;
147 
148  /* PLLSAI is dedicated to LCD periph. Do not use it to get 48MHz*/
149 
150  /* uSD device interface configuration */
151  uSdHandle.Instance = SDMMC2;
152  uSdHandle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
153  uSdHandle.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
154  uSdHandle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
155  uSdHandle.Init.BusWide = SDMMC_BUS_WIDE_1B;
156  uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
157  uSdHandle.Init.ClockDiv = SDMMC_TRANSFER_CLK_DIV;
158 
159  /* Msp SD Detect pin initialization */
160  BSP_SD_Detect_MspInit(&uSdHandle, NULL);
161  if(BSP_SD_IsDetected() != SD_PRESENT) /* Check if SD card is present */
162  {
164  }
165 
166  /* Msp SD initialization */
167  BSP_SD_MspInit(&uSdHandle, NULL);
168 
169  /* HAL SD initialization */
170  if(HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK)
171  {
172  sd_state = MSD_ERROR;
173  }
174 
175  /* Configure SD Bus width */
176  if(sd_state == MSD_OK)
177  {
178  /* Enable wide operation */
180  {
181  sd_state = MSD_ERROR;
182  }
183  else
184  {
185  sd_state = MSD_OK;
186  }
187  }
188  return sd_state;
189 }
190 
195 uint8_t BSP_SD_DeInit(void)
196 {
197  uint8_t sd_state = MSD_OK;
198 
199  uSdHandle.Instance = SDMMC2;
200 
201  /* HAL SD deinitialization */
202  if(HAL_SD_DeInit(&uSdHandle) != HAL_OK)
203  {
204  sd_state = MSD_ERROR;
205  }
206 
207  /* Msp SD deinitialization */
208  uSdHandle.Instance = SDMMC2;
209  BSP_SD_MspDeInit(&uSdHandle, NULL);
210 
211  return sd_state;
212 }
213 
218 uint8_t BSP_SD_ITConfig(void)
219 {
220  GPIO_InitTypeDef gpio_init_structure;
221 
222  /* Configure Interrupt mode for SD detection pin */
223  gpio_init_structure.Pin = SD_DETECT_PIN;
224  gpio_init_structure.Pull = GPIO_PULLUP;
225  gpio_init_structure.Speed = GPIO_SPEED_FAST;
226  gpio_init_structure.Mode = GPIO_MODE_IT_RISING_FALLING;
227  HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &gpio_init_structure);
228 
229  /* Enable and set SD detect EXTI Interrupt to the lowest priority */
232 
233  return MSD_OK;
234 }
235 
240 uint8_t BSP_SD_IsDetected(void)
241 {
242  __IO uint8_t status = SD_PRESENT;
243 
244  /* Check SD card detect pin */
246  {
247  status = SD_NOT_PRESENT;
248  }
249 
250  return status;
251 }
252 
253 
254 
263 uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
264 {
265  if(HAL_SD_ReadBlocks(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK)
266  {
267  return MSD_ERROR;
268  }
269  else
270  {
271  return MSD_OK;
272  }
273 }
274 
283 uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
284 {
285  if(HAL_SD_WriteBlocks(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK)
286  {
287  return MSD_ERROR;
288  }
289  else
290  {
291  return MSD_OK;
292  }
293 }
294 
303 uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
304 {
305  uint8_t sd_state = MSD_OK;
306 
307  /* Read block(s) in DMA transfer mode */
308  if(HAL_SD_ReadBlocks_DMA(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK)
309  {
310  sd_state = MSD_ERROR;
311  }
312 
313  /* Wait until transfer is complete */
314  if(sd_state == MSD_OK)
315  {
316  if(HAL_SD_CheckReadOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK)
317  {
318  sd_state = MSD_ERROR;
319  }
320  else
321  {
322  sd_state = MSD_OK;
323  }
324  }
325 
326  return sd_state;
327 }
328 
337 uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
338 {
339  uint8_t sd_state = MSD_OK;
340 
341  /* Write block(s) in DMA transfer mode */
342  if(HAL_SD_WriteBlocks_DMA(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK)
343  {
344  sd_state = MSD_ERROR;
345  }
346 
347  /* Wait until transfer is complete */
348  if(sd_state == MSD_OK)
349  {
350  if(HAL_SD_CheckWriteOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK)
351  {
352  sd_state = MSD_ERROR;
353  }
354  else
355  {
356  sd_state = MSD_OK;
357  }
358  }
359 
360  return sd_state;
361 }
362 
369 uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr)
370 {
371  if(HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr) != SD_OK)
372  {
373  return MSD_ERROR;
374  }
375  else
376  {
377  return MSD_OK;
378  }
379 }
380 
386 __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params)
387 {
388  static DMA_HandleTypeDef dma_rx_handle;
389  static DMA_HandleTypeDef dma_tx_handle;
390  GPIO_InitTypeDef gpio_init_structure;
391 
392  /* Enable SDMMC2 clock */
393  __HAL_RCC_SDMMC2_CLK_ENABLE();
394 
395  /* Enable DMA2 clocks */
397 
398  /* Enable GPIOs clock */
402 
403  /* Common GPIO configuration */
404  gpio_init_structure.Mode = GPIO_MODE_AF_PP;
405  gpio_init_structure.Pull = GPIO_PULLUP;
406  gpio_init_structure.Speed = GPIO_SPEED_HIGH;
407 
408  /* GPIOB configuration */
409  gpio_init_structure.Alternate = GPIO_AF10_SDMMC2;
410  gpio_init_structure.Pin = GPIO_PIN_3 | GPIO_PIN_4;
411  HAL_GPIO_Init(GPIOB, &gpio_init_structure);
412 
413  /* GPIOD configuration */
414  gpio_init_structure.Alternate = GPIO_AF11_SDMMC2;
415  gpio_init_structure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
416  HAL_GPIO_Init(GPIOD, &gpio_init_structure);
417 
418  /* GPIOG configuration */
419  gpio_init_structure.Pin = GPIO_PIN_9 | GPIO_PIN_10;
420  HAL_GPIO_Init(GPIOG, &gpio_init_structure);
421 
422  /* NVIC configuration for SDMMC2 interrupts */
425 
426  /* Configure DMA Rx parameters */
427  dma_rx_handle.Init.Channel = SD_DMAx_Rx_CHANNEL;
428  dma_rx_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
429  dma_rx_handle.Init.PeriphInc = DMA_PINC_DISABLE;
430  dma_rx_handle.Init.MemInc = DMA_MINC_ENABLE;
432  dma_rx_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
433  dma_rx_handle.Init.Mode = DMA_PFCTRL;
434  dma_rx_handle.Init.Priority = DMA_PRIORITY_VERY_HIGH;
435  dma_rx_handle.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
437  dma_rx_handle.Init.MemBurst = DMA_MBURST_INC4;
438  dma_rx_handle.Init.PeriphBurst = DMA_PBURST_INC4;
439 
440  dma_rx_handle.Instance = SD_DMAx_Rx_STREAM;
441 
442  /* Associate the DMA handle */
443  __HAL_LINKDMA(hsd, hdmarx, dma_rx_handle);
444 
445  /* Deinitialize the stream for new transfer */
446  HAL_DMA_DeInit(&dma_rx_handle);
447 
448  /* Configure the DMA stream */
449  HAL_DMA_Init(&dma_rx_handle);
450 
451  /* Configure DMA Tx parameters */
452  dma_tx_handle.Init.Channel = SD_DMAx_Tx_CHANNEL;
453  dma_tx_handle.Init.Direction = DMA_MEMORY_TO_PERIPH;
454  dma_tx_handle.Init.PeriphInc = DMA_PINC_DISABLE;
455  dma_tx_handle.Init.MemInc = DMA_MINC_ENABLE;
457  dma_tx_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
458  dma_tx_handle.Init.Mode = DMA_PFCTRL;
459  dma_tx_handle.Init.Priority = DMA_PRIORITY_VERY_HIGH;
460  dma_tx_handle.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
462  dma_tx_handle.Init.MemBurst = DMA_MBURST_INC4;
463  dma_tx_handle.Init.PeriphBurst = DMA_PBURST_INC4;
464 
465  dma_tx_handle.Instance = SD_DMAx_Tx_STREAM;
466 
467  /* Associate the DMA handle */
468  __HAL_LINKDMA(hsd, hdmatx, dma_tx_handle);
469 
470  /* Deinitialize the stream for new transfer */
471  HAL_DMA_DeInit(&dma_tx_handle);
472 
473  /* Configure the DMA stream */
474  HAL_DMA_Init(&dma_tx_handle);
475 
476  /* NVIC configuration for DMA transfer complete interrupt */
479 
480  /* NVIC configuration for DMA transfer complete interrupt */
483 }
484 
490 __weak void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params)
491 {
492  GPIO_InitTypeDef gpio_init_structure;
493 
495 
496  /* GPIO configuration in input for uSD_Detect signal */
497  gpio_init_structure.Pin = SD_DETECT_PIN;
498  gpio_init_structure.Mode = GPIO_MODE_INPUT;
499  gpio_init_structure.Pull = GPIO_PULLUP;
500  gpio_init_structure.Speed = GPIO_SPEED_HIGH;
501  HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &gpio_init_structure);
502 }
503 
509 __weak void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params)
510 {
511  static DMA_HandleTypeDef dma_rx_handle;
512  static DMA_HandleTypeDef dma_tx_handle;
513 
514  /* Disable NVIC for DMA transfer complete interrupts */
517 
518  /* Deinitialize the stream for new transfer */
519  dma_rx_handle.Instance = SD_DMAx_Rx_STREAM;
520  HAL_DMA_DeInit(&dma_rx_handle);
521 
522  /* Deinitialize the stream for new transfer */
523  dma_tx_handle.Instance = SD_DMAx_Tx_STREAM;
524  HAL_DMA_DeInit(&dma_tx_handle);
525 
526  /* Disable NVIC for SDIO interrupts */
527  HAL_NVIC_DisableIRQ(SDIO_IRQn);
528 
529  /* DeInit GPIO pins can be done in the application
530  (by surcharging this __weak function) */
531 
532  /* Disable SDIO clock */
533  __HAL_RCC_SDIO_CLK_DISABLE();
534 
535  /* GPOI pins clock and DMA cloks can be shut down in the applic
536  by surcgarging this __weak function */
537 }
538 
548 {
549  return(HAL_SD_GetStatus(&uSdHandle));
550 }
551 
557 {
558  /* Get SD card Information */
559  HAL_SD_Get_CardInfo(&uSdHandle, CardInfo);
560 }
561 
578 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypedef *CardInfo)
Get SD information about specific SD card.
#define DMA_PFCTRL
#define GPIOD
Definition: stm32f745xx.h:1316
#define SDMMC_CLOCK_POWER_SAVE_DISABLE
#define DMA_MBURST_INC4
HAL_SD_ErrorTypedef HAL_SD_WideBusOperation_Config(SD_HandleTypeDef *hsd, uint32_t WideMode)
#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__)
#define SD_DMAx_Tx_STREAM
#define SDMMC_BUS_WIDE_4B
uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
Writes block(s) to a specified address in an SD card, in DMA mode.
#define GPIOB
Definition: stm32f745xx.h:1314
HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)
#define SD_DMAx_Tx_CHANNEL
__weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params)
Initializes the SD MSP.
#define MSD_OK
SD status structure definition.
HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
This file contains the common defines and functions prototypes for the stm32f769i_discovery_sd.c driver.
#define GPIO_PIN_4
#define SD_PRESENT
DMA_InitTypeDef Init
#define DMA_PBURST_INC4
HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
#define SD_DMAx_Tx_IRQn
#define DMA_PINC_DISABLE
__weak void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params)
Initializes the SD Detect pin MSP.
HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo)
HAL_SD_TransferStateTypedef BSP_SD_GetStatus(void)
Gets the current SD card data status.
HAL_SD_ErrorTypedef HAL_SD_Get_CardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *pCardInfo)
uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr)
Erases the specified memory area of the given SD card.
#define GPIO_MODE_INPUT
#define SD_DETECT_GPIO_PORT
#define GPIO_PULLUP
#define DMA_FIFO_THRESHOLD_FULL
#define MSD_ERROR_SD_NOT_PRESENT
HAL_SD_TransferStateTypedef
#define MSD_ERROR
#define __HAL_RCC_GPIOD_CLK_ENABLE()
#define GPIO_PIN_10
uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
Reads block(s) from a specified address in an SD card, in DMA mode.
HAL_SD_TransferStateTypedef HAL_SD_GetStatus(SD_HandleTypeDef *hsd)
#define GPIO_PIN_7
uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
Reads block(s) from a specified address in an SD card, in polling mode.
#define NULL
Definition: usbd_def.h:53
#define SD_DETECT_PIN
SD-detect signal.
#define DMA_PDATAALIGN_WORD
#define __IO
Definition: core_cm0.h:213
HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd)
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
#define SD_DMAx_Rx_CHANNEL
uint8_t BSP_SD_DeInit(void)
DeInitializes the SD card device.
IRQn_Type
STM32F7xx Interrupt Number Definition, according to the selected device in Library_configuration_sect...
Definition: stm32f745xx.h:67
DMA_Stream_TypeDef * Instance
#define SD_CardInfo
SD Card information structure.
HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t startaddr, uint64_t endaddr)
HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)
__weak void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params)
DeInitializes the SD MSP.
#define SD_DMAx_Rx_STREAM
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
#define SD_DMAx_Rx_IRQn
GPIO Init structure definition.
#define GPIO_PIN_3
uint32_t PeriphDataAlignment
#define SDMMC_HARDWARE_FLOW_CONTROL_DISABLE
#define SD_DATATIMEOUT
#define GPIO_MODE_IT_RISING_FALLING
#define DMA_MDATAALIGN_WORD
#define SDMMC_TRANSFER_CLK_DIV
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
#define GPIO_PIN_9
#define __HAL_RCC_GPIOG_CLK_ENABLE()
uint8_t BSP_SD_ITConfig(void)
Configures Interrupt mode for SD detection pin.
#define DMA_MINC_ENABLE
#define __HAL_RCC_GPIOB_CLK_ENABLE()
uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
Writes block(s) to a specified address in an SD card, in polling mode.
#define DMA_PRIORITY_VERY_HIGH
#define SD_DETECT_GPIO_CLK_ENABLE()
#define SDMMC2
Definition: stm32f765xx.h:1500
DMA handle Structure definition.
#define SD_DETECT_EXTI_IRQn
HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
#define SDMMC_BUS_WIDE_1B
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
#define DMA_FIFOMODE_ENABLE
SD_HandleTypeDef uSdHandle
#define SDMMC_CLOCK_EDGE_RISING
HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
uint8_t BSP_SD_Init(void)
Initializes the SD card device.
#define GPIOG
Definition: stm32f745xx.h:1319
#define GPIO_MODE_AF_PP
SD_InitTypeDef Init
uint32_t MemDataAlignment
HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
#define DMA_PERIPH_TO_MEMORY
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
SD_TypeDef * Instance
#define __DMAx_TxRx_CLK_ENABLE
#define SDMMC_CLOCK_BYPASS_DISABLE
#define GPIO_PIN_6
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
#define DMA_MEMORY_TO_PERIPH
uint8_t BSP_SD_IsDetected(void)
Detects if SD card is correctly plugged in the memory slot or not.
#define SD_NOT_PRESENT