📄 sdi.c
字号:
//--Stop cmd(CMD12)
//SDICARG CmdArg [31:0] = 0 : Command Argument
rSDICARG=0x0; //CMD12(stuff bit)
//SDICCON CmdIndex [7:0] = 0X4C : CMD12
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait_resp
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;
//-- Check end of CMD12
if(SD_NO_ERR==Chk_CMDend(12, 1))return SD_NO_ERR;
//goto RERCMD12;
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
}
return SD_ERR;
}
return SD_NO_ERR;
}
/*****************************************
写存储块函数
函数名: Wt_Block
描述: 通过三种方式写存储块
返回值:void
*****************************************/
U8 Wt_Block(U32 block,U32 *src,U32 *dst)
{
U32 m,n;
//SDICON FIFO Reset (FRST) [1] = 1 : FIFO reset
rSDICON |= rSDICON|(1<<1); // FIFO reset
//SDICARG CmdArg [31:0] = 0 : Command Argument
rSDICARG=(int)(dst); // CMD24/25(addr)
//REWTCMD:
//use dma
for(n=0;n<100;n++)
{
pISR_DMA0=(unsigned)DMA_end;
//INTMSK INT_DMA0 [17] = 0 : Service availa
rINTMSK = ~(BIT_DMA0);
//DISRC0 S_ADDR [30:0] = Tx_buffer : Tx_buffer
rDISRC0=(int)(src);
//DISRCC0 INC [0] = 0 : inc
//DISRCC0 LOC [1] = 0 : AHB
rDISRCC0=(0<<1)+(0<<0); // AHB, inc
rDIDST0=(U32)(SDIDAT); // SDIDAT
//DIDSTC0 INC [0] = 1 : fix
//DIDSTC0 LOC [1] = 1 : APB
rDIDSTC0=(1<<1)+(1<<0); // APB, fix
//DCON0 TC [19: 0] = 128*block: Initial transfer count (or transfer beat).
//DCON0 DSZ [21:20] = 10 : Word
//DCON0 RELOAD [22 ] = 1 : auto-reload of
//DCON0 SWHW_SEL [23 ] = 1 : H/W request
//DCON0 HWSRCSEL [26:24] = 10 : SDI
//DCON0 SERVMODE [27 ] = 0 : single service
//DCON0 TSZ [28 ] = 0 : single tx
//DCON0 INT [29 ] = 1 : TC int
//DCON0 SYNC [30 ] = 0 : sync PCLK
//DCON0 DMD_HS [31 ] = 1 : handshake
rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;
//DMASKTRIG0 SW_TRIG [0] = 0 : no-sw trigger
//DMASKTRIG0 ON_OFF [1] = 1 : DMA2 channel on
//DMASKTRIG0 STOP [2] = 0 : no-stop
rDMASKTRIG0=(0<<2)+(1<<1)+0;
//SDIDCON BlkNum [11: 0] = block : Block Number (0~4095).
//SDIDCON Data Transfer Mode (DatMode) [13:12] = 3 : data transmit start
//SDIDCON Stop by force (STOP) [14 ] = 1 : stop by force
//SDIDCON DMA Enable(EnDMA) [15 ] = 1 : dma enable,
//SDIDCON Wide bus enable (WideBus) [16 ] = 0 : standard bus mode(only SDIDAT[0] used),
//SDIDCON Block mode (BlkMode) [17 ] = 1 : block data transfer
//SDIDCON Busy AfterCommand(BACMD) [18 ] = 0 : directly after DatMode set,
//SDIDCON Receive After Command (RACMD) [19 ] = 1 : Rx after cmd
//SDIDCON Transmit After Response(TARSP) [20 ] = 1 : after response receive(assume DatMode sets to 2’b11)
//SDIDCON SDIO InterruptPeriodType(PrdType)[21 ] = 0 : exactly 2 cycle,
rSDIDCON=(1<<20)|(1<<17)|(Wide<<16)|(1<<15)|(3<<12)|(block<<0);
// Tx after rsp, blk, 4bit bus, dma enable, Tx start, blk num
if(block<2) // SINGLE_WRITE
{
//SDICCON CmdIndex [7:0] = 0X58 : CMD24
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait_resp
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<9)|(0x1<<8)|0x58; //sht_resp, wait_resp, dat, start, CMD24
if(SD_NO_ERR==Chk_CMDend(24, 1)) //-- Check end of CMD24
break;
}
else // MULTI_WRITE
{
//SDICCON CmdIndex [7:0] = 0X59 : CMD25
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait_resp
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<9)|(0x1<<8)|0x59; //sht_resp, wait_resp, dat, start, CMD25
if(SD_NO_ERR==Chk_CMDend(25, 1)) //-- Check end of CMD25
break;
}
}
if(n==100)return SD_ERR;
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
while(!TR_end);
//INTMSK BIT_DMA0 [17] = 1 : MASK
rINTMSK |= (BIT_DMA0);
TR_end=0;
//DMASKTRIG0 STOP [2] = 1 : DMA0 stop
rDMASKTRIG0=(1<<2); //DMA0 stop
//-- Check end of DATA
if(!Chk_DATend())
{
Uart_Printf("dat error\n");
rSDIDSTA=0x10;
return SD_ERR;
}
//SDIDSTA Rx Data Progress On (RxDatOn) [0 ] R : Data receive in progress.
//SDIDSTA Tx Data progress On (TxDatOn) [1 ] R : Data transmit in progress.
//SDIDSTA Start Bit Error (SbitErr) [2 ] =0 : not detect,
//SDIDSTA Busy Finish (BusyFin) [3 ] =0 : not detect,
//SDIDSTA Data Transfer Finish (DatFin) [4 ] =1 : data finish detect
//SDIDSTA Data Time Out (DatTout) [5 ] =0 : not detect,
//SDIDSTA Data Receive CRC Fail (DatCrc)[6 ] =0 : not detect,
//SDIDSTA CRC Status Fail(CrcSta) [7 ] =0 : not detect,
//SDIDSTA FIFO Fail error (FFfail) [8 ] =0 : not detect,
//SDIDSTA SDIO InterruptDetect(IOIntDet)[9 ] =0 : not detect,
//SDIDSTA Data Time Out (DatTout) [10] =0 : not occur,
rSDIDSTA=0x10;
if(block>1)
{
//--Stop cmd(CMD12)
//REWCMD12:
for(m=0;m<100;m++)
{
//SDIDCON BlkNum [11: 0] = block : Block Number (0~4095).
//SDIDCON Data Transfer Mode (DatMode) [13:12] = 1 : only busy check start
//SDIDCON Stop by force (STOP) [14 ] = 0 : normal
//SDIDCON DMA Enable(EnDMA) [15 ] = 0 : disable(polling),
//SDIDCON Wide bus enable (WideBus) [16 ] = 0 : standard bus mode(only SDIDAT[0] used),
//SDIDCON Block mode (BlkMode) [17 ] = 1 : blk
//SDIDCON Busy AfterCommand(BACMD) [18 ] = 1 : after command sent (assume DatMode sets to 2’b01)
//SDIDCON Receive After Command (RACMD) [19 ] = 1 : Rx after cmd
//SDIDCON Transmit After Response(TARSP) [20 ] = 0 : directly after DatMode set,
//SDIDCON SDIO InterruptPeriodType(PrdType)[21 ] = 0 : exactly 2 cycle,
rSDIDCON=(1<<18)|(1<<17)|(0<<16)|(1<<12)|(block<<0);
//--Stop cmd(CMD12)
//SDICARG CmdArg [31:0] = 0 : Command Argument
rSDICARG=0x0; //CMD12(stuff bit)
//SDICCON CmdIndex [7:0] = 0X4c : CMD12
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait_resp
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<9)|(0x1<<8)|0x4c; //sht_resp, wait_resp, start, CMD12
//-- Check end of CMD12
if(SD_NO_ERR==Chk_CMDend(12, 1))
break;
}
if(m==100)return SD_ERR;
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
//-- Check end of DATA(with busy state)
if(!Chk_BUSYend())
{
Uart_Printf("error\n");
rSDIDSTA=0x08;
return SD_ERR;
}
//SDIDSTA Rx Data Progress On (RxDatOn) [0 ] R : Data receive in progress.
//SDIDSTA Tx Data progress On (TxDatOn) [1 ] R : Data transmit in progress.
//SDIDSTA Start Bit Error (SbitErr) [2 ] =0 : not detect,
//SDIDSTA Busy Finish (BusyFin) [3 ] =1 : busy finish detect
//SDIDSTA Data Transfer Finish (DatFin) [4 ] =0 : not detect,
//SDIDSTA Data Time Out (DatTout) [5 ] =0 : not detect,
//SDIDSTA Data Receive CRC Fail (DatCrc)[6 ] =0 : not detect,
//SDIDSTA CRC Status Fail(CrcSta) [7 ] =0 : not detect,
//SDIDSTA FIFO Fail error (FFfail) [8 ] =0 : not detect,
//SDIDSTA SDIO InterruptDetect(IOIntDet)[9 ] =0 : not detect,
//SDIDSTA Data Time Out (DatTout) [10] =0 : not occur,
rSDIDSTA=0x08;
return SD_NO_ERR;
}
return SD_NO_ERR;
}
U8 Chk_CMDend(int cmd, int be_resp)
//0: Timeout
{
int finish0;
if(!be_resp) // No response
{
//SDICSTA RspIndex [7:0] R Response index 6bit with start 2bit (8bit)
//SDICSTA CMD line progress On (CmdOn) [8 ] R Command transfer in progress.
//SDICSTA Response Receive End (RspFin)[9 ] = 1 : response end
// = 0 : not detect,
//SDICSTA Command Time Out (CmdTout) [10 ] = 1 : timeout
// = 0 : not detect
//SDICSTA Command Sent (CmdSent) [11 ] = 1 : command end
// = 0 : not detect
//SDICSTA Response CRC Fail(RspCrc [12 ] = 1 : crc fail
// = 0 : not detect
finish0=rSDICSTA;
while((finish0&0x800)!=0x800) // Check cmdend==1,
finish0=rSDICSTA;
rSDICSTA=finish0;// Clear cmd end state
return SD_NO_ERR;
}
else // With response
{
finish0=rSDICSTA;
while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) )) // Check cmd/rsp end
finish0=rSDICSTA;
if(cmd==1 | cmd==9 | cmd==41) // CRC no check
{
if( (finish0&0xf00) != 0xa00 ) // Check error
{
rSDICSTA=finish0; // Clear error state
if(((finish0&0x400)==0x400))
return CMD_ERR; // Timeout error
}
rSDICSTA=finish0; // Clear cmd & rsp end state
}
else // CRC check
{
if( (finish0&0x1f00) != 0xa00 ) // Check error
{
Uart_Printf("CMD%d:rSDICSTA=0x%x, rSDIRSP0=0x%x, 0x%x\n",cmd, rSDICSTA, rSDIRSP0,(finish0&0x1f00));
rSDICSTA=finish0; // Clear error state
if(((finish0&0x400)==0x400))
return CMD_ERR; // Timeout error
}
rSDICSTA=finish0;
}
return SD_NO_ERR;
}
}
int Chk_DATend(void)
{
int finish;
finish=rSDIDSTA;
while( !( ((finish&0x10)==0x10) | ((finish&0x20)==0x20) ))
// Chek timeout or data end
finish=rSDIDSTA;
if( (finish&0xfc) != 0x10 )
{
Uart_Printf("DATA:finish=0x%x\n", finish);
rSDIDSTA=0xec; // Clear error state
return 0;
}
return 1;
}
int Chk_BUSYend(void)
{
int finish;
finish=rSDIDSTA;
while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) ))
finish=rSDIDSTA;
if( (finish&0xfc) != 0x08 )
{
Uart_Printf("DATA:finish=0x%x\n", finish);
rSDIDSTA=0xf4; //clear error state
return 0;
}
return 1;
}
U8 CMD0(void)
{
//-- Make card idle state
//SDICARG CmdArg [31:0] = 0 : Command Argument
rSDICARG=0x0; // CMD0(stuff bit)
//SDICCON CmdIndex [7:0] = 0X40 : CMD0
//SDICCON Command Start(CMST) [8 ] = 1 : command start
rSDICCON=(1<<8)|0x40;
//-- Check end of CMD0
return (Chk_CMDend(0, 0));
//rSDICSTA=0x800; // Clear cmd_end(no rsp)
}
U8 CMD55(U16 RCA)
{
//--Make ACMD
//SDICARG CmdArg [31:0] = 0 : Command Argument
rSDICARG=RCA<<16; //CMD7(RCA,stuff bit)
//SDICCON CmdIndex [7:0] = 0X77 : CMD55
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait_resp
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<9)|(0x1<<8)|0x77; //sht_resp, wait_resp, start, CMD55
//-- Check end of CMD55
if(SD_NO_ERR!=Chk_CMDend(55, 1))
return CMD_ERR;
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
return SD_NO_ERR;
}
U8 Set_4bit_bus(U16 RCA)
{
U8 ret;
Wide=1;
ret=SetBus(RCA);
if(ret!=SD_NO_ERR)return ret;
Uart_Printf("\n****4bit bus****\n");
return ret;
}
U8 SetBus(U16 RCA)
{
U32 n;
//SET_BUS:
for(n=0;n<100;n++)
{
if(SD_NO_ERR!=CMD55(RCA))return SD_ERR; // Make ACMD
//-- CMD6 implement
//SDICARG CmdArg [31:0] = 0 : Command Argument
rSDICARG=Wide<<1; //Wide 0: 1bit, 1: 4bit
//SDICCON CmdIndex [7:0] = 0X46 : CMD55
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait_resp
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<9)|(0x1<<8)|0x46; //sht_resp, wait_resp, start, CMD55
if(SD_NO_ERR==Chk_CMDend(6, 1))break; // ACMD6
}
if(n==100)return SD_ERR;
return SD_NO_ERR;
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
}
void Set_Prt(void)
{
//-- Set protection addr.0 ~ 262144(32*16*512)
Uart_Printf("[Set protection(addr.0 ~ 262144) test]\n");
RECMD28:
//--Make ACMD
//SDICARG CmdArg [31:0] = 0 : Command Argument
rSDICARG=0; // CMD28(addr)
//SDICCON CmdIndex [7:0] = 0X5c : CMD28
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait_resp
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<9)|(0x1<<8)|0x5c; //sht_resp, wait_resp, start, CMD28
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -