diff --git a/board/TencentOS_Tiny_CH32V307_EVB/.cproject b/board/TencentOS_Tiny_CH32V307_EVB/.cproject
index e89af0de..d9d977c8 100644
--- a/board/TencentOS_Tiny_CH32V307_EVB/.cproject
+++ b/board/TencentOS_Tiny_CH32V307_EVB/.cproject
@@ -91,6 +91,7 @@
+
diff --git a/board/TencentOS_Tiny_CH32V307_EVB/.launch b/board/TencentOS_Tiny_CH32V307_EVB/.launch
index 7c5e1c4a..e2da7bfe 100644
--- a/board/TencentOS_Tiny_CH32V307_EVB/.launch
+++ b/board/TencentOS_Tiny_CH32V307_EVB/.launch
@@ -1,61 +1,61 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
diff --git a/board/TencentOS_Tiny_CH32V307_EVB/.project b/board/TencentOS_Tiny_CH32V307_EVB/.project
index c351b367..207673be 100644
--- a/board/TencentOS_Tiny_CH32V307_EVB/.project
+++ b/board/TencentOS_Tiny_CH32V307_EVB/.project
@@ -1,18 +1,18 @@
-
+
TencentOS-Tiny
-
-
+
+
org.eclipse.cdt.managedbuilder.core.genmakebuilder
clean,full,incremental,
-
+
org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
full,incremental,
-
+
@@ -60,7 +60,7 @@
1595986042669
-
+
22
org.eclipse.ui.ide.multiFilter
diff --git a/board/TencentOS_Tiny_CH32V307_EVB/User/ch32v30x_it.c b/board/TencentOS_Tiny_CH32V307_EVB/User/ch32v30x_it.c
index 40608f8f..ee63c836 100644
--- a/board/TencentOS_Tiny_CH32V307_EVB/User/ch32v30x_it.c
+++ b/board/TencentOS_Tiny_CH32V307_EVB/User/ch32v30x_it.c
@@ -8,12 +8,10 @@
#include "ch32v30x_it.h"
#include "tos_k.h"
#include "tos_at.h"
-
extern at_agent_t esp8266_tf_agent;
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART6_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART7_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
diff --git a/board/TencentOS_Tiny_CH32V307_EVB/User/main.c b/board/TencentOS_Tiny_CH32V307_EVB/User/main.c
index 2ecd8617..b6068087 100644
--- a/board/TencentOS_Tiny_CH32V307_EVB/User/main.c
+++ b/board/TencentOS_Tiny_CH32V307_EVB/User/main.c
@@ -7,21 +7,186 @@
*******************************************************************************/
#include "debug.h"
#include "tos_k.h"
+#include "sdio.h"
#include "lcd_init.h"
#include "lcd.h"
#include "pic.h"
+#include "spi_flash.h"
-
-void led_init(void)
+void led_key_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
+ GPIO_SetBits(GPIOE,GPIO_Pin_2);
+ GPIO_SetBits(GPIOE,GPIO_Pin_3);
+ GPIO_SetBits(GPIOE,GPIO_Pin_4);
+ GPIO_SetBits(GPIOE,GPIO_Pin_5);
+ /* key 1 2 3 */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_8;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
}
+
+uint8_t get_key(void)
+{
+ uint16_t value=0;
+ if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) & GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)\
+ & GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)) == 0 )
+ {
+ Delay_Ms(15);
+ if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) & GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)\
+ & GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)) == 0 )
+ {
+ value= GPIO_ReadInputData(GPIOA);
+ if((value&0x1)==0) return 1;
+ else if((value&0x2)==0)return 2;
+ else if((value&0x100)==0) return 3;
+ else return 0;
+ }
+ }
+ return 0;
+}
+
+/*********************************************************************
+ * @fn show_sdcard_info
+ *
+ * @brief SD Card information.
+ *
+ * @return none
+ */
+void show_sdcard_info(void)
+{
+ switch(SDCardInfo.CardType)
+ {
+ case SDIO_STD_CAPACITY_SD_CARD_V1_1:printf("Card Type:SDSC V1.1\r\n");break;
+ case SDIO_STD_CAPACITY_SD_CARD_V2_0:printf("Card Type:SDSC V2.0\r\n");break;
+ case SDIO_HIGH_CAPACITY_SD_CARD:printf("Card Type:SDHC V2.0\r\n");break;
+ case SDIO_MULTIMEDIA_CARD:printf("Card Type:MMC Card\r\n");break;
+ }
+ printf("Card ManufacturerID:%d\r\n",SDCardInfo.SD_cid.ManufacturerID);
+ printf("Card RCA:%d\r\n",SDCardInfo.RCA);
+ printf("Card Capacity:%d MB\r\n",(u32)(SDCardInfo.CardCapacity>>20));
+ printf("Card BlockSize:%d\r\n\r\n",SDCardInfo.CardBlockSize);
+}
+const u8 TEXT_Buf[]={"CH32V307 SPI FLASH W25Qxx"};
+void spi_flash_test(void)
+{
+ u8 datap[SIZE];
+ u16 Flash_Model;
+// SPI_Flash_Init();
+ Delay_Ms(50);
+
+ Flash_Model = SPI_Flash_ReadID();
+
+ switch(Flash_Model)
+ {
+ case W25Q80:
+ printf("W25Q80 OK!\r\n");
+ break;
+
+ case W25Q16:
+ printf("W25Q16 OK!\r\n");
+ break;
+
+ case W25Q32:
+ printf("W25Q32 OK!\r\n");
+ break;
+
+ case W25Q64:
+ printf("W25Q64 OK!\r\n");
+ break;
+
+ case W25Q128:
+ printf("W25Q128 OK!\r\n");
+ break;
+
+ default:
+ printf("Fail!\r\n");
+ break;
+ }
+
+ printf("Start Erase W25Qxx....\r\n");
+ SPI_Flash_Erase_Sector(0);
+ Delay_Ms(500);
+ printf("Start Read W25Qxx....\r\n");
+ SPI_Flash_Read(datap,0x0,SIZE);
+ for(int16_t i=0;i>20))/2;
+ printf("Sector_Nums:%d\r\n", Sector_Nums);
+
+ for(i=0; i<512; i++){
+ buf[i] = i;
+ }
+
+ for(i=0; iCLKCR;
+
+ tmpreg&=0XFFFFFF00;
+ tmpreg|=clkdiv;
+ SDIO->CLKCR=tmpreg;
+}
+
+/*********************************************************************
+ * @fn SD_PowerON
+ *
+ * @brief SD care Power on
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_PowerON(void)
+{
+ u8 i=0;
+ SD_Error errorstatus=SD_OK;
+ u32 response=0,count=0,validvoltage=0;
+ u32 SDType=SD_STD_CAPACITY;
+
+ SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV;
+ SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
+ SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
+ SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
+ SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;
+ SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
+ SDIO_Init(&SDIO_InitStructure);
+
+ SDIO_SetPowerState(SDIO_PowerState_ON);
+
+ SDIO_ClockCmd(ENABLE);
+
+ Delay_Us(1000);
+
+ for(i=0;i<74;i++)
+ {
+ SDIO_CmdInitStructure.SDIO_Argument = 0x0;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_GO_IDLE_STATE;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdError();
+ if(errorstatus==SD_OK)break;
+ }
+ if(errorstatus)return errorstatus;
+
+ SDIO_CmdInitStructure.SDIO_Argument = SD_CHECK_PATTERN;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_IF_COND;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp7Error();
+ if(errorstatus==SD_OK)
+ {
+ CardType=SDIO_STD_CAPACITY_SD_CARD_V2_0;
+ SDType=SD_HIGH_CAPACITY;
+ }
+ SDIO_CmdInitStructure.SDIO_Argument = 0x00;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_APP_CMD);
+
+ if(errorstatus==SD_OK)
+ {
+ while((!validvoltage)&&(countRESP1;;
+ validvoltage=(((response>>31)==1)?1:0);
+ count++;
+ }
+ if(count>=SD_MAX_VOLT_TRIAL)
+ {
+ errorstatus=SD_INVALID_VOLTRANGE;
+ return errorstatus;
+ }
+ if(response&=SD_HIGH_CAPACITY)
+ {
+ CardType=SDIO_HIGH_CAPACITY_SD_CARD;
+ }
+ }
+ else{
+ while((!validvoltage)&&(countRESP1;;
+ validvoltage=(((response>>31)==1)?1:0);
+ count++;
+ }
+ if(count>=SD_MAX_VOLT_TRIAL)
+ {
+ errorstatus=SD_INVALID_VOLTRANGE;
+ return errorstatus;
+ }
+ CardType=SDIO_MULTIMEDIA_CARD;
+ }
+ return(errorstatus);
+}
+
+/*********************************************************************
+ * @fn SD_PowerOFF
+ *
+ * @brief SD care Power off
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_PowerOFF(void)
+{
+ SDIO_SetPowerState(SDIO_PowerState_OFF);
+ return SD_OK;
+}
+
+/*********************************************************************
+ * @fn SD_InitializeCards
+ *
+ * @brief Init SD care
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_InitializeCards(void)
+{
+ SD_Error errorstatus=SD_OK;
+ u16 rca = 0x01;
+ if(SDIO_GetPowerState()==0)return SD_REQUEST_NOT_APPLICABLE;
+ if(SDIO_SECURE_DIGITAL_IO_CARD!=CardType)
+ {
+ SDIO_CmdInitStructure.SDIO_Argument = 0x0;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_ALL_SEND_CID;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp2Error();
+ if(errorstatus!=SD_OK)return errorstatus;
+ CID_Tab[0]=SDIO->RESP1;
+ CID_Tab[1]=SDIO->RESP2;
+ CID_Tab[2]=SDIO->RESP3;
+ CID_Tab[3]=SDIO->RESP4;
+ }
+ if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_SECURE_DIGITAL_IO_COMBO_CARD==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))//ÅжϿ¨ÀàÐÍ
+ {
+ SDIO_CmdInitStructure.SDIO_Argument = 0x00;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_REL_ADDR;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp6Error(SD_CMD_SET_REL_ADDR,&rca);
+ if(errorstatus!=SD_OK)return errorstatus;
+ }
+ if (SDIO_MULTIMEDIA_CARD==CardType)
+ {
+ SDIO_CmdInitStructure.SDIO_Argument = (u32)(rca<<16);
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_REL_ADDR;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r6
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp2Error();
+ if(errorstatus!=SD_OK)return errorstatus;
+ }
+ if (SDIO_SECURE_DIGITAL_IO_CARD!=CardType)
+ {
+ RCA = rca;
+ SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)(rca << 16);
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_CSD;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp2Error();
+ if(errorstatus!=SD_OK)return errorstatus;
+ CSD_Tab[0]=SDIO->RESP1;
+ CSD_Tab[1]=SDIO->RESP2;
+ CSD_Tab[2]=SDIO->RESP3;
+ CSD_Tab[3]=SDIO->RESP4;
+ }
+ return SD_OK;
+}
+
+/*********************************************************************
+ * @fn SD_GetCardInfo
+ *
+ * @brief Get SD information
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo)
+{
+ SD_Error errorstatus=SD_OK;
+ u8 tmp=0;
+ cardinfo->CardType=(u8)CardType;
+ cardinfo->RCA=(u16)RCA;
+ tmp=(u8)((CSD_Tab[0]&0xFF000000)>>24);
+ cardinfo->SD_csd.CSDStruct=(tmp&0xC0)>>6;
+ cardinfo->SD_csd.SysSpecVersion=(tmp&0x3C)>>2;
+ cardinfo->SD_csd.Reserved1=tmp&0x03;
+ tmp=(u8)((CSD_Tab[0]&0x00FF0000)>>16);
+ cardinfo->SD_csd.TAAC=tmp;
+ tmp=(u8)((CSD_Tab[0]&0x0000FF00)>>8);
+ cardinfo->SD_csd.NSAC=tmp;
+ tmp=(u8)(CSD_Tab[0]&0x000000FF);
+ cardinfo->SD_csd.MaxBusClkFrec=tmp;
+ tmp=(u8)((CSD_Tab[1]&0xFF000000)>>24);
+ cardinfo->SD_csd.CardComdClasses=tmp<<4;
+ tmp=(u8)((CSD_Tab[1]&0x00FF0000)>>16);
+ cardinfo->SD_csd.CardComdClasses|=(tmp&0xF0)>>4;
+ cardinfo->SD_csd.RdBlockLen=tmp&0x0F;
+ tmp=(u8)((CSD_Tab[1]&0x0000FF00)>>8);
+ cardinfo->SD_csd.PartBlockRead=(tmp&0x80)>>7;
+ cardinfo->SD_csd.WrBlockMisalign=(tmp&0x40)>>6;
+ cardinfo->SD_csd.RdBlockMisalign=(tmp&0x20)>>5;
+ cardinfo->SD_csd.DSRImpl=(tmp&0x10)>>4;
+ cardinfo->SD_csd.Reserved2=0;
+ if((CardType==SDIO_STD_CAPACITY_SD_CARD_V1_1)||(CardType==SDIO_STD_CAPACITY_SD_CARD_V2_0)||(SDIO_MULTIMEDIA_CARD==CardType))//±ê×¼1.1/2.0¿¨/MMC¿¨
+ {
+ cardinfo->SD_csd.DeviceSize=(tmp&0x03)<<10;
+ tmp=(u8)(CSD_Tab[1]&0x000000FF);
+ cardinfo->SD_csd.DeviceSize|=(tmp)<<2;
+ tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);
+ cardinfo->SD_csd.DeviceSize|=(tmp&0xC0)>>6;
+ cardinfo->SD_csd.MaxRdCurrentVDDMin=(tmp&0x38)>>3;
+ cardinfo->SD_csd.MaxRdCurrentVDDMax=(tmp&0x07);
+ tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16);
+ cardinfo->SD_csd.MaxWrCurrentVDDMin=(tmp&0xE0)>>5;
+ cardinfo->SD_csd.MaxWrCurrentVDDMax=(tmp&0x1C)>>2;
+ cardinfo->SD_csd.DeviceSizeMul=(tmp&0x03)<<1;
+ tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8);
+ cardinfo->SD_csd.DeviceSizeMul|=(tmp&0x80)>>7;
+ cardinfo->CardCapacity=(cardinfo->SD_csd.DeviceSize+1);
+ cardinfo->CardCapacity*=(1<<(cardinfo->SD_csd.DeviceSizeMul+2));
+ cardinfo->CardBlockSize=1<<(cardinfo->SD_csd.RdBlockLen);
+ cardinfo->CardCapacity*=cardinfo->CardBlockSize;
+ }else if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)
+ {
+ tmp=(u8)(CSD_Tab[1]&0x000000FF);
+ cardinfo->SD_csd.DeviceSize=(tmp&0x3F)<<16;
+ tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);
+ cardinfo->SD_csd.DeviceSize|=(tmp<<8);
+ tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16);
+ cardinfo->SD_csd.DeviceSize|=(tmp);
+ tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8);
+ cardinfo->CardCapacity=(long long)(cardinfo->SD_csd.DeviceSize+1)*512*1024;
+ cardinfo->CardBlockSize=512;
+ }
+ cardinfo->SD_csd.EraseGrSize=(tmp&0x40)>>6;
+ cardinfo->SD_csd.EraseGrMul=(tmp&0x3F)<<1;
+ tmp=(u8)(CSD_Tab[2]&0x000000FF);
+ cardinfo->SD_csd.EraseGrMul|=(tmp&0x80)>>7;
+ cardinfo->SD_csd.WrProtectGrSize=(tmp&0x7F);
+ tmp=(u8)((CSD_Tab[3]&0xFF000000)>>24);
+ cardinfo->SD_csd.WrProtectGrEnable=(tmp&0x80)>>7;
+ cardinfo->SD_csd.ManDeflECC=(tmp&0x60)>>5;
+ cardinfo->SD_csd.WrSpeedFact=(tmp&0x1C)>>2;
+ cardinfo->SD_csd.MaxWrBlockLen=(tmp&0x03)<<2;
+ tmp=(u8)((CSD_Tab[3]&0x00FF0000)>>16);
+ cardinfo->SD_csd.MaxWrBlockLen|=(tmp&0xC0)>>6;
+ cardinfo->SD_csd.WriteBlockPaPartial=(tmp&0x20)>>5;
+ cardinfo->SD_csd.Reserved3=0;
+ cardinfo->SD_csd.ContentProtectAppli=(tmp&0x01);
+ tmp=(u8)((CSD_Tab[3]&0x0000FF00)>>8);
+ cardinfo->SD_csd.FileFormatGrouop=(tmp&0x80)>>7;
+ cardinfo->SD_csd.CopyFlag=(tmp&0x40)>>6;
+ cardinfo->SD_csd.PermWrProtect=(tmp&0x20)>>5;
+ cardinfo->SD_csd.TempWrProtect=(tmp&0x10)>>4;
+ cardinfo->SD_csd.FileFormat=(tmp&0x0C)>>2;
+ cardinfo->SD_csd.ECC=(tmp&0x03);
+ tmp=(u8)(CSD_Tab[3]&0x000000FF);
+ cardinfo->SD_csd.CSD_CRC=(tmp&0xFE)>>1;
+ cardinfo->SD_csd.Reserved4=1;
+ tmp=(u8)((CID_Tab[0]&0xFF000000)>>24);
+ cardinfo->SD_cid.ManufacturerID=tmp;
+ tmp=(u8)((CID_Tab[0]&0x00FF0000)>>16);
+ cardinfo->SD_cid.OEM_AppliID=tmp<<8;
+ tmp=(u8)((CID_Tab[0]&0x000000FF00)>>8);
+ cardinfo->SD_cid.OEM_AppliID|=tmp;
+ tmp=(u8)(CID_Tab[0]&0x000000FF);
+ cardinfo->SD_cid.ProdName1=tmp<<24;
+ tmp=(u8)((CID_Tab[1]&0xFF000000)>>24);
+ cardinfo->SD_cid.ProdName1|=tmp<<16;
+ tmp=(u8)((CID_Tab[1]&0x00FF0000)>>16);
+ cardinfo->SD_cid.ProdName1|=tmp<<8;
+ tmp=(u8)((CID_Tab[1]&0x0000FF00)>>8);
+ cardinfo->SD_cid.ProdName1|=tmp;
+ tmp=(u8)(CID_Tab[1]&0x000000FF);
+ cardinfo->SD_cid.ProdName2=tmp;
+ tmp=(u8)((CID_Tab[2]&0xFF000000)>>24);
+ cardinfo->SD_cid.ProdRev=tmp;
+ tmp=(u8)((CID_Tab[2]&0x00FF0000)>>16);
+ cardinfo->SD_cid.ProdSN=tmp<<24;
+ tmp=(u8)((CID_Tab[2]&0x0000FF00)>>8);
+ cardinfo->SD_cid.ProdSN|=tmp<<16;
+ tmp=(u8)(CID_Tab[2]&0x000000FF);
+ cardinfo->SD_cid.ProdSN|=tmp<<8;
+ tmp=(u8)((CID_Tab[3]&0xFF000000)>>24);
+ cardinfo->SD_cid.ProdSN|=tmp;
+ tmp=(u8)((CID_Tab[3]&0x00FF0000)>>16);
+ cardinfo->SD_cid.Reserved1|=(tmp&0xF0)>>4;
+ cardinfo->SD_cid.ManufactDate=(tmp&0x0F)<<8;
+ tmp=(u8)((CID_Tab[3]&0x0000FF00)>>8);
+ cardinfo->SD_cid.ManufactDate|=tmp;
+ tmp=(u8)(CID_Tab[3]&0x000000FF);
+ cardinfo->SD_cid.CID_CRC=(tmp&0xFE)>>1;
+ cardinfo->SD_cid.Reserved2=1;
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn SD_EnableWideBusOperation
+ *
+ * @brief Enable SDIO Wide bus
+ *
+ * @param wmode -
+ * 0-1bit
+ * 1-4bit
+ * 2-8bit
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_EnableWideBusOperation(u32 wmode)
+{
+ SD_Error errorstatus=SD_OK;
+ if(SDIO_MULTIMEDIA_CARD==CardType)
+ return SD_UNSUPPORTED_FEATURE;
+ else if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))
+ {
+ if(wmode>=2)return SD_UNSUPPORTED_FEATURE;
+ else
+ {
+ errorstatus=SDEnWideBus(wmode);
+ if(SD_OK==errorstatus)
+ {
+ SDIO->CLKCR&=~(3<<11);
+ SDIO->CLKCR|=(u16)wmode<<11;
+ SDIO->CLKCR|=0<<14;
+ }
+ }
+ }
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn SD_EnableWideBusOperation
+ *
+ * @brief Enable SD care work mode
+ *
+ * @param Mode - work mode
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_SetDeviceMode(u32 Mode)
+{
+ SD_Error errorstatus = SD_OK;
+ if((Mode==SD_DMA_MODE)||(Mode==SD_POLLING_MODE))DeviceMode=Mode;
+ else errorstatus=SD_INVALID_PARAMETER;
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn SD_SelectDeselect
+ *
+ * @brief Select deselect
+ *
+ * @param addr - RCA address
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_SelectDeselect(u32 addr)
+{
+ SDIO_CmdInitStructure.SDIO_Argument = addr;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEL_DESEL_CARD;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ return CmdResp1Error(SD_CMD_SEL_DESEL_CARD);
+}
+
+/*********************************************************************
+ * @fn SD_ReadBlock
+ *
+ * @brief Read block
+ *
+ * @param *buf - data
+ * addr -RCA address
+ * blksize - block size
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_ReadBlock(u8 *buf,long long addr,u16 blksize)
+{
+ SD_Error errorstatus=SD_OK;
+ u8 power;
+ u32 count=0,*tempbuff=(u32*)buf;
+ u32 timeout=SDIO_DATATIMEOUT;
+ if(NULL==buf)return SD_INVALID_PARAMETER;
+ SDIO->DCTRL=0x0;
+ if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)
+ {
+ blksize=512;
+ addr>>=9;
+ }
+
+ SDIO_DataInitStructure.SDIO_DataBlockSize= SDIO_DataBlockSize_1b ;
+ SDIO_DataInitStructure.SDIO_DataLength= 0 ;
+ SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
+ SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
+ SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
+ SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
+ SDIO_DataConfig(&SDIO_DataInitStructure);
+
+ if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;
+
+ if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
+ {
+ power=convert_from_bytes_to_power_of_two(blksize);
+
+ SDIO_CmdInitStructure.SDIO_Argument = blksize;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+ }else return SD_INVALID_PARAMETER;
+ SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4 ;
+ SDIO_DataInitStructure.SDIO_DataLength= blksize ;
+ SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
+ SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
+ SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToSDIO;
+ SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
+ SDIO_DataConfig(&SDIO_DataInitStructure);
+
+ SDIO_CmdInitStructure.SDIO_Argument = addr;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_READ_SINGLE_BLOCK);
+ if(errorstatus!=SD_OK)return errorstatus;
+ if(DeviceMode==SD_POLLING_MODE)
+ {
+ while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<10)|(1<<9))))
+ {
+ if(SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)
+ {
+ for(count=0;count<8;count++)
+ {
+ *(tempbuff+count)=SDIO->FIFO;
+ }
+ tempbuff+=8;
+ timeout=0X7FFFFF;
+ }else
+ {
+ if(timeout==0)return SD_DATA_TIMEOUT;
+ timeout--;
+ }
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
+ return SD_DATA_TIMEOUT;
+ }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
+ return SD_DATA_CRC_FAIL;
+ }else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_RXOVERR);
+ return SD_RX_OVERRUN;
+ }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_STBITERR);
+ return SD_START_BIT_ERR;
+ }
+ while(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)
+ {
+ *tempbuff=SDIO_ReadData();
+ tempbuff++;
+ }
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+ }else if(DeviceMode==SD_DMA_MODE)
+ {
+ SD_DMA_Config((u32*)buf,blksize,DMA_DIR_PeripheralSRC);
+ TransferError=SD_OK;
+ StopCondition=0;
+ TransferEnd=0;
+ SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<5)|(1<<9);
+ SDIO_DMACmd(ENABLE);
+ while(((DMA2->INTFR&0X2000)==RESET)&&(TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;
+ if(timeout==0)return SD_DATA_TIMEOUT;
+ if(TransferError!=SD_OK)errorstatus=TransferError;
+ }
+ return errorstatus;
+}
+
+__attribute__ ((aligned(4))) u32 *tempbuff;
+/*********************************************************************
+ * @fn SD_ReadMultiBlocks
+ *
+ * @brief Read multiple block
+ *
+ * @param *buf - data
+ * addr - RCA address
+ * blksize - block size
+ * nblks - block number
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_ReadMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks)
+{
+ SD_Error errorstatus=SD_OK;
+ u8 power;
+ u32 count=0;
+ u32 timeout=SDIO_DATATIMEOUT;
+ tempbuff=(u32*)buf;
+
+ SDIO->DCTRL=0x0;
+ if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)
+ {
+ blksize=512;
+ addr>>=9;
+ }
+
+ SDIO_DataInitStructure.SDIO_DataBlockSize= 0; ;
+ SDIO_DataInitStructure.SDIO_DataLength= 0 ;
+ SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
+ SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
+ SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
+ SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
+ SDIO_DataConfig(&SDIO_DataInitStructure);
+
+ if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;
+ if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
+ {
+ power=convert_from_bytes_to_power_of_two(blksize);
+
+ SDIO_CmdInitStructure.SDIO_Argument = blksize;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);
+ if(errorstatus!=SD_OK)return errorstatus;
+ }else return SD_INVALID_PARAMETER;
+ if(nblks>1)
+ {
+ if(nblks*blksize>SD_MAX_DATA_LENGTH)return SD_INVALID_PARAMETER;
+ SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ;
+ SDIO_DataInitStructure.SDIO_DataLength= nblks*blksize ;
+ SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
+ SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
+ SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToSDIO;
+ SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
+ SDIO_DataConfig(&SDIO_DataInitStructure);
+
+ SDIO_CmdInitStructure.SDIO_Argument = addr;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_MULT_BLOCK;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_READ_MULT_BLOCK);
+ if(errorstatus!=SD_OK)return errorstatus;
+ if(DeviceMode==SD_POLLING_MODE)
+ {
+ while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<8)|(1<<9))))
+ {
+ if(SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)
+ {
+ for(count=0;count<8;count++)
+ {
+ *(tempbuff+count)=SDIO->FIFO;
+ }
+ tempbuff+=8;
+ timeout=0X7FFFFF;
+ }else
+ {
+ if(timeout==0)return SD_DATA_TIMEOUT;
+ timeout--;
+ }
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
+ return SD_DATA_TIMEOUT;
+ }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
+ return SD_DATA_CRC_FAIL;
+ }else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_RXOVERR);
+ return SD_RX_OVERRUN;
+ }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_STBITERR);
+ return SD_START_BIT_ERR;
+ }
+
+ while(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)
+ {
+ *tempbuff=SDIO_ReadData();
+ tempbuff++;
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET)
+ {
+ if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))
+ {
+
+ SDIO_CmdInitStructure.SDIO_Argument = 0;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_STOP_TRANSMISSION;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);
+ if(errorstatus!=SD_OK)return errorstatus;
+ }
+ }
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+ }else if(DeviceMode==SD_DMA_MODE)
+ {
+ SD_DMA_Config((u32*)buf,nblks*blksize,DMA_DIR_PeripheralSRC);
+ TransferError=SD_OK;
+ StopCondition=1;
+ TransferEnd=0;
+ SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<5)|(1<<9);
+ SDIO->DCTRL|=1<<3;
+ while(((DMA2->INTFR&0X2000)==RESET)&&timeout)timeout--;
+ if(timeout==0)return SD_DATA_TIMEOUT;
+ while((TransferEnd==0)&&(TransferError==SD_OK));
+ if(TransferError!=SD_OK)errorstatus=TransferError;
+ }
+ }
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn SD_WriteBlock
+ *
+ * @brief Write block
+ *
+ * @param *buf - data
+ * addr - RCA address
+ * blksize - block size
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_WriteBlock(u8 *buf,long long addr, u16 blksize)
+{
+ SD_Error errorstatus = SD_OK;
+ u8 power=0,cardstate=0;
+ u32 timeout=0,bytestransferred=0;
+ u32 cardstatus=0,count=0,restwords=0;
+ u32 tlen=blksize;
+ u32*tempbuff=(u32*)buf;
+
+ if(buf==NULL)return SD_INVALID_PARAMETER;
+
+ SDIO->DCTRL=0x0;
+
+ SDIO_DataInitStructure.SDIO_DataBlockSize= 0; ;
+ SDIO_DataInitStructure.SDIO_DataLength= 0 ;
+ SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
+ SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
+ SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
+ SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
+ SDIO_DataConfig(&SDIO_DataInitStructure);
+
+
+ if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;
+ if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)
+ {
+ blksize=512;
+ addr>>=9;
+ }
+ if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
+ {
+ power=convert_from_bytes_to_power_of_two(blksize);
+
+ SDIO_CmdInitStructure.SDIO_Argument = blksize;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+
+ }else return SD_INVALID_PARAMETER;
+
+ SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+ cardstatus=SDIO->RESP1;
+ timeout=SD_DATATIMEOUT;
+ while(((cardstatus&0x00000100)==0)&&(timeout>0))
+ {
+ timeout--;
+
+ SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS);
+ if(errorstatus!=SD_OK)return errorstatus;
+ cardstatus=SDIO->RESP1;
+ }
+ if(timeout==0)return SD_ERROR;
+
+ SDIO_CmdInitStructure.SDIO_Argument = addr;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_WRITE_SINGLE_BLOCK);
+ if(errorstatus!=SD_OK)return errorstatus;
+ StopCondition=0;
+
+ SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ;
+ SDIO_DataInitStructure.SDIO_DataLength= blksize ;
+ SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
+ SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
+ SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
+ SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
+ SDIO_DataConfig(&SDIO_DataInitStructure);
+
+ timeout=SDIO_DATATIMEOUT;
+ if (DeviceMode == SD_POLLING_MODE)
+ {
+ while(!(SDIO->STA&((1<<10)|(1<<4)|(1<<1)|(1<<3)|(1<<9))))
+ {
+ if(SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)
+ {
+ if((tlen-bytestransferred)ICR=0X5FF;
+ }else if(DeviceMode==SD_DMA_MODE)
+ {
+ SD_DMA_Config((u32*)buf,blksize,DMA_DIR_PeripheralDST);
+ TransferError=SD_OK;
+ StopCondition=0;
+ TransferEnd=0;
+ SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<4)|(1<<9);
+ SDIO->DCTRL|=1<<3;
+ while(((DMA2->INTFR&0X2000)==RESET)&&timeout)timeout--;
+ if(timeout==0)
+ {
+ SD_Init();
+ return SD_DATA_TIMEOUT;
+ }
+ timeout=SDIO_DATATIMEOUT;
+ while((TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;
+ if(timeout==0)return SD_DATA_TIMEOUT;
+ if(TransferError!=SD_OK)return TransferError;
+ }
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+ errorstatus=IsCardProgramming(&cardstate);
+ while((errorstatus==SD_OK)&&((cardstate==SD_CARD_PROGRAMMING)||(cardstate==SD_CARD_RECEIVING)))
+ {
+ errorstatus=IsCardProgramming(&cardstate);
+ }
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn SD_WriteBlock
+ *
+ * @brief Write multiple block
+ *
+ * @param buf - data
+ * addr - RCA address
+ * blksize - block size
+ * nblks - block number
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_WriteMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks)
+{
+ SD_Error errorstatus = SD_OK;
+ u8 power = 0, cardstate = 0;
+ u32 timeout=0,bytestransferred=0;
+ u32 count = 0, restwords = 0;
+ u32 tlen=nblks*blksize;
+ u32 *tempbuff = (u32*)buf;
+ if(buf==NULL)return SD_INVALID_PARAMETER;
+ SDIO->DCTRL=0x0;
+
+ SDIO_DataInitStructure.SDIO_DataBlockSize= 0;
+ SDIO_DataInitStructure.SDIO_DataLength= 0 ;
+ SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
+ SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
+ SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
+ SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
+ SDIO_DataConfig(&SDIO_DataInitStructure);
+
+ if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;
+ if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)
+ {
+ blksize=512;
+ addr>>=9;
+ }
+ if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
+ {
+ power=convert_from_bytes_to_power_of_two(blksize);
+
+ SDIO_CmdInitStructure.SDIO_Argument = blksize;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+
+ }else return SD_INVALID_PARAMETER;
+ if(nblks>1)
+ {
+ if(nblks*blksize>SD_MAX_DATA_LENGTH)return SD_INVALID_PARAMETER;
+ if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))
+ {
+ SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_APP_CMD);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+
+ SDIO_CmdInitStructure.SDIO_Argument =nblks;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCK_COUNT;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SET_BLOCK_COUNT);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+
+ }
+
+ SDIO_CmdInitStructure.SDIO_Argument =addr;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_WRITE_MULT_BLOCK);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+
+ SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ;
+ SDIO_DataInitStructure.SDIO_DataLength= nblks*blksize ;
+ SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
+ SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
+ SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
+ SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
+ SDIO_DataConfig(&SDIO_DataInitStructure);
+
+ if(DeviceMode==SD_POLLING_MODE)
+ {
+ timeout=SDIO_DATATIMEOUT;
+
+ while(!(SDIO->STA&((1<<4)|(1<<1)|(1<<8)|(1<<3)|(1<<9))))
+ {
+ if(SDIO->STA&(1<<14))
+ {
+ if((tlen-bytestransferred)MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<4)|(1<<9);
+ SDIO->DCTRL|=1<<3;
+ timeout=SDIO_DATATIMEOUT;
+ while(((DMA2->INTFR&0X2000)==RESET)&&timeout)timeout--;
+ if(timeout==0)
+ {
+ SD_Init();
+ return SD_DATA_TIMEOUT;
+ }
+ timeout=SDIO_DATATIMEOUT;
+ while((TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;
+ if(timeout==0)return SD_DATA_TIMEOUT;
+ if(TransferError!=SD_OK)return TransferError;
+ }
+ }
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+ errorstatus=IsCardProgramming(&cardstate);
+ while((errorstatus==SD_OK)&&((cardstate==SD_CARD_PROGRAMMING)||(cardstate==SD_CARD_RECEIVING)))
+ {
+ errorstatus=IsCardProgramming(&cardstate);
+ }
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn SDIO_IRQHandler
+ *
+ * @brief This function handles SDIO exception.
+ *
+ * @return none
+ */
+void SDIO_IRQHandler(void)
+{
+ SD_ProcessIRQSrc();
+}
+
+/*********************************************************************
+ * @fn SD_ProcessIRQSrc
+ *
+ * @brief IRQ deal function
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_ProcessIRQSrc(void)
+{
+ if(SDIO->STA&(1<<8))
+ {
+ if (StopCondition==1)
+ {
+ SDIO_CmdInitStructure.SDIO_Argument =0;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_STOP_TRANSMISSION;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ TransferError=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);
+ }else TransferError = SD_OK;
+ SDIO->ICR|=1<<8;
+ SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));
+ TransferEnd = 1;
+ return(TransferError);
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
+ SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));
+ TransferError = SD_DATA_CRC_FAIL;
+ return(SD_DATA_CRC_FAIL);
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
+ SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));
+ TransferError = SD_DATA_TIMEOUT;
+ return(SD_DATA_TIMEOUT);
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_RXOVERR);
+ SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));
+ TransferError = SD_RX_OVERRUN;
+ return(SD_RX_OVERRUN);
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);
+ SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));
+ TransferError = SD_TX_UNDERRUN;
+ return(SD_TX_UNDERRUN);
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_STBITERR);
+ SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));
+ TransferError = SD_START_BIT_ERR;
+ return(SD_START_BIT_ERR);
+ }
+ return(SD_OK);
+}
+
+/*********************************************************************
+ * @fn CmdError
+ *
+ * @brief Errer commend
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error CmdError(void)
+{
+ SD_Error errorstatus = SD_OK;
+ u32 timeout=SDIO_CMD0TIMEOUT;
+ while(timeout--)
+ {
+ if(SDIO_GetFlagStatus(SDIO_FLAG_CMDSENT) != RESET)break;
+ }
+ if(timeout==0)return SD_CMD_RSP_TIMEOUT;
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn CmdResp7Error
+ *
+ * @brief R7 Errer commend
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error CmdResp7Error(void)
+{
+ SD_Error errorstatus=SD_OK;
+ u32 status = 0;
+ u32 timeout=SDIO_CMD0TIMEOUT;
+ while(timeout--)
+ {
+ status=SDIO->STA;
+ if(status&((1<<0)|(1<<2)|(1<<6)))break;
+ }
+ if((timeout==0)||(status&(1<<2)))
+ {
+ errorstatus=SD_CMD_RSP_TIMEOUT;
+ SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);
+ return errorstatus;
+ }
+ if((status)&(1<<6))
+ {
+ errorstatus=SD_OK;
+ SDIO_ClearFlag(SDIO_FLAG_CMDREND);
+ }
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn CmdResp7Error
+ *
+ * @brief R1 Errer commend
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error CmdResp1Error(u8 cmd)
+{
+ u32 status;
+ while(1)
+ {
+ status=SDIO->STA;
+ if(status&((1<<0)|(1<<2)|(1<<6)))break;
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);
+ return SD_CMD_RSP_TIMEOUT;
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);
+ return SD_CMD_CRC_FAIL;
+ }
+ if(SDIO->RESPCMD!=cmd)return SD_ILLEGAL_CMD;
+ SDIO->ICR=0X5FF;
+ return (SD_Error)(SDIO->RESP1&SD_OCR_ERRORBITS);
+}
+
+/*********************************************************************
+ * @fn CmdResp3Error
+ *
+ * @brief R3 Errer commend
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error CmdResp3Error(void)
+{
+ u32 status;
+ while(1)
+ {
+ status=SDIO->STA;
+ if(status&((1<<0)|(1<<2)|(1<<6)))break;
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);
+ return SD_CMD_RSP_TIMEOUT;
+ }
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+ return SD_OK;
+}
+
+/*********************************************************************
+ * @fn CmdResp2Error
+ *
+ * @brief R2 Errer commend
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error CmdResp2Error(void)
+{
+ SD_Error errorstatus=SD_OK;
+ u32 status = 0;
+ u32 timeout=SDIO_CMD0TIMEOUT;
+ while(timeout--)
+ {
+ status=SDIO->STA;
+ if(status&((1<<0)|(1<<2)|(1<<6)))break;
+ }
+ if((timeout==0)||(status&(1<<2)))
+ {
+ errorstatus=SD_CMD_RSP_TIMEOUT;
+ SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);
+ return errorstatus;
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)
+ {
+ errorstatus=SD_CMD_CRC_FAIL;
+ SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);
+ }
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn CmdResp6Error
+ *
+ * @brief R6 Errer commend
+ *
+ * @param cmd - Send commend
+ * *prca - RCA address
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error CmdResp6Error(u8 cmd,u16*prca)
+{
+ SD_Error errorstatus=SD_OK;
+ u32 status;
+ u32 rspr1;
+ while(1)
+ {
+ status=SDIO->STA;
+ if(status&((1<<0)|(1<<2)|(1<<6)))break;
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);
+ return SD_CMD_RSP_TIMEOUT;
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);
+ return SD_CMD_CRC_FAIL;
+ }
+ if(SDIO->RESPCMD!=cmd)
+ {
+ return SD_ILLEGAL_CMD;
+ }
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+
+ rspr1=SDIO->RESP1;
+ if(SD_ALLZERO==(rspr1&(SD_R6_GENERAL_UNKNOWN_ERROR|SD_R6_ILLEGAL_CMD|SD_R6_COM_CRC_FAILED)))
+ {
+ *prca=(u16)(rspr1>>16);
+ return errorstatus;
+ }
+ if(rspr1&SD_R6_GENERAL_UNKNOWN_ERROR)return SD_GENERAL_UNKNOWN_ERROR;
+ if(rspr1&SD_R6_ILLEGAL_CMD)return SD_ILLEGAL_CMD;
+ if(rspr1&SD_R6_COM_CRC_FAILED)return SD_COM_CRC_FAILED;
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn SDEnWideBus
+ *
+ * @brief Enable bus width
+ *
+ * @param enx - 0-disable 1-enable
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SDEnWideBus(u8 enx)
+{
+ SD_Error errorstatus = SD_OK;
+ u32 scr[2]={0,0};
+ u8 arg=0X00;
+ if(enx)arg=0X02;
+ else arg=0X00;
+ if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;
+ errorstatus=FindSCR(RCA,scr);
+ if(errorstatus!=SD_OK)return errorstatus;
+ if((scr[1]&SD_WIDE_BUS_SUPPORT)!=SD_ALLZERO)
+ {
+ SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_APP_CMD);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+
+ SDIO_CmdInitStructure.SDIO_Argument = arg;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_APP_SD_SET_BUSWIDTH);
+ return errorstatus;
+ }else return SD_REQUEST_NOT_APPLICABLE;
+}
+
+/*********************************************************************
+ * @fn IsCardProgramming
+ *
+ * @brief Check SD card write statue
+ *
+ * @param pstatus - Current status
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error IsCardProgramming(u8 *pstatus)
+{
+ vu32 respR1 = 0, status = 0;
+
+ SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ status=SDIO->STA;
+
+ while(!(status&((1<<0)|(1<<6)|(1<<2))))status=SDIO->STA;
+
+ if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);
+ return SD_CMD_CRC_FAIL;
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);
+ return SD_CMD_RSP_TIMEOUT;
+ }
+ if(SDIO->RESPCMD!=SD_CMD_SEND_STATUS)return SD_ILLEGAL_CMD;
+
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+
+ respR1=SDIO->RESP1;
+
+ *pstatus=(u8)((respR1>>9)&0x0000000F);
+ return SD_OK;
+}
+
+/*********************************************************************
+ * @fn SD_SendStatus
+ *
+ * @brief Read SD card write statue
+ *
+ * @param pcardstatus - Current status
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error SD_SendStatus(uint32_t *pcardstatus)
+{
+ SD_Error errorstatus = SD_OK;
+ if(pcardstatus==NULL)
+ {
+ errorstatus=SD_INVALID_PARAMETER;
+ return errorstatus;
+ }
+
+ SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS);
+ if(errorstatus!=SD_OK)return errorstatus;
+ *pcardstatus=SDIO->RESP1;
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn SD_GetState
+ *
+ * @brief Get SD card write statue
+ *
+ * @return SD_Error - ERR code
+ */
+SDCardState SD_GetState(void)
+{
+ u32 resp1=0;
+ if(SD_SendStatus(&resp1)!=SD_OK)return SD_CARD_ERROR;
+ else return (SDCardState)((resp1>>9) & 0x0F);
+}
+
+/*********************************************************************
+ * @fn FindSCR
+ *
+ * @brief Find SD card SCR
+ *
+ * @return SD_Error - ERR code
+ */
+SD_Error FindSCR(u16 rca,u32 *pscr)
+{
+ u32 index = 0;
+ SD_Error errorstatus = SD_OK;
+ u32 tempscr[2]={0,0};
+
+ SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)8;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+
+ SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_APP_CMD);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+
+ SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
+ SDIO_DataInitStructure.SDIO_DataLength = 8;
+ SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_8b ;
+ SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
+ SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
+ SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
+ SDIO_DataConfig(&SDIO_DataInitStructure);
+
+ SDIO_CmdInitStructure.SDIO_Argument = 0x0;
+ SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SD_APP_SEND_SCR;
+ SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r1
+ SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
+ SDIO_SendCommand(&SDIO_CmdInitStructure);
+
+ errorstatus=CmdResp1Error(SD_CMD_SD_APP_SEND_SCR);
+
+ if(errorstatus!=SD_OK)return errorstatus;
+
+ while(!(SDIO->STA&(SDIO_FLAG_RXOVERR|SDIO_FLAG_DCRCFAIL|SDIO_FLAG_DTIMEOUT|SDIO_FLAG_DBCKEND|SDIO_FLAG_STBITERR)))
+ {
+ if(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)
+ {
+ *(tempscr+index)=SDIO_ReadData();
+ index++;
+ if(index>=2)break;
+ }
+ }
+ if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
+ return SD_DATA_TIMEOUT;
+ }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
+ return SD_DATA_CRC_FAIL;
+ }else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_RXOVERR);
+ return SD_RX_OVERRUN;
+ }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
+ {
+ SDIO_ClearFlag(SDIO_FLAG_STBITERR);
+ return SD_START_BIT_ERR;
+ }
+ SDIO_ClearFlag(SDIO_STATIC_FLAGS);
+
+ *(pscr+1)=((tempscr[0]&SD_0TO7BITS)<<24)|((tempscr[0]&SD_8TO15BITS)<<8)|((tempscr[0]&SD_16TO23BITS)>>8)|((tempscr[0]&SD_24TO31BITS)>>24);
+ *(pscr)=((tempscr[1]&SD_0TO7BITS)<<24)|((tempscr[1]&SD_8TO15BITS)<<8)|((tempscr[1]&SD_16TO23BITS)>>8)|((tempscr[1]&SD_24TO31BITS)>>24);
+ return errorstatus;
+}
+
+/*********************************************************************
+ * @fn convert_from_bytes_to_power_of_two
+ *
+ * @brief Get NumberOfBytes value
+ *
+ * @param NumberOfBytes - byte number
+ *
+ * @return SD_Error - ERR code
+ */
+u8 convert_from_bytes_to_power_of_two(u16 NumberOfBytes)
+{
+ u8 count=0;
+ while(NumberOfBytes!=1)
+ {
+ NumberOfBytes>>=1;
+ count++;
+ }
+ return count;
+}
+
+/*********************************************************************
+ * @fn SD_DMA_Config
+ *
+ * @brief configure DMA
+ *
+ * @param mbuf - Storage address
+ * bufsize - data size
+ *
+ * @return SD_Error - ERR code
+ */
+void SD_DMA_Config(u32*mbuf,u32 bufsize,u32 DMA_DIR)
+{
+ DMA_InitTypeDef DMA_InitStructure;
+
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
+
+ DMA_DeInit(DMA2_Channel4);
+ DMA_Cmd(DMA2_Channel4, DISABLE );
+
+ DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SDIO->FIFO;
+ DMA_InitStructure.DMA_MemoryBaseAddr = (u32)mbuf;
+ DMA_InitStructure.DMA_DIR = DMA_DIR;
+ DMA_InitStructure.DMA_BufferSize = bufsize/4;
+ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
+ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
+ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
+ DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
+ DMA_Init(DMA2_Channel4, &DMA_InitStructure);
+
+ DMA_Cmd(DMA2_Channel4, DISABLE );
+}
+
+/*********************************************************************
+ * @fn SD_ReadDisk
+ *
+ * @brief Read SD care
+ *
+ * @param buf - data
+ * sector - sector addr
+ * cnt - sector number
+ *
+ * @return SD_Error - ERR code
+ */
+u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
+{
+ u8 sta=SD_OK;
+ long long lsector=sector;
+ u8 n;
+ lsector<<=9;
+ if((u32)buf%4!=0)
+ {
+ for(n=0;n200)return 0;
+ }
+
+ SPI_I2S_SendData(SPI3, TxData);
+ i=0;
+
+ while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET)
+ {
+ i++;
+ if(i>200)return 0;
+ }
+
+ return SPI_I2S_ReceiveData(SPI3);
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_Init
+ *
+ * @brief Configuring the SPI for operation flash.
+ *
+ * @return none
+ */
+void SPI_Flash_Init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStructure={0};
+ SPI_InitTypeDef SPI_InitStructure={0};
+
+ RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA/*|RCC_APB2Periph_SPI1*/|RCC_APB2Periph_GPIOB, ENABLE );
+ RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI3, ENABLE );
+
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ GPIO_SetBits(GPIOA, GPIO_Pin_15); //SPI3_NSS
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init( GPIOB, &GPIO_InitStructure );//SPI3_SCK
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+ GPIO_Init( GPIOB, &GPIO_InitStructure );//SPI3_MISO
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init( GPIOB, &GPIO_InitStructure );//SPI3_MOSI
+
+ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
+ SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
+ SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
+ SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
+ SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
+ SPI_InitStructure.SPI_CRCPolynomial = 7;
+ SPI_Init(SPI3, &SPI_InitStructure);
+
+ SPI_Cmd(SPI3, ENABLE);
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_ReadSR
+ *
+ * @brief Read W25Qxx status register.
+ * ¡ª¡ªBIT7 6 5 4 3 2 1 0
+ * ¡ª¡ªSPR RV TB BP2 BP1 BP0 WEL BUSY
+ *
+ * @return byte - status register value.
+ */
+u8 SPI_Flash_ReadSR(void)
+{
+ u8 byte=0;
+
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ SPI1_ReadWriteByte(W25X_ReadStatusReg);
+ byte=SPI1_ReadWriteByte(0Xff);
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
+
+ return byte;
+}
+
+/*********************************************************************
+ * @fn SPI_FLASH_Write_SR
+ *
+ * @brief Write W25Qxx status register.
+ *
+ * @param sr - status register value.
+ *
+ * @return none
+ */
+void SPI_FLASH_Write_SR(u8 sr)
+{
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ SPI1_ReadWriteByte(W25X_WriteStatusReg);
+ SPI1_ReadWriteByte(sr);
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_Wait_Busy
+ *
+ * @brief Wait flash free.
+ *
+ * @return none
+ */
+void SPI_Flash_Wait_Busy(void)
+{
+ while((SPI_Flash_ReadSR()&0x01)==0x01);
+}
+
+/*********************************************************************
+ * @fn SPI_FLASH_Write_Enable
+ *
+ * @brief Enable flash write.
+ *
+ * @return none
+ */
+void SPI_FLASH_Write_Enable(void)
+{
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ SPI1_ReadWriteByte(W25X_WriteEnable);
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
+}
+
+/*********************************************************************
+ * @fn SPI_FLASH_Write_Disable
+ *
+ * @brief Disable flash write.
+ *
+ * @return none
+ */
+void SPI_FLASH_Write_Disable(void)
+{
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ SPI1_ReadWriteByte(W25X_WriteDisable);
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_ReadID
+ *
+ * @brief Read flash ID.
+ *
+ * @return Temp - FLASH ID.
+ */
+u16 SPI_Flash_ReadID(void)
+{
+ u16 Temp = 0;
+
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ Delay_Ms(10);
+ SPI1_ReadWriteByte(W25X_ManufactDeviceID);
+ SPI1_ReadWriteByte(0x00);
+ SPI1_ReadWriteByte(0x00);
+ SPI1_ReadWriteByte(0x00);
+ Temp|=SPI1_ReadWriteByte(0xFF)<<8;
+ Temp|=SPI1_ReadWriteByte(0xFF);
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
+
+ return Temp;
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_Erase_Sector
+ *
+ * @brief Erase one sector(4Kbyte).
+ *
+ * @param Dst_Addr - 0 ¡ª¡ª 2047
+ *
+ * @return none
+ */
+void SPI_Flash_Erase_Sector(u32 Dst_Addr)
+{
+ Dst_Addr*=4096;
+ SPI_FLASH_Write_Enable();
+ SPI_Flash_Wait_Busy();
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ SPI1_ReadWriteByte(W25X_SectorErase);
+ SPI1_ReadWriteByte((u8)((Dst_Addr)>>16));
+ SPI1_ReadWriteByte((u8)((Dst_Addr)>>8));
+ SPI1_ReadWriteByte((u8)Dst_Addr);
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
+ SPI_Flash_Wait_Busy();
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_Read
+ *
+ * @brief Read data from flash.
+ *
+ * @param pBuffer -
+ * ReadAddr -Initial address(24bit).
+ * size - Data length.
+ *
+ * @return none
+ */
+void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 size)
+{
+ u16 i;
+
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ SPI1_ReadWriteByte(W25X_ReadData);
+ SPI1_ReadWriteByte((u8)((ReadAddr)>>16));
+ SPI1_ReadWriteByte((u8)((ReadAddr)>>8));
+ SPI1_ReadWriteByte((u8)ReadAddr);
+
+ for(i=0;i>16));
+ SPI1_ReadWriteByte((u8)((WriteAddr)>>8));
+ SPI1_ReadWriteByte((u8)WriteAddr);
+
+ for(i=0;i256)pageremain=256;
+ else pageremain=size;
+ }
+ }
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_Write
+ *
+ * @brief Write data to flash.(no need Erase)
+ *
+ * @param pBuffer -
+ * WriteAddr - Initial address(24bit).
+ * size - Data length.
+ *
+ * @return none
+ */
+void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 size)
+{
+ u32 secpos;
+ u16 secoff;
+ u16 secremain;
+ u16 i;
+
+ secpos=WriteAddr/4096;
+ secoff=WriteAddr%4096;
+ secremain=4096-secoff;
+
+ if(size<=secremain)secremain=size;
+
+ while(1)
+ {
+ SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);
+
+ for(i=0;i4096)
+ {
+ secremain=4096;
+ }
+ else
+ {
+ secremain=size;
+ }
+ }
+ }
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_Erase_Chip
+ *
+ * @brief Erase all FLASH pages.
+ *
+ * @return none
+ */
+void SPI_Flash_Erase_Chip(void)
+{
+ SPI_FLASH_Write_Enable();
+ SPI_Flash_Wait_Busy();
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ SPI1_ReadWriteByte(W25X_ChipErase);
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
+ SPI_Flash_Wait_Busy();
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_PowerDown
+ *
+ * @brief Enter power down mode.
+ *
+ * @return none
+ */
+void SPI_Flash_PowerDown(void)
+{
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ SPI1_ReadWriteByte(W25X_PowerDown);
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
+ Delay_Us(3);
+}
+
+/*********************************************************************
+ * @fn SPI_Flash_WAKEUP
+ *
+ * @brief Power down wake up.
+ *
+ * @return none
+ */
+void SPI_Flash_WAKEUP(void)
+{
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
+ SPI1_ReadWriteByte(W25X_ReleasePowerDown);
+ GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
+ Delay_Us(3);
+}
+
+
diff --git a/board/TencentOS_Tiny_CH32V307_EVB/User/spi_flash.h b/board/TencentOS_Tiny_CH32V307_EVB/User/spi_flash.h
new file mode 100644
index 00000000..b5271d97
--- /dev/null
+++ b/board/TencentOS_Tiny_CH32V307_EVB/User/spi_flash.h
@@ -0,0 +1,63 @@
+#ifndef __SPI_FLASH_H
+#define __SPI_FLASH_H
+#include "debug.h"
+#include "string.h"
+
+/* Winbond SPIFalsh ID */
+#define W25Q80 0XEF13
+#define W25Q16 0XEF14
+#define W25Q32 0XEF15
+#define W25Q64 0XEF16
+#define W25Q128 0XEF17
+
+/* Winbond SPIFalsh Instruction List */
+#define W25X_WriteEnable 0x06
+#define W25X_WriteDisable 0x04
+#define W25X_ReadStatusReg 0x05
+#define W25X_WriteStatusReg 0x01
+#define W25X_ReadData 0x03
+#define W25X_FastReadData 0x0B
+#define W25X_FastReadDual 0x3B
+#define W25X_PageProgram 0x02
+#define W25X_BlockErase 0xD8
+#define W25X_SectorErase 0x20
+#define W25X_ChipErase 0xC7
+#define W25X_PowerDown 0xB9
+#define W25X_ReleasePowerDown 0xAB
+#define W25X_DeviceID 0xAB
+#define W25X_ManufactDeviceID 0x90
+#define W25X_JedecDeviceID 0x9F
+
+#define SIZE sizeof(TEXT_Buf)
+u8 SPI_FLASH_BUF[4096];
+
+
+
+
+
+
+u8 SPI1_ReadWriteByte(u8 TxData);
+void SPI_Flash_Init(void);
+u8 SPI_Flash_ReadSR(void);
+void SPI_FLASH_Write_SR(u8 sr);
+void SPI_Flash_Wait_Busy(void);
+void SPI_FLASH_Write_Enable(void);
+void SPI_FLASH_Write_Disable(void);
+u16 SPI_Flash_ReadID(void);
+void SPI_Flash_Erase_Sector(u32 Dst_Addr);
+void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 size);
+void SPI_Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 size);
+void SPI_Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 size);
+void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 size);
+void SPI_Flash_Erase_Chip(void);
+void SPI_Flash_PowerDown(void);
+void SPI_Flash_WAKEUP(void);
+
+#endif
+
+
+
+
+
+
+