STM32L4xx_HAL_Driver  1.14.0
stm32l4xx_hal_sd_ex.c
Go to the documentation of this file.
1 
35 /* Includes ------------------------------------------------------------------*/
36 #include "stm32l4xx_hal.h"
37 
38 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
39 
49 #ifdef HAL_SD_MODULE_ENABLED
50 
51 /* Private typedef -----------------------------------------------------------*/
52 /* Private define ------------------------------------------------------------*/
53 /* Private macro -------------------------------------------------------------*/
54 /* Private variables ---------------------------------------------------------*/
55 /* Private function prototypes -----------------------------------------------*/
56 /* Private functions ---------------------------------------------------------*/
57 extern uint32_t SD_HighSpeed(SD_HandleTypeDef *hsd);
58 /* Exported functions --------------------------------------------------------*/
86 {
87  return SD_HighSpeed (hsd);
88 }
89 
95 __weak void HAL_SDEx_DriveTransceiver_1_8V_Callback(FlagStatus status)
96 {
97  /* Prevent unused argument(s) compilation warning */
98  UNUSED(status);
99 
100  /* NOTE : This function Should not be modified, when the callback is needed,
101  the HAL_SD_EnableTransciver could be implemented in the user file
102  */
103 }
104 
132 HAL_StatusTypeDef HAL_SDEx_ConfigDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t *pDataBuffer0, uint32_t *pDataBuffer1, uint32_t BufferSize)
133 {
134  if(hsd->State == HAL_SD_STATE_READY)
135  {
136  hsd->Instance->IDMABASE0= (uint32_t) pDataBuffer0;
137  hsd->Instance->IDMABASE1= (uint32_t) pDataBuffer1;
138  hsd->Instance->IDMABSIZE= (uint32_t) (BLOCKSIZE * BufferSize);
139 
140  return HAL_OK;
141  }
142  else
143  {
144  return HAL_BUSY;
145  }
146 }
147 
156 HAL_StatusTypeDef HAL_SDEx_ReadBlocksDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t BlockAdd, uint32_t NumberOfBlocks)
157 {
158  SDMMC_DataInitTypeDef config;
159  uint32_t errorstate;
160  uint32_t DmaBase0_reg, DmaBase1_reg;
161  uint32_t add = BlockAdd;
162 
163  if(hsd->State == HAL_SD_STATE_READY)
164  {
165  if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
166  {
167  hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
168  return HAL_ERROR;
169  }
170 
171  DmaBase0_reg = hsd->Instance->IDMABASE0;
172  DmaBase1_reg = hsd->Instance->IDMABASE1;
173  if ((hsd->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U))
174  {
175  hsd->ErrorCode = HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
176  return HAL_ERROR;
177  }
178 
179  /* Initialize data control register */
180  hsd->Instance->DCTRL = 0;
181  /* Clear old Flags*/
182  __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS);
183 
184  hsd->ErrorCode = HAL_SD_ERROR_NONE;
185  hsd->State = HAL_SD_STATE_BUSY;
186 
187  if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
188  {
189  add *= 512U;
190  }
191 
192  /* Set Block Size for Card */
193  errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
194  if(errorstate != HAL_SD_ERROR_NONE)
195  {
196  /* Clear all the static flags */
197  __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
198  hsd->ErrorCode |= errorstate;
199  hsd->State = HAL_SD_STATE_READY;
200  return HAL_ERROR;
201  }
202 
203  /* Configure the SD DPSM (Data Path State Machine) */
204  config.DataTimeOut = SDMMC_DATATIMEOUT;
205  config.DataLength = BLOCKSIZE * NumberOfBlocks;
206  config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
207  config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
208  config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
209  config.DPSM = SDMMC_DPSM_DISABLE;
210  (void)SDMMC_ConfigData(hsd->Instance, &config);
211 
212  hsd->Instance->DCTRL |= SDMMC_DCTRL_FIFORST;
213 
214  __SDMMC_CMDTRANS_ENABLE( hsd->Instance);
215 
216  hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0;
217 
218  __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_IT_IDMABTC));
219 
220  /* Read Blocks in DMA mode */
221  hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
222 
223  /* Read Multi Block command */
224  errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add);
225  if(errorstate != HAL_SD_ERROR_NONE)
226  {
227  hsd->State = HAL_SD_STATE_READY;
228  hsd->ErrorCode |= errorstate;
229  return HAL_ERROR;
230  }
231 
232  return HAL_OK;
233  }
234  else
235  {
236  return HAL_BUSY;
237  }
238 
239 }
240 
249 HAL_StatusTypeDef HAL_SDEx_WriteBlocksDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t BlockAdd, uint32_t NumberOfBlocks)
250 {
251  SDMMC_DataInitTypeDef config;
252  uint32_t errorstate;
253  uint32_t DmaBase0_reg, DmaBase1_reg;
254  uint32_t add = BlockAdd;
255 
256  if(hsd->State == HAL_SD_STATE_READY)
257  {
258  if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
259  {
260  hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
261  return HAL_ERROR;
262  }
263 
264  DmaBase0_reg = hsd->Instance->IDMABASE0;
265  DmaBase1_reg = hsd->Instance->IDMABASE1;
266  if ((hsd->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U))
267  {
268  hsd->ErrorCode = HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
269  return HAL_ERROR;
270  }
271 
272  /* Initialize data control register */
273  hsd->Instance->DCTRL = 0;
274 
275  hsd->ErrorCode = HAL_SD_ERROR_NONE;
276 
277  hsd->State = HAL_SD_STATE_BUSY;
278 
279  if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
280  {
281  add *= 512U;
282  }
283 
284  /* Set Block Size for Card */
285  errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
286  if(errorstate != HAL_SD_ERROR_NONE)
287  {
288  /* Clear all the static flags */
289  __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
290  hsd->ErrorCode |= errorstate;
291  hsd->State = HAL_SD_STATE_READY;
292  return HAL_ERROR;
293  }
294 
295  /* Configure the SD DPSM (Data Path State Machine) */
296  config.DataTimeOut = SDMMC_DATATIMEOUT;
297  config.DataLength = BLOCKSIZE * NumberOfBlocks;
298  config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
299  config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
300  config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
301  config.DPSM = SDMMC_DPSM_DISABLE;
302  (void)SDMMC_ConfigData(hsd->Instance, &config);
303 
304  __SDMMC_CMDTRANS_ENABLE( hsd->Instance);
305 
306  hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0;
307 
308  __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_IT_IDMABTC));
309 
310  /* Write Blocks in DMA mode */
311  hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
312 
313  /* Write Multi Block command */
314  errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);
315  if(errorstate != HAL_SD_ERROR_NONE)
316  {
317  hsd->State = HAL_SD_STATE_READY;
318  hsd->ErrorCode |= errorstate;
319  return HAL_ERROR;
320  }
321 
322  return HAL_OK;
323  }
324  else
325  {
326  return HAL_BUSY;
327  }
328 }
329 
330 
342 HAL_StatusTypeDef HAL_SDEx_ChangeDMABuffer(SD_HandleTypeDef *hsd, HAL_SDEx_DMABuffer_MemoryTypeDef Buffer, uint32_t *pDataBuffer)
343 {
344  if(Buffer == SD_DMA_BUFFER0)
345  {
346  /* change the buffer0 address */
347  hsd->Instance->IDMABASE0 = (uint32_t)pDataBuffer;
348  }
349  else
350  {
351  /* change the memory1 address */
352  hsd->Instance->IDMABASE1 = (uint32_t)pDataBuffer;
353  }
354 
355  return HAL_OK;
356 }
357 
364 {
365  /* Prevent unused argument(s) compilation warning */
366  UNUSED(hsd);
367 
368  /* NOTE : This function should not be modified, when the callback is needed,
369  the HAL_SDEx_Read_DMADoubleBuffer0CpltCallback can be implemented in the user file
370  */
371 }
372 
379 {
380  /* Prevent unused argument(s) compilation warning */
381  UNUSED(hsd);
382 
383  /* NOTE : This function should not be modified, when the callback is needed,
384  the HAL_SDEx_Read_DMADoubleBuffer1CpltCallback can be implemented in the user file
385  */
386 }
387 
394 {
395  /* Prevent unused argument(s) compilation warning */
396  UNUSED(hsd);
397 
398  /* NOTE : This function should not be modified, when the callback is needed,
399  the HAL_SDEx_Write_DMADoubleBuffer0CpltCallback can be implemented in the user file
400  */
401 }
402 
409 {
410  /* Prevent unused argument(s) compilation warning */
411  UNUSED(hsd);
412 
413  /* NOTE : This function should not be modified, when the callback is needed,
414  the HAL_SDEx_Write_DMADoubleBuffer0CpltCallback can be implemented in the user file
415  */
416 }
417 
426 #endif /* HAL_SD_MODULE_ENABLED */
427 
436 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
437 
438 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
uint32_t SDMMC_CmdBlockLength(SDMMC_TypeDef *SDMMCx, uint32_t BlockSize)
Send the Data Block Lenght command and check the response.
uint32_t HAL_SDEx_HighSpeed(SD_HandleTypeDef *hsd)
Switches the SD card to High Speed mode. This API must be used after "Transfer State".
uint32_t SDMMC_CmdWriteMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
Send the Write Multi Block command and check the response.
This file contains all the functions prototypes for the HAL module driver.
SDMMC Data Control structure.
HAL_StatusTypeDef HAL_SDEx_WriteBlocksDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t BlockAdd, uint32_t NumberOfBlocks)
Write block(s) to a specified address in a card. The transfered Data are stored in Buffer0 and Buffer...
struct __SD_HandleTypeDef else typedef struct endif SD_HandleTypeDef
SD handle Structure definition.
void HAL_SDEx_Write_DMADoubleBuffer0CpltCallback(SD_HandleTypeDef *hsd)
Write DMA Buffer 0 Transfer completed callbacks.
void HAL_SDEx_Read_DMADoubleBuffer0CpltCallback(SD_HandleTypeDef *hsd)
Read DMA Buffer 0 Transfer completed callbacks.
void HAL_SDEx_Write_DMADoubleBuffer1CpltCallback(SD_HandleTypeDef *hsd)
Write DMA Buffer 1 Transfer completed callbacks.
return HAL_OK
uint32_t SD_HighSpeed(SD_HandleTypeDef *hsd)
Switches the SD card to High Speed mode. This API must be used after "Transfer State".
HAL_StatusTypeDef HAL_SDEx_ChangeDMABuffer(SD_HandleTypeDef *hsd, HAL_SDEx_DMABuffer_MemoryTypeDef Buffer, uint32_t *pDataBuffer)
Change the DMA Buffer0 or Buffer1 address on the fly.
HAL_StatusTypeDef HAL_SDEx_ReadBlocksDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t BlockAdd, uint32_t NumberOfBlocks)
Reads block(s) from a specified address in a card. The received Data will be stored in Buffer0 and Bu...
uint32_t SDMMC_CmdReadMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
Send the Read Multi Block command and check the response.
HAL_StatusTypeDef HAL_SDEx_ConfigDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t *pDataBuffer0, uint32_t *pDataBuffer1, uint32_t BufferSize)
Configure DMA Dual Buffer mode. The Data transfer is managed by an Internal DMA.
void HAL_SDEx_Read_DMADoubleBuffer1CpltCallback(SD_HandleTypeDef *hsd)
Read DMA Buffer 1 Transfer completed callbacks.
void HAL_SDEx_DriveTransceiver_1_8V_Callback(FlagStatus status)
Enable/Disable the SD Transceiver 1.8V Mode Callback.
HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef *Data)
Configure the SDMMC data path according to the specified parameters in the SDMMC_DataInitTypeDef.