STM32L4xx_HAL_Driver  1.14.0
stm32l4xx_ll_sdmmc.c
Go to the documentation of this file.
1 
166 /* Includes ------------------------------------------------------------------*/
167 #include "stm32l4xx_hal.h"
168 
169 #if defined(SDMMC1)
170 
180 #if defined (HAL_SD_MODULE_ENABLED) || defined (HAL_MMC_MODULE_ENABLED)
181 
182 /* Private typedef -----------------------------------------------------------*/
183 /* Private define ------------------------------------------------------------*/
184 /* Private macro -------------------------------------------------------------*/
185 /* Private variables ---------------------------------------------------------*/
186 /* Private function prototypes -----------------------------------------------*/
187 static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx);
188 static uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout);
189 static uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx);
190 static uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx);
191 static uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx);
192 static uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA);
193 
194 /* Exported functions --------------------------------------------------------*/
195 
220 HAL_StatusTypeDef SDMMC_Init(SDMMC_TypeDef *SDMMCx, SDMMC_InitTypeDef Init)
221 {
222  uint32_t tmpreg = 0;
223 
224  /* Check the parameters */
225  assert_param(IS_SDMMC_ALL_INSTANCE(SDMMCx));
226  assert_param(IS_SDMMC_CLOCK_EDGE(Init.ClockEdge));
227 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
228  assert_param(IS_SDMMC_CLOCK_BYPASS(Init.ClockBypass));
229 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */
230  assert_param(IS_SDMMC_CLOCK_POWER_SAVE(Init.ClockPowerSave));
231  assert_param(IS_SDMMC_BUS_WIDE(Init.BusWide));
232  assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
233  assert_param(IS_SDMMC_CLKDIV(Init.ClockDiv));
234 
235  /* Set SDMMC configuration parameters */
236 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
237  tmpreg |= Init.ClockBypass;
238 #endif
239  tmpreg |= (Init.ClockEdge |\
240  Init.ClockPowerSave |\
241  Init.BusWide |\
242  Init.HardwareFlowControl |\
243  Init.ClockDiv
244  );
245 
246  /* Write to SDMMC CLKCR */
247  MODIFY_REG(SDMMCx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);
248 
249  return HAL_OK;
250 }
251 
252 
277 uint32_t SDMMC_ReadFIFO(SDMMC_TypeDef *SDMMCx)
278 {
279  /* Read data from Rx FIFO */
280  return (SDMMCx->FIFO);
281 }
282 
289 HAL_StatusTypeDef SDMMC_WriteFIFO(SDMMC_TypeDef *SDMMCx, uint32_t *pWriteData)
290 {
291  /* Write data to FIFO */
292  SDMMCx->FIFO = *pWriteData;
293 
294  return HAL_OK;
295 }
296 
321 HAL_StatusTypeDef SDMMC_PowerState_ON(SDMMC_TypeDef *SDMMCx)
322 {
323  /* Set power state to ON */
324 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
325  SDMMCx->POWER |= SDMMC_POWER_PWRCTRL;
326 #else
327  SDMMCx->POWER = SDMMC_POWER_PWRCTRL;
328 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
329 
330  /* 1ms: required power up waiting time before starting the SD initialization
331  sequence */
332  HAL_Delay(2);
333 
334  return HAL_OK;
335 }
336 
337 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
338 
343 HAL_StatusTypeDef SDMMC_PowerState_Cycle(SDMMC_TypeDef *SDMMCx)
344 {
345  /* Set power state to Power Cycle*/
346  SDMMCx->POWER |= SDMMC_POWER_PWRCTRL_1;
347 
348  return HAL_OK;
349 }
350 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
351 
357 HAL_StatusTypeDef SDMMC_PowerState_OFF(SDMMC_TypeDef *SDMMCx)
358 {
359  /* Set power state to OFF */
360 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
361  SDMMCx->POWER &= ~(SDMMC_POWER_PWRCTRL);
362 #else
363  SDMMCx->POWER = (uint32_t)0x00000000;
364 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
365 
366  return HAL_OK;
367 }
368 
378 uint32_t SDMMC_GetPowerState(SDMMC_TypeDef *SDMMCx)
379 {
380  return (SDMMCx->POWER & SDMMC_POWER_PWRCTRL);
381 }
382 
391 HAL_StatusTypeDef SDMMC_SendCommand(SDMMC_TypeDef *SDMMCx, SDMMC_CmdInitTypeDef *Command)
392 {
393  uint32_t tmpreg = 0;
394 
395  /* Check the parameters */
396  assert_param(IS_SDMMC_CMD_INDEX(Command->CmdIndex));
397  assert_param(IS_SDMMC_RESPONSE(Command->Response));
398  assert_param(IS_SDMMC_WAIT(Command->WaitForInterrupt));
399  assert_param(IS_SDMMC_CPSM(Command->CPSM));
400 
401  /* Set the SDMMC Argument value */
402  SDMMCx->ARG = Command->Argument;
403 
404  /* Set SDMMC command parameters */
405  tmpreg |= (uint32_t)(Command->CmdIndex |\
406  Command->Response |\
407  Command->WaitForInterrupt |\
408  Command->CPSM);
409 
410  /* Write to SDMMC CMD register */
411  MODIFY_REG(SDMMCx->CMD, CMD_CLEAR_MASK, tmpreg);
412 
413  return HAL_OK;
414 }
415 
421 uint8_t SDMMC_GetCommandResponse(SDMMC_TypeDef *SDMMCx)
422 {
423  return (uint8_t)(SDMMCx->RESPCMD);
424 }
425 
426 
438 uint32_t SDMMC_GetResponse(SDMMC_TypeDef *SDMMCx, uint32_t Response)
439 {
440  uint32_t tmp;
441 
442  /* Check the parameters */
443  assert_param(IS_SDMMC_RESP(Response));
444 
445  /* Get the response */
446  tmp = (uint32_t)(&(SDMMCx->RESP1)) + Response;
447 
448  return (*(__IO uint32_t *) tmp);
449 }
450 
459 HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef* Data)
460 {
461  uint32_t tmpreg = 0;
462 
463  /* Check the parameters */
464  assert_param(IS_SDMMC_DATA_LENGTH(Data->DataLength));
465  assert_param(IS_SDMMC_BLOCK_SIZE(Data->DataBlockSize));
466  assert_param(IS_SDMMC_TRANSFER_DIR(Data->TransferDir));
467  assert_param(IS_SDMMC_TRANSFER_MODE(Data->TransferMode));
468  assert_param(IS_SDMMC_DPSM(Data->DPSM));
469 
470  /* Set the SDMMC Data TimeOut value */
471  SDMMCx->DTIMER = Data->DataTimeOut;
472 
473  /* Set the SDMMC DataLength value */
474  SDMMCx->DLEN = Data->DataLength;
475 
476  /* Set the SDMMC data configuration parameters */
477  tmpreg |= (uint32_t)(Data->DataBlockSize |\
478  Data->TransferDir |\
479  Data->TransferMode |\
480  Data->DPSM);
481 
482  /* Write to SDMMC DCTRL */
483  MODIFY_REG(SDMMCx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
484 
485  return HAL_OK;
486 
487 }
488 
494 uint32_t SDMMC_GetDataCounter(SDMMC_TypeDef *SDMMCx)
495 {
496  return (SDMMCx->DCOUNT);
497 }
498 
504 uint32_t SDMMC_GetFIFOCount(SDMMC_TypeDef *SDMMCx)
505 {
506  return (SDMMCx->FIFO);
507 }
508 
518 HAL_StatusTypeDef SDMMC_SetSDMMCReadWaitMode(SDMMC_TypeDef *SDMMCx, uint32_t SDMMC_ReadWaitMode)
519 {
520  /* Check the parameters */
521  assert_param(IS_SDMMC_READWAIT_MODE(SDMMC_ReadWaitMode));
522 
523  /* Set SDMMC read wait mode */
524  MODIFY_REG(SDMMCx->DCTRL, SDMMC_DCTRL_RWMOD, SDMMC_ReadWaitMode);
525 
526  return HAL_OK;
527 }
528 
553 uint32_t SDMMC_CmdBlockLength(SDMMC_TypeDef *SDMMCx, uint32_t BlockSize)
554 {
555  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
556  uint32_t errorstate;
557 
558  /* Set Block Size for Card */
559  sdmmc_cmdinit.Argument = (uint32_t)BlockSize;
560  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCKLEN;
561  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
562  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
563  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
564  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
565 
566  /* Check for error conditions */
567  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_BLOCKLEN, SDMMC_CMDTIMEOUT);
568 
569  return errorstate;
570 }
571 
577 uint32_t SDMMC_CmdReadSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
578 {
579  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
580  uint32_t errorstate;
581 
582  /* Set Block Size for Card */
583  sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
584  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_SINGLE_BLOCK;
585  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
586  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
587  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
588  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
589 
590  /* Check for error conditions */
591  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_SINGLE_BLOCK, SDMMC_CMDTIMEOUT);
592 
593  return errorstate;
594 }
595 
601 uint32_t SDMMC_CmdReadMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
602 {
603  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
604  uint32_t errorstate;
605 
606  /* Set Block Size for Card */
607  sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
608  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_MULT_BLOCK;
609  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
610  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
611  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
612  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
613 
614  /* Check for error conditions */
615  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_MULT_BLOCK, SDMMC_CMDTIMEOUT);
616 
617  return errorstate;
618 }
619 
625 uint32_t SDMMC_CmdWriteSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
626 {
627  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
628  uint32_t errorstate;
629 
630  /* Set Block Size for Card */
631  sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
632  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_SINGLE_BLOCK;
633  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
634  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
635  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
636  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
637 
638  /* Check for error conditions */
639  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDMMC_CMDTIMEOUT);
640 
641  return errorstate;
642 }
643 
649 uint32_t SDMMC_CmdWriteMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
650 {
651  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
652  uint32_t errorstate;
653 
654  /* Set Block Size for Card */
655  sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
656  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_MULT_BLOCK;
657  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
658  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
659  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
660  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
661 
662  /* Check for error conditions */
663  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_MULT_BLOCK, SDMMC_CMDTIMEOUT);
664 
665  return errorstate;
666 }
667 
673 uint32_t SDMMC_CmdSDEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
674 {
675  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
676  uint32_t errorstate;
677 
678  /* Set Block Size for Card */
679  sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
680  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_START;
681  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
682  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
683  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
684  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
685 
686  /* Check for error conditions */
687  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_START, SDMMC_CMDTIMEOUT);
688 
689  return errorstate;
690 }
691 
697 uint32_t SDMMC_CmdSDEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
698 {
699  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
700  uint32_t errorstate;
701 
702  /* Set Block Size for Card */
703  sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
704  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_END;
705  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
706  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
707  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
708  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
709 
710  /* Check for error conditions */
711  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_END, SDMMC_CMDTIMEOUT);
712 
713  return errorstate;
714 }
715 
721 uint32_t SDMMC_CmdEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
722 {
723  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
724  uint32_t errorstate;
725 
726  /* Set Block Size for Card */
727  sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
728  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_START;
729  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
730  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
731  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
732  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
733 
734  /* Check for error conditions */
735  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_START, SDMMC_CMDTIMEOUT);
736 
737  return errorstate;
738 }
739 
745 uint32_t SDMMC_CmdEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
746 {
747  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
748  uint32_t errorstate;
749 
750  /* Set Block Size for Card */
751  sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
752  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_END;
753  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
754  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
755  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
756  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
757 
758  /* Check for error conditions */
759  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_END, SDMMC_CMDTIMEOUT);
760 
761  return errorstate;
762 }
763 
769 uint32_t SDMMC_CmdErase(SDMMC_TypeDef *SDMMCx)
770 {
771  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
772  uint32_t errorstate;
773 
774  /* Set Block Size for Card */
775  sdmmc_cmdinit.Argument = 0U;
776  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE;
777  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
778  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
779  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
780  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
781 
782  /* Check for error conditions */
783  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE, SDMMC_MAXERASETIMEOUT);
784 
785  return errorstate;
786 }
787 
793 uint32_t SDMMC_CmdStopTransfer(SDMMC_TypeDef *SDMMCx)
794 {
795  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
796  uint32_t errorstate;
797 
798  /* Send CMD12 STOP_TRANSMISSION */
799  sdmmc_cmdinit.Argument = 0U;
800  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION;
801  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
802  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
803  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
804 
805 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
806  __SDMMC_CMDSTOP_ENABLE(SDMMCx);
807  __SDMMC_CMDTRANS_DISABLE(SDMMCx);
808 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
809 
810  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
811 
812  /* Check for error conditions */
813  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_STOP_TRANSMISSION, SDMMC_STOPTRANSFERTIMEOUT);
814 
815 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
816  __SDMMC_CMDSTOP_DISABLE(SDMMCx);
817 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
818 
819  return errorstate;
820 }
821 
828 uint32_t SDMMC_CmdSelDesel(SDMMC_TypeDef *SDMMCx, uint64_t Addr)
829 {
830  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
831  uint32_t errorstate;
832 
833  /* Send CMD7 SDMMC_SEL_DESEL_CARD */
834  sdmmc_cmdinit.Argument = (uint32_t)Addr;
835  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEL_DESEL_CARD;
836  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
837  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
838  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
839  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
840 
841  /* Check for error conditions */
842  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEL_DESEL_CARD, SDMMC_CMDTIMEOUT);
843 
844  return errorstate;
845 }
846 
852 uint32_t SDMMC_CmdGoIdleState(SDMMC_TypeDef *SDMMCx)
853 {
854  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
855  uint32_t errorstate;
856 
857  sdmmc_cmdinit.Argument = 0U;
858  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE;
859  sdmmc_cmdinit.Response = SDMMC_RESPONSE_NO;
860  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
861  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
862  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
863 
864  /* Check for error conditions */
865  errorstate = SDMMC_GetCmdError(SDMMCx);
866 
867  return errorstate;
868 }
869 
875 uint32_t SDMMC_CmdOperCond(SDMMC_TypeDef *SDMMCx)
876 {
877  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
878  uint32_t errorstate;
879 
880  /* Send CMD8 to verify SD card interface operating condition */
881  /* Argument: - [31:12]: Reserved (shall be set to '0')
882  - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
883  - [7:0]: Check Pattern (recommended 0xAA) */
884  /* CMD Response: R7 */
885  sdmmc_cmdinit.Argument = SDMMC_CHECK_PATTERN;
886  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
887  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
888  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
889  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
890  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
891 
892  /* Check for error conditions */
893  errorstate = SDMMC_GetCmdResp7(SDMMCx);
894 
895  return errorstate;
896 }
897 
906 uint32_t SDMMC_CmdAppCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
907 {
908  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
909  uint32_t errorstate;
910 
911  sdmmc_cmdinit.Argument = (uint32_t)Argument;
912  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_CMD;
913  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
914  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
915  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
916  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
917 
918  /* Check for error conditions */
919  /* If there is a HAL_ERROR, it is a MMC card, else
920  it is a SD card: SD card 2.0 (voltage range mismatch)
921  or SD card 1.x */
922  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_CMD, SDMMC_CMDTIMEOUT);
923 
924  return errorstate;
925 }
926 
934 uint32_t SDMMC_CmdAppOperCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
935 {
936  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
937  uint32_t errorstate;
938 
939 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
940  sdmmc_cmdinit.Argument = Argument;
941 #else
942  sdmmc_cmdinit.Argument = SDMMC_VOLTAGE_WINDOW_SD | Argument;
943 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
944  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_OP_COND;
945  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
946  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
947  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
948  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
949 
950  /* Check for error conditions */
951  errorstate = SDMMC_GetCmdResp3(SDMMCx);
952 
953  return errorstate;
954 }
955 
962 uint32_t SDMMC_CmdBusWidth(SDMMC_TypeDef *SDMMCx, uint32_t BusWidth)
963 {
964  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
965  uint32_t errorstate;
966 
967  sdmmc_cmdinit.Argument = (uint32_t)BusWidth;
968  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
969  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
970  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
971  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
972  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
973 
974  /* Check for error conditions */
975  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDMMC_CMDTIMEOUT);
976 
977  return errorstate;
978 }
979 
985 uint32_t SDMMC_CmdSendSCR(SDMMC_TypeDef *SDMMCx)
986 {
987  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
988  uint32_t errorstate;
989 
990  /* Send CMD51 SD_APP_SEND_SCR */
991  sdmmc_cmdinit.Argument = 0U;
992  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR;
993  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
994  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
995  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
996  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
997 
998  /* Check for error conditions */
999  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_SEND_SCR, SDMMC_CMDTIMEOUT);
1000 
1001  return errorstate;
1002 }
1003 
1009 uint32_t SDMMC_CmdSendCID(SDMMC_TypeDef *SDMMCx)
1010 {
1011  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1012  uint32_t errorstate;
1013 
1014  /* Send CMD2 ALL_SEND_CID */
1015  sdmmc_cmdinit.Argument = 0U;
1016  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID;
1017  sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG;
1018  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1019  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1020  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1021 
1022  /* Check for error conditions */
1023  errorstate = SDMMC_GetCmdResp2(SDMMCx);
1024 
1025  return errorstate;
1026 }
1027 
1034 uint32_t SDMMC_CmdSendCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1035 {
1036  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1037  uint32_t errorstate;
1038 
1039  /* Send CMD9 SEND_CSD */
1040  sdmmc_cmdinit.Argument = Argument;
1041  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_CSD;
1042  sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG;
1043  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1044  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1045  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1046 
1047  /* Check for error conditions */
1048  errorstate = SDMMC_GetCmdResp2(SDMMCx);
1049 
1050  return errorstate;
1051 }
1052 
1059 uint32_t SDMMC_CmdSetRelAdd(SDMMC_TypeDef *SDMMCx, uint16_t *pRCA)
1060 {
1061  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1062  uint32_t errorstate;
1063 
1064  /* Send CMD3 SD_CMD_SET_REL_ADDR */
1065  sdmmc_cmdinit.Argument = 0U;
1066  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
1067  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1068  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1069  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1070  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1071 
1072  /* Check for error conditions */
1073  errorstate = SDMMC_GetCmdResp6(SDMMCx, SDMMC_CMD_SET_REL_ADDR, pRCA);
1074 
1075  return errorstate;
1076 }
1077 
1084 uint32_t SDMMC_CmdSendStatus(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1085 {
1086  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1087  uint32_t errorstate;
1088 
1089  sdmmc_cmdinit.Argument = Argument;
1090  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS;
1091  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1092  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1093  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1094  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1095 
1096  /* Check for error conditions */
1097  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEND_STATUS, SDMMC_CMDTIMEOUT);
1098 
1099  return errorstate;
1100 }
1101 
1107 uint32_t SDMMC_CmdStatusRegister(SDMMC_TypeDef *SDMMCx)
1108 {
1109  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1110  uint32_t errorstate;
1111 
1112  sdmmc_cmdinit.Argument = 0U;
1113  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS;
1114  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1115  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1116  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1117  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1118 
1119  /* Check for error conditions */
1120  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_STATUS, SDMMC_CMDTIMEOUT);
1121 
1122  return errorstate;
1123 }
1124 
1132 uint32_t SDMMC_CmdOpCondition(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1133 {
1134  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1135  uint32_t errorstate;
1136 
1137  sdmmc_cmdinit.Argument = Argument;
1138  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_OP_COND;
1139  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1140  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1141  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1142  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1143 
1144  /* Check for error conditions */
1145  errorstate = SDMMC_GetCmdResp3(SDMMCx);
1146 
1147  return errorstate;
1148 }
1149 
1156 uint32_t SDMMC_CmdSwitch(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1157 {
1158  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1159  uint32_t errorstate;
1160 
1161  /* Send CMD6 to activate SDR50 Mode and Power Limit 1.44W */
1162  /* CMD Response: R1 */
1163  sdmmc_cmdinit.Argument = Argument; /* SDMMC_SDR25_SWITCH_PATTERN;*/
1164  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SWITCH;
1165  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1166  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1167  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1168  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1169 
1170  /* Check for error conditions */
1171  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SWITCH, SDMMC_CMDTIMEOUT);
1172 
1173  return errorstate;
1174 }
1175 
1176 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1177 
1183 uint32_t SDMMC_CmdVoltageSwitch(SDMMC_TypeDef *SDMMCx)
1184 {
1185  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1186  uint32_t errorstate;
1187 
1188  sdmmc_cmdinit.Argument = 0x00000000;
1189  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_VOLTAGE_SWITCH;
1190  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1191  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1192  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1193  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1194 
1195  /* Check for error conditions */
1196  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_VOLTAGE_SWITCH, SDMMC_CMDTIMEOUT);
1197 
1198  return errorstate;
1199 }
1200 
1207 uint32_t SDMMC_CmdSendEXTCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
1208 {
1209  SDMMC_CmdInitTypeDef sdmmc_cmdinit;
1210  uint32_t errorstate;
1211 
1212  /* Send CMD9 SEND_CSD */
1213  sdmmc_cmdinit.Argument = Argument;
1214  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
1215  sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
1216  sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
1217  sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
1218  (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
1219 
1220  /* Check for error conditions */
1221  errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SEND_EXT_CSD,SDMMC_CMDTIMEOUT);
1222 
1223  return errorstate;
1224 }
1225 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
1226 
1231 /* Private function ----------------------------------------------------------*/
1241 static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx)
1242 {
1243  /* 8 is the number of required instructions cycles for the below loop statement.
1244  The SDMMC_CMDTIMEOUT is expressed in ms */
1245  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1246 
1247  do
1248  {
1249  if (count-- == 0U)
1250  {
1251  return SDMMC_ERROR_TIMEOUT;
1252  }
1253 
1254  }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDSENT));
1255 
1256  /* Clear all the static flags */
1257  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1258 
1259  return SDMMC_ERROR_NONE;
1260 }
1261 
1268 static uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout)
1269 {
1270  uint32_t response_r1;
1271  uint32_t sta_reg;
1272 
1273  /* 8 is the number of required instructions cycles for the below loop statement.
1274  The Timeout is expressed in ms */
1275  register uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
1276 
1277  do
1278  {
1279  if (count-- == 0U)
1280  {
1281  return SDMMC_ERROR_TIMEOUT;
1282  }
1283  sta_reg = SDMMCx->STA;
1284 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1285  }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT | SDMMC_FLAG_BUSYD0END)) == 0U) ||
1286  ((sta_reg & SDMMC_FLAG_CMDACT) != 0U ));
1287 #else
1288  }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1289  ((sta_reg & SDMMC_FLAG_CMDACT) != 0U ));
1290 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
1291 
1292  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1293  {
1294  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1295 
1296  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1297  }
1298  else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
1299  {
1300  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
1301 
1302  return SDMMC_ERROR_CMD_CRC_FAIL;
1303  }
1304  else
1305  {
1306  /* Nothing to do */
1307  }
1308 
1309  /* Clear all the static flags */
1310  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1311 
1312  /* Check response received is of desired command */
1313  if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD)
1314  {
1315  return SDMMC_ERROR_CMD_CRC_FAIL;
1316  }
1317 
1318  /* We have received response, retrieve it for analysis */
1319  response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
1320 
1321  if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
1322  {
1323  return SDMMC_ERROR_NONE;
1324  }
1325  else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
1326  {
1327  return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
1328  }
1329  else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
1330  {
1331  return SDMMC_ERROR_ADDR_MISALIGNED;
1332  }
1333  else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
1334  {
1335  return SDMMC_ERROR_BLOCK_LEN_ERR;
1336  }
1337  else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
1338  {
1339  return SDMMC_ERROR_ERASE_SEQ_ERR;
1340  }
1341  else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
1342  {
1343  return SDMMC_ERROR_BAD_ERASE_PARAM;
1344  }
1345  else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
1346  {
1347  return SDMMC_ERROR_WRITE_PROT_VIOLATION;
1348  }
1349  else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
1350  {
1351  return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
1352  }
1353  else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
1354  {
1355  return SDMMC_ERROR_COM_CRC_FAILED;
1356  }
1357  else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
1358  {
1359  return SDMMC_ERROR_ILLEGAL_CMD;
1360  }
1361  else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
1362  {
1363  return SDMMC_ERROR_CARD_ECC_FAILED;
1364  }
1365  else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
1366  {
1367  return SDMMC_ERROR_CC_ERR;
1368  }
1369  else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
1370  {
1371  return SDMMC_ERROR_STREAM_READ_UNDERRUN;
1372  }
1373  else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
1374  {
1375  return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
1376  }
1377  else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
1378  {
1379  return SDMMC_ERROR_CID_CSD_OVERWRITE;
1380  }
1381  else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
1382  {
1383  return SDMMC_ERROR_WP_ERASE_SKIP;
1384  }
1385  else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
1386  {
1387  return SDMMC_ERROR_CARD_ECC_DISABLED;
1388  }
1389  else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
1390  {
1391  return SDMMC_ERROR_ERASE_RESET;
1392  }
1393  else if((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
1394  {
1395  return SDMMC_ERROR_AKE_SEQ_ERR;
1396  }
1397  else
1398  {
1399  return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1400  }
1401 }
1402 
1408 static uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx)
1409 {
1410  uint32_t sta_reg;
1411  /* 8 is the number of required instructions cycles for the below loop statement.
1412  The SDMMC_CMDTIMEOUT is expressed in ms */
1413  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1414 
1415  do
1416  {
1417  if (count-- == 0U)
1418  {
1419  return SDMMC_ERROR_TIMEOUT;
1420  }
1421  sta_reg = SDMMCx->STA;
1422  }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1423  ((sta_reg & SDMMC_FLAG_CMDACT) != 0U ));
1424 
1425  if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1426  {
1427  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1428 
1429  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1430  }
1431  else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
1432  {
1433  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
1434 
1435  return SDMMC_ERROR_CMD_CRC_FAIL;
1436  }
1437  else
1438  {
1439  /* No error flag set */
1440  /* Clear all the static flags */
1441  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1442  }
1443 
1444  return SDMMC_ERROR_NONE;
1445 }
1446 
1452 static uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx)
1453 {
1454  uint32_t sta_reg;
1455  /* 8 is the number of required instructions cycles for the below loop statement.
1456  The SDMMC_CMDTIMEOUT is expressed in ms */
1457  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1458 
1459  do
1460  {
1461  if (count-- == 0U)
1462  {
1463  return SDMMC_ERROR_TIMEOUT;
1464  }
1465  sta_reg = SDMMCx->STA;
1466  }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1467  ((sta_reg & SDMMC_FLAG_CMDACT) != 0U ));
1468 
1469  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1470  {
1471  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1472 
1473  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1474  }
1475  else
1476  {
1477  /* Clear all the static flags */
1478  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1479  }
1480 
1481  return SDMMC_ERROR_NONE;
1482 }
1483 
1492 static uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA)
1493 {
1494  uint32_t response_r1;
1495  uint32_t sta_reg;
1496 
1497  /* 8 is the number of required instructions cycles for the below loop statement.
1498  The SDMMC_CMDTIMEOUT is expressed in ms */
1499  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1500 
1501  do
1502  {
1503  if (count-- == 0U)
1504  {
1505  return SDMMC_ERROR_TIMEOUT;
1506  }
1507  sta_reg = SDMMCx->STA;
1508  }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1509  ((sta_reg & SDMMC_FLAG_CMDACT) != 0U ));
1510 
1511  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1512  {
1513  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1514 
1515  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1516  }
1517  else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
1518  {
1519  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
1520 
1521  return SDMMC_ERROR_CMD_CRC_FAIL;
1522  }
1523  else
1524  {
1525  /* Nothing to do */
1526  }
1527 
1528  /* Check response received is of desired command */
1529  if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD)
1530  {
1531  return SDMMC_ERROR_CMD_CRC_FAIL;
1532  }
1533 
1534  /* Clear all the static flags */
1535  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
1536 
1537  /* We have received response, retrieve it. */
1538  response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1);
1539 
1540  if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
1541  {
1542  *pRCA = (uint16_t) (response_r1 >> 16);
1543 
1544  return SDMMC_ERROR_NONE;
1545  }
1546  else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
1547  {
1548  return SDMMC_ERROR_ILLEGAL_CMD;
1549  }
1550  else if((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
1551  {
1552  return SDMMC_ERROR_COM_CRC_FAILED;
1553  }
1554  else
1555  {
1556  return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1557  }
1558 }
1559 
1565 static uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx)
1566 {
1567  uint32_t sta_reg;
1568  /* 8 is the number of required instructions cycles for the below loop statement.
1569  The SDMMC_CMDTIMEOUT is expressed in ms */
1570  register uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1571 
1572  do
1573  {
1574  if (count-- == 0U)
1575  {
1576  return SDMMC_ERROR_TIMEOUT;
1577  }
1578  sta_reg = SDMMCx->STA;
1579  }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) ||
1580  ((sta_reg & SDMMC_FLAG_CMDACT) != 0U ));
1581 
1582  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
1583  {
1584  /* Card is SD V2.0 compliant */
1585  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);
1586 
1587  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1588  }
1589 
1590  else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL))
1591  {
1592  /* Card is SD V2.0 compliant */
1593  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL);
1594 
1595  return SDMMC_ERROR_CMD_CRC_FAIL;
1596  }
1597  else
1598  {
1599  /* Nothing to do */
1600  }
1601 
1602  if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDREND))
1603  {
1604  /* Card is SD V2.0 compliant */
1605  __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND);
1606  }
1607 
1608  return SDMMC_ERROR_NONE;
1609 
1610 }
1611 
1616 #endif /* HAL_SD_MODULE_ENABLED || HAL_MMC_MODULE_ENABLED */
1617 
1625 #endif /* SDMMC1 */
1626 
1627 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
uint32_t SDMMC_CmdSelDesel(SDMMC_TypeDef *SDMMCx, uint64_t Addr)
Send the Select Deselect command and check the response.
uint32_t SDMMC_CmdReadSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
Send the Read Single Block command and check the response.
uint32_t SDMMC_GetDataCounter(SDMMC_TypeDef *SDMMCx)
Returns number of remaining data bytes to be transferred.
uint32_t SDMMC_CmdVoltageSwitch(SDMMC_TypeDef *SDMMCx)
Send the command asking the accessed card to send its operating condition register (OCR) ...
uint32_t SDMMC_CmdOperCond(SDMMC_TypeDef *SDMMCx)
Send the Operating Condition command and check the response.
uint32_t SDMMC_CmdSDEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
Send the Start Address Erase command for SD and check the response.
This file contains all the functions prototypes for the HAL module driver.
void HAL_Delay(uint32_t Delay)
This function provides minimum delay (in milliseconds) based on variable incremented.
SDMMC Data Control structure.
uint32_t SDMMC_CmdStatusRegister(SDMMC_TypeDef *SDMMCx)
Send the Status register command and check the response.
uint32_t SDMMC_CmdSendCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
Send the Send CSD command and check the response.
static uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx)
Checks for error conditions for R7 response.
uint32_t SDMMC_GetPowerState(SDMMC_TypeDef *SDMMCx)
Get SDMMC Power state.
static uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx)
Checks for error conditions for R2 (CID or CSD) response.
uint32_t SDMMC_CmdSwitch(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH comand.
WWDG_InitTypeDef Init
uint32_t SDMMC_CmdBusWidth(SDMMC_TypeDef *SDMMCx, uint32_t BusWidth)
Send the Bus Width command and check the response.
uint32_t SDMMC_GetFIFOCount(SDMMC_TypeDef *SDMMCx)
Get the FIFO data.
return HAL_OK
static uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx)
Checks for error conditions for R3 (OCR) response.
uint32_t SDMMC_ReadFIFO(SDMMC_TypeDef *SDMMCx)
Read data (word) from Rx FIFO in blocking mode (polling)
uint32_t SDMMC_CmdGoIdleState(SDMMC_TypeDef *SDMMCx)
Send the Go Idle State command and check the response.
HAL_StatusTypeDef SDMMC_SendCommand(SDMMC_TypeDef *SDMMCx, SDMMC_CmdInitTypeDef *Command)
Configure the SDMMC command path according to the specified parameters in SDMMC_CmdInitTypeDef struct...
static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx)
Checks for error conditions for CMD0.
uint32_t SDMMC_CmdEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
Send the End Address Erase command and check the response.
uint32_t SDMMC_CmdBlockLength(SDMMC_TypeDef *SDMMCx, uint32_t BlockSize)
Send the Data Block Lenght command and check the response.
uint32_t SDMMC_GetResponse(SDMMC_TypeDef *SDMMCx, uint32_t Response)
Return the response received from the card for the last command.
uint32_t SDMMC_CmdEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd)
Send the Start Address Erase command and check the response.
HAL_StatusTypeDef SDMMC_PowerState_Cycle(SDMMC_TypeDef *SDMMCx)
Set SDMMC Power state to Power-Cycle.
uint32_t SDMMC_CmdOpCondition(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
Sends host capacity support information and activates the card's initialization process. Send SDMMC_CMD_SEND_OP_COND command.
uint32_t SDMMC_CmdSendSCR(SDMMC_TypeDef *SDMMCx)
Send the Send SCR command and check the response.
static uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout)
Checks for error conditions for R1 response.
SDMMC Command Control structure.
uint32_t SDMMC_CmdAppOperCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
Send the command asking the accessed card to send its operating condition register (OCR) ...
uint32_t SDMMC_CmdErase(SDMMC_TypeDef *SDMMCx)
Send the Erase command and check the response.
uint8_t SDMMC_GetCommandResponse(SDMMC_TypeDef *SDMMCx)
Return the command index of last command for which response received.
uint32_t SDMMC_CmdWriteMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
Send the Write Multi Block command and check the response.
static uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA)
Checks for error conditions for R6 (RCA) response.
uint32_t SDMMC_CmdStopTransfer(SDMMC_TypeDef *SDMMCx)
Send the Stop Transfer command and check the response.
uint32_t SDMMC_CmdAppCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
Send the Application command to verify that that the next command is an application specific com-mand...
HAL_StatusTypeDef SDMMC_Init(SDMMC_TypeDef *SDMMCx, SDMMC_InitTypeDef Init)
Initializes the SDMMC according to the specified parameters in the SDMMC_InitTypeDef and create the a...
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
uint32_t SDMMC_CmdSetRelAdd(SDMMC_TypeDef *SDMMCx, uint16_t *pRCA)
Send the Send CSD command and check the response.
HAL_StatusTypeDef SDMMC_PowerState_ON(SDMMC_TypeDef *SDMMCx)
Set SDMMC Power state to ON.
uint32_t SDMMC_CmdSendCID(SDMMC_TypeDef *SDMMCx)
Send the Send CID command and check the response.
HAL_StatusTypeDef SDMMC_SetSDMMCReadWaitMode(SDMMC_TypeDef *SDMMCx, uint32_t SDMMC_ReadWaitMode)
Sets one of the two options of inserting read wait interval.
uint32_t SDMMC_CmdSendEXTCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
Send the Send EXT_CSD command and check the response.
HAL_StatusTypeDef SDMMC_WriteFIFO(SDMMC_TypeDef *SDMMCx, uint32_t *pWriteData)
Write data (word) to Tx FIFO in blocking mode (polling)
uint32_t SDMMC_CmdSendStatus(SDMMC_TypeDef *SDMMCx, uint32_t Argument)
Send the Status command and check the response.
uint32_t SDMMC_CmdSDEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd)
Send the End Address Erase command for SD and check the response.
uint32_t SDMMC_CmdWriteSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd)
Send the Write Single Block command and check the response.
assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock))
HAL_StatusTypeDef SDMMC_PowerState_OFF(SDMMC_TypeDef *SDMMCx)
Set SDMMC Power state to OFF.
HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef *Data)
Configure the SDMMC data path according to the specified parameters in the SDMMC_DataInitTypeDef.
uint32_t SDMMC_CmdReadMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
Send the Read Multi Block command and check the response.