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

📄 sdi.c

📁 2410TK测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//====================================================================
//File Name : sdi.c
//Function  : SD and MMC Card Test Program
//Program   : Weon-Tark Kang (Tark), Young-Hun Kim (Leon)
//Modify    : On-Pil Shin (SOP)
//Date      : July 11, 2003
//Version   : 0.0
//History
//  0.0 : Programming start -> Tark
//      :07/12/2003 -> SOP
//      :12/17/2003 -> SOP
//       1) S3C2410A01 SDICON bit[0] function change to the following
//          Clock Type(CYTP) : Determines which clock type used as SDCLK
//          0= MMC Type (Rising Edge)     1= SD Type (Falling Edge)
//       2) Chip ID Check
//      :02/06/2004 -> SOP
//====================================================================


#include <stdio.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2410addr.h"
#include "2410lib.h"
#include "sdi.h"

#define INICLK	400000				//400KHz
//#define NORCLK	25000000
//#define SDCLK	25000000
//#define SDCLK	20000000			//PCLK=40MHz,   SDCLK Max =20MHz
#define SDCLK	16000000        	//PCLK=67.5MHz, SDCLK Max =16.875MHz
//#define MMCCLK	20000000        //PCLK=40MHz,   SDCLK Max =20MHz
#define MMCCLK	16000000        	//PCLK=67.5MHz, SDCLK Max =16.875MHz
//#define MMCCLK	40000000

#define S3C2410A01 0x32410002		//270MHz AP 12/17/2003 SOP

#define POL 0
#define INT 1
#define DMA 2
//#define Insert_Repeat	1		//0:Card Insert No Repeat Test, 1:Insertion Repeat Test

int CMD13(void);    			//Send card status
int CMD9(void);

//Global variables
int *Tx_buffer;             	//128[word]*16[blk]=8192[byte]
int *Rx_buffer;                 //128[word]*16[blk]=8192[byte]
volatile unsigned int rd_cnt;
volatile unsigned int wt_cnt;
volatile unsigned int block;
volatile unsigned int TR_end=0;

int Wide=0;         //0:1bit, 1:4bit
int MMC=1;          //0:SD  , 1:MMC
extern int Insert_Repeat=0;

int  Maker_ID;
char Product_Name[7]; 
int  Serial_Num;

volatile int RCA;

//=============================================================================
void Test_SDI(void)
{
    RCA=0;
    MMC=0;
//   block=7;
    block=4095;    			//12/17/2003 SOP
    
    rGPEUP  = 0xf83f;     	//The pull up
    rGPECON = 0xaaaaaaaa;

    Uart_Printf("\n[ SDIO Test Program ]\n");

//02/07/2004 SOP    
    Uart_Printf("0: SD/MMC Card Test     1: Insetion Repeat Test\n");
	Uart_Printf("\nSelect the test mode ? ");    
    Insert_Repeat=Uart_GetIntNum();
    Uart_Printf("\n");    
//End
    
    if(!SD_MMC_Card_Init())
    	return;
    	
    Uart_Printf("\nTest Size : %d Bytes\n", (512*block));    //Size = 512 Byte * Block  12/17/2003 SOP
       
    TR_Buf_new();

    //CMD13();

    Wt_Block();

    Rd_Block();

    View_Rx_buf();

    if(MMC)
    	TR_Buf_new();

    Card_sel_desel(0);  	//Card deselect

    if(!CMD9())
    	Uart_Printf("Get CSD fail!!!\n");
    	
    rSDIDCON=0;				//tark???
    rSDICSTA=0xffff;
}

//=============================================================================
void TR_Buf_new(void)			    //Tx & Rx Buffer initialize
{
    int i, j;
    int start = 0x03020100;

    Tx_buffer=(int *)0x31000000;

    j=0;
    
    for(i=0;i<2048;i++) 		//128[word]*16[blk]=8192[byte]
    	*(Tx_buffer+i)=i+j;
    	
    Flush_Rx_buf();
}

//=============================================================================
void Flush_Rx_buf(void)			    //Flushing Rx buffer
{
    int i;

    Rx_buffer=(int *)0x31800000;
    for(i=0;i<2048;i++) 			//128[word]*16[blk]=8192[byte]
    	*(Rx_buffer+i)=0;
//   Uart_Printf("\nEnd Rx buffer flush\n");
}

//=============================================================================
void View_Rx_buf()				    //Display Rx buffer
{
    int i,error=0;

    Tx_buffer=(int *)0x31000000;
    Rx_buffer=(int *)0x31800000;
    Uart_Printf("Check Rx Data\n");
    for(i=0;i<128*block;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("Rx 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]);
}

//=============================================================================
int SD_MMC_Card_Init(void)			//SD controller & card initialize 
{
    int i, cnt_mmcok=0, cnt_sdok=0;
    char key;

    //Important notice for MMC test condition
    //Cmd & Data lines must be enabled pull up resister

    rSDIPRE   = PCLK/(2*INICLK)-1;  	//400KHz
    rSDICON   = (1<<4)|(1<<1)|(1<<0);   //Type B, FIFO reset, SD Type    02/06/2004 SOP
    rSDIBSIZE = 0x200;        			//512byte(128word)
    rSDIDTIMER= 0xffff;      			//Set timeout count

    for(i=0;i<0x1000;i++);  			//Wait 74 SDCLK for MMC card

	while(1)             					//02/07/2004 SOP
	{
    	rSDICON   = (1<<4)|(1<<1)|(1<<0);   //Type B, FIFO reset, SD Type    02/06/2004 SOP		
    	CMD0();

    	if(Chk_MMC_OCR()) 					//Check MMC card OCR
    	{
    		cnt_mmcok++;
    		Uart_Printf("\nMMC Card Ready OK.......,  Count = %d\n\n", cnt_mmcok);
    	
//12/17/2003 SOP
			if (S3C2410A01 == rGSTATUS1)	
			{
    			rSDICON   = (1<<4)|(1<<1)|(0<<0);    //Type B, FIFO reset, MMC		
			}
		    	
    		MMC=1;
			if (Insert_Repeat==0)		//02/07/2004 SOP
    			goto RECMD2;
		}
   		else
   		{
   			Uart_Printf("\nNo Insert MMC Card !!!\n");
   		}
    
    	if(Chk_SD_OCR()) 		    	//Check SD card OCR
    	{
    		cnt_sdok++;
        	Uart_Printf("\nSD Card Ready OK.......,  Count = %d\n", cnt_sdok);

			if (Insert_Repeat==0)		//02/07/2004 SOP
    			goto RECMD2;   			//02/07/2004 SOP    	
    	}
    	else
    	{
    		Uart_Printf("No Insert SD  Card !!!\n");
			if (Insert_Repeat==0)		//02/07/2004 SOP   		
        		return 0;
    	}
    }

RECMD2:					    //Check attaced cards, it makes card identification state
    rSDICARG=0x0;   							//CMD2(stuff bit)
    rSDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x42;  //lng_resp, wait_resp, start, CMD2

    //Check end of CMD2
    if(!Chk_CMDend(2, 1)) 
    	goto RECMD2;
    	
    //rSDICSTA=0xa00;   //Clear cmd_end(with rsp)

    Uart_Printf("\nEnd of the ID Check\n\n");

RECMD3:					    //Send RCA
    rSDICARG=MMC<<16;       			//CMD3(MMC:Set RCA, SD:Ask RCA-->SBZ)
    rSDICCON=(0x1<<9)|(0x1<<8)|0x43;    //sht_resp, wait_resp, start, CMD3

    //Check end of CMD3
    if(!Chk_CMDend(3, 1)) 
	    goto RECMD3;
	    
    //rSDICSTA=0xa00;   	//Clear cmd_end(with rsp)

    if(MMC)					//Publish RCA
    {
        RCA=1;

//12/17/2003 SOP        
        rSDIPRE=(PCLK/(MMCCLK*2))-1;    	//Normal clock=20MHz
        Uart_Printf("MMCCLK        : %dHz\n",MMCCLK);                
        Uart_Printf("PCLK          : %dHz\n",PCLK);        
        Uart_Printf("rSDIPRE       : %d\n"  ,rSDIPRE);        
        Uart_Printf("MMC Frequency : %dHz\n",(PCLK/2/(rSDIPRE+1)));        
    } 
    else 
    {
    	RCA=( rSDIRSP0 & 0xffff0000 )>>16;

//12/17/2003 SOP           	
        rSDIPRE=(PCLK/(SDCLK*2))-1;    		//Normal clock=25MHz
        Uart_Printf("SDCLK        : %dHz\n",SDCLK);                
        Uart_Printf("PCLK         : %dHz\n",PCLK);        
        Uart_Printf("rSDIPRE      : %d\n"  ,rSDIPRE);     	
        Uart_Printf("SD Frequency : %dHz\n",(PCLK/2/(rSDIPRE+1)));     	
	}    	
    	
    Uart_Printf("RCA=0x%x\n",RCA);

    //State(stand-by) check
    if( rSDIRSP0 & 0x1e00!=0x600 )  		//CURRENT_STATE check
    	goto RECMD3;
    
    Uart_Printf("\nSD/MMC Card Initialized OK\n");

    Card_sel_desel(1);  		//Select
    
    Delay(200);					//02/07/2004 SOP

    if(!MMC)
    	Set_4bit_bus();
    else
    	Set_1bit_bus();

    return 1;
}

//=============================================================================
void Card_sel_desel(char sel_desel)
{
    if(sel_desel)			    //Card select or deselect
    {
RECMDS7:    
    	rSDICARG=RCA<<16;   				//CMD7(RCA,stuff bit)
    	rSDICCON= (0x1<<9)|(0x1<<8)|0x47;   //sht_resp, wait_resp, start, CMD7

    	if(!Chk_CMDend(7, 1))				//Check end of CMD7
        	goto RECMDS7;
        	
    //rSDICSTA=0xa00;   					//Clear cmd_end(with rsp)


    	if( rSDIRSP0 & 0x1e00!=0x800 )		//State(transfer) check
        	goto RECMDS7;
    }
    else
    {
RECMDD7:    
    	rSDICARG=0<<16;     			//CMD7(RCA,stuff bit)
    	rSDICCON=(0x1<<8)|0x47; 		//no_resp, start, CMD7

    	if(!Chk_CMDend(7, 0))			//Check end of CMD7
        	goto RECMDD7;
        	
        //rSDICSTA=0x800;   			//Clear cmd_end(no rsp)
    }
}

//=============================================================================
void __irq Rd_Int(void)
{
    U32 i,status;

    status=rSDIFSTA;
    if( (status&0x200) == 0x200 )   		//Check Last interrupt?
    {
    	for(i=(status & 0x7f)/4;i>0;i--)
    	{
        	*Rx_buffer++=rSDIDAT;
        	rd_cnt++;
    	}
    }
    else if( (status&0x80) == 0x80 )    	//Check Half interrupt?
    {
        for(i=0;i<8;i++)
        {
            *Rx_buffer++=rSDIDAT;
        	rd_cnt++;
    	}
    }

    ClearPending(BIT_SDI);
}

//=============================================================================
void __irq Wt_Int(void)
{
    ClearPending(BIT_SDI);

    rSDIDAT=*Tx_buffer++;
    wt_cnt++;

    if(wt_cnt==128*block)
    {
    	rINTMSK |= BIT_SDI;
    	rSDIDAT=*Tx_buffer;
    	TR_end=1;
    }
}

//=============================================================================
void __irq DMA_end(void)
{
    ClearPending(BIT_DMA0);
    
    TR_end=1;
}

//=============================================================================
void Rd_Block(void)
{
    U32 mode;
    int status;

    rd_cnt=0;    
    Uart_Printf("[ Block read test ]\n");

RE0:
    Uart_Printf("0:Polling read   1:Interrupt read   2:DMA read\nSelect the test mode? ");
    mode=(U32)Uart_GetIntNum();
    Uart_Printf("\n");

    if(mode>2)
    	goto RE0;

    rSDICON |= rSDICON|(1<<1);  	//FIFO reset

    if(mode!=2)		//Rx after cmd, blk, 4bit bus, Rx start, blk num
    	rSDIDCON=(1<<19)|(1<<17)|(Wide<<16)|(2<<12)|(block<<0);

    rSDICARG=0x0;   //CMD17/18(addr)

RERDCMD:
    switch(mode)
    {
    	case POL:
        	if(block<2) 	//SINGLE_READ
        	{
        		rSDICCON=(0x1<<9)|(0x1<<8)|0x51;    //sht_resp, wait_resp, dat, start, CMD17
        		if(!Chk_CMDend(17, 1))  			//Check end of CMD17
            		goto RERDCMD;       
        	}
        	else    //MULTI_READ
        	{
        		rSDICCON=(0x1<<9)|(0x1<<8)|0x52;    //sht_resp, wait_resp, dat, start, CMD18
        		if(!Chk_CMDend(18, 1))  			//Check end of CMD18 
            		goto RERDCMD;
        	}

            //rSDICSTA=0xa00;   	//Clear cmd_end(with rsp)      

        	while(rd_cnt<128*block) 		//512*block bytes
        	{
        		if((rSDIDSTA&0x20)==0x20) 	//Check timeout 
        		{
            		rSDIDSTA=0x1<<0x5;  	//Clear timeout flag
            		break;
        		}
        		status=rSDIFSTA;
        		
        		if((status&0x1000)==0x1000) 	//Is Rx data?
        		{
            		*Rx_buffer++=rSDIDAT;
            		rd_cnt++;
        		}
        	}
        	break;
    
    	case INT:
        	pISR_SDI=(unsigned)Rd_Int;
        	rINTMSK = ~(BIT_SDI);
        
        	rSDIIMSK=5; 		//Last & Rx FIFO half int.

        	if(block<2) 		//SINGLE_READ
        	{
        		rSDICCON=(0x1<<9)|(0x1<<8)|0x51;    //sht_resp, wait_resp, dat, start, CMD17
        		if(!Chk_CMDend(17, 1))  			//Check end of CMD17
            		goto RERDCMD;       
        	}
        	else    	//MULTI_READ
        	{
        		rSDICCON=(0x1<<9)|(0x1<<8)|0x52;    //sht_resp, wait_resp, dat, start, CMD18
        		if(!Chk_CMDend(18, 1))  			//Check end of CMD18 
            		goto RERDCMD;
        	}
    
        	//rSDICSTA=0xa00;   	//Clear cmd_end(with rsp)

        	while(rd_cnt<128*block);

        	rINTMSK |= (BIT_SDI);
        	rSDIIMSK=0; 			//All mask
        	break;

    	case DMA:
        	pISR_DMA0=(unsigned)DMA_end;
        	rINTMSK = ~(BIT_DMA0);

        	rDISRC0=(int)(SDIDAT);  		//SDIDAT
        	rDISRCC0=(1<<1)+(1<<0); 		//APB, fix
        	rDIDST0=(U32)(Rx_buffer);   	//Rx_buffer
        	rDIDSTC0=(0<<1)+(0<<0); 		//AHB, inc
        	rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;
        	//handshake, sync PCLK, TC int, single tx, single service, SDI, H/W request, 
        	//auto-reload off, word, 128blk*num
        	rDMASKTRIG0=(0<<2)+(1<<1)+0;    //no-stop, DMA2 channel on, no-sw trigger 

        	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
        	{
        		rSDICCON=(0x1<<9)|(0x1<<8)|0x51;    //sht_resp, wait_resp, dat, start, CMD17
        		if(!Chk_CMDend(17, 1))  			//Check end of CMD17
            		goto RERDCMD;       
        	}
        	else    //MULTI_READ
        	{
        		rSDICCON=(0x1<<9)|(0x1<<8)|0x52;    //sht_resp, wait_resp, dat, start, CMD18
        		if(!Chk_CMDend(18, 1))  			//Check end of CMD18 
            		goto RERDCMD;
        	}

        	//rSDICSTA=0xa00;   		//Clear cmd_end(with rsp)
        	while(!TR_end);
        	//Uart_Printf("rSDIFSTA=0x%x\n",rSDIFSTA);
        	rINTMSK |= (BIT_DMA0);
        	TR_end=0;
        	rDMASKTRIG0=(1<<2); 		//DMA0 stop
        	break;

    	default:
        	break;
    }

    if(!Chk_DATend())    //Check end of DATA
    	Uart_Printf("Dat error\n");

    rSDIDSTA=0x10;  	//Clear data Tx/Rx end

    if(block>1)
    {
RERCMD12:        	//Stop cmd(CMD12)

    	rSDICARG=0x0;       				//CMD12(stuff bit)
    	rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;	//sht_resp, wait_resp, start, CMD12

    	if(!Chk_CMDend(12, 1)) 				//Check end of CMD12
        	goto RERCMD12;
        	
    	//rSDICSTA=0xa00;   				//Clear cmd_end(with rsp)
    }
}

//=============================================================================
void Rd_Stream(void)    	//only for MMC, 3blk read
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -