#include "mmc.h"
/******************************************************************************
FileName: mmc.c
Description: MMC/SD卡驱动
Author:WangWeimin Version : V1.0 Date: 2009/01/31
所引用的与硬件有关的函数如下:
void SPI_MasterInit(void)
U08 mmc_read_byte (void)
void mmc_write_byte (U08 _Byte_)
void uart_puthex(U8 hex)
void uart_putchar (U8 c)
void uart_putstring(U8 *s)
宏定义:
nop()
uart_innit()
MMC_Disable()
MMC_Enable()
*******************************************************************************/
/*******************************************************************************/
/************************以下宏定义与硬件有关***********************************/
/*****************************移植须注意****************************************/
/*******************************************************************************/
/******************************************************************************/
//############################################################################
void SPI_MasterInit(void)
//############################################################################
{
spi_init();
}
//############################################################################
U08 mmc_read_byte (void)
//############################################################################
{
return (spi_read());
}
//############################################################################
void mmc_write_byte (U08 _Byte_)
//############################################################################
{
spi_write(_Byte_);
}
//############################################################################
//############################################################################
void uart_putchar (U8 c)
//############################################################################
{
while ( !( UCSRA & (1<<UDRE)) );
UDR = c;
}
//############################################################################
void uart_puthex(U8 hex)
//############################################################################
{
U8 data[16]={"0123456789ABCDEF"};
uart_putchar('0');
uart_putchar('X');
uart_putchar(data[hex/16]);
uart_putchar(data[hex%16]);
}
//############################################################################
void uart_putstring(U8 *s)
//############################################################################
{
while(*s)
uart_putchar(*s++);
}
/******************************************************************************/
/************************以下与硬件无关***************************************/
/******************************************************************************/
//############################################################################
U08 mmc_init ()
//############################################################################
{
U08 Timeout = 0,a;
U08 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
MMC_Disable();
for(a=0;a<200;a++){ nop(); };
for (a = 0;a<20;a++)
{
mmc_read_byte();
}
MMC_Enable();
for(a=0;a<200;a++){ nop(); };
while( mmc_write_command (CMD)!=1)
{
if (Timeout++ > 254)
{
return(1);
}
}
Timeout = 0;
CMD[0] = 0x41;
//CMD[5]=0XFF;
while( mmc_write_command (CMD) !=0)
{
if (Timeout++ > 200)
{
return(2);
}
}
return(0);
}
//############################################################################
void mmc_goidel()
//############################################################################
{
U08 Timeout = 0;
U08 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
while( mmc_write_command (CMD)!=1)
{
if (Timeout++ > 200)
{
return;//(1);
}
}
}
//############################################################################
U08 mmc_write_command ( U08 *cmd )
//############################################################################
{
U08 tmp=0xff;
U08 a;
for(a=0;a<16;a++) mmc_read_byte();
for(a=0;a<6;a++) mmc_write_byte(cmd[a]);
for(a=0;a< 100;a++)
{
tmp=mmc_read_byte();
if (tmp!=0xff) break;
}
return(tmp);
}
//############################################################################
U08 mmc_write_sector (U32 addr,U08 *Buffer)
//############################################################################
{
U08 tmp;
U08 cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
U16 a;
addr = addr << 9; //addr = addr * 512
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
tmp = mmc_write_command (cmd);
if (tmp != 0)
{
return(tmp);
}
for (a=0;a<100;a++)
{
mmc_read_byte();
}
mmc_write_byte(0xFE);
for (a=0;a<512;a++)
{
mmc_write_byte(*Buffer++);
}
mmc_write_byte(0xFF); //Schreibt Dummy CRC
mmc_write_byte(0xFF); //CRC Code wird nicht benutzt
while (mmc_read_byte() != 0xff){};
return(0);
}
//############################################################################
void mmc_set_blocklen(U32 BLOCKLENTH,U8 RW)//1:read 0:write
//############################################################################
{
U08 cmd[] = {0x50,0x00,0x00,0x00,0x00,0xFF};
BLOCKLENTH = BLOCKLENTH << 1; //addr = addr * 512
cmd[1] = ((BLOCKLENTH & 0xFF000000) >>24 );
cmd[2] = ((BLOCKLENTH & 0x00FF0000) >>16 );
cmd[3] = ((BLOCKLENTH & 0x0000FF00) >>8 );
cmd[3] = BLOCKLENTH+(RW&0x01);
if (mmc_write_command (cmd) != 0)
{
uart_putchar('*');
return;
}
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
}
//############################################################################
void mmc_read_block(U08 *cmd,U08 *Buffer,U16 Bytes)
//############################################################################
{
U16 a;
if (mmc_write_command (cmd) != 0)
{
return;
}
while (mmc_read_byte() != 0xfe){};
for (a=0;a<Bytes;a++)
{
*Buffer++ = mmc_read_byte();
}
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
}
//############################################################################
void mmc_print_block(U32 addr,U16 Bytes)
//############################################################################
{
U16 a;
U08 cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
cmd[4] = addr&0xff;
if (mmc_write_command (cmd) != 0)
{
return;
}
while (mmc_read_byte() != 0xfe){};
for (a=0;a<Bytes;a++)
{
uart_puthex(mmc_read_byte());
if((a+1)%16==0)uart_putchar('\r');
}
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
}
//############################################################################
void mmc_write_block(U32 addr,U16 Bytes)////////////////////////////////////////////////////////////
//############################################################################
{
U16 a;
U08 cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
cmd[4] = addr&0xff;
if (mmc_write_command (cmd) != 0)
{
return;
}
for (a=0;a<100;a++)
{
mmc_read_byte();
}
mmc_write_byte(0xFE);
for (a=0;a<Bytes;a++)
{
mmc_write_byte(a);
}
//if(Bytes<512){
//for(a=0;a<(512-Bytes);a++)
//mmc_read_byte();
//}
mmc_write_byte(0xFF); //Schreibt Dummy CRC
mm