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

📄 mmc.c

📁 深圳优龙公司LPC2148开发板(与iar公司开发板基本相同)的原理图和配套样例程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	{
		// SS = LOW (on)
		CS_LOW();
		// send write command
		mmcSendCmd( 24 , address , 0xFF );

		// check if the MMC acknowledged the write block command
		// it will do this by sending an affirmative response
		// in the R1 format (0x00 is no errors)
		// UART_PutString(UART0,"set write block length\n");//add by chang
		if ( mmcGetXXResponse( MMC_R1_RESPONSE ) == MMC_R1_RESPONSE )
		{
			// UART_PutString(UART0,"write signal block\n");//add by chang
			spiSendByte( 0xff );
			// send the data token to signify the start of the data
			spiSendByte( 0xfe );
			// clock the actual data transfer and transmitt the bytes
			for ( i = 0; i < 512; i++ )
				spiSendByte( mmc_buffer[i] );	// mmc_buffer[i];   	Test: i & 0xff
			// put CRC bytes (not really needed by us, but required by MMC)
			spiSendByte( 0xff );
			spiSendByte( 0xff );
			// read the data response xxx0<status>1 : status 010: Data accected, status 101: Data
			//   rejected due to a crc error, status 110: Data rejected due to a Write error.
			mmcCheckBusy();
		}
		else
		{
			// the MMC never acknowledge the write command
			rvalue = MMC_RESPONSE_ERROR;	// 2
		}
		rvalue = MMC_SUCCESS;
	}
	else
	{
		rvalue = MMC_BLOCK_SET_ERROR;	// 1
	}
	//give the MMC the required clocks to finish up what ever it needs to do
	//for (i = 0; i < 9; ++i)
	//spiSendByte(0xff);

	CS_HIGH();
	// Uart_Printf("rvalue=%d\n",rvalue);
	// Send 8 Clock pulses of delay.
	spiSendByte( 0xff );
	return rvalue;
}// mmc_write_block


//---------------------------------------------------------------------
void mmcSendCmd( const char cmd , unsigned long data , const char crc )
{
	char frame[6];
	char temp;
	int i;

	frame[0] = ( cmd | 0x40 );
	for ( i = 3; i >= 0; i-- )
	{
		temp = ( char ) ( data >> ( 8 * i ) );
		frame[4 - i] = ( temp );
	}
	frame[5] = ( crc );
	for ( i = 0; i < 6; i++ )
		spiSendByte( frame[i] );
}


//--------------- set blocklength 2^n ------------------------------------------------------
// Ti Modification: long int-> long
char mmcSetBlockLength( const unsigned long blocklength )
{
	//char rValue = MMC_TIMEOUT_ERROR;
	//char i = 0;

	// SS = LOW (on)
	CS_LOW();

	// Set the block length to read
	//MMC_SET_BLOCKLEN =CMD16
	mmcSendCmd( 16 , blocklength , 0xFF );

	// get response from MMC - make sure that its 0x00 (R1 ok response format)
	if ( mmcGetResponse() != 0x00 )
	{
		//UART_PutString(UART0,"not set \n");
		return 0xff;
	}
	CS_HIGH();

	// Send 8 Clock pulses of delay.
	spiSendByte( 0xff );
	spiSendByte( 0xff );

	return MMC_SUCCESS;
}				


unsigned char spiSendByte( const unsigned char data )
{
	/*
	unsigned char spib;
	//while(SSIOST_bit.BUSY != 0);    // Wait until the character can be sent
	SSIOINT_bit.TXCMP = 1;  		  //clear interrupt register
	SSIOBUF = data; 				  // Send the data
	while((SSIOINT & 0x02) != 0x02);   // Wait for the transfer to complete
	spib = SSIOBUF; 				  // Get the data received
	SSIOINT_bit.RXCMP = 1;  		  //clear interrupt register
	return spib;					  //return transmited character
	*/

	//NOTE!!! This function send character to SPI bus when mode is MASTER
	//NOTE!!! This function receive character from SPI when mode is SLAVE
	unsigned int spib;

	//while(SSPSR_bit.BSY); 	 // Wait until the character can be sent
	while ( SSPSR_bit.TNF == 0 );
	SSPDR = data;   		   // Send the data

	//while(!SPSR0_bit.SPIF);     // Wait for the transfer to complete
	while ( SSPSR_bit.RNE == 0 );    // Wait until the character can be sent
	spib = SSPDR;   			  // Get the data received
	return spib;
	//return 0;
}

void spiWriteByte( const unsigned char data )
{
	//while(SSIOST_bit.BUSY != 0);  	// Wait until the character can be sent
	//SSIOINT_bit.TXCMP = 1;			// clear interrupt register
	//SSIOBUF = data;
}

unsigned char spiReadByte()
{
	//unsigned char spib;
	//while(SSIOINT_bit.RXCMP == 0);
	//spib = SSIOBUF;   				// Get the data received
	//SSIOINT_bit.RXCMP = 1;			//clear interrupt register
	//return spib;
	return 0;
}

// Reading the contents of the CSD and CID registers in SPI mode is a simple
// read-block transaction.
char mmcReadRegister( const char cmd_register , const unsigned char length )
{
	char uc = 0;
	char rvalue = MMC_TIMEOUT_ERROR;
	//  char i = 0;

	if ( mmcSetBlockLength( length ) == MMC_SUCCESS )
	{
		CS_LOW();
		// CRC not used: 0xff as last byte
		mmcSendCmd( cmd_register , 0x000000 , 0xff );

		// wait for response
		// in the R1 format (0x00 is no errors)
		if ( mmcGetResponse() == 0x00 )
		{
			//UART_PutString(UART0,"set MMC BlockLength ok\n");
			if ( mmcGetXXResponse( 0xfe ) == 0xfe )
			{
				//UART_PutString( UART0 , "\nread register\n" );//add by chang
				for ( uc = 0; uc < length; uc++ )
					mmc_buffer[uc] = spiSendByte( 0xff );
			}
			// get CRC bytes (not really needed by us, but required by MMC)
			//add chang guo feng
			rvalue = 0x00;
			spiSendByte( 0xff );
			spiSendByte( 0xff );
		}
		else
			rvalue = MMC_RESPONSE_ERROR;
		// CS = HIGH (off)
		//  CS_HIGH ();

		// Send 8 Clock pulses of delay.
		spiSendByte( 0xff );
		// CS_HIGH ();
	}
	CS_HIGH();
	return rvalue;
}// mmc_read_register


/************************************************************************************
**Function:MMC_Test
**autor:chang guofeng
*************************************************************************************/
void MMC_Test( void )
{
	int err;
	int i;//,j;
	int block_len, block_num, tmp;
	unsigned char ret;//,csdbuf[16];

	
	PINSEL0 = PINSEL0 & (~(0x3<<8)) ; //P0.4,GPIO(sck0)
	IO0DIR = IO0DIR | 0x1<<4 ;  //output
	
	err = initMMC();
	
	if ( err == 0 )
		UART_PutStringByPolling( UART0 , "\nInit MMC OK\n" );
	else
		UART_PutStringByPolling( UART0 , "\nInit MMC error\n" );
		
	// Uart_Printf("MMC Test\n");
	ret = mmcReadRegister( MMC_READ_CSD , 16 );
	if ( ret != 0 )
	{
		UART_PutStringByPolling( UART0 , "Get Card info error\n" );
		return;
	}
	
	IO0CLR = IO0CLR | 0x1 << 4; //Clear P0.4,0
	///* 计算块的最大长度  */														/* calculate the size of a sector */
	block_len = 1 << ( mmc_buffer[READ_BL_LEN_POS] & READ_BL_LEN_MSK );  			///* (2 ^ READ_BL_LEN) */

	///* 计算卡中块的个数 */														/* calculate the sector numbers of the SD Card */
	block_num = ( ( mmc_buffer[C_SIZE_POS1] & C_SIZE_MSK1 ) << 10 ) +
		( mmc_buffer[C_SIZE_POS2] << 2 ) +
		( ( mmc_buffer[C_SIZE_POS3] & C_SIZE_MSK3 ) >> 6 ) +
		1;				/* (C_SIZE + 1)*/

	tmp = ( ( mmc_buffer[C_SIZE_MULT_POS1] & C_SIZE_MULT_MSK1 ) << 1 ) +
		( ( mmc_buffer[C_SIZE_MULT_POS2] & C_SIZE_MULT_MSK2 ) >> 7 ) +
		2;				/* (C_SIZE_MULT + 2) */

	/* 获得卡中块的数量 */														/* get the block numbers in card */
	block_num = block_num * ( 1 << tmp );									/* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */

	/* 计算擦除的单位(单位: 块) */	
	tmp = ( ( mmc_buffer[ERASE_GRP_SIZE_POS] & ERASE_GRP_SIZE_MSK ) >> 2 ) + 1;  	/* (ERASE_GRP_SIZE + 1)  */

	/* (ERASE_GRP_SIZE + 1) * (ERASE_GRP_MULTI + 1) */
	tmp *= ( ( mmc_buffer[ERASE_GRP_MULTI_POS1] & ERASE_GRP_MULTI_MSK1 ) << 3 ) +
		( ( mmc_buffer[ERASE_GRP_MULTI_POS2] & ERASE_GRP_MULTI_MSK2 ) >> 5 ) +
		1;	
		
	/* MMC: SECTOR_SIZE */
	UART_PutStringByPolling( UART0 , "MMC Card Info:\n" );
	Uart_Printf( UART0, "    Max Bock Length : %dbyte\n" , block_len );
	Uart_Printf( UART0, "    Bock Number     : %d\n" , block_num );
	Uart_Printf( UART0, "    Size            : %dM\n" , tmp );

	for ( i = 0; i < 512; i++ )
		mmc_buffer[i] = 5;

	// for(i=0;i<=4;i++)
	//{
	// for(j=0;j<16;j++)
	//  Uart_Printf(" %02u ",mmc_buffer[i*16+j]);
	//  Uart_Printf("\n");
	// }

	UART_PutStringByPolling( UART0 , "\nWrite a block\n" );	
	if ( mmcWriteBlock( 0x0 ) != 0 )
	{
		UART_PutStringByPolling( UART0 , "    Write error\n" );
		return;
	}
	UART_PutStringByPolling( UART0 , "    Write OK\n" );

	for ( i = 0; i < 512; i++ )
		mmc_buffer[i] = 0;  //clear mmc_buffer

	UART_PutStringByPolling( UART0 , "\nRead a Block\n" );	
	if ( mmcReadBlock( 0x0 , 512 ) != 0 )
	{
		UART_PutStringByPolling( UART0 , "    Read error\n" );
		return;
	}
	
	UART_PutStringByPolling( UART0 , "    Read OK\n" );
	for ( i = 0; i < 512; i++ )
	{
		if ( mmc_buffer[i] != 5 )
		{
			UART_PutStringByPolling( UART0 , "\n    Data compare is error\n" );	
			return ;
		}
		//else
			//UART_PutStringByPolling( UART0 , "\n    Data compare is OK\n" );	
	}

	UART_PutStringByPolling( UART0 , "\nRead and write is OK\n" );
}
//---------------------------------------------------------------------
#endif /* _MMCLIB_C */

⌨️ 快捷键说明

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