📄 mmc_sd.c
字号:
/* ELEC254 Group32 USB SD Card Reader */
#include <avr/io.h>
#include "MMC_SD.h"
#include "LED.h"
void SPI_Low(void)
{
SPCR = _BV(SPE)|_BV(MSTR)|_BV(SPR1)|_BV(SPR0);
SPSR &= ~_BV(SPI2X);
}
void SPI_High(void)
{
SPCR = _BV(SPE)|_BV(MSTR);
SPSR |= _BV(SPI2X);
}
void SPI_Init(void)
{
DDR_INI();
SPI_Low();
}
uint8 SPI_WriteByte(uint8 val)
{
SPDR = val;
while(!(SPSR & _BV(SPIF)));
return SPDR;
}
uint8 SPI_ReadByte(void)
{
SPDR = 0xff;
while(!(SPSR & _BV(SPIF)));
return SPDR;
}
void MMC_SD_Init(void)
{
SPI_Init();
SPI_CS_Deassert();
LED_ON();
}
uint8 MMC_SD_SendCommand(uint8 cmd, uint32 arg)
{
uint8 r1;
uint8 retry=0;
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_CS_Assert();
SPI_WriteByte(cmd | 0x40);
SPI_WriteByte(arg>>24);
SPI_WriteByte(arg>>16);
SPI_WriteByte(arg>>8);
SPI_WriteByte(arg);
SPI_WriteByte(0x95);
while((r1 = SPI_WriteByte(0xff)) == 0xff)
if(retry++ > 100) break; //time out error
SPI_CS_Deassert();
return r1;
}
uint8 MMC_SD_Reset(void)
{
uint8 i;
uint8 retry;
uint8 r1=0;
retry = 0;
SPI_Low();
do
{
for(i=0;i<100;i++) SPI_WriteByte(0xff);
r1 = MMC_SD_SendCommand(0, 0); //send idle command
retry++;
if(retry>10) return 1; //time out
} while(r1 != 0x01);
retry = 0;
do
{
r1 = MMC_SD_SendCommand(1, 0); //send active command
retry++;
if(retry>100) return 1; //time out
} while(r1);
SPI_High();
r1 = MMC_SD_SendCommand(59, 0); //disable CRC
r1 = MMC_SD_SendCommand(16, 512); //set sector size to 512
return 0;
}
uint8 MMC_SD_ReadSingleBlock(uint32 sector, uint8* buffer)
{
uint8 r1;
uint16 i;
uint8 retry=0;
do
{
r1 = MMC_SD_SendCommand(17, sector<<9); //read command
retry++;
if(retry>10) return 1; //time out
} while(r1 != 0x00);
SPI_CS_Assert();
//wait to start recieve data
while(SPI_WriteByte(0xff) != 0xfe);
for(i=0; i<512; i++) //read 512 bytes
{
*buffer++ = SPI_WriteByte(0xff);
}
SPI_WriteByte(0xff);//crc
SPI_WriteByte(0xff);
SPI_CS_Deassert();
return 0;
}
uint8 MMC_SD_WriteSingleBlock(uint32 sector, uint8* buffer)
{
uint8 r1;
uint16 i;
uint8 retry=0;
do
{
r1 = MMC_SD_SendCommand(24, sector<<9);//send command
retry++;
if(retry>10) return 1; //time out
} while(r1 != 0x00);
SPI_CS_Assert();
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xfe); //send start byte
for(i=0; i<512; i++) //send 512 bytes data
{
SPI_WriteByte(*buffer++);
}
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
r1 = SPI_WriteByte(0xff);
if( (r1&0x1f) != 0x05)
{
SPI_CS_Deassert();
return r1;
}
while(!SPI_WriteByte(0xff));
SPI_CS_Deassert();
return 0;
}
uint32_t MMC_SD_ReadCapacity()
{
uint8 r1;
uint16 i;
uint16 temp;
uint8 buffer[16];
uint32 Capacity;
r1 = MMC_SD_SendCommand(9, 0);
if(r1 != 0x00)
return r1;
SPI_CS_Assert();
while(SPI_WriteByte(0xff) != 0xfe);
for(i=0;i<16;i++)
{
buffer[i]=SPI_WriteByte(0xff);
}
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_CS_Deassert();
i = buffer[6]&0x03;
i<<=8;
i += buffer[7];
i<<=2;
i += ((buffer[8]&0xc0)>>6);
r1 = buffer[9]&0x03;
r1<<=1;
r1 += ((buffer[10]&0x80)>>7);
r1+=2;
temp = 1;
while(r1)
{
temp*=2;
r1--;
}
Capacity = ((uint32)(i+1))*((uint32)temp);
i = buffer[5]&0x0f;
temp = 1;
while(i)
{
temp*=2;
i--;
}
Capacity *= (uint32)temp;
return Capacity;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -