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

📄 sdi.c

📁 2440 开发板的测试程序。包括uart,iic,lcd
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "sdi.h"

//YH 0811#define INICLK	300000
#define INICLK	300000
//#define NORCLK	25000000
#define SDCLK	24000000	//PCLK=49.392MHz
#define MMCCLK	15000000	//PCLK=49.392MHz

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

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

//YH 0728 int *Tx_buffer;	//128[word]*16[blk]=8192[byte]
//YH 0728 int *Rx_buffer;	//128[word]*16[blk]=8192[byte]

unsigned int* Tx_buffer;	//128[word]*16[blk]=8192[byte]
unsigned 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 )
{
	U32 save_rGPEUP, save_rGPECON;
	int k;

	RCA = 0;
	MMC = 0;
	block = 3072;   //3072Blocks=1.5MByte, ((2Block=1024Byte)*1024Block=1MByte)
	//    block=13;

	save_rGPEUP = rGPEUP;
	save_rGPECON = rGPECON;

	rGPEUP = 0xf83f;	 // SDCMD, SDDAT[3:0] => PU En.
	rGPECON = 0xaaaaaaaa;	//SDCMD, SDDAT[3:0]
	//    rGPECON = 0xaaa800aa;	//SDCMD, SDDAT[3:0] => Input


	Uart_Printf( "\nSDI Card Write and Read 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");
	*/

	//CMD13();
	//YH 040227
	//	for(k=0;k<4;k++)
	Wt_Block();

	Rd_Block();
	View_Rx_buf();

	if ( MMC )
		TR_Buf_new();

	if ( MMC )
	{
		rSDICON |= ( 1 << 5 );    // YH 0519, MMC Type SDCLK

		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;
	rGPEUP = save_rGPEUP;
	rGPECON = save_rGPECON;
}

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

	Tx_buffer = ( unsigned 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 = ( unsigned int * ) 0x31800000;

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

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

	Tx_buffer = ( unsigned int * ) 0x31000000;
	Rx_buffer = ( unsigned 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( "\nThe Tx_buffer is same to Rx_buffer!\n" );
		Uart_Printf( "SD CARD Write and Read test is OK!\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 by pull up resister */

	//YH 0816, Org    rSDIPRE=PCLK/(2*INICLK)-1;	// 400KHz
	rSDIPRE = PCLK / ( INICLK ) - 1;	// 400KHz
	Uart_Printf( "Init. Frequency is %dHz\n" , ( PCLK / ( rSDIPRE + 1 ) ) );

	//    rSDICON=(1<<4)|(1<<1)|1;	// Type B, FIFO reset, clk enable
	rSDICON = ( 1 << 4 ) | 1;	// Type B, clk enable
	rSDIFSTA = rSDIFSTA | ( 1 << 16 );	//YH 040223 FIFO reset
	rSDIBSIZE = 0x200;		// 512byte(128word)
	rSDIDTIMER = 0x7fffff;		// Set timeout count

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

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

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

	Uart_Printf( "MMC check end!!\n" );
	//-- Check SD card OCR
	if ( Chk_SD_OCR() )
		Uart_Printf( "In SD ready\n" );
	else
	{
		Uart_Printf( "Initialize 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( "End 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;
		//YH 0812   	 rSDIPRE=(PCLK/(MMCCLK)+1)-1;	// YH 0716, Normal clock=20MHz
		rSDIPRE = ( PCLK / MMCCLK ) - 1;	// YH 0812, Normal clock=20MHz

		Uart_Printf( "MMC Frequency is %dHz\n" , ( PCLK / ( rSDIPRE + 1 ) ) );
	}
	else
	{
		RCA = ( rSDIRSP0 & 0xffff0000 ) >> 16;
		Uart_Printf( "RCA=0x%x\n" , RCA );

		rSDIPRE = PCLK / ( SDCLK ) - 1;	// Normal clock=25MHz
		Uart_Printf( "SD Frequency is %dHz\n" , ( PCLK / ( rSDIPRE + 1 ) ) );
	}	//YH 0716
	//--State(stand-by) check
	if ( rSDIRSP0 & 0x1e00 != 0x600 )  // CURRENT_STATE check
		goto RECMD3;

	Uart_Printf( "In stand-by\n" );

	//    rSDIPRE=PCLK/(2*NORCLK)-1;	// Normal clock=25MHz
	//YH 0716    rSDIPRE=PCLK/(SDCLK)-1;	// Normal clock=25MHz
	//YH 0716    //Uart_Printf("SD Frequency is %dMHz\n",(PCLK/(rSDIPRE+1)));

	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++;
		}
		//	Uart_Printf("status1=0x%x\n", status);
		//	status=rSDIFSTA&0x200;	//If you do like this, rSDIFSTA register will not be updated., YH 040221
		rSDIFSTA = rSDIFSTA & 0x200;	//Clear Rx FIFO Last data Ready, YH 040221
		//	Uart_Printf("rSDIFSTA=0x%x\n", rSDIFSTA);
	}
	else if ( ( status & 0x80 ) == 0x80 )	// Check Half interrupt?
	{
		for ( i = 0; i < 8; i++ )
		{
			*Rx_buffer++ = rSDIDAT;
			rd_cnt++;
		}
	}
	//	Uart_Printf("rSDIFSTA=0x%x\n", rSDIFSTA);	//YH 040221

	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[ Polling read ]\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;*/

	mode = 0 ;

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

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

	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 );
			rSDIDCON = rSDIDCON | ( 1 << 24 ); //YH 040227, Burst4 Enable

			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=(2<<22)|(1<<19)|(1<<17)|(Wide<<16)|(1<<15)|(2<<12)|(block<<0);
			rSDIDCON = ( 2 << 22 ) |
				( 1 << 19 ) |
				( 1 << 17 ) |
				( Wide << 16 ) |
				( 1 << 15 ) |
				( 1 << 14 ) |
				( 2 << 12 ) |
				( block << 0 );
			// Word Rx, Rx after rsp, blk, 4bit bus, dma enable, Rx start, blk num, Data start, data receive mode, YH 040220
			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" );

	rSDIDCON = rSDIDCON & ~( 7 << 12 );		//YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start
	rSDIFSTA = rSDIFSTA & 0x200;	//Clear Rx FIFO Last data Ready, YH 040221
	rSDIDSTA = 0x10;	// Clear data Tx/Rx end detect

	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=(2<<22)|(1<<19)|(0<<17)|(0<<16)|(2<<12);
	rSDIDCON = ( 2 << 22 ) | ( 1 << 19 ) | ( 0 << 17 ) | ( 0 << 16 ) | ( 1 << 14 ) | ( 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 )

⌨️ 快捷键说明

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