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

📄 mmc.c

📁 深圳优龙公司LPC2148开发板(与iar公司开发板基本相同)的原理图和配套样例程序
💻 C
📖 第 1 页 / 共 2 页
字号:
// mmc.c : MultiMediaCard functions: init, read, write ...
//
// Rolf Freitag 5/2003
//

#ifndef _MMCLIB_C
#define _MMCLIB_C

//---------------------------------------------------------------------
#include "mmc.h"
#include  "math.h"
#include  "string.h"


//#define debug_printf(char*  UART_PutString(UART0,(char*)UART_Menu)
char mmcGetResponse( void );
char mmcGetXXResponse( const char resp );
char mmcCheckBusy( void );

void initSSP( void );

static char mmc_buffer[512] =
{
	0
};	// Buffer for mmc i/o for data and registers

extern char card_state;		// 0 for no card found, 1 for card found (init successfull)


//---------------------------------------------------------------------
void Delays( unsigned long a )
{
	while ( --a != 0 );
}

unsigned long SSPSetBaudRate( unsigned long baudrate , unsigned long systemfreq )
{
	//Compute the new value for SPICK
	//baudrate = systemfreq / (2 * (SPICK + 1))
	unsigned long spick = ( ( systemfreq / baudrate ) >> 1 );

	//Only divide ratios between 1 & 256 are supported
	spick &= 0x0FF;

	//Set the SPICK register
	SSPCPSR = ( spick & 0x0FF );

	//Return the actual value achieved
	return ( systemfreq / ( ( spick + 1 ) << 1 ) );
}

// setup usart1 in spi mode
void initSSP( void )
{
	//set functionalite to pins:
	PINSEL1_bit.P0_17 = 0x2;
	PINSEL1_bit.P0_18 = 0x2;
	PINSEL1_bit.P0_19 = 0x2;
	PINSEL1_bit.P0_20 = 0x2;

	//ADD BY CHANG GUO FENG
	PINSEL2 = 0x0;  	//P1.24
	IO1DIR = IO1DIR & ( 0x0 << 24 );

	//SET SSP Interface
	PINSEL1 = ( PINSEL1 & ~( 0x3 << 2 ) ) | ( 0x2 << 2 ); //SCK1
	PINSEL1 = ( PINSEL1 & ~( 0x3 << 4 ) ) | ( 0x2 << 4 );//moso1
	PINSEL1 = ( PINSEL1 & ~( 0x3 << 6 ) ) | ( 0x2 << 6 );//mosi1
	PINSEL1 = ( PINSEL1 & ~( 0x3 << 8 ) );  	   //|(0x2<<8);//ssle1

	IO0DIR = IO0DIR | 0x1 << 20;   //ssle1->P0.20,output

	SSPCR0_bit.CPHA = 0;	  //ClockPhase (active)
	SSPCR0_bit.CPOL = 0;	  //ClockPlarity
	SSPCR0_bit.FRF = 0; 	 //Select SPI mode
	SSPCR0_bit.DSS = 0x7;    //8 bits data size

	SSPCR1_bit.MS = 0;  	//Master mode (0) or Slave mode (1)
	SSPCR1_bit.SSE = 1; 	 //Enable SPI

	//Set Baund Rate
	//1st operand - data rate - must be max 1/8 from System frequency
	//2nd operand - system freguency
	SSPSetBaudRate(9600, 12000000);
	//SSPSetBaudRate( 9600 , 14745600 );
}


// Initialisieren
char initMMC( void )
{
	//raise SS and MOSI for 80 clock cycles
	//SendByte(0xff) 10 times with SS high
	//RAISE SS
	int i;
	// int Probe;
	char response = 0x01;
	
	if ( IO1PIN & ( 0x1 << 24 ) )
		UART_PutString( UART0 , "\nNO MMC\n" );//card probe,P1.24
	//debug_printf("\nStart iniMMC......");
	//UART_PutString(UART0,"\nStart iniMMC....\n");
	initSSP();
	//initialization sequence on PowerUp

	// CS_HIGH();
	CS_LOW();
	for ( i = 0; i <= 30; i++ )
		spiSendByte( 0xff );		//delay more than 74 clocks
	CS_HIGH();
	for ( i = 0; i <= 10; i++ )
		spiSendByte( 0xff );		//delay more than 74 clocks

	CS_LOW();
	//Send Command 0 to put MMC in SPI mode

	mmcSendCmd( 0x00 , 0 , 0x95 );//software reset
	//Now wait for READY RESPONSE
	if ( mmcGetResponse() != 0x01 )
	{
		UART_PutString( UART0 , "\nno responce\n" );
		return 0xff;
	}
	//  	 debug_printf("no responce");
	CS_HIGH();
	while ( response == 0x01 )
	{
		//  debug_printf("Sending Command 1");
		//UART_PutString(UART0,"Sending Command 1\n");
		// CS_HIGH();
		spiSendByte( 0xff );
		CS_LOW();
		mmcSendCmd( 0x01 , 0x00 , 0xff );
		response = mmcGetResponse();
	}
	CS_HIGH();
	spiSendByte( 0xff );
	// UART_PutString(UART0,"MMC INITIALIZED AND SET TO SPI MODE PROPERLY\n");
	// debug_printf("MMC INITIALIZED AND SET TO SPI MODE PROPERLY.");
	return MMC_SUCCESS;
}



// Ti added mmc Get Responce
char mmcGetResponse( void )
{
	//Response comes 1-8bytes after command
	//the first bit will be a 0
	//followed by an error code
	//data will be 0xff until response
	int i = 0;

	char response;

	while ( i <= 64 )
	{
		response = spiSendByte( 0xff );
		if ( response == 0x00 )
			break;
		if ( response == 0x01 )
			break;
		i++;
	}
	return response;
}

char mmcGetXXResponse( const char resp )
{
	//Response comes 1-8bytes after command
	//the first bit will be a 0
	//followed by an error code
	//data will be 0xff until response
	int i = 0;

	char response;

	while ( i <= 500 )
	{
		response = spiSendByte( 0xff );
		if ( response == resp )
			break;
		i++;
	}
	//Uart_Printf("\nresponse=%d\n",response);
	return response;
}
char mmcCheckBusy( void )
{
	//Response comes 1-8bytes after command
	//the first bit will be a 0
	//followed by an error code
	//data will be 0xff until response
	int i = 0;

	char response;
	char rvalue;
	while ( i <= 64 )
	{
		response = spiSendByte( 0xff );
		response &= 0x1f;
		switch ( response )
		{
			case 0x05:
				rvalue = MMC_SUCCESS;break;
			case 0x0b:
				return( MMC_CRC_ERROR );
			case 0x0d:
				return( MMC_WRITE_ERROR );
			default:
				rvalue = MMC_OTHER_ERROR;
				break;
		}
		if ( rvalue == MMC_SUCCESS )
			break;
		i++;
	}
	i = 0;
	do
	{
		response = spiSendByte( 0xff );
		i++;
	}
	while ( response == 0 );
	return response;
}

// The card will respond with a standard response token followed by a data
// block suffixed with a 16 bit CRC.
// Ti Modification: long int -> long ; int -> long
char mmcReadBlock( const unsigned long address , const unsigned long count )
{
	unsigned long i = 0;
	char rvalue = MMC_RESPONSE_ERROR;

	// Set the block length to read
	if ( mmcSetBlockLength( count ) == MMC_SUCCESS )	// block length could be set
	{
		// Uart_Printf("\n set read length ok\n");
		// UART_PutString(UART0,"o\n");//add by chang
		// SS = LOW (on)
		CS_LOW();
		// send read command MMC_READ_SINGLE_BLOCK=CMD17
		mmcSendCmd( 17 , address , 0xFF );
		// Send 8 Clock pulses of delay, check if the MMC acknowledged the read block command
		// it will do this by sending an affirmative response
		// in the R1 format (0x00 is no errors)
		if ( mmcGetResponse() == 0x00 )
		{
			// now look for the data token to signify the start of
			// the data
			if ( mmcGetXXResponse( MMC_START_DATA_BLOCK_TOKEN ) == MMC_START_DATA_BLOCK_TOKEN )
			{
				// UART_PutString(UART0,"read sigal block\n");//add by chang
				// clock the actual data transfer and receive the bytes; spi_read automatically finds the Data Block
				for ( i = 0; i < 512; i++ )
					mmc_buffer[i] = spiSendByte( 0xff );	// is executed with card inserted

				// get CRC bytes (not really needed by us, but required by MMC)
				spiSendByte( 0xff );
				spiSendByte( 0xff );
				rvalue = MMC_SUCCESS;
			}
			else
			{
				// the data token was never received
				rvalue = MMC_DATA_TOKEN_ERROR;	// 3
			}
		}
		else
		{
			// the MMC never acknowledge the read command
			rvalue = MMC_RESPONSE_ERROR;	// 2
		}
		rvalue = MMC_SUCCESS;
	}
	else
	{
		rvalue = MMC_BLOCK_SET_ERROR;	// 1
	}
	CS_HIGH();
	spiSendByte( 0xff );
	return rvalue;
}				// mmc_read_block

//---------------------------------------------------------------------
// Ti Modification: long int -> long
char mmcWriteBlock( const unsigned long address )
{
	unsigned long i = 0;
	char rvalue = MMC_RESPONSE_ERROR;	// MMC_SUCCESS;
	//char c = 0x00;

	// Set the block length to read
	if ( mmcSetBlockLength( 512 ) == MMC_SUCCESS )	// block length could be set

⌨️ 快捷键说明

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