📄 sdi.c
字号:
#include <stdio.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2410addr.h"
#include "2410lib.h"
#include "sdi.h"
#include "fs_int.h"
SDFSDisk SanDisk_info_table={
0,
N_CARD,
0,
0,
0,
0,
0,
0,
};
/***********************************/
/*********glocbal data**************/
/************************************/
const SDDriver SanDisk_driver_table={
SD_ReadBlock,
SD_WriteBlock,
0,
0,
};
// Global variables
U8 *Tx_buffer; //128[word]*16[blk]=8192[byte]
U8 *Rx_buffer; //128[word]*16[blk]=8192[byte]
volatile unsigned int TR_end=0;
int Wide=1;
static U32 card_id=0;
/*****************************************
SD卡测试函数
函数名: Test_SDI
描述: SD卡测试函数
返回值:void
*****************************************/
void Test_SDI(void)
{
Uart_Printf("\n[SDI test]\n");
SD_Initialize(FS__pDevInfo[0].harddisk_info);
Uart_Printf("block_num=0x%x\n",FS__pDevInfo[0].harddisk_info->block_num);
Uart_Printf("block_len=0x%x\n",FS__pDevInfo[0].harddisk_info->block_len);
Uart_Printf("sector_size=0x%x\n",FS__pDevInfo[0].harddisk_info->sector_size);
Uart_Printf("card_type=0x%x\n",FS__pDevInfo[0].harddisk_info->card_type);
TR_Buf_new();
/*
INOM:
Uart_Printf("How many blocks to test?(1~16)?");
block=(U32)Uart_GetIntNum();
if((block==0)|block>16)
goto INOM;
//block=1;//tark
Uart_Printf("\n");
*/
//CMD13();
SD_WriteBlock(&SanDisk_info_table,(U32)0,(U8 *)Tx_buffer);
SD_ReadBlock(&SanDisk_info_table,(U32)0,(U8 *)Rx_buffer);
View_Rx_buf();
// Card deselect
//SDIDCON BlkNum [11: 0] = 0 : Block Number (0~4095).
//SDIDCON Data Transfer Mode (DatMode) [13:12] = 0 : ready,
//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 ] = 0 : stream data transfer,
//SDIDCON Busy AfterCommand(BACMD) [18 ] = 0 : directly after DatMode set,
//SDIDCON Receive After Command (RACMD) [19 ] = 0 : directly after DatMode set,
//SDIDCON Transmit After Response(TARSP) [20 ] = 0 : directly after DatMode set,
//SDIDCON SDIO InterruptPeriodType(PrdType)[21 ] = 0 : exactly 2 cycle,
rSDIDCON=0;
//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
//SDICSTA Command Time Out (CmdTout) [10 ] = 1 : timeout
//SDICSTA Command Sent (CmdSent) [11 ] = 1 : command end
//SDICSTA Response CRC Fail(RspCrc [12 ] = 1 : crc fail
rSDICSTA=0xffff;
}
void TR_Buf_new(void)
{
//-- Tx & Rx Buffer initialize
int i, j;
int start = 0x03020100;
Tx_buffer=(U8 *)0x31000000;
j=0;
for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]
{
j+=0;
*(Tx_buffer+j)=0xaa;
j+=1;
*(Tx_buffer+j)=0xbb;
j+=2;
*(Tx_buffer+j)=0xcc;
j+=3;
*(Tx_buffer+j)=0xdd; //i+j's value sent into the address
j+=4;
}
// *(Tx_buffer+i)=0x5555aaaa;
Flush_Rx_buf();
/*
for(i=0;i<20;i++){
for(j=0;j<128;j++){
Tx_buffer[j+i*128]=start;
if(j % 64 == 63) start = 0x0302010;
else start = start + 0x04040404;
}
start = 0x03020100;
}
*/
}
void Flush_Rx_buf(void)
{
//-- Flushing Rx buffer
int i;
int j=0;
Rx_buffer=(U8 *)0x31800000;
for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]
{
j+=0;
*(Rx_buffer+j)=0;
j+=1;
*(Rx_buffer+j)=0;
j+=2;
*(Rx_buffer+j)=0;
j+=3;
*(Rx_buffer+j)=0;
j+=4;
}
// Uart_Printf("\n--End Rx buffer flush\n");
}
/*****************************************
写入和读出缓冲区数据检查函数
函数名: View_Rx_buf
描述: 检测写入和输出数据
返回值:
*****************************************/
void View_Rx_buf()
{
//-- Display Rx buffer
int i,error=0;
/*
for(i=0;i<2048;i++)
Uart_Printf("RB[%02x]=%x,",Rx_buffer[i]);
*/
Tx_buffer=(U8 *)0x31000000;
Rx_buffer=(U8 *)0x31800000;
Uart_Printf("Check Rx data\n");
for(i=0;i<128;i++)
{
if(Rx_buffer[i] != Tx_buffer[i])
{
Uart_Printf("\nTx/Rx error\n");
Uart_Printf("%d:Tx-0x%08x, Rx-0x%08x\n",i,Tx_buffer[i], Rx_buffer[i]);
error=1;
break;
}
Uart_Printf(".");
}
if(!error)
Uart_Printf(" O.K.\n");
}
void View_Tx_buf(void)
{
//-- Display Tx buffer
int i;
for(i=0;i<2048;i++)
Uart_Printf("TB[%02x]=%x,",Tx_buffer[i]);
}
/*****************************************
SD卡初始化函数
函数名: SD_card_init
描述: SD卡的初始化
返回值:void
*****************************************/
U8 Card_sel_desel(U16 RCA,char sel_desel)
{
int m,n;
//-- Card select or deselect
if(sel_desel)
{
for(n=0;n<10;n++)
{
for(m=0;m<10;m++)
{
//SDICARG CmdArg [31:0] = RCA<<16 : CMD7(RCA,stuff bit)
rSDICARG=RCA<<16;
//SDICCON CmdIndex [7:0] = 0X47 : Command index with start 2bit (8bit)
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait response //SDICCON LongRsp [10 ] = 0 : short response
rSDICCON= (0x1<<9)|(0x1<<8)|0x47; // sht_resp, wait_resp, start, CMD7
//-- Check end of CMD7
if(SD_NO_ERR==Chk_CMDend(7, 1))break;
}
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
//--State(transfer) check
if( rSDIRSP0 & 0x1e00==0x800 )return SD_NO_ERR;
}
return SD_ERR;
}
else
{
for(n=0;n<100;n++)
{
//SDICARG CmdArg [31:0] = 0<<16 : CMD7(RCA,stuff bit)
rSDICARG=RCA<<16; //CMD7(RCA,stuff bit)
//SDICCON CmdIndex [7:0] = 0X47 : Command index with start 2bit (8bit)
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 0 : no respons
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<8)|0x47; //no_resp, start, CMD7
//-- Check end of CMD7
if(SD_NO_ERR==Chk_CMDend(7, 0))return SD_NO_ERR;
}
return SD_ERR;
//rSDICSTA=0x800; // Clear cmd_end(no rsp)
}
}
void __irq DMA_end(void)
{
ClearPending(BIT_DMA0);
TR_end=1;
}
/*****************************************
读存储块函数
函数名: Rd_Block
描述: 通过三种方式读存储块
返回值:void
*****************************************/
U8 Rd_Block(U32 block,U32 *src,U32 *dst)
{
int m,n;
//SDICON FIFO Reset (FRST) [1] = 1 : FIFO reset
rSDICON |= rSDICON|(1<<1);
//SDICARG CmdArg [31:0] = 0 : CMD17/18(addr)
rSDICARG=(int)src;
//RERDCMD:
for(n=0;n<100;n++)
{
//use dma
pISR_DMA0=(unsigned)DMA_end;
//INTMSK INT_DMA0 [17] = 0 : Service availa
rINTMSK = ~(BIT_DMA0);
//DISRC0 S_ADDR [30:0] = SDIDAT : SDIDAT
rDISRC0=SDIDAT; // SDIDAT
//DISRCC0 INC [0] = 1 : Fixed
//DISRCC0 LOC [1] = 1 : the source is in the peripheral bus (APB).
rDISRCC0=(1<<1)+(1<<0);
rDIDST0=(int)dst; // Rx_buffer
//DIDSTC0 INC [0] = 0 : Increment
//DIDSTC0 LOC [1] = 0 : AHB
rDIDSTC0=(0<<1)+(0<<0); // AHB, inc
//DCON0 TC [19: 0] = 10000000 : 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] = 2 : Rx start
//SDIDCON Stop by force (STOP) [14 ] = 0 : normal
//SDIDCON DMA Enable(EnDMA) [15 ] = 1 : dma enable,
//SDIDCON Wide bus enable (WideBus) [16 ] = Wide : 4bit bus
//SDIDCON Block mode (BlkMode) [17 ] = 1 : blk
//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 ] = 0 : directly after DatMode set,
//SDIDCON SDIO InterruptPeriodType(PrdType)[21 ] = 0 : exactly 2 cycle,
rSDIDCON=(1<<19)|(1<<17)|(Wide<<16)|(1<<15)|(2<<12)|(block<<0);
// Rx after rsp, blk, 4bit bus, dma enable, Rx start, blk num
if(block<2) // SINGLE_READ
{
//SDICCON CmdIndex [7:0] = 0X51 : CMD17
//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)|0x51; // sht_resp, wait_resp, dat, start, CMD17
if(SD_NO_ERR==Chk_CMDend(17, 1)) //-- Check end of CMD17
break;
}
else // MULTI_READ
{
//SDICCON CmdIndex [7:0] = 0X52 : CMD18
//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)|0x52; // sht_resp, wait_resp, dat, start, CMD18
if(SD_NO_ERR==Chk_CMDend(18, 1)) //-- Check end of CMD18
break;
}
}
if(n==100)return SD_ERR;
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
while(!TR_end);
//Uart_Printf("rSDIFSTA=0x%x\n",rSDIFSTA);
//INTMSK BIT_DMA0 [17] = 1 : MASK
rINTMSK |= (BIT_DMA0);
TR_end=0;
//DMASKTRIG0 STOP [2] = 1 : DMA0 stop
rDMASKTRIG0=(1<<2);
//-- 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; // Clear data Tx/Rx end
if(block>1)
{
//RERCMD12:
for(m=0;m<100;m++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -