📄 mmc.c
字号:
{
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
{
// 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,"read 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];
err=initMMC();
if(err==0)UART_PutString(UART0,"Init MMC OK\n");
else UART_PutString(UART0,"Init MMC error\n");
// Uart_Printf("MMC Test\n");
ret=mmcReadRegister (MMC_READ_CSD, 16);
if(ret !=0)
{
UART_PutString(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_PutString(UART0,"MMC Card Info:\n");
Uart_Printf("Max Bock Length :%dbyte\n",block_len);
Uart_Printf("Bock Number:%d\n",block_num);
Uart_Printf("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_PutString(UART0,"Write a block\n");
if(mmcWriteBlock (0x0)!=0)
{
UART_PutString(UART0,"Write error\n");
return;
}
UART_PutString(UART0,"Write OK\n");
for(i=0;i<512;i++)mmc_buffer[i]=0; //clear mmc_buffer
UART_PutString(UART0,"Read a Block\n");
if(mmcReadBlock(0x0,512)!=0)
{
UART_PutString(UART0,"Read error\n");
return;
}
UART_PutString(UART0,"Read OK\n");
// UART_PutString(UART0,"compare data\n");
for(i=0;i<512;i++)
{ if(mmc_buffer[i]!=5)
{
UART_PutString(UART0,"Compare error\n");
return ;
}
//else
}
UART_PutString(UART0,"Read and write is OK\n");
}
//---------------------------------------------------------------------
#endif /* _MMCLIB_C */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -