📄 mmc_spi.c
字号:
//###########################################################
// File: mmc_spi.c
//
// Read-/Writeroutines for MMC MultiMedia cards and
// SD SecureDigital cards in SPI mode.
//
// This will work only for MMC cards with 512 bytes block length !
// This will work only for MMC cards with a partition table !
//
//
//#########################################################################
// Last change: 21.05.2006
//#########################################################################
#include <msp430x16x.h>
#include "dos.h"
#ifdef MMC_CARD_SPI
#define set_SD_nCs (P3OUT |= BIT0)
#define clr_SD_nCs (P3OUT &= ~BIT0)
#define set_SD_MOSI (P3OUT |= BIT1)
#define clr_SD_MOSI (P3OUT &= ~BIT1)
#define SD_MISO ((P3IN & ( BIT2))>>1)
#define set_SD_SCK (P3OUT |= BIT3)
#define clr_SD_SCK (P3OUT &= ~BIT3)
//set MMC_Chip_Select to high (MMC/SD-Card Invalid)
#define MMC_Disable() set_SD_nCs;
//set MMC_Chip_Select to low (MMC/SD-Card Active)
#define MMC_Enable() clr_SD_nCs;
#define SomeNOP {_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();}
unsigned char Init_Flag; //Set it to 1 when Init is processing.
unsigned char Read_Byte_MMC(void);
void Write_Byte_MMC(unsigned char value);
unsigned char Write_Command_MMC(unsigned char *CMD);
//****************************************************************************
// Port Init
void MMC_Port_Init(void)
//****************************************************************************
{
P3SEL = 0x00;
P3DIR |= (BIT0 + BIT1 + BIT3);
P3DIR &= ~BIT2;
set_SD_nCs;
set_SD_SCK;
set_SD_MOSI;
}
//****************************************************************************
//Routine for Init MMC/SD card(SPI-MODE)
unsigned char MMCIdentify(void)
//****************************************************************************
{
unsigned char retry,temp;
unsigned char i;
unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
MMC_Port_Init(); //Init SPI port
for(i=0;i<250;i++) //Wait MMC/SD ready...
{
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
}
Init_Flag=1; //Set the init flag
for (i=0;i<0x0f;i++)
{
Write_Byte_MMC(0xff); //send 74 clock at least!!!
}
//Send Command CMD0 to MMC/SD Card
retry=0;
do
{ //retry 200 times to send CMD0 command
temp=Write_Command_MMC(CMD);
retry++;
if(retry==200)
{ //time out
return(1);//CMD0 Error!
}
}
while(temp!=1);
//Send Command CMD1 to MMC/SD-Card
CMD[0] = 0x41; //Command 1
CMD[5] = 0xFF;
retry=0;
do
{ //retry 100 times to send CMD1 command
temp=Write_Command_MMC(CMD);
retry++;
if(retry==250)
{ //time out
return(1);//CMD1 Error!
}
}
while(temp!=0);
Init_Flag=0; //Init is completed,clear the flag
MMC_Disable(); //set MMC_Chip_Select to high
return(0); //All commands have been taken.
}
//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
unsigned char Write_Command_MMC(unsigned char *CMD)
//****************************************************************************
{
unsigned char tmp;
unsigned char retry=0;
unsigned char i;
//set MMC_Chip_Select to high (MMC/SD-Card disable)
MMC_Disable();
//send 8 Clock Impulse
Write_Byte_MMC(0xFF);
//set MMC_Chip_Select to low (MMC/SD-Card active)
MMC_Enable();
//send 6 Byte Command to MMC/SD-Card
for (i=0;i<0x06;i++)
{
Write_Byte_MMC(*CMD++);
}
//get 16 bit response
Read_Byte_MMC(); //read the first byte,ignore it.
do
{ //Only last 8 bit is used here.Read it out.
tmp = Read_Byte_MMC();
retry++;
}
while((tmp==0xff)&&(retry<100));
return(tmp);
}
//****************************************************************************
//Routine for reading a byte from MMC/SD-Card
unsigned char Read_Byte_MMC(void)
//****************************************************************************
{
unsigned char i,rByte=0;
for(i=0;i<8;i++){
clr_SD_SCK;
if(Init_Flag){
SomeNOP;
}
rByte<<=1;
if((P3IN & BIT2)){
rByte |= 1;
} else {
rByte |= 0;
}
set_SD_SCK;
if(Init_Flag){
SomeNOP;
}
}
return rByte;
}
//****************************************************************************
//Routine for sending a byte to MMC/SD-Card
void Write_Byte_MMC(unsigned char value)
//****************************************************************************
{
unsigned char i;
for(i=0;i<8;i++){
if ((value<<i) & 0x80) {
set_SD_MOSI;
} else {
clr_SD_MOSI;
}
clr_SD_SCK;
if(Init_Flag){
SomeNOP;
}
set_SD_SCK;
if(Init_Flag){
SomeNOP;
}
}
set_SD_MOSI;
}
#ifdef DOS_WRITE
//****************************************************************************
//Routine for writing a Block(512Byte) to MMC/SD-Card
//Return 0 if sector writing is completed.
unsigned char MMCWriteSector(unsigned long sector, unsigned char *buf)
//unsigned char MMC_write_sector(unsigned long addr,unsigned char *Buffer)
//****************************************************************************
{
unsigned char tmp,retry;
unsigned int i;
//Command 24 is a writing blocks command for MMC/SD-Card.
unsigned char CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
// if(sector>=maxsect) return 1; //sectornumber too big
sector = sector << 9; //addr = addr * 512
CMD[1] = ((sector & 0xFF000000) >>24 );
CMD[2] = ((sector & 0x00FF0000) >>16 );
CMD[3] = ((sector & 0x0000FF00) >>8 );
//Send Command CMD24 to MMC/SD-Card (Write 1 Block/512 Bytes)
retry=0;
do
{ //Retry 100 times to send command.
tmp=Write_Command_MMC(CMD);
retry++;
if(retry==100)
{
return(tmp); //send commamd Error!
}
}
while(tmp!=0);
//Before writing,send 100 clock to MMC/SD-Card
for (i=0;i<100;i++)
{
Read_Byte_MMC();
}
//Send Start Byte to MMC/SD-Card
Write_Byte_MMC(0xFE);
//Now send real data Bolck (512Bytes) to MMC/SD-Card
for (i=0;i<512;i++)
{
Write_Byte_MMC(*buf++); //send 512 bytes to Card
}
//CRC-Byte
Write_Byte_MMC(0xFF); //Dummy CRC
Write_Byte_MMC(0xFF); //CRC Code
tmp=Read_Byte_MMC(); // read response
if((tmp & 0x1F)!=0x05) // data block accepted ?
{
MMC_Disable();
return(1); //Error!
}
//Wait till MMC/SD-Card is not busy
while (Read_Byte_MMC()!=0xff){};
//set MMC_Chip_Select to high (MMC/SD-Card Invalid)
MMC_Disable();
return(0);
}
#endif
//****************************************************************************
//Routine for reading data Registers of MMC/SD-Card
//Return 0 if no Error.
unsigned char MMC_Read_Block(unsigned char *CMD,unsigned char *Buffer,unsigned int Bytes)
//****************************************************************************
{
unsigned int i; unsigned retry,temp;
//Send Command CMD to MMC/SD-Card
retry=0;
do
{ //Retry 100 times to send command.
temp=Write_Command_MMC(CMD);
retry++;
if(retry==100)
{
return(1); //block write Error!
}
}
while(temp!=0);
//Read Start Byte form MMC/SD-Card (FEh/Start Byte)
while (Read_Byte_MMC() != 0xfe){};
//Write blocks(normal 512Bytes) to MMC/SD-Card
for (i=0;i<Bytes;i++)
{
*Buffer++ = Read_Byte_MMC();
}
//CRC-Byte
Read_Byte_MMC();//CRC - Byte
Read_Byte_MMC();//CRC - Byte
//set MMC_Chip_Select to high (MMC/SD-Card invalid)
MMC_Disable();
return(0);
}
//****************************************************************************
//Routine for reading Blocks(512Byte) from MMC/SD-Card
//Return 0 if no Error.
unsigned char MMCReadSector(unsigned long sector, unsigned char *buf)
//unsigned char MMC_read_sector(unsigned long addr,unsigned char *Buffer)
//****************************************************************************
{
//Command 16 is reading Blocks from MMC/SD-Card
unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
unsigned char temp;
//Address conversation(logic block address-->byte address)
sector = sector << 9; // addr = addr * 512;
CMD[1] = (unsigned char)((sector & 0xFF000000) >>24 );
CMD[2] = (unsigned char)((sector & 0x00FF0000) >>16 );
CMD[3] = (unsigned char)((sector & 0x0000FF00) >>8 );
CMD[4] = (unsigned char)((sector & 0x000000FF) );
temp=MMC_Read_Block(CMD,buf,512);
return(temp);
}
#endif //MMC_CARD_SPI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -