STM32F4xx_HAL_Driver  1.8.3
stm32f4xx_ll_sdmmc.c
Go to the documentation of this file.
1 
158 /* Includes ------------------------------------------------------------------*/
159 #include "stm32f4xx_hal.h"
160 
161 #if defined(SDIO)
162 
172 #if defined(HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED)
173 
174 /* Private typedef -----------------------------------------------------------*/
175 /* Private define ------------------------------------------------------------*/
176 /* Private macro -------------------------------------------------------------*/
177 /* Private variables ---------------------------------------------------------*/
178 /* Private function prototypes -----------------------------------------------*/
179 static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx);
180 
181 /* Exported functions --------------------------------------------------------*/
182 
207 HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init)
208 {
209  uint32_t tmpreg = 0;
210 
211  /* Check the parameters */
212  assert_param(IS_SDIO_ALL_INSTANCE(SDIOx));
213  assert_param(IS_SDIO_CLOCK_EDGE(Init.ClockEdge));
214  assert_param(IS_SDIO_CLOCK_BYPASS(Init.ClockBypass));
215  assert_param(IS_SDIO_CLOCK_POWER_SAVE(Init.ClockPowerSave));
216  assert_param(IS_SDIO_BUS_WIDE(Init.BusWide));
217  assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
218  assert_param(IS_SDIO_CLKDIV(Init.ClockDiv));
219 
220  /* Set SDMMC configuration parameters */
221  tmpreg |= (Init.ClockEdge |\
222  Init.ClockBypass |\
223  Init.ClockPowerSave |\
224  Init.BusWide |\
225  Init.HardwareFlowControl |\
226  Init.ClockDiv
227  );
228 
229  /* Write to SDMMC CLKCR */
230  MODIFY_REG(SDIOx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);
231 
232  return HAL_OK;
233 }
234 
235 
260 uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx)
261 {
262  /* Read data from Rx FIFO */
263  return (SDIOx->FIFO);
264 }
265 
272 HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData)
273 {
274  /* Write data to FIFO */
275  SDIOx->FIFO = *pWriteData;
276 
277  return HAL_OK;
278 }
279 
304 HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx)
305 {
306  /* Set power state to ON */
307  SDIOx->POWER = SDIO_POWER_PWRCTRL;
308 
309  return HAL_OK;
310 }
311 
317 HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx)
318 {
319  /* Set power state to OFF */
320  SDIOx->POWER = (uint32_t)0x00000000;
321 
322  return HAL_OK;
323 }
324 
334 uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx)
335 {
336  return (SDIOx->POWER & SDIO_POWER_PWRCTRL);
337 }
338 
347 HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command)
348 {
349  uint32_t tmpreg = 0;
350 
351  /* Check the parameters */
352  assert_param(IS_SDIO_CMD_INDEX(Command->CmdIndex));
353  assert_param(IS_SDIO_RESPONSE(Command->Response));
354  assert_param(IS_SDIO_WAIT(Command->WaitForInterrupt));
355  assert_param(IS_SDIO_CPSM(Command->CPSM));
356 
357  /* Set the SDMMC Argument value */
358  SDIOx->ARG = Command->Argument;
359 
360  /* Set SDMMC command parameters */
361  tmpreg |= (uint32_t)(Command->CmdIndex |\
362  Command->Response |\
363  Command->WaitForInterrupt |\
364  Command->CPSM);
365 
366  /* Write to SDMMC CMD register */
367  MODIFY_REG(SDIOx->CMD, CMD_CLEAR_MASK, tmpreg);
368 
369  return HAL_OK;
370 }
371 
377 uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx)
378 {
379  return (uint8_t)(SDIOx->RESPCMD);
380 }
381 
382 
394 uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response)
395 {
396  uint32_t tmp;
397 
398  /* Check the parameters */
399  assert_param(IS_SDIO_RESP(Response));
400 
401  /* Get the response */
402  tmp = (uint32_t)(&(SDIOx->RESP1)) + Response;
403 
404  return (*(__IO uint32_t *) tmp);
405 }
406 
415 HAL_StatusTypeDef SDIO_ConfigData(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data)
416 {
417  uint32_t tmpreg = 0;
418 
419  /* Check the parameters */
420  assert_param(IS_SDIO_DATA_LENGTH(Data->DataLength));
421  assert_param(IS_SDIO_BLOCK_SIZE(Data->DataBlockSize));
422  assert_param(IS_SDIO_TRANSFER_DIR(Data->TransferDir));
423  assert_param(IS_SDIO_TRANSFER_MODE(Data->TransferMode));
424  assert_param(IS_SDIO_DPSM(Data->DPSM));
425 
426  /* Set the SDMMC Data TimeOut value */
427  SDIOx->DTIMER = Data->DataTimeOut;
428 
429  /* Set the SDMMC DataLength value */
430  SDIOx->DLEN = Data->DataLength;
431 
432  /* Set the SDMMC data configuration parameters */
433  tmpreg |= (uint32_t)(Data->DataBlockSize |\
434  Data->TransferDir |\
435  Data->TransferMode |\
436  Data->DPSM);
437 
438  /* Write to SDMMC DCTRL */
439  MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
440 
441  return HAL_OK;
442 
443 }
444 
450 uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx)
451 {
452  return (SDIOx->DCOUNT);
453 }
454 
460 uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx)
461 {
462  return (SDIOx->FIFO);
463 }
464 
474 HAL_StatusTypeDef SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode)
475 {
476  /* Check the parameters */
477  assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode));
478 
479  /* Set SDMMC read wait mode */
480  MODIFY_REG(SDIOx->DCTRL, SDIO_DCTRL_RWMOD, SDIO_ReadWaitMode);
481 
482  return HAL_OK;
483 }
484 
509 uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef *SDIOx, uint32_t BlockSize)
510 {
511  SDIO_CmdInitTypeDef sdmmc_cmdinit;
512  uint32_t errorstate;
513 
514  /* Set Block Size for Card */
515  sdmmc_cmdinit.Argument = (uint32_t)BlockSize;
516  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCKLEN;
517  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
518  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
519  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
520  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
521 
522  /* Check for error conditions */
523  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SET_BLOCKLEN, SDIO_CMDTIMEOUT);
524 
525  return errorstate;
526 }
527 
533 uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
534 {
535  SDIO_CmdInitTypeDef sdmmc_cmdinit;
536  uint32_t errorstate;
537 
538  /* Set Block Size for Card */
539  sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
540  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_SINGLE_BLOCK;
541  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
542  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
543  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
544  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
545 
546  /* Check for error conditions */
547  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
548 
549  return errorstate;
550 }
551 
557 uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
558 {
559  SDIO_CmdInitTypeDef sdmmc_cmdinit;
560  uint32_t errorstate;
561 
562  /* Set Block Size for Card */
563  sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
564  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_MULT_BLOCK;
565  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
566  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
567  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
568  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
569 
570  /* Check for error conditions */
571  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_MULT_BLOCK, SDIO_CMDTIMEOUT);
572 
573  return errorstate;
574 }
575 
581 uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
582 {
583  SDIO_CmdInitTypeDef sdmmc_cmdinit;
584  uint32_t errorstate;
585 
586  /* Set Block Size for Card */
587  sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
588  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_SINGLE_BLOCK;
589  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
590  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
591  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
592  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
593 
594  /* Check for error conditions */
595  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
596 
597  return errorstate;
598 }
599 
605 uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
606 {
607  SDIO_CmdInitTypeDef sdmmc_cmdinit;
608  uint32_t errorstate;
609 
610  /* Set Block Size for Card */
611  sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
612  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_MULT_BLOCK;
613  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
614  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
615  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
616  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
617 
618  /* Check for error conditions */
619  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_MULT_BLOCK, SDIO_CMDTIMEOUT);
620 
621  return errorstate;
622 }
623 
629 uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
630 {
631  SDIO_CmdInitTypeDef sdmmc_cmdinit;
632  uint32_t errorstate;
633 
634  /* Set Block Size for Card */
635  sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
636  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_START;
637  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
638  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
639  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
640  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
641 
642  /* Check for error conditions */
643  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
644 
645  return errorstate;
646 }
647 
653 uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
654 {
655  SDIO_CmdInitTypeDef sdmmc_cmdinit;
656  uint32_t errorstate;
657 
658  /* Set Block Size for Card */
659  sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
660  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_END;
661  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
662  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
663  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
664  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
665 
666  /* Check for error conditions */
667  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
668 
669  return errorstate;
670 }
671 
677 uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
678 {
679  SDIO_CmdInitTypeDef sdmmc_cmdinit;
680  uint32_t errorstate;
681 
682  /* Set Block Size for Card */
683  sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
684  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_START;
685  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
686  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
687  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
688  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
689 
690  /* Check for error conditions */
691  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
692 
693  return errorstate;
694 }
695 
701 uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
702 {
703  SDIO_CmdInitTypeDef sdmmc_cmdinit;
704  uint32_t errorstate;
705 
706  /* Set Block Size for Card */
707  sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
708  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_END;
709  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
710  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
711  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
712  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
713 
714  /* Check for error conditions */
715  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
716 
717  return errorstate;
718 }
719 
725 uint32_t SDMMC_CmdErase(SDIO_TypeDef *SDIOx)
726 {
727  SDIO_CmdInitTypeDef sdmmc_cmdinit;
728  uint32_t errorstate;
729 
730  /* Set Block Size for Card */
731  sdmmc_cmdinit.Argument = 0U;
732  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE;
733  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
734  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
735  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
736  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
737 
738  /* Check for error conditions */
739  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE, SDIO_MAXERASETIMEOUT);
740 
741  return errorstate;
742 }
743 
749 uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef *SDIOx)
750 {
751  SDIO_CmdInitTypeDef sdmmc_cmdinit;
752  uint32_t errorstate;
753 
754  /* Send CMD12 STOP_TRANSMISSION */
755  sdmmc_cmdinit.Argument = 0U;
756  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION;
757  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
758  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
759  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
760  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
761 
762  /* Check for error conditions */
763  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_STOP_TRANSMISSION, SDIO_STOPTRANSFERTIMEOUT);
764 
765  return errorstate;
766 }
767 
774 uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef *SDIOx, uint64_t Addr)
775 {
776  SDIO_CmdInitTypeDef sdmmc_cmdinit;
777  uint32_t errorstate;
778 
779  /* Send CMD7 SDMMC_SEL_DESEL_CARD */
780  sdmmc_cmdinit.Argument = (uint32_t)Addr;
781  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEL_DESEL_CARD;
782  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
783  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
784  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
785  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
786 
787  /* Check for error conditions */
788  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEL_DESEL_CARD, SDIO_CMDTIMEOUT);
789 
790  return errorstate;
791 }
792 
798 uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef *SDIOx)
799 {
800  SDIO_CmdInitTypeDef sdmmc_cmdinit;
801  uint32_t errorstate;
802 
803  sdmmc_cmdinit.Argument = 0U;
804  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE;
805  sdmmc_cmdinit.Response = SDIO_RESPONSE_NO;
806  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
807  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
808  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
809 
810  /* Check for error conditions */
811  errorstate = SDMMC_GetCmdError(SDIOx);
812 
813  return errorstate;
814 }
815 
821 uint32_t SDMMC_CmdOperCond(SDIO_TypeDef *SDIOx)
822 {
823  SDIO_CmdInitTypeDef sdmmc_cmdinit;
824  uint32_t errorstate;
825 
826  /* Send CMD8 to verify SD card interface operating condition */
827  /* Argument: - [31:12]: Reserved (shall be set to '0')
828  - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
829  - [7:0]: Check Pattern (recommended 0xAA) */
830  /* CMD Response: R7 */
831  sdmmc_cmdinit.Argument = SDMMC_CHECK_PATTERN;
832  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
833  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
834  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
835  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
836  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
837 
838  /* Check for error conditions */
839  errorstate = SDMMC_GetCmdResp7(SDIOx);
840 
841  return errorstate;
842 }
843 
852 uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
853 {
854  SDIO_CmdInitTypeDef sdmmc_cmdinit;
855  uint32_t errorstate;
856 
857  sdmmc_cmdinit.Argument = (uint32_t)Argument;
858  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_CMD;
859  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
860  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
861  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
862  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
863 
864  /* Check for error conditions */
865  /* If there is a HAL_ERROR, it is a MMC card, else
866  it is a SD card: SD card 2.0 (voltage range mismatch)
867  or SD card 1.x */
868  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_CMD, SDIO_CMDTIMEOUT);
869 
870  return errorstate;
871 }
872 
880 uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
881 {
882  SDIO_CmdInitTypeDef sdmmc_cmdinit;
883  uint32_t errorstate;
884 
885  sdmmc_cmdinit.Argument = SDMMC_VOLTAGE_WINDOW_SD | Argument;
886  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_OP_COND;
887  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
888  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
889  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
890  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
891 
892  /* Check for error conditions */
893  errorstate = SDMMC_GetCmdResp3(SDIOx);
894 
895  return errorstate;
896 }
897 
904 uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef *SDIOx, uint32_t BusWidth)
905 {
906  SDIO_CmdInitTypeDef sdmmc_cmdinit;
907  uint32_t errorstate;
908 
909  sdmmc_cmdinit.Argument = (uint32_t)BusWidth;
910  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
911  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
912  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
913  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
914  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
915 
916  /* Check for error conditions */
917  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDIO_CMDTIMEOUT);
918 
919  return errorstate;
920 }
921 
927 uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef *SDIOx)
928 {
929  SDIO_CmdInitTypeDef sdmmc_cmdinit;
930  uint32_t errorstate;
931 
932  /* Send CMD51 SD_APP_SEND_SCR */
933  sdmmc_cmdinit.Argument = 0U;
934  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR;
935  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
936  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
937  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
938  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
939 
940  /* Check for error conditions */
941  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_SEND_SCR, SDIO_CMDTIMEOUT);
942 
943  return errorstate;
944 }
945 
951 uint32_t SDMMC_CmdSendCID(SDIO_TypeDef *SDIOx)
952 {
953  SDIO_CmdInitTypeDef sdmmc_cmdinit;
954  uint32_t errorstate;
955 
956  /* Send CMD2 ALL_SEND_CID */
957  sdmmc_cmdinit.Argument = 0U;
958  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID;
959  sdmmc_cmdinit.Response = SDIO_RESPONSE_LONG;
960  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
961  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
962  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
963 
964  /* Check for error conditions */
965  errorstate = SDMMC_GetCmdResp2(SDIOx);
966 
967  return errorstate;
968 }
969 
976 uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef *SDIOx, uint32_t Argument)
977 {
978  SDIO_CmdInitTypeDef sdmmc_cmdinit;
979  uint32_t errorstate;
980 
981  /* Send CMD9 SEND_CSD */
982  sdmmc_cmdinit.Argument = Argument;
983  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_CSD;
984  sdmmc_cmdinit.Response = SDIO_RESPONSE_LONG;
985  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
986  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
987  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
988 
989  /* Check for error conditions */
990  errorstate = SDMMC_GetCmdResp2(SDIOx);
991 
992  return errorstate;
993 }
994 
1001 uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef *SDIOx, uint16_t *pRCA)
1002 {
1003  SDIO_CmdInitTypeDef sdmmc_cmdinit;
1004  uint32_t errorstate;
1005 
1006  /* Send CMD3 SD_CMD_SET_REL_ADDR */
1007  sdmmc_cmdinit.Argument = 0U;
1008  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
1009  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
1010  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1011  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
1012  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1013 
1014  /* Check for error conditions */
1015  errorstate = SDMMC_GetCmdResp6(SDIOx, SDMMC_CMD_SET_REL_ADDR, pRCA);
1016 
1017  return errorstate;
1018 }
1019 
1026 uint32_t SDMMC_CmdSetRelAddMmc(SDIO_TypeDef *SDIOx, uint16_t RCA)
1027 {
1028  SDIO_CmdInitTypeDef sdmmc_cmdinit;
1029  uint32_t errorstate;
1030 
1031  /* Send CMD3 SD_CMD_SET_REL_ADDR */
1032  sdmmc_cmdinit.Argument = ((uint32_t)RCA << 16U);
1033  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
1034  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
1035  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1036  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
1037  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1038 
1039  /* Check for error conditions */
1040  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SET_REL_ADDR, SDIO_CMDTIMEOUT);
1041 
1042  return errorstate;
1043 }
1044 
1051 uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef *SDIOx, uint32_t Argument)
1052 {
1053  SDIO_CmdInitTypeDef sdmmc_cmdinit;
1054  uint32_t errorstate;
1055 
1056  sdmmc_cmdinit.Argument = Argument;
1057  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS;
1058  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
1059  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1060  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
1061  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1062 
1063  /* Check for error conditions */
1064  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEND_STATUS, SDIO_CMDTIMEOUT);
1065 
1066  return errorstate;
1067 }
1068 
1074 uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef *SDIOx)
1075 {
1076  SDIO_CmdInitTypeDef sdmmc_cmdinit;
1077  uint32_t errorstate;
1078 
1079  sdmmc_cmdinit.Argument = 0U;
1080  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS;
1081  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
1082  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1083  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
1084  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1085 
1086  /* Check for error conditions */
1087  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_STATUS, SDIO_CMDTIMEOUT);
1088 
1089  return errorstate;
1090 }
1091 
1099 uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef *SDIOx, uint32_t Argument)
1100 {
1101  SDIO_CmdInitTypeDef sdmmc_cmdinit;
1102  uint32_t errorstate;
1103 
1104  sdmmc_cmdinit.Argument = Argument;
1105  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_OP_COND;
1106  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
1107  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1108  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
1109  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1110 
1111  /* Check for error conditions */
1112  errorstate = SDMMC_GetCmdResp3(SDIOx);
1113 
1114  return errorstate;
1115 }
1116 
1123 uint32_t SDMMC_CmdSwitch(SDIO_TypeDef *SDIOx, uint32_t Argument)
1124 {
1125  SDIO_CmdInitTypeDef sdmmc_cmdinit;
1126  uint32_t errorstate;
1127 
1128  /* Send CMD6 to activate SDR50 Mode and Power Limit 1.44W */
1129  /* CMD Response: R1 */
1130  sdmmc_cmdinit.Argument = Argument; /* SDMMC_SDR25_SWITCH_PATTERN */
1131  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SWITCH;
1132  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
1133  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1134  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
1135  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1136 
1137  /* Check for error conditions */
1138  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_HS_SWITCH, SDIO_CMDTIMEOUT);
1139 
1140  return errorstate;
1141 }
1142 
1149 uint32_t SDMMC_CmdSendEXTCSD(SDIO_TypeDef *SDIOx, uint32_t Argument)
1150 {
1151  SDIO_CmdInitTypeDef sdmmc_cmdinit;
1152  uint32_t errorstate;
1153 
1154  /* Send CMD9 SEND_CSD */
1155  sdmmc_cmdinit.Argument = Argument;
1156  sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
1157  sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
1158  sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
1159  sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
1160  (void)SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
1161 
1162  /* Check for error conditions */
1163  errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_HS_SEND_EXT_CSD,SDIO_CMDTIMEOUT);
1164 
1165  return errorstate;
1166 }
1167 
1191 uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
1192 {
1193  uint32_t response_r1;
1194  uint32_t sta_reg;
1195 
1196  /* 8 is the number of required instructions cycles for the below loop statement.
1197  The Timeout is expressed in ms */
1198  uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
1199 
1200  do
1201  {
1202  if (count-- == 0U)
1203  {
1204  return SDMMC_ERROR_TIMEOUT;
1205  }
1206  sta_reg = SDIOx->STA;
1207  }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1208  ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1209 
1210  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1211  {
1212  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1213 
1214  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1215  }
1216  else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1217  {
1218  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1219 
1220  return SDMMC_ERROR_CMD_CRC_FAIL;
1221  }
1222  else
1223  {
1224  /* Nothing to do */
1225  }
1226 
1227  /* Clear all the static flags */
1228  __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1229 
1230  /* Check response received is of desired command */
1231  if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
1232  {
1233  return SDMMC_ERROR_CMD_CRC_FAIL;
1234  }
1235 
1236  /* We have received response, retrieve it for analysis */
1237  response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
1238 
1239  if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
1240  {
1241  return SDMMC_ERROR_NONE;
1242  }
1243  else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
1244  {
1245  return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
1246  }
1247  else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
1248  {
1249  return SDMMC_ERROR_ADDR_MISALIGNED;
1250  }
1251  else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
1252  {
1253  return SDMMC_ERROR_BLOCK_LEN_ERR;
1254  }
1255  else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
1256  {
1257  return SDMMC_ERROR_ERASE_SEQ_ERR;
1258  }
1259  else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
1260  {
1261  return SDMMC_ERROR_BAD_ERASE_PARAM;
1262  }
1263  else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
1264  {
1265  return SDMMC_ERROR_WRITE_PROT_VIOLATION;
1266  }
1267  else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
1268  {
1269  return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
1270  }
1271  else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
1272  {
1273  return SDMMC_ERROR_COM_CRC_FAILED;
1274  }
1275  else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
1276  {
1277  return SDMMC_ERROR_ILLEGAL_CMD;
1278  }
1279  else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
1280  {
1281  return SDMMC_ERROR_CARD_ECC_FAILED;
1282  }
1283  else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
1284  {
1285  return SDMMC_ERROR_CC_ERR;
1286  }
1287  else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
1288  {
1289  return SDMMC_ERROR_STREAM_READ_UNDERRUN;
1290  }
1291  else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
1292  {
1293  return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
1294  }
1295  else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
1296  {
1297  return SDMMC_ERROR_CID_CSD_OVERWRITE;
1298  }
1299  else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
1300  {
1301  return SDMMC_ERROR_WP_ERASE_SKIP;
1302  }
1303  else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
1304  {
1305  return SDMMC_ERROR_CARD_ECC_DISABLED;
1306  }
1307  else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
1308  {
1309  return SDMMC_ERROR_ERASE_RESET;
1310  }
1311  else if((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
1312  {
1313  return SDMMC_ERROR_AKE_SEQ_ERR;
1314  }
1315  else
1316  {
1317  return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1318  }
1319 }
1320 
1326 uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx)
1327 {
1328  uint32_t sta_reg;
1329  /* 8 is the number of required instructions cycles for the below loop statement.
1330  The SDIO_CMDTIMEOUT is expressed in ms */
1331  uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1332 
1333  do
1334  {
1335  if (count-- == 0U)
1336  {
1337  return SDMMC_ERROR_TIMEOUT;
1338  }
1339  sta_reg = SDIOx->STA;
1340  }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1341  ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1342 
1343  if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1344  {
1345  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1346 
1347  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1348  }
1349  else if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1350  {
1351  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1352 
1353  return SDMMC_ERROR_CMD_CRC_FAIL;
1354  }
1355  else
1356  {
1357  /* No error flag set */
1358  /* Clear all the static flags */
1359  __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1360  }
1361 
1362  return SDMMC_ERROR_NONE;
1363 }
1364 
1370 uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx)
1371 {
1372  uint32_t sta_reg;
1373  /* 8 is the number of required instructions cycles for the below loop statement.
1374  The SDIO_CMDTIMEOUT is expressed in ms */
1375  uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1376 
1377  do
1378  {
1379  if (count-- == 0U)
1380  {
1381  return SDMMC_ERROR_TIMEOUT;
1382  }
1383  sta_reg = SDIOx->STA;
1384  }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1385  ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1386 
1387  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1388  {
1389  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1390 
1391  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1392  }
1393  else
1394  {
1395  /* Clear all the static flags */
1396  __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1397  }
1398 
1399  return SDMMC_ERROR_NONE;
1400 }
1401 
1410 uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA)
1411 {
1412  uint32_t response_r1;
1413  uint32_t sta_reg;
1414 
1415  /* 8 is the number of required instructions cycles for the below loop statement.
1416  The SDIO_CMDTIMEOUT is expressed in ms */
1417  uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1418 
1419  do
1420  {
1421  if (count-- == 0U)
1422  {
1423  return SDMMC_ERROR_TIMEOUT;
1424  }
1425  sta_reg = SDIOx->STA;
1426  }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1427  ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1428 
1429  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1430  {
1431  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1432 
1433  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1434  }
1435  else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1436  {
1437  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1438 
1439  return SDMMC_ERROR_CMD_CRC_FAIL;
1440  }
1441  else
1442  {
1443  /* Nothing to do */
1444  }
1445 
1446  /* Check response received is of desired command */
1447  if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
1448  {
1449  return SDMMC_ERROR_CMD_CRC_FAIL;
1450  }
1451 
1452  /* Clear all the static flags */
1453  __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1454 
1455  /* We have received response, retrieve it. */
1456  response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
1457 
1458  if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
1459  {
1460  *pRCA = (uint16_t) (response_r1 >> 16);
1461 
1462  return SDMMC_ERROR_NONE;
1463  }
1464  else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
1465  {
1466  return SDMMC_ERROR_ILLEGAL_CMD;
1467  }
1468  else if((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
1469  {
1470  return SDMMC_ERROR_COM_CRC_FAILED;
1471  }
1472  else
1473  {
1474  return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
1475  }
1476 }
1477 
1483 uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx)
1484 {
1485  uint32_t sta_reg;
1486  /* 8 is the number of required instructions cycles for the below loop statement.
1487  The SDIO_CMDTIMEOUT is expressed in ms */
1488  uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1489 
1490  do
1491  {
1492  if (count-- == 0U)
1493  {
1494  return SDMMC_ERROR_TIMEOUT;
1495  }
1496  sta_reg = SDIOx->STA;
1497  }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
1498  ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
1499 
1500  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
1501  {
1502  /* Card is SD V2.0 compliant */
1503  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
1504 
1505  return SDMMC_ERROR_CMD_RSP_TIMEOUT;
1506  }
1507  else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
1508  {
1509  /* Card is SD V2.0 compliant */
1510  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
1511 
1512  return SDMMC_ERROR_CMD_CRC_FAIL;
1513  }
1514  else
1515  {
1516  /* Nothing to do */
1517  }
1518 
1519  if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDREND))
1520  {
1521  /* Card is SD V2.0 compliant */
1522  __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
1523  }
1524 
1525  return SDMMC_ERROR_NONE;
1526 
1527 }
1528 
1533 /* Private function ----------------------------------------------------------*/
1543 static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx)
1544 {
1545  /* 8 is the number of required instructions cycles for the below loop statement.
1546  The SDIO_CMDTIMEOUT is expressed in ms */
1547  uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
1548 
1549  do
1550  {
1551  if (count-- == 0U)
1552  {
1553  return SDMMC_ERROR_TIMEOUT;
1554  }
1555 
1556  }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDSENT));
1557 
1558  /* Clear all the static flags */
1559  __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS);
1560 
1561  return SDMMC_ERROR_NONE;
1562 }
1563 
1564 
1569 #endif /* HAL_SD_MODULE_ENABLED || HAL_MMC_MODULE_ENABLED */
1578 #endif /* SDIO */
HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init)
Initializes the SDMMC according to the specified parameters in the SDMMC_InitTypeDef and create the a...
uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx)
Read data (word) from Rx FIFO in blocking mode (polling)
HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData)
Write data (word) to Tx FIFO in blocking mode (polling)
HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx)
Set SDMMC Power state to OFF.
uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx)
Get SDMMC Power state.
HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command)
Configure the SDMMC command path according to the specified parameters in SDIO_CmdInitTypeDef structu...
HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx)
Set SDMMC Power state to ON.
HAL_StatusTypeDef SDIO_ConfigData(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef *Data)
Configure the SDMMC data path according to the specified parameters in the SDIO_DataInitTypeDef.
uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx)
Return the command index of last command for which response received.
uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx)
Get the FIFO data.
uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx)
Returns number of remaining data bytes to be transferred.
uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response)
Return the response received from the card for the last command.
HAL_StatusTypeDef SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode)
Sets one of the two options of inserting read wait interval.
uint32_t SDMMC_CmdSwitch(SDIO_TypeDef *SDIOx, uint32_t Argument)
Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH command.
uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef *SDIOx, uint64_t Addr)
Send the Select Deselect command and check the response.
uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef *SDIOx, uint32_t BlockSize)
Send the Data Block Length command and check the response.
uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
Send the Write Single Block command and check the response.
uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
Send the Application command to verify that that the next command is an application specific com-mand...
uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
Send the Start Address Erase command and check the response.
uint32_t SDMMC_CmdOperCond(SDIO_TypeDef *SDIOx)
Send the Operating Condition command and check the response.
uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef *SDIOx)
Send the Go Idle State command and check the response.
uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef *SDIOx, uint32_t BusWidth)
Send the Bus Width command and check the response.
uint32_t SDMMC_CmdSetRelAddMmc(SDIO_TypeDef *SDIOx, uint16_t RCA)
Send the Set Relative Address command to MMC card (not SD card).
uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
Send the Write Multi Block command and check the response.
uint32_t SDMMC_CmdErase(SDIO_TypeDef *SDIOx)
Send the Erase command and check the response.
uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
Send the End Address Erase command and check the response.
uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef *SDIOx)
Send the Stop Transfer command and check the response.
uint32_t SDMMC_CmdSendEXTCSD(SDIO_TypeDef *SDIOx, uint32_t Argument)
Send the Send EXT_CSD command and check the response.
uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
Send the Start Address Erase command for SD and check the response.
uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef *SDIOx)
Send the Send SCR command and check the response.
uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef *SDIOx)
Send the Status register command and check the response.
uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef *SDIOx, uint32_t Argument)
Send the Send CSD command and check the response.
uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
Send the Read Multi Block command and check the response.
uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef *SDIOx, uint32_t Argument)
Sends host capacity support information and activates the card's initialization process....
uint32_t SDMMC_CmdSendCID(SDIO_TypeDef *SDIOx)
Send the Send CID command and check the response.
uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef *SDIOx, uint16_t *pRCA)
Send the Send CSD command and check the response.
uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
Send the Read Single Block command and check the response.
uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
Send the End Address Erase command for SD and check the response.
uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
Send the command asking the accessed card to send its operating condition register (OCR)
uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef *SDIOx, uint32_t Argument)
Send the Status command and check the response.
uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx)
Checks for error conditions for R7 response.
uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx)
Checks for error conditions for R2 (CID or CSD) response.
uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA)
Checks for error conditions for R6 (RCA) response.
uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx)
Checks for error conditions for R3 (OCR) response.
uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
Checks for error conditions for R1 response.
This file contains all the functions prototypes for the HAL module driver.
SDMMC Command Control structure.
SDMMC Data Control structure.