搜索

GD32F207 操作SD卡

[复制链接]
168|28
 楼主 | 2020-3-31 22:29 | 显示全部楼层 |阅读模式
初始化SD卡
  1. SD_Err SD_Init(void)
  2. {
  3.     SD_Err Status = SD_OK;
  4.    
  5.     /* Configure GPIO about SDIO interface */
  6.     GPIO_Configuration();
  7.    
  8.     /* Enable the SDIO and DMA2 Clock */
  9.     RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_SDIO | RCC_AHBPERIPH_DMA2, ENABLE);
  10.    
  11.     /* Deinitialize the SDIO */
  12.     SDIO_DeInit();
  13.    
  14.     /* Configure the communication clock and the work voltage */
  15.     Status = SD_PWR_ON();
  16.     if (Status != SD_OK)
  17.     {
  18.         return(Status);
  19.     }

  20.     /* Init the card */
  21.     Status = SD_Init_Card();
  22.     if (Status != SD_OK)
  23.     {
  24.         return(Status);
  25.     }

  26.     /* Configure the SDIO peripheral */
  27.     /* HCLK = SDIOCLK = 72 MHz, SDIO_CLK = HCLK/(2 + 1) = 24 MHz */  
  28.     SDIO_InitStructure.SDIO_ClockDiv = 0x04;
  29.     SDIO_InitStructure.SDIO_ClockEdge = SDIO_CLOCKEDGE_RISING;
  30.     SDIO_InitStructure.SDIO_ClockBypassState = SDIO_CLOCKBYPASSSTATE_DISABLE;
  31.     SDIO_InitStructure.SDIO_ClockPWRSave = SDIO_CLOCKPWRSAVE_DISABLE;
  32.     SDIO_InitStructure.SDIO_BusMode = SDIO_BUSMODE_1B;
  33.     SDIO_InitStructure.SDIO_HWFlowCtrlState = SDIO_HWFLOWCTRLSTATE_ENABLE;
  34.     SDIO_Init(&SDIO_InitStructure);
  35.    
  36.     return(Status);
  37. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 22:30 | 显示全部楼层
配置通讯时钟和工作电压
  1. SD_Err SD_PWR_ON(void)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint32_t response = 0, count = 0;
  5.     uint8_t busy =0;
  6.     uint32_t SDType = SD_STD_CAPACITY;
  7.    
  8.     /* Configure the SDIO peripheral */
  9.     SDIO_InitStructure.SDIO_ClockDiv = 298;
  10.     SDIO_InitStructure.SDIO_ClockEdge = SDIO_CLOCKEDGE_RISING ;
  11.     SDIO_InitStructure.SDIO_ClockBypassState = SDIO_CLOCKBYPASSSTATE_DISABLE;
  12.     SDIO_InitStructure.SDIO_ClockPWRSave = SDIO_CLOCKPWRSAVE_DISABLE;
  13.     SDIO_InitStructure.SDIO_BusMode = SDIO_BUSMODE_1B;
  14.     SDIO_InitStructure.SDIO_HWFlowCtrlState = SDIO_HWFLOWCTRLSTATE_DISABLE;
  15.     SDIO_Init(&SDIO_InitStructure);
  16.    
  17.     /* Configure Power State to ON */
  18.     SDIO_SetPWRState(SDIO_PWRSTATE_ON);
  19.    
  20.     /* Enable SDIO Clock */
  21.     SDIO_Clock_Enable(ENABLE);
  22.    
  23.     /* Send CMD0 to reset the card(No response required) */
  24.     SDIO_CmdInitStructure.SDIO_CMDParameter = 0x0;
  25.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_GO_IDLE_STATE;
  26.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_NO;
  27.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  28.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  29.     SDIO_SendCMD(&SDIO_CmdInitStructure);
  30.    
  31.     /* Check CMD errors */
  32.     Status = Check_Err();
  33.     if (Status != SD_OK)
  34.     {
  35.         return(Status);
  36.     }

  37.     /* Send CMD8 to verify SD card interface operating condition(R7 response required) */
  38.     SDIO_CmdInitStructure.SDIO_CMDParameter = SD_CHECK_PATTERN;
  39.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_IF_COND;
  40.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  41.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  42.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  43.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  44.     /* Check CMD errors */
  45.     if (Check_Err_R7() == SD_OK)
  46.     {
  47.         CardType = SDIO_STD_CAPACITY_SD_CARD_V2_0; /* SD Card 2.0 */
  48.         SDType = SD_HIGH_CAPACITY;
  49.     }

  50.     /* Send CMD55, the next CMD is Application Specific Commands */
  51.     SDIO_CmdInitStructure.SDIO_CMDParameter = 0x00;
  52.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_CMD;
  53.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  54.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  55.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  56.     SDIO_SendCMD(&SDIO_CmdInitStructure);
  57.    
  58.    
  59.     /* It is SD memory card */
  60.     if (Check_Err_R1(SDIO_APP_CMD) == SD_OK)
  61.     {
  62.         /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
  63.         while ((!busy) && (count < SD_MAX_VOLT_TRIAL))
  64.         {
  65.             /* SEND CMD55 APP_CMD with RCA as 0 */
  66.             SDIO_CmdInitStructure.SDIO_CMDParameter = 0x00;
  67.             SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_CMD;
  68.             SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  69.             SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  70.             SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  71.             SDIO_SendCMD(&SDIO_CmdInitStructure);

  72.             /* Check CMD errors */
  73.             Status = Check_Err_R1(SDIO_APP_CMD);
  74.             if (Status != SD_OK)
  75.             {
  76.                 return(Status);
  77.             }

  78.             /* Send ACMD41 to know the work voltage */
  79.             SDIO_CmdInitStructure.SDIO_CMDParameter = SD_VOLTAGE_WINDOW_SD | SDType;
  80.             SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SD_APP_OP_COND;
  81.             SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  82.             SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  83.             SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  84.             SDIO_SendCMD(&SDIO_CmdInitStructure);

  85.             /* Check CMD errors */
  86.             Status = Check_Err_R3();
  87.             if (Status != SD_OK)
  88.             {
  89.                 return(Status);
  90.             }
  91.             response = SDIO_GetResponse(SDIO_RESP1);
  92.             busy = (uint8_t) (((response >> 31) == 1) ? 1 : 0);
  93.             count++;
  94.         }
  95.         if (count >= SD_MAX_VOLT_TRIAL)
  96.         {
  97.             Status = SD_INVALID_VOLTRANGE;
  98.             return(Status);
  99.         }
  100.         /* It is SDHC card */
  101.         if (response &= SD_HIGH_CAPACITY)
  102.         {
  103.             CardType = SDIO_HIGH_CAPACITY_SD_CARD;
  104.         }
  105.     }/* else MMC Card */
  106.   return(Status);
  107. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 22:31 | 显示全部楼层
关闭SDIO的电源
  1. SD_Err SD_PowerOFF(void)
  2. {
  3.     SD_Err Status = SD_OK;

  4.     /* Set Power State to OFF */
  5.     SDIO_SetPWRState(SDIO_PWRSTATE_OFF);

  6.     return(Status);
  7. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 22:32 | 显示全部楼层
获取卡的CID和CSD,使其进入待机状态
  1. SD_Err SD_Init_Card(void)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint16_t rca = 0x01;
  5.    
  6.     if (SDIO_GetPWRState() == SDIO_PWRSTATE_OFF)
  7.     {
  8.         Status = SD_REQUEST_NOT_APPLICABLE;
  9.         return(Status);
  10.     }
  11.    
  12.     /* The card is not I/O only card */
  13.     if (SDIO_SECURE_DIGITAL_IO_CARD != CardType)      
  14.     {
  15.         /* Send CMD2 to get the CID */
  16.         SDIO_CmdInitStructure.SDIO_CMDParameter = 0x0;
  17.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_ALL_SEND_CID;
  18.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_LONG;
  19.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  20.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  21.         SDIO_SendCMD(&SDIO_CmdInitStructure);
  22.         
  23.         /* Check CMD errors */
  24.         Status = Check_Err_R2();
  25.         if (SD_OK != Status)
  26.         {
  27.           return(Status);
  28.         }

  29.         CID_Tab[0] = SDIO_GetResponse(SDIO_RESP1);
  30.         CID_Tab[1] = SDIO_GetResponse(SDIO_RESP2);
  31.         CID_Tab[2] = SDIO_GetResponse(SDIO_RESP3);
  32.         CID_Tab[3] = SDIO_GetResponse(SDIO_RESP4);
  33.     }

  34.     /* The card is SD memory or the I/O card has the memory portion */
  35.     if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_SECURE_DIGITAL_IO_COMBO_CARD == CardType)
  36.      || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
  37.     {
  38.         /* Send CMD3 to set the RCA */
  39.         SDIO_CmdInitStructure.SDIO_CMDParameter = 0x00;
  40.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SET_REL_ADDR;
  41.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  42.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  43.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  44.         SDIO_SendCMD(&SDIO_CmdInitStructure);
  45.         
  46.         /* Check CMD errors */
  47.         Status = Check_Err_R6(SDIO_SET_REL_ADDR, &rca);
  48.         if (SD_OK != Status)
  49.         {
  50.             return(Status);
  51.         }
  52.     }
  53.    
  54.     /* The card is not I/O only card */
  55.     if (SDIO_SECURE_DIGITAL_IO_CARD != CardType)
  56.     {
  57.         RCA = rca;

  58.         /* Send CMD9 SEND_CSD with argument as card's RCA */
  59.         SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t)(rca << 16);
  60.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_CSD;
  61.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_LONG;
  62.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  63.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  64.         SDIO_SendCMD(&SDIO_CmdInitStructure);
  65.         
  66.         /* Check CMD errors */
  67.         Status = Check_Err_R2();
  68.         if (SD_OK != Status)
  69.         {
  70.             return(Status);
  71.         }
  72.         
  73.         CSD_Tab[0] = SDIO_GetResponse(SDIO_RESP1);
  74.         CSD_Tab[1] = SDIO_GetResponse(SDIO_RESP2);
  75.         CSD_Tab[2] = SDIO_GetResponse(SDIO_RESP3);
  76.         CSD_Tab[3] = SDIO_GetResponse(SDIO_RESP4);
  77.     }

  78.     Status = SD_OK;

  79.     return(Status);
  80. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 22:34 | 显示全部楼层
从CID和CSD获取卡的信息
  1. SD_Err SD_Get_Card_Information(SD_CardInformation *cardinfo)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint8_t tmp = 0;
  5.    
  6.     /* Card type */
  7.     cardinfo->CardType = (uint8_t)CardType;

  8.     /* Relative card address */
  9.     cardinfo->RCA = (uint16_t)RCA;
  10.    
  11.     /* CSD Bytes */
  12.     /* Byte 0 */
  13.     tmp = (uint8_t)((CSD_Tab[0] & 0xFF000000) >> 24);
  14.     cardinfo->SD_csd.CSDStruct = (tmp & 0xC0) >> 6;
  15.     cardinfo->SD_csd.SysSpecVersion = (tmp & 0x3C) >> 2;
  16.     cardinfo->SD_csd.Reserved1 = tmp & 0x03;
  17.    
  18.     /* Byte 1 */
  19.     tmp = (uint8_t)((CSD_Tab[0] & 0x00FF0000) >> 16);
  20.     cardinfo->SD_csd.TAAC = tmp;
  21.    
  22.     /* Byte 2 */
  23.     tmp = (uint8_t)((CSD_Tab[0] & 0x0000FF00) >> 8);
  24.     cardinfo->SD_csd.NSAC = tmp;
  25.    
  26.     /* Byte 3 */
  27.     tmp = (uint8_t)(CSD_Tab[0] & 0x000000FF);
  28.     cardinfo->SD_csd.MaxBusClkFrec = tmp;
  29.    
  30.     /* Byte 4 */
  31.     tmp = (uint8_t)((CSD_Tab[1] & 0xFF000000) >> 24);
  32.     cardinfo->SD_csd.CardComdClasses = tmp << 4;

  33.     /* Byte 5 */
  34.     tmp = (uint8_t)((CSD_Tab[1] & 0x00FF0000) >> 16);
  35.     cardinfo->SD_csd.CardComdClasses |= (tmp & 0xF0) >> 4;
  36.     cardinfo->SD_csd.RdBlockLen = tmp & 0x0F;
  37.    
  38.     /* Byte 6 */
  39.     tmp = (uint8_t)((CSD_Tab[1] & 0x0000FF00) >> 8);
  40.     cardinfo->SD_csd.PartBlockRead = (tmp & 0x80) >> 7;
  41.     cardinfo->SD_csd.WrBlockMisalign = (tmp & 0x40) >> 6;
  42.     cardinfo->SD_csd.RdBlockMisalign = (tmp & 0x20) >> 5;
  43.     cardinfo->SD_csd.DSRImpl = (tmp & 0x10) >> 4;
  44.     cardinfo->SD_csd.Reserved2 = 0; /* Reserved */

  45.     /* The card is SDSC card */
  46.     if ((CardType == SDIO_STD_CAPACITY_SD_CARD_V1_1) || (CardType == SDIO_STD_CAPACITY_SD_CARD_V2_0))
  47.     {
  48.         cardinfo->SD_csd.DeviceSize = (tmp & 0x03) << 10;
  49.         
  50.         /* Byte 7 */
  51.         tmp = (uint8_t)(CSD_Tab[1] & 0x000000FF);
  52.         cardinfo->SD_csd.DeviceSize |= (tmp) << 2;
  53.         
  54.         /* Byte 8 */
  55.         tmp = (uint8_t)((CSD_Tab[2] & 0xFF000000) >> 24);
  56.         cardinfo->SD_csd.DeviceSize |= (tmp & 0xC0) >> 6;
  57.         
  58.         cardinfo->SD_csd.MaxRdCurrentVDDMin = (tmp & 0x38) >> 3;
  59.         cardinfo->SD_csd.MaxRdCurrentVDDMax = (tmp & 0x07);
  60.         
  61.         /* Byte 9 */
  62.         tmp = (uint8_t)((CSD_Tab[2] & 0x00FF0000) >> 16);
  63.         cardinfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5;
  64.         cardinfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2;
  65.         cardinfo->SD_csd.DeviceSizeMul = (tmp & 0x03) << 1;
  66.         /* Byte 10 */
  67.         tmp = (uint8_t)((CSD_Tab[2] & 0x0000FF00) >> 8);
  68.         cardinfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7;
  69.         
  70.         cardinfo->CardCapacity = (cardinfo->SD_csd.DeviceSize + 1) ;
  71.         cardinfo->CardCapacity *= (1 << (cardinfo->SD_csd.DeviceSizeMul + 2));
  72.         cardinfo->CardBlockSize = 1 << (cardinfo->SD_csd.RdBlockLen);
  73.         cardinfo->CardCapacity *= cardinfo->CardBlockSize;
  74.     }
  75.     /* The card is SDHC card */
  76.     else if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  77.     {
  78.         /* Byte 7 */
  79.         tmp = (uint8_t)(CSD_Tab[1] & 0x000000FF);
  80.         cardinfo->SD_csd.DeviceSize = (tmp & 0x3F) << 16;
  81.         
  82.         /* Byte 8 */
  83.         tmp = (uint8_t)((CSD_Tab[2] & 0xFF000000) >> 24);
  84.         
  85.         cardinfo->SD_csd.DeviceSize |= (tmp << 8);
  86.         
  87.         /* Byte 9 */
  88.         tmp = (uint8_t)((CSD_Tab[2] & 0x00FF0000) >> 16);
  89.         
  90.         cardinfo->SD_csd.DeviceSize |= (tmp);
  91.         
  92.         /* Byte 10 */
  93.         tmp = (uint8_t)((CSD_Tab[2] & 0x0000FF00) >> 8);
  94.         
  95.         cardinfo->CardCapacity = (cardinfo->SD_csd.DeviceSize + 1) * 512 * 1024;
  96.         cardinfo->CardBlockSize = 512;
  97.     }
  98.    

  99.     cardinfo->SD_csd.EraseGrSize = (tmp & 0x40) >> 6;
  100.     cardinfo->SD_csd.EraseGrMul = (tmp & 0x3F) << 1;
  101.    
  102.     /* Byte 11 */
  103.     tmp = (uint8_t)(CSD_Tab[2] & 0x000000FF);
  104.     cardinfo->SD_csd.EraseGrMul |= (tmp & 0x80) >> 7;
  105.     cardinfo->SD_csd.WrProtectGrSize = (tmp & 0x7F);
  106.    
  107.     /* Byte 12 */
  108.     tmp = (uint8_t)((CSD_Tab[3] & 0xFF000000) >> 24);
  109.     cardinfo->SD_csd.WrProtectGrEnable = (tmp & 0x80) >> 7;
  110.     cardinfo->SD_csd.ManDeflECC = (tmp & 0x60) >> 5;
  111.     cardinfo->SD_csd.WrSpeedFact = (tmp & 0x1C) >> 2;
  112.     cardinfo->SD_csd.MaxWrBlockLen = (tmp & 0x03) << 2;
  113.    
  114.     /* Byte 13 */
  115.     tmp = (uint8_t)((CSD_Tab[3] & 0x00FF0000) >> 16);
  116.     cardinfo->SD_csd.MaxWrBlockLen |= (tmp & 0xC0) >> 6;
  117.     cardinfo->SD_csd.WriteBlockPaPartial = (tmp & 0x20) >> 5;
  118.     cardinfo->SD_csd.Reserved3 = 0;
  119.     cardinfo->SD_csd.ContentProtectAppli = (tmp & 0x01);
  120.    
  121.     /* Byte 14 */
  122.     tmp = (uint8_t)((CSD_Tab[3] & 0x0000FF00) >> 8);
  123.     cardinfo->SD_csd.FileFormatGrouop = (tmp & 0x80) >> 7;
  124.     cardinfo->SD_csd.CopyFlag = (tmp & 0x40) >> 6;
  125.     cardinfo->SD_csd.PermWrProtect = (tmp & 0x20) >> 5;
  126.     cardinfo->SD_csd.TempWrProtect = (tmp & 0x10) >> 4;
  127.     cardinfo->SD_csd.FileFormat = (tmp & 0x0C) >> 2;
  128.     cardinfo->SD_csd.ECC = (tmp & 0x03);
  129.    
  130.     /* Byte 15 */
  131.     tmp = (uint8_t)(CSD_Tab[3] & 0x000000FF);
  132.     cardinfo->SD_csd.CSD_CRC = (tmp & 0xFE) >> 1;
  133.     cardinfo->SD_csd.Reserved4 = 1;
  134.    
  135.     /* CID Bytes */
  136.     /* Byte 0 */
  137.     tmp = (uint8_t)((CID_Tab[0] & 0xFF000000) >> 24);
  138.     cardinfo->SD_cid.ManufacturerID = tmp;
  139.    
  140.     /* Byte 1 */
  141.     tmp = (uint8_t)((CID_Tab[0] & 0x00FF0000) >> 16);
  142.     cardinfo->SD_cid.OEM_AppliID = tmp << 8;
  143.    
  144.     /* Byte 2 */
  145.     tmp = (uint8_t)((CID_Tab[0] & 0x000000FF00) >> 8);
  146.     cardinfo->SD_cid.OEM_AppliID |= tmp;
  147.    
  148.     /* Byte 3 */
  149.     tmp = (uint8_t)(CID_Tab[0] & 0x000000FF);
  150.     cardinfo->SD_cid.ProdName1 = tmp << 24;
  151.    
  152.     /* Byte 4 */
  153.     tmp = (uint8_t)((CID_Tab[1] & 0xFF000000) >> 24);
  154.     cardinfo->SD_cid.ProdName1 |= tmp << 16;
  155.    
  156.     /* Byte 5 */
  157.     tmp = (uint8_t)((CID_Tab[1] & 0x00FF0000) >> 16);
  158.     cardinfo->SD_cid.ProdName1 |= tmp << 8;
  159.    
  160.     /* Byte 6 */
  161.     tmp = (uint8_t)((CID_Tab[1] & 0x0000FF00) >> 8);
  162.     cardinfo->SD_cid.ProdName1 |= tmp;
  163.    
  164.     /* Byte 7 */
  165.     tmp = (uint8_t)(CID_Tab[1] & 0x000000FF);
  166.     cardinfo->SD_cid.ProdName2 = tmp;
  167.    
  168.     /* Byte 8 */
  169.     tmp = (uint8_t)((CID_Tab[2] & 0xFF000000) >> 24);
  170.     cardinfo->SD_cid.ProdRev = tmp;
  171.    
  172.     /* Byte 9 */
  173.     tmp = (uint8_t)((CID_Tab[2] & 0x00FF0000) >> 16);
  174.     cardinfo->SD_cid.ProdSN = tmp << 24;
  175.    
  176.     /* Byte 10 */
  177.     tmp = (uint8_t)((CID_Tab[2] & 0x0000FF00) >> 8);
  178.     cardinfo->SD_cid.ProdSN |= tmp << 16;
  179.    
  180.     /* Byte 11 */
  181.     tmp = (uint8_t)(CID_Tab[2] & 0x000000FF);
  182.     cardinfo->SD_cid.ProdSN |= tmp << 8;
  183.    
  184.     /* Byte 12 */
  185.     tmp = (uint8_t)((CID_Tab[3] & 0xFF000000) >> 24);
  186.     cardinfo->SD_cid.ProdSN |= tmp;
  187.    
  188.     /* Byte 13 */
  189.     tmp = (uint8_t)((CID_Tab[3] & 0x00FF0000) >> 16);
  190.     cardinfo->SD_cid.Reserved1 |= (tmp & 0xF0) >> 4;
  191.     cardinfo->SD_cid.ManufactDate = (tmp & 0x0F) << 8;
  192.    
  193.     /* Byte 14 */
  194.     tmp = (uint8_t)((CID_Tab[3] & 0x0000FF00) >> 8);
  195.     cardinfo->SD_cid.ManufactDate |= tmp;
  196.    
  197.     /* Byte 15 */
  198.     tmp = (uint8_t)(CID_Tab[3] & 0x000000FF);
  199.     cardinfo->SD_cid.CID_CRC = (tmp & 0xFE) >> 1;
  200.     cardinfo->SD_cid.Reserved2 = 1;
  201.    
  202.     return(Status);
  203. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 22:35 | 显示全部楼层
配置总线宽度
  1. SD_Err SD_BusWide_Configure(uint32_t WideMode)
  2. {
  3.     SD_Err Status = SD_OK;

  4.     /* MMC Card doesn't support this feature */
  5.     if (SDIO_MULTIMEDIA_CARD == CardType)
  6.     {
  7.         Status = SD_UNSUPPORTED_FEATURE;
  8.         return(Status);
  9.     }
  10.     else if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
  11.     {
  12.         if (SDIO_BUSMODE_8B == WideMode)
  13.         {
  14.             Status = SD_UNSUPPORTED_FEATURE;
  15.             return(Status);
  16.         }
  17.         else if (SDIO_BUSMODE_4B == WideMode)
  18.         {
  19.             Status = WideBus_Enable(ENABLE);
  20.             if (SD_OK == Status)
  21.             {
  22.                 /* Configure the SDIO peripheral */
  23.                 SDIO_InitStructure.SDIO_ClockDiv = 0x01;
  24.                 SDIO_InitStructure.SDIO_ClockEdge = SDIO_CLOCKEDGE_RISING;
  25.                 SDIO_InitStructure.SDIO_ClockBypassState = SDIO_CLOCKBYPASSSTATE_DISABLE;
  26.                 SDIO_InitStructure.SDIO_ClockPWRSave = SDIO_CLOCKPWRSAVE_DISABLE;
  27.                 SDIO_InitStructure.SDIO_BusMode = SDIO_BUSMODE_4B;
  28.                 SDIO_InitStructure.SDIO_HWFlowCtrlState = SDIO_HWFLOWCTRLSTATE_DISABLE;
  29.                 SDIO_Init(&SDIO_InitStructure);
  30.             }
  31.         }
  32.         else
  33.         {
  34.             Status = WideBus_Enable(DISABLE);

  35.             if (SD_OK == Status)
  36.             {
  37.                 /* Configure the SDIO peripheral */
  38.                 SDIO_InitStructure.SDIO_ClockDiv = 0x01;
  39.                 SDIO_InitStructure.SDIO_ClockEdge = SDIO_CLOCKEDGE_RISING;
  40.                 SDIO_InitStructure.SDIO_ClockBypassState = SDIO_CLOCKBYPASSSTATE_DISABLE;
  41.                 SDIO_InitStructure.SDIO_ClockPWRSave = SDIO_CLOCKPWRSAVE_DISABLE;
  42.                 SDIO_InitStructure.SDIO_BusMode = SDIO_BUSMODE_1B;
  43.                 SDIO_InitStructure.SDIO_HWFlowCtrlState = SDIO_HWFLOWCTRLSTATE_DISABLE;
  44.                 SDIO_Init(&SDIO_InitStructure);
  45.             }
  46.         }
  47.     }

  48.     return(Status);
  49. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 22:39 | 显示全部楼层
配置SD卡转换模式
  1. SD_Err SD_Set_Devicemode(uint32_t Mode)
  2. {
  3.     SD_Err Status = SD_OK;

  4.     /* Select the transfer mode */
  5.     if ((Mode == SD_DMA_MODE) || (Mode == SD_POLLING_MODE))
  6.     {
  7.        TransmissionMode = Mode;
  8.     }
  9.     else
  10.     {
  11.         Status = SD_INVALID_PARAMETER;
  12.     }
  13.     return(Status);
  14. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 22:41 | 显示全部楼层
片选SD卡,选择或者取消
  1. SD_Err SD_Select_Deselect_Card(uint32_t addr)
  2. {
  3.     SD_Err Status = SD_OK;

  4.     /* Send CMD7 SDIO_SEL_DESEL_CARD */
  5.     SDIO_CmdInitStructure.SDIO_CMDParameter =  addr;
  6.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEL_DESEL_CARD;
  7.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  8.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  9.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  10.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  11.     Status = Check_Err_R1(SDIO_SEL_DESEL_CARD);

  12.     return(Status);
  13. }
复制代码




使用特权

评论回复
 楼主 | 2020-3-31 22:41 | 显示全部楼层
从卡中指定的地址读取一个数据块
  1. SD_Err SD_ReadBlock(uint32_t addr, uint32_t *readbuff, uint16_t BlockSize)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint32_t count = 0, *tempbuff = readbuff;
  5.     uint8_t power = 0;

  6.     if (NULL == readbuff)
  7.     {
  8.         Status = SD_INVALID_PARAMETER;
  9.         return(Status);
  10.     }

  11.     TransferError = SD_OK;
  12.     TransferEnd = 0;
  13.     TotalNumberOfBytes = 0;

  14.     /* Clear all DSM configuration */
  15.     SDIO_DataInitStructure.SDIO_DataTimeOut = 0;
  16.     SDIO_DataInitStructure.SDIO_DataLength = 0;
  17.     SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DATABLOCKSIZE_1B;
  18.     SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
  19.     SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  20.     SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_DISABLE;
  21.     SDIO_DataConfig(&SDIO_DataInitStructure);
  22.     SDIO_DMA_Enable(DISABLE);

  23.     /* Check whether the card is locked */
  24.     if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
  25.     {
  26.         Status = SD_LOCK_UNLOCK_FAILED;
  27.         return(Status);
  28.     }

  29.     /* SDHC card the blocksize is fixed in 512B */
  30.     if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  31.     {
  32.         BlockSize = 512;
  33.         addr /= 512;
  34.     }
  35.     if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0))
  36.     {
  37.         power = Bytes_To_PowerTwo(BlockSize);

  38.         /* CMD16 Set Block Size for Card */
  39.         SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) BlockSize;
  40.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SET_BLOCKLEN;
  41.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  42.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  43.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  44.         SDIO_SendCMD(&SDIO_CmdInitStructure);

  45.         /* Check CMD errors */
  46.         Status = Check_Err_R1(SDIO_SET_BLOCKLEN);
  47.         if (SD_OK != Status)
  48.         {
  49.             return(Status);
  50.         }
  51.     }
  52.     else
  53.     {
  54.         Status = SD_INVALID_PARAMETER;
  55.         return(Status);
  56.     }

  57.     /* SDIO data transmisson config */
  58.     SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  59.     SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
  60.     SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) power << 4;
  61.     SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOSDIO;
  62.     SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  63.     SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_ENABLE;
  64.     SDIO_DataConfig(&SDIO_DataInitStructure);

  65.     TotalNumberOfBytes = BlockSize;
  66.     StopCondition = 0;
  67.     DestBuffer = readbuff;

  68.     /* Send CMD17 READ_SINGLE_BLOCK */
  69.     SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t)addr;
  70.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_READ_SINGLE_BLOCK;
  71.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  72.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  73.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  74.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  75.     /* Check CMD errors */
  76.     Status = Check_Err_R1(SDIO_READ_SINGLE_BLOCK);
  77.     if (Status != SD_OK)
  78.     {
  79.         return(Status);
  80.     }

  81.     /* In case of single block transfer, no need of stop transfer at all.*/
  82.     if (TransmissionMode == SD_POLLING_MODE)
  83.     {
  84.     /* Polling mode */
  85.         while (!(SDIO->STR &(SDIO_FLAG_RXORE | SDIO_FLAG_DTCRCFAIL | SDIO_FLAG_DTTMOUT | SDIO_FLAG_DTBLKEND | SDIO_FLAG_STBITE)))
  86.         {
  87.             if (SDIO_GetBitState(SDIO_FLAG_RXFIFOHF) != RESET)
  88.             {
  89.                 for (count = 0; count < 8; count++)
  90.                 {
  91.                     *(tempbuff + count) = SDIO_ReadData();
  92.                 }
  93.                 tempbuff += 8;
  94.             }
  95.         }

  96.         if (SDIO_GetBitState(SDIO_FLAG_DTTMOUT) != RESET)
  97.         {
  98.             SDIO_ClearBitState(SDIO_FLAG_DTTMOUT);
  99.             Status = SD_DATA_TIMEOUT;
  100.             return(Status);
  101.         }
  102.         else if (SDIO_GetBitState(SDIO_FLAG_DTCRCFAIL) != RESET)
  103.         {
  104.             SDIO_ClearBitState(SDIO_FLAG_DTCRCFAIL);
  105.             Status = SD_DATA_CRC_FAIL;
  106.             return(Status);
  107.         }
  108.         else if (SDIO_GetBitState(SDIO_FLAG_RXORE) != RESET)
  109.         {
  110.             SDIO_ClearBitState(SDIO_FLAG_RXORE);
  111.             Status = SD_RX_OVERRUN;
  112.             return(Status);
  113.         }
  114.         else if (SDIO_GetBitState(SDIO_FLAG_STBITE) != RESET)
  115.         {
  116.             SDIO_ClearBitState(SDIO_FLAG_STBITE);
  117.             Status = SD_START_BIT_ERR;
  118.             return(Status);
  119.         }
  120.         while (SDIO_GetBitState(SDIO_FLAG_RXDTVAL) != RESET)
  121.         {
  122.             *tempbuff = SDIO_ReadData();
  123.             tempbuff++;
  124.         }

  125.         /* Clear all the static flags */
  126.         SDIO_ClearBitState(SDIO_STATIC_FLAGS);
  127.     }
  128.     else if (TransmissionMode == SD_DMA_MODE)
  129.     {
  130.         /* DMA mode */
  131.         /* Enable SDIO corresponding interrupts */
  132.         SDIO_INTConfig(SDIO_INT_CCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_RXORE | SDIO_INT_STBITE, ENABLE);

  133.         /* Enable the DMA of SDIO */
  134.         SDIO_DMA_Enable(ENABLE);

  135.         DMA_RxConfiguration(readbuff, BlockSize);

  136.         while (DMA_GetBitState(DMA2_FLAG_TC4) == RESET)
  137.         {}
  138.     }
  139.     return(Status);
  140. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:01 | 显示全部楼层
从卡中的指定地址读取多个块
  1. SD_Err SD_ReadMultiBlocks(uint32_t addr, uint32_t *readbuff, uint16_t BlockSize, uint32_t NumberOfBlocks)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint32_t count = 0, *tempbuff = readbuff;
  5.     uint8_t power = 0;

  6.     if (NULL == readbuff)
  7.     {
  8.         Status = SD_INVALID_PARAMETER;
  9.         return(Status);
  10.     }

  11.     TransferError = SD_OK;
  12.     TransferEnd = 0;
  13.     TotalNumberOfBytes = 0;

  14.     /* Clear all DSM configuration */
  15.     SDIO_DataInitStructure.SDIO_DataTimeOut = 0;
  16.     SDIO_DataInitStructure.SDIO_DataLength = 0;
  17.     SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DATABLOCKSIZE_1B;
  18.     SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
  19.     SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  20.     SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_DISABLE;
  21.     SDIO_DataConfig(&SDIO_DataInitStructure);
  22.     SDIO_DMA_Enable(DISABLE);

  23.     /* Check whether the card is locked */
  24.     if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
  25.     {
  26.         Status = SD_LOCK_UNLOCK_FAILED;
  27.         return(Status);
  28.     }
  29.         /* SDHC card the blocksize is fixed in 512B */
  30.         if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  31.     {
  32.         BlockSize = 512;
  33.         addr /= 512;
  34.     }

  35.     if ((BlockSize > 0) && (BlockSize <= 2048) && (0 == (BlockSize & (BlockSize - 1))))
  36.     {
  37.         power = Bytes_To_PowerTwo(BlockSize);
  38.         
  39.         /* CMD16 Set Block Size for Card */
  40.         SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) BlockSize;
  41.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SET_BLOCKLEN;
  42.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  43.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  44.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  45.         SDIO_SendCMD(&SDIO_CmdInitStructure);
  46.         
  47.         /* Check CMD errors */
  48.         Status = Check_Err_R1(SDIO_SET_BLOCKLEN);
  49.         if (SD_OK != Status)
  50.         {
  51.             return(Status);
  52.         }
  53.     }
  54.     else
  55.     {
  56.         Status = SD_INVALID_PARAMETER;
  57.         return(Status);
  58.     }

  59.     if (NumberOfBlocks > 1)
  60.     {
  61.         /* Common to all modes */
  62.         if (NumberOfBlocks * BlockSize > SD_MAX_DATA_LENGTH)
  63.         {
  64.           Status = SD_INVALID_PARAMETER;
  65.           return(Status);
  66.         }

  67.         TotalNumberOfBytes = NumberOfBlocks * BlockSize;
  68.         StopCondition = 1;
  69.         DestBuffer = readbuff;

  70.         /* SDIO data transmisson config */
  71.         SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  72.         SDIO_DataInitStructure.SDIO_DataLength = NumberOfBlocks * BlockSize;
  73.         SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) power << 4;
  74.         SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOSDIO;
  75.         SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  76.         SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_ENABLE;
  77.         SDIO_DataConfig(&SDIO_DataInitStructure);

  78.         /* Send CMD18 READ_MULT_BLOCK */
  79.         SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t)addr;
  80.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_READ_MULT_BLOCK;
  81.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  82.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  83.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  84.         SDIO_SendCMD(&SDIO_CmdInitStructure);

  85.         /* Check CMD errors */
  86.         Status = Check_Err_R1(SDIO_READ_MULT_BLOCK);
  87.         if (Status != SD_OK)
  88.         {
  89.             return(Status);
  90.         }

  91.         if (TransmissionMode == SD_POLLING_MODE)
  92.         {
  93.             /* Polling mode */
  94.             while (!(SDIO->STR &(SDIO_FLAG_RXORE | SDIO_FLAG_DTCRCFAIL | SDIO_FLAG_DTEND | SDIO_FLAG_DTTMOUT | SDIO_FLAG_STBITE)))
  95.             {
  96.                 if (SDIO_GetBitState(SDIO_FLAG_RXFIFOHF) != RESET)
  97.                 {
  98.                     for (count = 0; count < SD_HALFFIFO; count++)
  99.                     {
  100.                         *(tempbuff + count) = SDIO_ReadData();
  101.                     }
  102.                     tempbuff += SD_HALFFIFO;
  103.                 }
  104.             }

  105.             if (SDIO_GetBitState(SDIO_FLAG_DTTMOUT) != RESET)
  106.             {
  107.                 SDIO_ClearBitState(SDIO_FLAG_DTTMOUT);
  108.                 Status = SD_DATA_TIMEOUT;
  109.                 return(Status);
  110.             }
  111.             else if (SDIO_GetBitState(SDIO_FLAG_DTCRCFAIL) != RESET)
  112.             {
  113.                 SDIO_ClearBitState(SDIO_FLAG_DTCRCFAIL);
  114.                 Status = SD_DATA_CRC_FAIL;
  115.                 return(Status);
  116.             }
  117.             else if (SDIO_GetBitState(SDIO_FLAG_RXORE) != RESET)
  118.             {
  119.                 SDIO_ClearBitState(SDIO_FLAG_RXORE);
  120.                 Status = SD_RX_OVERRUN;
  121.                 return(Status);
  122.             }
  123.             else if (SDIO_GetBitState(SDIO_FLAG_STBITE) != RESET)
  124.             {
  125.                 SDIO_ClearBitState(SDIO_FLAG_STBITE);
  126.                 Status = SD_START_BIT_ERR;
  127.                 return(Status);
  128.             }
  129.             while (SDIO_GetBitState(SDIO_FLAG_RXDTVAL) != RESET)
  130.             {
  131.                 *tempbuff = SDIO_ReadData();
  132.                 tempbuff++;
  133.             }

  134.             if (SDIO_GetBitState(SDIO_FLAG_DTEND) != RESET)
  135.             {
  136.                 /* In Case Of sdcard Send Command STOP_TRANSMISSION */
  137.                 if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType))
  138.                 {
  139.                     /* Send CMD12 STOP_TRANSMISSION */
  140.                     SDIO_CmdInitStructure.SDIO_CMDParameter = 0x0;
  141.                     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_STOP_TRANSMISSION;
  142.                     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  143.                     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  144.                     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  145.                     SDIO_SendCMD(&SDIO_CmdInitStructure);

  146.                     /* Check CMD errors */
  147.                     Status = Check_Err_R1(SDIO_STOP_TRANSMISSION);
  148.                     if (Status != SD_OK)
  149.                     {
  150.                         return(Status);
  151.                     }
  152.                 }
  153.             }
  154.             /* Clear all the static flags */
  155.             SDIO_ClearBitState(SDIO_STATIC_FLAGS);
  156.         }
  157.         else if (TransmissionMode == SD_DMA_MODE)
  158.         {
  159.             /* DMA mode */
  160.             /* Enable SDIO corresponding interrupts */
  161.             SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_RXORE | SDIO_INT_STBITE, ENABLE);

  162.             /* Enable the DMA of SDIO */
  163.             SDIO_DMA_Enable(ENABLE);
  164.       
  165.             DMA_RxConfiguration(readbuff, (NumberOfBlocks * BlockSize));
  166.       
  167.             while (DMA_GetBitState(DMA2_FLAG_TC4) == RESET)
  168.             {}
  169.       
  170.             while ((TransferEnd == 0) && (TransferError == SD_OK))
  171.             {}
  172.       
  173.             if (TransferError != SD_OK)
  174.             {
  175.                 return(TransferError);
  176.             }
  177.         }
  178.     }
  179.     return(Status);
  180. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:02 | 显示全部楼层
本帖最后由 gaoke231 于 2020-3-31 23:04 编辑

在卡中指定地址写一个块
  1. SD_Err SD_WriteBlock(uint32_t addr, uint32_t *writebuff, uint16_t BlockSize)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint8_t  power = 0, cardstate = 0;
  5.     uint32_t timeout = 0, bytestransferred = 0;
  6.     uint32_t cardstatus = 0, count = 0, restwords = 0;
  7.     uint32_t *tempbuff = writebuff;

  8.     if (writebuff == NULL)
  9.     {
  10.         Status = SD_INVALID_PARAMETER;
  11.         return(Status);
  12.     }

  13.     TransferError = SD_OK;
  14.     TransferEnd = 0;
  15.     TotalNumberOfBytes = 0;

  16.     /* Clear all DSM configuration */
  17.     SDIO_DataInitStructure.SDIO_DataTimeOut = 0;
  18.     SDIO_DataInitStructure.SDIO_DataLength = 0;
  19.     SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DATABLOCKSIZE_1B;
  20.     SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
  21.     SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  22.     SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_DISABLE;
  23.     SDIO_DataConfig(&SDIO_DataInitStructure);
  24.     SDIO_DMA_Enable(DISABLE);

  25.     /* Check whether the card is locked */
  26.     if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
  27.     {
  28.         Status = SD_LOCK_UNLOCK_FAILED;
  29.         return(Status);
  30.     }

  31.     /* SDHC card the blocksize is fixed in 512B */
  32.     if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  33.     {
  34.         BlockSize = 512;
  35.         addr /= 512;
  36.     }

  37.     /* Set the block size, both on controller and card */
  38.     if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0))
  39.     {
  40.         power = Bytes_To_PowerTwo(BlockSize);

  41.         /* CMD16 Set Block Size for Card */
  42.         SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) BlockSize;
  43.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SET_BLOCKLEN;
  44.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  45.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  46.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  47.         SDIO_SendCMD(&SDIO_CmdInitStructure);

  48.         /* Check CMD errors */
  49.         Status = Check_Err_R1(SDIO_SET_BLOCKLEN);
  50.         if (Status != SD_OK)
  51.         {
  52.             return(Status);
  53.         }
  54.     }
  55.     else
  56.     {
  57.         Status = SD_INVALID_PARAMETER;
  58.         return(Status);
  59.     }

  60.     /* Wait till card is ready for writing data */
  61.     SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) (RCA << 16);
  62.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
  63.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  64.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  65.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  66.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  67.     /* Check CMD errors */
  68.     Status = Check_Err_R1(SDIO_SEND_STATUS);
  69.     if (Status != SD_OK)
  70.     {
  71.         return(Status);
  72.     }

  73.     cardstatus = SDIO_GetResponse(SDIO_RESP1);

  74.     timeout = 10000;

  75.     while (((cardstatus & 0x00000100) == 0) && (timeout > 0))
  76.     {
  77.         /* Card is busy, continue to send CMD13 to polling the state of the card */
  78.         timeout--;
  79.         SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) (RCA << 16);
  80.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
  81.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  82.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  83.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  84.         SDIO_SendCMD(&SDIO_CmdInitStructure);

  85.         /* Check CMD errors */
  86.         Status = Check_Err_R1(SDIO_SEND_STATUS);
  87.         if (Status != SD_OK)
  88.         {
  89.             return(Status);
  90.         }
  91.         cardstatus = SDIO_GetResponse(SDIO_RESP1);
  92.     }

  93.     /* Polling timeout */
  94.     if (timeout == 0)
  95.     {
  96.         return(SD_ERROR);
  97.     }

  98.     /* Send CMD24 WRITE_SINGLE_BLOCK */
  99.     SDIO_CmdInitStructure.SDIO_CMDParameter = addr;
  100.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_WRITE_SINGLE_BLOCK;
  101.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  102.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  103.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  104.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  105.     /* Check CMD errors */
  106.     Status = Check_Err_R1(SDIO_WRITE_SINGLE_BLOCK);
  107.     if (Status != SD_OK)
  108.     {
  109.         return(Status);
  110.     }

  111.     TotalNumberOfBytes = BlockSize;
  112.     StopCondition = 0;
  113.     SrcBuffer = writebuff;

  114.     /* SDIO data transmisson config */
  115.     SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  116.     SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
  117.     SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) power << 4;
  118.     SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
  119.     SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  120.     SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_ENABLE;
  121.     SDIO_DataConfig(&SDIO_DataInitStructure);


  122.     /* In case of single data block transfer no need of stop command at all */
  123.     if (TransmissionMode == SD_POLLING_MODE)
  124.     {
  125.         /* Polling mode */
  126.         while (!(SDIO->STR & (SDIO_FLAG_DTBLKEND | SDIO_FLAG_TXURE | SDIO_FLAG_DTCRCFAIL | SDIO_FLAG_DTTMOUT | SDIO_FLAG_STBITE)))
  127.         {
  128.             if (SDIO_GetBitState(SDIO_FLAG_TXFIFOHE) != RESET)
  129.             {
  130.                 if ((TotalNumberOfBytes - bytestransferred) < 32)
  131.                 {
  132.                     restwords = ((TotalNumberOfBytes - bytestransferred) % 4 == 0) ? ((TotalNumberOfBytes - bytestransferred) / 4) : (( TotalNumberOfBytes -  bytestransferred) / 4 + 1);

  133.                     for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4)
  134.                     {
  135.                         SDIO_WriteData(*tempbuff);
  136.                     }
  137.                 }
  138.                 else
  139.                 {
  140.                     for (count = 0; count < 8; count++)
  141.                     {
  142.                         SDIO_WriteData(*(tempbuff + count));
  143.                     }
  144.                     tempbuff += 8;
  145.                     bytestransferred += 32;
  146.                 }
  147.             }
  148.         }
  149.         if (SDIO_GetBitState(SDIO_FLAG_DTTMOUT) != RESET)
  150.         {
  151.             SDIO_ClearBitState(SDIO_FLAG_DTTMOUT);
  152.             Status = SD_DATA_TIMEOUT;
  153.             return(Status);
  154.         }
  155.         else if (SDIO_GetBitState(SDIO_FLAG_DTCRCFAIL) != RESET)
  156.         {
  157.             SDIO_ClearBitState(SDIO_FLAG_DTCRCFAIL);
  158.             Status = SD_DATA_CRC_FAIL;
  159.             return(Status);
  160.         }
  161.         else if (SDIO_GetBitState(SDIO_FLAG_TXURE) != RESET)
  162.         {
  163.             SDIO_ClearBitState(SDIO_FLAG_TXURE);
  164.             Status = SD_TX_UNDERRUN;
  165.             return(Status);
  166.         }
  167.         else if (SDIO_GetBitState(SDIO_FLAG_STBITE) != RESET)
  168.         {
  169.             SDIO_ClearBitState(SDIO_FLAG_STBITE);
  170.             Status = SD_START_BIT_ERR;
  171.             return(Status);
  172.         }
  173.     }
  174.     else if (TransmissionMode == SD_DMA_MODE)
  175.     {
  176.         /* DMA mode */
  177.         /* Enable SDIO corresponding interrupts */
  178.         SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_TXURE | SDIO_INT_STBITE, ENABLE);

  179.         DMA_TxConfiguration(writebuff, BlockSize);

  180.         /* Enable the DMA of SDIO */
  181.         SDIO_DMA_Enable(ENABLE);

  182.         while (DMA_GetBitState(DMA2_FLAG_TC4) == RESET)
  183.         {}

  184.         while ((TransferEnd == 0) && (TransferError == SD_OK))
  185.         {}

  186.         if (TransferError != SD_OK)
  187.         {
  188.             return(TransferError);
  189.         }
  190.     }

  191.     /* Clear all the static flags */
  192.     SDIO_ClearBitState(SDIO_STATIC_FLAGS);

  193.     /* Wait till the card is in programming state */
  194.     Status = IsCardProgramming(&cardstate);
  195.     while ((Status == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
  196.     {
  197.         Status = IsCardProgramming(&cardstate);
  198.     }

  199.     return(Status);
  200. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:03 | 显示全部楼层
在卡中指定地址写多个块
  1. SD_Err SD_WriteMultiBlocks(uint32_t addr, uint32_t *writebuff, uint16_t BlockSize, uint32_t NumberOfBlocks)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint8_t  power = 0, cardstate = 0;
  5.     uint32_t bytestransferred = 0;
  6.     uint32_t count = 0, restwords = 0;
  7.     uint32_t *tempbuff = writebuff;

  8.     if (writebuff == NULL)
  9.     {
  10.         Status = SD_INVALID_PARAMETER;
  11.         return(Status);
  12.     }

  13.     TransferError = SD_OK;
  14.     TransferEnd = 0;
  15.     TotalNumberOfBytes = 0;

  16.     /* Clear all DSM configuration */
  17.     SDIO_DataInitStructure.SDIO_DataTimeOut = 0;
  18.     SDIO_DataInitStructure.SDIO_DataLength = 0;
  19.     SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DATABLOCKSIZE_1B;
  20.     SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
  21.     SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  22.     SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_DISABLE;
  23.     SDIO_DataConfig(&SDIO_DataInitStructure);
  24.     SDIO_DMA_Enable(DISABLE);

  25.     /* Check whether the card is locked */
  26.     if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
  27.     {
  28.         Status = SD_LOCK_UNLOCK_FAILED;
  29.         return(Status);
  30.     }

  31.     /* SDHC card the blocksize is fixed in 512B */
  32.     if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  33.     {
  34.         BlockSize = 512;
  35.         addr /= 512;
  36.     }

  37.     /* Set the block size, both on controller and card */
  38.     if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0))
  39.     {
  40.         power = Bytes_To_PowerTwo(BlockSize);

  41.         /* CMD16 Set Block Size for Card */
  42.         SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) BlockSize;
  43.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SET_BLOCKLEN;
  44.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  45.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  46.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  47.         SDIO_SendCMD(&SDIO_CmdInitStructure);

  48.         /* Check CMD errors */
  49.         Status = Check_Err_R1(SDIO_SET_BLOCKLEN);
  50.         if (Status != SD_OK)
  51.         {
  52.             return(Status);
  53.         }
  54.     }
  55.     else
  56.     {
  57.         Status = SD_INVALID_PARAMETER;
  58.         return(Status);
  59.     }

  60.     /* Wait till card is ready for data writing */
  61.     SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) (RCA << 16);
  62.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
  63.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  64.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  65.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  66.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  67.     /* Check CMD errors */
  68.     Status = Check_Err_R1(SDIO_SEND_STATUS);
  69.     if (Status != SD_OK)
  70.     {
  71.         return(Status);
  72.     }

  73.     if (NumberOfBlocks > 1)
  74.     {
  75.         /* Common to all modes */
  76.         if (NumberOfBlocks * BlockSize > SD_MAX_DATA_LENGTH)
  77.         {
  78.             Status = SD_INVALID_PARAMETER;
  79.             return(Status);
  80.         }

  81.         if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
  82.         {
  83.             /* CMD55 the next command is Application Specific Commands */
  84.             SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) (RCA << 16);
  85.             SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_CMD;
  86.             SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  87.             SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  88.             SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  89.             SDIO_SendCMD(&SDIO_CmdInitStructure);

  90.             /* Check CMD errors */
  91.             Status = Check_Err_R1(SDIO_APP_CMD);
  92.             if (Status != SD_OK)
  93.             {
  94.                 return(Status);
  95.             }

  96.             /*ACMD23 Pre-erased to improve performance */
  97.             SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t)NumberOfBlocks;
  98.             SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SET_BLOCK_COUNT;
  99.             SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  100.             SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  101.             SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  102.             SDIO_SendCMD(&SDIO_CmdInitStructure);

  103.             /* Check CMD errors */
  104.             Status = Check_Err_R1(SDIO_SET_BLOCK_COUNT);
  105.             if (Status != SD_OK)
  106.             {
  107.                 return(Status);
  108.             }
  109.         }

  110.         /* Send CMD25 WRITE_MULT_BLOCK with argument data address */
  111.         SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t)addr;
  112.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_WRITE_MULT_BLOCK;
  113.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  114.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  115.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  116.         SDIO_SendCMD(&SDIO_CmdInitStructure);

  117.         /* Check CMD errors */
  118.         Status = Check_Err_R1(SDIO_WRITE_MULT_BLOCK);
  119.         if (SD_OK != Status)
  120.         {
  121.             return(Status);
  122.         }

  123.         TotalNumberOfBytes = NumberOfBlocks * BlockSize;
  124.         StopCondition = 1;
  125.         SrcBuffer = writebuff;

  126.         /* SDIO data transmisson config */
  127.         SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  128.         SDIO_DataInitStructure.SDIO_DataLength = NumberOfBlocks * BlockSize;
  129.         SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) power << 4;
  130.         SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
  131.         SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
  132.         SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_ENABLE;
  133.         SDIO_DataConfig(&SDIO_DataInitStructure);

  134.         if (TransmissionMode == SD_POLLING_MODE)
  135.         {
  136.             /* Polling mode */
  137.             while (!(SDIO->STR & (SDIO_FLAG_TXURE | SDIO_FLAG_DTCRCFAIL | SDIO_FLAG_DTEND | SDIO_FLAG_DTTMOUT | SDIO_FLAG_STBITE)))
  138.             {
  139.                 if (SDIO_GetBitState(SDIO_FLAG_TXFIFOHE) != RESET)
  140.                 {
  141.                     if (!((TotalNumberOfBytes - bytestransferred) < SD_HALFFIFOBYTES))
  142.                     {
  143.                         for (count = 0; count < SD_HALFFIFO; count++)
  144.                         {
  145.                             SDIO_WriteData(*(tempbuff + count));
  146.                         }
  147.                         tempbuff += SD_HALFFIFO;
  148.                         bytestransferred += SD_HALFFIFOBYTES;
  149.                     }
  150.                     else
  151.                     {
  152.                         restwords = ((TotalNumberOfBytes - bytestransferred) % 4 == 0) ? ((TotalNumberOfBytes - bytestransferred) / 4) :
  153.                                     ((TotalNumberOfBytes - bytestransferred) / 4 + 1);

  154.                         for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4)
  155.                         {
  156.                           SDIO_WriteData(*tempbuff);
  157.                         }
  158.                     }
  159.                 }
  160.             }

  161.             if (SDIO_GetBitState(SDIO_FLAG_DTTMOUT) != RESET)
  162.             {
  163.                 SDIO_ClearBitState(SDIO_FLAG_DTTMOUT);
  164.                 Status = SD_DATA_TIMEOUT;
  165.                 return(Status);
  166.             }
  167.             else if (SDIO_GetBitState(SDIO_FLAG_DTCRCFAIL) != RESET)
  168.             {
  169.                 SDIO_ClearBitState(SDIO_FLAG_DTCRCFAIL);
  170.                 Status = SD_DATA_CRC_FAIL;
  171.                 return(Status);
  172.             }
  173.             else if (SDIO_GetBitState(SDIO_FLAG_TXURE) != RESET)
  174.             {
  175.                 SDIO_ClearBitState(SDIO_FLAG_TXURE);
  176.                 Status = SD_TX_UNDERRUN;
  177.                 return(Status);
  178.             }
  179.             else if (SDIO_GetBitState(SDIO_FLAG_STBITE) != RESET)
  180.             {
  181.                 SDIO_ClearBitState(SDIO_FLAG_STBITE);
  182.                 Status = SD_START_BIT_ERR;
  183.                 return(Status);
  184.             }

  185.             if (SDIO_GetBitState(SDIO_FLAG_DTEND) != RESET)
  186.             {
  187.                 if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
  188.                 {
  189.                     /* Send CMD12 STOP_TRANSMISSION */
  190.                     SDIO_CmdInitStructure.SDIO_CMDParameter = 0x0;
  191.                     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_STOP_TRANSMISSION;
  192.                     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  193.                     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  194.                     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  195.                     SDIO_SendCMD(&SDIO_CmdInitStructure);

  196.                     /* Check CMD errors */
  197.                     Status = Check_Err_R1(SDIO_STOP_TRANSMISSION);
  198.                     if (Status != SD_OK)
  199.                     {
  200.                         return(Status);
  201.                     }
  202.                 }
  203.             }
  204.         }
  205.         else if (TransmissionMode == SD_DMA_MODE)
  206.         {
  207.             /* DMA mode */
  208.             /* Enable SDIO corresponding interrupts */
  209.             SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_TXURE | SDIO_INT_STBITE, ENABLE);

  210.             /* Enable the DMA of SDIO */
  211.             SDIO_DMA_Enable(ENABLE);

  212.             DMA_TxConfiguration(writebuff, (NumberOfBlocks * BlockSize));

  213.             while (DMA_GetBitState(DMA2_FLAG_TC4) == RESET)
  214.             {}

  215.             while ((TransferEnd == 0) && (TransferError == SD_OK))
  216.             {}

  217.             if (TransferError != SD_OK)
  218.             {
  219.                 return(TransferError);
  220.             }
  221.         }
  222.     }
  223.     /* Clear all the static flags */
  224.     SDIO_ClearBitState(SDIO_STATIC_FLAGS);

  225.     /* Wait till the card is in programming state */
  226.     Status = IsCardProgramming(&cardstate);

  227.     while ((Status == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
  228.     {
  229.         Status = IsCardProgramming(&cardstate);
  230.     }

  231.     return(Status);
  232. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:05 | 显示全部楼层
获取当前数据传输状态
  1. SDTransferState SD_GetTransferState(void)
  2. {
  3.     if (SDIO->STR & (SDIO_FLAG_TXRUN | SDIO_FLAG_RXRUN))
  4.     {
  5.         return(SD_TRANSFER_IN_PROGRESS);
  6.     }
  7.     else
  8.     {
  9.         return(SD_NO_TRANSFER);
  10.     }
  11. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:06 | 显示全部楼层
停止SD卡的传输
  1. SD_Err SD_Stop_Transfer(void)
  2. {
  3.     SD_Err Status = SD_OK;

  4.     /* Send CMD12 STOP_TRANSMISSION  */
  5.     SDIO_CmdInitStructure.SDIO_CMDParameter = 0x0;
  6.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_STOP_TRANSMISSION;
  7.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  8.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  9.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  10.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  11.     Status = Check_Err_R1(SDIO_STOP_TRANSMISSION);

  12.     return(Status);
  13. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:08 | 显示全部楼层
擦除SD卡中的数据
  1. SD_Err SD_Erase(uint32_t startaddr, uint32_t endaddr)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint32_t delay = 0;
  5.     __IO uint32_t maxdelay = 0;
  6.     uint8_t cardstate = 0;

  7.     /* Check if the card command class supports erase command */
  8.     if ((SD_CCC_ERASE&SDIOInfo.SD_csd.CardComdClasses) == 0)
  9.     {
  10.         Status = SD_REQUEST_NOT_APPLICABLE;
  11.         return(Status);
  12.     }

  13.     maxdelay = 72000 / ((SDIO->CLKCTLR & 0xFF) + 2);

  14.     /* Check whether the card is locked */
  15.     if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
  16.     {
  17.         Status = SD_LOCK_UNLOCK_FAILED;
  18.         return(Status);
  19.     }

  20.     /* SDHC card the blocksize is fixed in 512B */
  21.     if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  22.     {
  23.         startaddr /= 512;
  24.         endaddr /= 512;
  25.     }

  26.     /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
  27.     if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
  28.     {
  29.         /* Send CMD32 SD_ERASE_GRP_START with argument as addr  */
  30.         SDIO_CmdInitStructure.SDIO_CMDParameter = startaddr;
  31.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SD_ERASE_GRP_START;
  32.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  33.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  34.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  35.         SDIO_SendCMD(&SDIO_CmdInitStructure);

  36.         Status = Check_Err_R1(SDIO_SD_ERASE_GRP_START);
  37.         if (Status != SD_OK)
  38.         {
  39.             return(Status);
  40.         }

  41.         /* Send CMD33 SD_ERASE_GRP_END with argument as addr  */
  42.         SDIO_CmdInitStructure.SDIO_CMDParameter = endaddr;
  43.         SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SD_ERASE_GRP_END;
  44.         SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  45.         SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  46.         SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  47.         SDIO_SendCMD(&SDIO_CmdInitStructure);

  48.         Status = Check_Err_R1(SDIO_SD_ERASE_GRP_END);
  49.         if (Status != SD_OK)
  50.         {
  51.             return(Status);
  52.         }
  53.     }

  54.     /* Send CMD38 ERASE */
  55.     SDIO_CmdInitStructure.SDIO_CMDParameter = 0;
  56.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_ERASE;
  57.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  58.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  59.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  60.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  61.     Status = Check_Err_R1(SDIO_ERASE);
  62.    
  63.     if (Status != SD_OK)
  64.     {
  65.         return(Status);
  66.     }

  67.     for (delay = 0; delay < maxdelay; delay++)
  68.     {}

  69.     /* Wait till the card is in programming state */
  70.     Status = IsCardProgramming(&cardstate);

  71.     while ((Status == SD_OK) && ((SD_CARD_PROGRAMMING == cardstate) || (SD_CARD_RECEIVING == cardstate)))
  72.     {
  73.         Status = IsCardProgramming(&cardstate);
  74.     }

  75.     return(Status);
  76. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:09 | 显示全部楼层
获取当前SD的状态
  1. SD_Err SD_Send_Status(uint32_t *pcardstatus)
  2. {
  3.     SD_Err Status = SD_OK;

  4.     if (pcardstatus == NULL)
  5.     {
  6.         Status = SD_INVALID_PARAMETER;
  7.         return(Status);
  8.     }

  9.     /* CMD13 to polling the state of the card */
  10.     SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) RCA << 16;
  11.     SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
  12.     SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  13.     SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  14.     SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  15.     SDIO_SendCMD(&SDIO_CmdInitStructure);

  16.     /* Check CMD errors */
  17.     Status = Check_Err_R1(SDIO_SEND_STATUS);
  18.     if (Status != SD_OK)
  19.     {
  20.         return(Status);
  21.     }

  22.     *pcardstatus = SDIO_GetResponse(SDIO_RESP1);

  23.     return(Status);
  24. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:10 | 显示全部楼层
SD卡中断处理函数
  1. SD_Err SD_IRQ(void)
  2. {
  3.     if (SDIO_GetIntBitState(SDIO_INT_DTEND) != RESET)
  4.     {
  5.         /* Receive data in polling mode, get the remainning words in the FIFO*/
  6.         if (TransmissionMode != SD_DMA_MODE)
  7.         {
  8.             while ((SDIO_GetBitState(SDIO_FLAG_RXDTVAL) != RESET)  &&  (NumberOfBytes < TotalNumberOfBytes))
  9.             {
  10.                 *DestBuffer = SDIO_ReadData();
  11.                 DestBuffer++;
  12.                 NumberOfBytes += 4;
  13.             }
  14.         }
  15.         /* Mul blocks operation, must send CMD12 to stop data transfer*/
  16.         if (StopCondition == 1)
  17.         {
  18.             TransferError = SD_Stop_Transfer();
  19.         }
  20.         else
  21.         {
  22.             TransferError = SD_OK;
  23.         }
  24.         SDIO_ClearIntBitState(SDIO_INT_DTEND);

  25.         /* Disenable all the interrupts*/
  26.         SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND |
  27.                        SDIO_INT_TXFIFOHE | SDIO_INT_RXFIFOHF | SDIO_INT_TXURE |
  28.                        SDIO_INT_RXORE | SDIO_INT_STBITE, DISABLE);
  29.         TransferEnd = 1;
  30.         NumberOfBytes = 0;
  31.         return(TransferError);
  32.     }

  33.     if (SDIO_GetIntBitState(SDIO_INT_DTCRCFAIL) != RESET)
  34.     {
  35.         SDIO_ClearIntBitState(SDIO_INT_DTCRCFAIL);
  36.         SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND |
  37.                       SDIO_INT_TXFIFOHE | SDIO_INT_RXFIFOHF | SDIO_INT_TXURE |
  38.                       SDIO_INT_RXORE | SDIO_INT_STBITE, DISABLE);
  39.         NumberOfBytes = 0;
  40.         TransferError = SD_DATA_CRC_FAIL;
  41.         return(SD_DATA_CRC_FAIL);
  42.     }

  43.     if (SDIO_GetIntBitState(SDIO_INT_DTTMOUT) != RESET)
  44.     {
  45.         SDIO_ClearIntBitState(SDIO_INT_DTTMOUT);
  46.         SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND |
  47.                       SDIO_INT_TXFIFOHE | SDIO_INT_RXFIFOHF | SDIO_INT_TXURE |
  48.                       SDIO_INT_RXORE | SDIO_INT_STBITE, DISABLE);
  49.         NumberOfBytes = 0;
  50.         TransferError = SD_DATA_TIMEOUT;
  51.         return(SD_DATA_TIMEOUT);
  52.     }

  53.     if (SDIO_GetIntBitState(SDIO_INT_RXORE) != RESET)
  54.     {
  55.         SDIO_ClearIntBitState(SDIO_INT_RXORE);
  56.         SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND |
  57.                       SDIO_INT_TXFIFOHE | SDIO_INT_RXFIFOHF | SDIO_INT_TXURE |
  58.                       SDIO_INT_RXORE | SDIO_INT_STBITE, DISABLE);
  59.         NumberOfBytes = 0;
  60.         TransferError = SD_RX_OVERRUN;
  61.         return(SD_RX_OVERRUN);
  62.     }

  63.     if (SDIO_GetIntBitState(SDIO_INT_TXURE) != RESET)
  64.     {
  65.         SDIO_ClearIntBitState(SDIO_INT_TXURE);
  66.         SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND |
  67.                       SDIO_INT_TXFIFOHE | SDIO_INT_RXFIFOHF | SDIO_INT_TXURE |
  68.                       SDIO_INT_RXORE | SDIO_INT_STBITE, DISABLE);
  69.         NumberOfBytes = 0;
  70.         TransferError = SD_TX_UNDERRUN;
  71.         return(SD_TX_UNDERRUN);
  72.     }

  73.     if (SDIO_GetIntBitState(SDIO_INT_STBITE) != RESET)
  74.     {
  75.         SDIO_ClearIntBitState(SDIO_INT_STBITE);
  76.         SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND |
  77.                       SDIO_INT_TXFIFOHE | SDIO_INT_RXFIFOHF | SDIO_INT_TXURE |
  78.                       SDIO_INT_RXORE | SDIO_INT_STBITE, DISABLE);
  79.         NumberOfBytes = 0;
  80.         TransferError = SD_START_BIT_ERR;
  81.         return(SD_START_BIT_ERR);
  82.     }

  83.     return(SD_OK);
  84. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:11 | 显示全部楼层
检查SD卡错误函数
  1. static SD_Err Check_Err(void)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint32_t timeout;

  5.     timeout = 10000;

  6.     while ((timeout > 0) && (SDIO_GetBitState(SDIO_FLAG_CMDSENT) == RESET))
  7.     {
  8.         timeout--;
  9.     }

  10.     if (timeout == 0)
  11.     {
  12.         Status = SD_CMD_RSP_TIMEOUT;
  13.         return(Status);
  14.     }

  15.     /* Clear all the static flags */
  16.     SDIO_ClearBitState(SDIO_STATIC_FLAGS);

  17.     return(Status);
  18. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:12 | 显示全部楼层
检查SD卡 R7错误
  1. static SD_Err Check_Err_R7(void)
  2. {
  3.     SD_Err Status = SD_OK;
  4.     uint32_t status;
  5.     uint32_t timeout = 10000;

  6.     status = SDIO->STR;

  7.     while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CMDTMOUT)) && (timeout > 0))
  8.     {
  9.         timeout--;
  10.         status = SDIO->STR;
  11.     }

  12.     if ((timeout == 0) || (status & SDIO_FLAG_CMDTMOUT))
  13.     {
  14.         /* Card is not V2.0 complient or card does not support the set voltage range */
  15.         Status = SD_CMD_RSP_TIMEOUT;
  16.         SDIO_ClearBitState(SDIO_FLAG_CMDTMOUT);
  17.         return(Status);
  18.     }

  19.     if (status & SDIO_FLAG_CMDREND)
  20.     {
  21.         /* Card is SD V2.0 compliant */
  22.         Status = SD_OK;
  23.         SDIO_ClearBitState(SDIO_FLAG_CMDREND);
  24.         return(Status);
  25.     }

  26.     return(Status);
  27. }
复制代码


使用特权

评论回复
 楼主 | 2020-3-31 23:13 | 显示全部楼层
开启或者关闭 SDIO总线模式
  1. static SD_Err WideBus_Enable(TypeState NewState)
  2. {
  3.     SD_Err Status = SD_OK;

  4.     /* Check whether the card is locked */
  5.     if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
  6.     {
  7.         Status = SD_LOCK_UNLOCK_FAILED;
  8.         return(Status);
  9.     }

  10.     /* Get SCR Register */
  11.     Status = Get_SCR(RCA, Scr);

  12.     if (Status != SD_OK)
  13.     {
  14.         return(Status);
  15.     }

  16.     /* If wide bus operation to be enabled */
  17.     if (NewState == ENABLE)
  18.     {
  19.         /* If requested card supports wide bus operation */
  20.         if ((Scr[1] & SD_WIDE_BUS_SUPPORT) != SD_ALLZERO)
  21.         {
  22.             /* Send CMD55 APP_CMD with argument as card's RCA.*/
  23.             SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) RCA << 16;
  24.             SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_CMD;
  25.             SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  26.             SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  27.             SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  28.             SDIO_SendCMD(&SDIO_CmdInitStructure);

  29.             Status = Check_Err_R1(SDIO_APP_CMD);

  30.             if (Status != SD_OK)
  31.             {
  32.                 return(Status);
  33.             }

  34.             /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
  35.             SDIO_CmdInitStructure.SDIO_CMDParameter = 0x2;
  36.             SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_SD_SET_BUSWIDTH;
  37.             SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  38.             SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  39.             SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  40.             SDIO_SendCMD(&SDIO_CmdInitStructure);
  41.             
  42.             Status = Check_Err_R1(SDIO_APP_SD_SET_BUSWIDTH);
  43.             
  44.             if (Status != SD_OK)
  45.             {
  46.                 return(Status);
  47.             }
  48.             return(Status);
  49.         }
  50.         else
  51.         {
  52.             Status = SD_REQUEST_NOT_APPLICABLE;
  53.             return(Status);
  54.         }
  55.     }   /* If wide bus operation to be disabled */
  56.     else
  57.     {
  58.         /* If requested card supports 1 bit mode operation */
  59.         if ((Scr[1] & SD_SINGLE_BUS_SUPPORT) != SD_ALLZERO)
  60.         {
  61.             /* Send CMD55 APP_CMD with argument as card's RCA.*/
  62.             SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) RCA << 16;
  63.             SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_CMD;
  64.             SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  65.             SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  66.             SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  67.             SDIO_SendCMD(&SDIO_CmdInitStructure);

  68.             /* Check CMD errors */
  69.             Status = Check_Err_R1(SDIO_APP_CMD);
  70.             if (Status != SD_OK)
  71.             {
  72.                 return(Status);
  73.             }

  74.             /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
  75.             SDIO_CmdInitStructure.SDIO_CMDParameter = 0x00;
  76.             SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_SD_SET_BUSWIDTH;
  77.             SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
  78.             SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
  79.             SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
  80.             SDIO_SendCMD(&SDIO_CmdInitStructure);

  81.             /* Check CMD errors */
  82.             Status = Check_Err_R1(SDIO_APP_SD_SET_BUSWIDTH);
  83.             if (Status != SD_OK)
  84.             {
  85.                 return(Status);
  86.             }
  87.             return(Status);
  88.         }
  89.         else
  90.         {
  91.             Status = SD_REQUEST_NOT_APPLICABLE;
  92.             return(Status);
  93.         }
  94.     }
  95. }
复制代码


使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表