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

📄 sdi.c

📁 2410开发测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2410addr.h"
#include "2410lib.h"
#include "sdi.h"

#define INICLK	400000	//300000
#define NORCLK	5000000

#define POL	0
#define INT	1
#define DMA	2

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=0;	// 0:SD	, 1:MMC

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

volatile int RCA;

void Test_SDI(void)
{
	RCA=0;
	MMC=0;

	rGPEUP	= 0xf83f;	// The pull up
	rGPECON = 0xaaaaaaaa;

	Uart_Printf("\n[SDI test]\n");
	
	if(!SD_card_init())
	return;
	
	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");
*/

	block=5;	
	//CMD13();
	Wt_Block();
	Rd_Block();
	View_Rx_buf();
	if(MMC)
		TR_Buf_new();
	if(MMC)
	{
		Wt_Stream();
		Rd_Stream();
		View_Rx_buf();
	}
	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;
//	*(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;

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

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=(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(" 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_card_init(void)
{
//-- SD controller & card initialize 
	int i;
//	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;	// Type B, FIFO reset, clk enable
	rSDIBSIZE=0x200;		// 512byte(128word)
	rSDIDTIMER=0xffff;		// Set timeout count

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

	//Uart_Printf("rSDIRSP0=0x%x\n",rSDIRSP0);
	CMD0();
	Uart_Printf("\nIn idle\n");

	//-- Check MMC card OCR
	if(Chk_MMC_OCR()) 
	{
		Uart_Printf("\nIn MMC ready\n");
		MMC=1;
		goto RECMD2;
	}

	//Uart_Printf("MMC check end!!\n");
	//-- Check SD card OCR
	if(Chk_SD_OCR()) 
		Uart_Printf("\nIn SD ready\n");
	else
	{
		Uart_Printf("\nInitialize fail\nNo Card assertion\n");
		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 id\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)

	//--Publish RCA
	if(MMC) 
		RCA=1;
	else 
		RCA=( rSDIRSP0 & 0xffff0000 )>>16;
	Uart_Printf("RCA=0x%x\n",RCA);

	//--State(stand-by) check
	if( rSDIRSP0 & 0x1e00!=0x600 )	// CURRENT_STATE check
		goto RECMD3;
	
	Uart_Printf("\nIn stand-by\n");
	
	rSDIPRE=PCLK/(2*NORCLK)-1;	// Normal clock=25MHz

	Card_sel_desel(1);	// Select

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

	return 1;
}

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

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

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

		//-- Check end of CMD7
		if(!Chk_CMDend(7, 0))
			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
//	mode=2;//tark
	if(mode!=2)
		rSDIDCON=(1<<19)|(1<<17)|(Wide<<16)|(2<<12)|(block<<0);
		// Rx after cmd, blk, 4bit bus, Rx start, blk num

	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=((U32)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;
	}
	//-- Check end of DATA
	if(!Chk_DATend()) 
		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

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

void Rd_Stream(void)	// only for MMC, 3blk read
{
//	int i;
	int status, rd_cnt=0;

	if(MMC!=1)
	{
		Uart_Printf("Stream read command supports only MMC!\n");
		return;
	}	
	Uart_Printf("\n[Stream read test]\n");
	
RECMD11:
	rSDIDCON=(1<<19)|(0<<17)|(0<<16)|(2<<12);

	rSDICARG=0x0;	// CMD11(addr)
	rSDICCON=(0x1<<9)|(0x1<<8)|0x4b;	//sht_resp, wait_resp, dat, start, CMD11

	while(rd_cnt<128*block)
	{
		if( (rSDIDSTA&0x20) == 0x20 )
		{
			Uart_Printf("Rread timeout error");
			return ;
		}
		status=rSDIFSTA;
		if((status&0x1000)==0x1000)
		{
			//*Rx_buffer++=rSDIDAT;
			//rd_cnt++;
			Rx_buffer[rd_cnt++]=rSDIDAT;
		}
	}
	//-- Check end of CMD11
	if(!Chk_CMDend(11, 1)) 
		goto RECMD11;
	//rSDICSTA=0xa00;	// Clear cmd_end(with rsp)
	//-- Check end of DATA

⌨️ 快捷键说明

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