STM32F4xx HAL Driver master
STM32CubeF4 HAL / LL Drivers API Reference
Loading...
Searching...
No Matches
stm32f4xx_ll_sdmmc.c
Go to the documentation of this file.
1
157
158/* Includes ------------------------------------------------------------------*/
159#include "stm32f4xx_hal.h"
160
161#if defined(SDIO)
162
166
171
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 -----------------------------------------------*/
179static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx);
180
181/* Exported functions --------------------------------------------------------*/
182
186
199
207HAL_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
239
254
260uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx)
261{
262 /* Read data from Rx FIFO */
263 return (SDIOx->FIFO);
264}
265
272HAL_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
283
298
304HAL_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
317HAL_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
334uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx)
335{
336 return (SDIOx->POWER & SDIO_POWER_PWRCTRL);
337}
338
347HAL_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
377uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx)
378{
379 return (uint8_t)(SDIOx->RESPCMD);
380}
381
382
394uint32_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
415HAL_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
450uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx)
451{
452 return (SDIOx->DCOUNT);
453}
454
460uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx)
461{
462 return (SDIOx->FIFO);
463}
464
474HAL_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
488
489
503
509uint32_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
533uint32_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
557uint32_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
581uint32_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
605uint32_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
629uint32_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
653uint32_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
677uint32_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
701uint32_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
725uint32_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
749uint32_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
774uint32_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
798uint32_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
821uint32_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
852uint32_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
880uint32_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
904uint32_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
927uint32_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
951uint32_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
976uint32_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
1001uint32_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
1026uint32_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
1051uint32_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
1074uint32_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
1099uint32_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
1123uint32_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
1149uint32_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
1171
1191uint32_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
1326uint32_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
1370uint32_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
1410uint32_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
1483uint32_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
1532
1533/* Private function ----------------------------------------------------------*/
1537
1543static 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
1568
1569#endif /* HAL_SD_MODULE_ENABLED || HAL_MMC_MODULE_ENABLED */
1573
1577
1578#endif /* SDIO */
#define assert_param(expr)
This file contains all the functions prototypes for the HAL module driver.
HAL_StatusTypeDef
HAL Status structures definition.
@ HAL_OK