⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdi.c

📁 s3c2410开发板
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -