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

📄 sd_test.c

📁 adi bf54x dsp sd卡程序
💻 C
字号:
/*****************************************************************************
**																			**
**	 Name: 	SD.c															**
**																			**
******************************************************************************

(C) Copyright 2006 - Analog Devices, Inc.  All rights reserved.

Project Name:	BF548 POST ATE

Date Modified:	01 Sept 2006

Software:		VisualDSP++ 4.5

Hardware:		ADSP-BF548 EZ-KIT Lite


Purpose:		Perform memory test on DDR

*****************************************************************************/

#include <cdefBF548.h>
#include <ccblkfn.h>
#include <sys\exception.h>
#include <signal.h>
#include <stdlib.h>
#include "SD_test.h"
#include "Timer_ISR.h"


unsigned long srand_val = 0xFFFFFFFF;

#define SD_4BIT 1
//#define READ_ONLY	1


// command table for the SD commands that are used in this example
SD_CMD SD_CmdTable[]=
{
 // CMD ID	CMD ARG			CMD Response			RCA needed?
	{ 0,	SD_STUFF_BITS,	SD_NO_RESPONSE,			SD_RCA_NOT_NEEDED 	},
	{ 2,	SD_STUFF_BITS,	CMD_L_RSP | CMD_RSP,	SD_RCA_NOT_NEEDED 	},
	{ 3,	SD_STUFF_BITS,	CMD_RSP,				SD_RCA_NOT_NEEDED 	},
	{ 7,	SD_STUFF_BITS,	CMD_RSP,				SD_RCA_NEEDED 		},
	{ 9,	SD_STUFF_BITS,	CMD_L_RSP | CMD_RSP,	SD_RCA_NEEDED 		},
	{ 13,	SD_STUFF_BITS,	CMD_RSP,				SD_RCA_NEEDED 		},
	{ 16,	SD_BLK_LEN_512,	CMD_RSP,				SD_RCA_NOT_NEEDED 	},
	{ 17,	SD_STUFF_BITS,	CMD_RSP,				SD_RCA_NOT_NEEDED 	},
	{ 24,	SD_STUFF_BITS,	CMD_RSP,				SD_RCA_NOT_NEEDED 	},
	{ 55,	SD_STUFF_BITS,	CMD_RSP,				SD_RCA_NEEDED 		},

	{ 6,	0x00000002,		CMD_RSP,				SD_RCA_NOT_NEEDED	},
	{ 13,	SD_STUFF_BITS,	CMD_RSP,				SD_RCA_NOT_NEEDED	},
	{ 41,	0x00FF8000,		CMD_RSP,				SD_RCA_NOT_NEEDED	},
    { 42,	SD_STUFF_BITS,	CMD_RSP,				SD_RCA_NOT_NEEDED	}
};


//--------------------------------------------------------------------------//
// Function:	Init_SD														//
//																			//
// Parameters:	None														//
//																			//
// Return:		None														//
//																			//
// Description:	This function configures the SD								//
//--------------------------------------------------------------------------//
void Init_SD_Interrupts(void)
{
    // assign ISRs to interrupt vectors
	register_handler(ik_ivg11, SD_ISR);

	//enable DMA ISR
	register_handler(ik_ivg7, SD_DMA_ISR);

	*pILAT |= EVT_IVG7;							// clear pending IVG8 interrupts
	ssync();
	
	*pILAT |= EVT_IVG11;							// clear pending IVG8 interrupts
	ssync();
	
    // unmask SD mask 0
	*pSIC_IMASK2 |= 0x100;
	ssync();

	//unmask SD DMA
	*pSIC_IMASK2 |= 0x8;
	ssync();

	*pPORTC_FER = 0x3F00;
	*pPORTC_MUX = 0x00000000;
	ssync();

    

}

void Init_DMA(unsigned long *buf_addr, unsigned short config_value)
{

    *(volatile unsigned short *)(0xFFC04340) = 0x1;

	*pDMA22_START_ADDR = buf_addr;
    *pDMA22_X_COUNT = 128;
    *pDMA22_X_MODIFY = 4;
    *pDMA22_CONFIG = config_value;
    ssync();

}
//--------------------------------------------------------------------------//
// Function:	Init_SD														//
//																			//
// Parameters:	None														//
//																			//
// Return:		None														//
//																			//
// Description:	This function configures the SD								//
//--------------------------------------------------------------------------//
void Init_SD(void)
{
    int temp;

    // disable SD card detection interrupt
    *pSDH_E_MASK = 0x0;
    ssync();

    // clear card detect bit
  	*pSDH_E_STATUS = SD_CARD_DET | SDIO_INT_DET;
   	ssync();

   	// Soft reset SDH
    *pSDH_CFG = SD_RST;
    ssync();

    // pull down on DATA3, pull up on DATA2-0, SDH clock enabled
    *pSDH_CFG |= ( CLKS_EN | PUP_SDDAT | PD_SDDAT3 );
    ssync();

    // power on
    *pSDH_PWR_CTL |= PWR_ON;
    ssync();

    // clock enable, SD_CLK should be 200kHz
    // for card initialization and Identification
    *pSDH_CLK_CTL |= ((CLK_E ) | 0xF9);
    ssync();

    // SD Int detected, SD card detected
    *pSDH_E_MASK |= (SCD_MSK | SDIO_MSK);
    ssync();
}


int SendCommand( SD_CMD *pSD_Cmd, bool bGetStatusReg )
{
    unsigned long ulStatusPoll = 0;
    int timeout = 0;
    unsigned long ulResponse = 0;

    // need to poll on either Response end
    // or CMD sent depending on whether we
    // are waiting for a response or not
    if( pSD_Cmd->CmdResponse & CMD_RSP )
		ulStatusPoll = CMD_RESP_END;
	else
		ulStatusPoll = CMD_SENT;


	// OR in the RCA if it is required in the argument
	if( pSD_Cmd->UseRCA )
	{
		// clear out the old RCA in case we
		// are doing the test more than 1 time
		pSD_Cmd->CmdArg &= 0xFFFF;
	    pSD_Cmd->CmdArg |= g_ulCardRCA;
	}

	// set the argument
    *pSDH_ARGUMENT = pSD_Cmd->CmdArg;
    ssync();

    // set the command, command response and enable it
	*pSDH_COMMAND = pSD_Cmd->CmdID | pSD_Cmd->CmdResponse | CMD_E;
	ssync();

	// poll to make sure command was sent and
	// a response was received if expected
	while( (!(*pSDH_STATUS & ulStatusPoll)) && (timeout < TIMEOUT_VAL) )
	{
	    timeout++;
	    asm("nop;");
	}

	// clear the Resp end or CMD sent bit
	*pSDH_STATUS_CLR |= ulStatusPoll;

	// if ACMD41, the CRC will fail so we need to clear it
	if( (pSD_Cmd->CmdID & 0x29) && (*pSDH_STATUS & CMD_CRC_FAIL) )
	{
	    *pSDH_STATUS_CLR = CMD_CRC_FAIL_STAT;
	}

	// clear the timeout status bit on a timeout
	if( timeout >= TIMEOUT_VAL )
		*pSDH_STATUS_CLR = CMD_TIMEOUT_STAT;

	if( bGetStatusReg )
	{
	    SendCommand( &SD_CmdTable[SD_CMD13], 0 );
	}

	return 1;
}

// puts card back to Idle State
int SD_reset( void )
{
    SendCommand( &SD_CmdTable[SD_CMD0], 0 );

    return 1;
}

// get the CID numbers from the card
int SD_ReadCardIdent(void)
{
	SendCommand( &SD_CmdTable[SD_CMD2], 0 );

	return 1;
}

// get the CSD numbers from the card
int SD_ReadCardData(void)
{
    unsigned long ulTemp = 0;
    SD_CSD_DATA CardData;

    SendCommand( &SD_CmdTable[SD_CMD9], 0 );

	CardData.ucMaxSpeed = (unsigned char)*pSDH_RESPONSE0;

	ulTemp = (unsigned long)*pSDH_RESPONSE1;
	CardData.ucMaxReadBlkLen = (unsigned char)( ( ulTemp >> 16 ) & 0xF );

	ulTemp <<= 2;
	ulTemp &= 0xFFF;
	ulTemp |= ( (unsigned long)*pSDH_RESPONSE2 >> 30 );
	CardData.usCardSize = (unsigned short)ulTemp;

	ulTemp = (unsigned long)*pSDH_RESPONSE2;
	ulTemp >>= 7;
	ulTemp &= 0x7F;
	CardData.usSectorSize = (unsigned short)ulTemp;

	ulTemp = (unsigned long)*pSDH_RESPONSE3;
	ulTemp >>= 22;
	CardData.ucMaxWriteBlkLen = ulTemp & 0xF;

	return 1;
}

int Set_4BitMode(void)
{
    // use WIDE BUS
    *pSDH_CLK_CTL |= WIDE_BUS;
    ssync();

 	SendCommand( &SD_CmdTable[SD_CMD55], 0 );
 	SendCommand( &SD_CmdTable[SD_ACMD42], 0 );

    // Set the bus width to 4 bit
    SendCommand( &SD_CmdTable[SD_CMD55], 0 );
 	SendCommand( &SD_CmdTable[SD_ACMD6], 0 );

    return 1;
}

EX_INTERRUPT_HANDLER(SD_DMA_ISR)
{

    *pDMA22_IRQ_STATUS |= 0x1;
    ssync();


}


EX_INTERRUPT_HANDLER(SD_ISR)
{
    int temp = 0;
    g_nISR_Count++;

    // card detected
    if( (*pSDH_E_STATUS & SD_CARD_DET) )
    {
        g_bCardDetected = true;

        // clear card detected bit
        *pSDH_E_STATUS |= SD_CARD_DET;
    }
}

int TX_Block(void)
{
    // set blk len to 512(SET_BLOCKLEN)
    SendCommand( &SD_CmdTable[SD_CMD16], 0 );

    // send write command(WRITE_SINGLE_BLOCK)
    SendCommand( &SD_CmdTable[SD_CMD24], 0 );

     // tx 512 bytes
    *pSDH_DATA_LGTH = 512;
    ssync();

    // set the timer
    *pSDH_DATA_TIMER = 0xFFFFFFFF;
    ssync();

    // 2^9 = 512 block length, enable write transfer
    *pSDH_DATA_CTL = 0x99;	//use DMA
    ssync();

    // wait until the data has been sent
	while( !(*pSDH_STATUS & DAT_END) )
	{
	    asm("nop;");
	}

	// clear the status bits
	*pSDH_STATUS_CLR = DAT_END_STAT | DAT_BLK_END;

	// stop transfer
	*pSDH_DATA_CTL = 0x0;
    ssync();



	return 1;
}

int RX_Block(void)
{
    // set blk len to 512(SET_BLOCKLEN)
    SendCommand( &SD_CmdTable[SD_CMD16], 0 );

    // send read command(READ_SINGLE_BLOCK)
    SendCommand( &SD_CmdTable[SD_CMD17], 0 );

    // rx 512 bytes
    *pSDH_DATA_LGTH = 512;
    ssync();

    // set the timer
    *pSDH_DATA_TIMER = 0xFFFFFFFF;
    ssync();

    // 2^9 = 512 block length, enable read transfer
    *pSDH_DATA_CTL = 0x9b;	//use DMA
    ssync();

    // wait until the data has been sent
	while( !(*pSDH_STATUS & DAT_END) )
	{
	    asm("nop;");
	}

	Delay_Loop( 0xFFFFFF );

	// clear the status bits
	*pSDH_STATUS_CLR = DAT_END_STAT | DAT_BLK_END;

	// stop transfer
	*pSDH_DATA_CTL = 0x0;
    ssync();

	return 1;

}

void Delay_Loop( int nDelay )
{
	int i = 0;

	for( ; i < nDelay; i++ )
	{
		asm("nop;");
	}
}

//////////////////////////////////////////////////////////////////////////////
// int TEST_SD(void)
//
// PURPOSE:		Test the SD counter
//////////////////////////////////////////////////////////////////////////////
int TEST_SD(void)
{
	int nIndex = 0;
	int bSuccess = 1; 	// returning 1 indicates a pass, anything else is a fail
	int n;
	int i = 0, j = 0x0;
	unsigned int nTimer;
	short sClkVal = 0;

	srand(srand_val);

	srand_val++;

	// fill our tx buffer
	for( i = 0; i < 128; i++ )
	{
		TX_SRC_BUF[i] = rand();
	}

	Init_Timers();			// initialize timers
	Init_SD_Interrupts();	// initialize interrupts
	Init_SD();				// initialize SD registers


	// wait until the card is detected
/**/	while( !g_bCardDetected )
    {
        asm("nop;");
    }

    //
    // start card identification mode
    //

	SD_reset();				// reset the card

	nTimer = SetTimeout(0x80000);
	
	do
	{

    	SendCommand( &SD_CmdTable[SD_CMD55], 0 );	// next command will be application specific
    	SendCommand( &SD_CmdTable[SD_ACMD41], 0 );	// sends HCS, gets OCR

	} while( !(*pSDH_RESPONSE0 & 0x80000000) && (!IsTimedout(nTimer)) );
	
	ClearTimeout(nTimer);

	
	if( !(*pSDH_RESPONSE0 & 0x80000000) )
		return 0;

		
    SD_ReadCardIdent();		// get CID numbers

    SendCommand( &SD_CmdTable[SD_CMD3], 0 );	// ask the card to publish new RCA

    g_ulCardRCA = *pSDH_RESPONSE0 & 0xFFFF0000;

    SD_ReadCardData();		// get CSD

    //
    // start data transfer mode
    //

    // get clock going at 25Mhz
    // SCLK is 50MHz because we are using the default value
    sClkVal = *pSDH_CLK_CTL;
    sClkVal &= ~(0x7F);
    sClkVal |= 0x3;
    
    *pSDH_CLK_CTL = sClkVal;
    ssync();

	SendCommand( &SD_CmdTable[SD_CMD7], 0 );	// put the card in transfer state

#ifdef SD_4BIT
	Set_4BitMode();
#endif

	Init_DMA(TX_SRC_BUF, 0x00a9);	//setup DMA

#ifndef READ_ONLY
    TX_Block();
#endif

	*pDMA22_CONFIG = 0x0;
	ssync();

	Init_DMA(RX_DEST_BUF, 0x00ab);
    RX_Block();

    for( i = 0; i < 128; i++ )
    {
        if( TX_SRC_BUF[i] != RX_DEST_BUF[i] )
        	bSuccess = 0;
    }

    g_ulCardRCA = 0x0;
    
    interrupt(ik_ivg7, SIG_IGN);
    interrupt(ik_ivg11, SIG_IGN);

	// disable SIC Level Interrupts
	*pSIC_IMASK2 &= (~(0x108));
	ssync();	
	
	return bSuccess;
}

//////////////////////////////////////////////////////////////////////////////
//
// stand alone test jig
//
//////////////////////////////////////////////////////////////////////////////

int main(void)
{
	int bPassed = 0;
	int count = 0;
	Init_PLL();
	Init_EBIU();
	Init_DDR();


	while( !bPassed )
	{
		 printf("Start Test SD Card!\n");
		bPassed = TEST_SD();
		if(!bPassed)
			printf("SD is ERROR!\n");
		else printf("SD is OK!\n");
		asm("nop;");
		printf("Test END!\n");
		asm("nop;");
		asm("nop;");
		asm("nop;");
	}


	return 0;
}

⌨️ 快捷键说明

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