📄 mmc.c
字号:
#include "mmc.h"
/*==========================================================
// function: spi mode send and receive data
// Parameter: data send data
// return: u8 receive data
// date: 2006/10/18
// note: none
==========================================================*/
unsigned char mmcSendByte(unsigned char data)
{
unsigned char tmp;
SPDR = data;
while( !(SPSR & (1 << SPIF)) );
tmp = SPDR;
return tmp;
}
/*==========================================================
// function: send command to mmc card
// Parameter: *cmd command 6bytes(cmd,d,d,d,d,crc)
// return: u8 return data
// date: 2006/10/18
// note: none
==========================================================*/
unsigned char mmcWriteCmd(unsigned char *cmd)
{
unsigned char tmp;
unsigned char retry=0;
mmcDisable();
mmcSendByte(0xFF);
mmcEnable();
for(tmp = 0; tmp < 6; tmp++) //command send
{
mmcSendByte(*cmd++);
}
tmp = 0xFF;
while(tmp == 0xFF)
{
tmp = mmcSendByte(0xFF); //wait return value
if(retry++ > 100)
{
break;
}
}
return(tmp);
}
/*==========================================================
// function: mmc init
// Parameter: void
// return: u8 init return
// date: 2006/10/18
// note: none
==========================================================*/
unsigned char mmcIni(void)
{
unsigned char retry=0;
unsigned char tmp;
unsigned char cmd[] = {0x40,0x00,0x00,0x00,0x00,0x95};
DDRB |= MMC_MSK;
PORTB |= MMC_CS;
DDRA &= ~(MMC_DET);
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0) | (1 << SPR1);
mmcDisable();
for(tmp = 0; tmp < 200; tmp++) //little wait
{
asm("NOP");
}
for(tmp = 0; tmp < 0x0F; tmp++) //min 74 clock
{
mmcSendByte(0xFF);
}
while(mmcWriteCmd(cmd) != 1) //step 1,CMD0,return 1
{
if(retry++ > 200)
{
return 1;
}
}
retry=0;
cmd[0] = 0x41;
cmd[5] = 0xFF;
while(mmcWriteCmd(cmd) != 0) //step 2,CMD1,return 0
{
if(retry++ > 200)
{
return 2;
}
}
SPCR &= ~((1 << SPR0) | (1 << SPR1));
SPSR |= (1 << SPI2X); //full speed spi
mmcDisable();
return 0;
}
/*==========================================================
// function: Write a sector,512 bytes
// Parameter: addr sector serial
// *buff data buffer
// return: u8 write return
// date: 2006/10/18
// note: none
==========================================================*/
unsigned char mmcWriteSector(unsigned long addr,unsigned char *buff)
{
unsigned char tmp;
unsigned int i;
unsigned char cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
addr = addr<<9; // *512
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
tmp = mmcWriteCmd(cmd); //CMD24
if(tmp != 0)
{
return tmp;
}
for(i = 0; i < 100; i++) //send dummy
{
mmcSendByte(0xFF);
}
mmcSendByte(0xFE); //send data start token
for(i = 0; i < 0x200; i++) //send data
{
mmcSendByte(*buff++);
}
mmcSendByte(0xFF);
mmcSendByte(0xFF); //write 16-bit CRC (dummy values)
while(0xFF != mmcSendByte(0xFF));
mmcDisable();
return 0;
}
/*==========================================================
// function: read data
// Parameter: *cmd command 6bytes
// *buff read data buffer
// size read data size
// return: void
// date: 2006/10/18
// note: none
==========================================================*/
void mmcReadBlock(unsigned char *cmd,unsigned char *buff,unsigned int size)
{
unsigned int i;
asm("cli");
if(mmcWriteCmd(cmd) != 0)
{
return;
}
while(0xFE != mmcSendByte(0xFF));
for(i = 0; i < size; i++)
{
*buff++ = mmcSendByte(0xFF);
}
mmcSendByte(0xFF);
mmcSendByte(0xFF);
mmcDisable();
asm("sei");
return;
}
/*==========================================================
// function: read 1 sector data,512 bytes
// Parameter: addr sector serial
// *buff read data buffer
// return: u8 always return 0
// date: 2006/10/18
// note: none
==========================================================*/
unsigned char mmcReadSector(unsigned long addr,unsigned char *buff)
{
unsigned char cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
addr = addr<<9;
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
mmcReadBlock(cmd,buff,512);
return 0;
}
/*==========================================================
// function: read card cid
// Parameter: *buff cid buffer(03,53,44,53,44,...)
// return: u8 always return 0
// date: 2006/10/18
// note: none
==========================================================*/
unsigned char mmcReadCid(unsigned char *buff)
{
unsigned char cmd[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
mmcReadBlock(cmd,buff,16);
return 0;
}
/*==========================================================
// function: read card csd
// Parameter: *buff csd buffer(P3.5.3)
// return: u8 always return 0
// date: 2006/10/18
// note: none
==========================================================*/
unsigned char mmcReadCsd(unsigned char *buff)
{
unsigned char cmd[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
mmcReadBlock(cmd,buff,16);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -