📄 mmc_drv.c
字号:
#include "AT91SAM7S64.h"
#include "Board.h"
#include "datatype.h"
#define MMC_CS (1 << 31)
#define MMC_CLK (1 << 14)
#define MMC_MOSI (1 << 13)
#define MMC_MISO (1 << 12)
#define VS1003_CS (1 << 11)
#define VS1003_DS (1 << 22)
#define VS1003_RST (1 << 20)
#define VS1003_DREQ (1 << 21)
#define VS1003_CS_HIGH() (*AT91C_PIOA_SODR |= VS1003_CS)
#define VS1003_CS_LOW() (*AT91C_PIOA_CODR |= VS1003_CS)
#define VS1003_DS_HIGH() (*AT91C_PIOA_SODR |= VS1003_DS)
#define VS1003_DS_LOW() (*AT91C_PIOA_CODR |= VS1003_DS)
#define VS1003_RST_HIGH() (*AT91C_PIOA_SODR |= VS1003_RST)
#define VS1003_RST_LOW() (*AT91C_PIOA_CODR |= VS1003_RST)
#define MMC_CS_HIGH() (*AT91C_PIOA_SODR |= MMC_CS)
#define MMC_CS_LOW() (*AT91C_PIOA_CODR |= MMC_CS)
#define MMC_CLK_HIGH() (*AT91C_PIOA_SODR |= MMC_CLK)
#define MMC_CLK_LOW() (*AT91C_PIOA_CODR |= MMC_CLK)
#define MMC_MOSI_HIGH() (*AT91C_PIOA_SODR |= MMC_MOSI)
#define MMC_MOSI_LOW() (*AT91C_PIOA_CODR |= MMC_MOSI)
#define MMC_PORT_MASK (MMC_CS|MMC_CLK|MMC_MOSI|MMC_MISO|VS1003_CS|VS1003_DS|VS1003_RST|VS1003_DREQ)
#define MMC_PORT_OUT_MASK (MMC_CS|MMC_CLK|MMC_MOSI|VS1003_CS|VS1003_DS|VS1003_RST)
#define MMC_PORT_IN_MASK (MMC_MISO | VS1003_DREQ)
//------------------------------------------------------------------------
void PIO_Init(void)
{
*AT91C_PIOA_PER |= (MMC_PORT_MASK | LED_MASK);
*AT91C_PIOA_OER |= (MMC_PORT_OUT_MASK | LED_MASK);
*AT91C_PIOA_ODR |= MMC_PORT_IN_MASK;
*AT91C_PIOA_PPUER |= SPIPULLUP; //Pull-up enable
*AT91C_PIOA_SODR = LED1;
}
//------------------------------------------------------------------------
INT8U vGet_MISO(void)
{
if(*AT91C_PIOA_PDSR & MMC_MISO)
return 1;
else
return 0;
}
//------------------------------------------------------------------------
INT8U vGet_DREQ(void)
{
if(*AT91C_PIOA_PDSR & VS1003_DREQ)
return 1;
else
return 0;
}
/**************************************************************************/
//-------------------------------------------------------------------------
void vMmcWriteByte(INT8U u8Data)
{
INT8U i;
for(i=0; i<8; i++)
{
MMC_CLK_LOW();
if( ((u8Data<<i) & 0x80) == 0x80 )
MMC_MOSI_HIGH();
else
MMC_MOSI_LOW();
//delay(10);
MMC_CLK_HIGH();
}
MMC_MOSI_HIGH();
}
//-------------------------------------------------------------------------
INT8U vMmcReadByte(void)
{
INT8U i;
INT8U u8Data = 1;
for(i=0; i<8; i++)
{
MMC_CLK_LOW();
//delay(10);
u8Data = (u8Data << 1) + vGet_MISO();
MMC_CLK_HIGH();
}
return(u8Data);
}
//-------------------------------------------------------------------------
INT8U vMmcWriteCommand(INT8U* pCommand)
{
INT8U i;
INT8U temp;
INT8U u8Retry = 0;
MMC_CS_HIGH();
vMmcWriteByte(0xff);
MMC_CS_LOW();
for(i=0; i<6; i++)
vMmcWriteByte(*pCommand ++);
vMmcReadByte();
do
{
temp = vMmcReadByte();
u8Retry ++;
}
while( (temp == 0xff) && (u8Retry < 100) );
return(temp);
}
//------------------------------------------------------------------------
INT8U vMmcReadBlock(INT8U* pCommand, INT8U* pBuffer, INT16U u16Bytes)
{
INT16U i;
INT8U u8Retry,temp;
u8Retry = 0;
do
{
temp = vMmcWriteCommand(pCommand);
u8Retry ++;
if(u8Retry == 100)
{
return(0xff);
}
}
while(temp != 0);
while (vMmcReadByte() != 0xfe);
//Write blocks(normal 512Bytes) to MMC/SD-Card
for (i=0; i<u16Bytes; i++)
{
*pBuffer++ = vMmcReadByte();
}
//CRC-Byte
vMmcReadByte();//CRC - Byte
vMmcReadByte();//CRC - Byte
//set MMC_Chip_Select to high (MMC/SD-Card invalid)
MMC_CS_HIGH();
return(0);
}
//------------------------------------------------------------------------
INT8U vMmcReadSector(INT32U addr, INT8U *Buffer)
{
//Command 16 is reading Blocks from MMC/SD-Card
INT8U CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
INT8U temp;
//Address conversation(logic block address-->byte address)
addr = addr << 9; //addr = addr * 512
CMD[1] = ((addr & 0xFF000000) >>24 );
CMD[2] = ((addr & 0x00FF0000) >>16 );
CMD[3] = ((addr & 0x0000FF00) >>8 );
temp = vMmcReadBlock(CMD, Buffer, 512);
return(temp);
}
//------------------------------------------------------------------------
INT8U MMC_Init()
{
INT8U CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
INT8U i;
INT8U u8Retry;
INT8U temp;
delay(0xffff);
for(i=0; i<0x0f; i++) //at lease 74 clock
{
vMmcWriteByte(0xff);
}
u8Retry = 0;
do
{
temp = vMmcWriteCommand(CMD);
u8Retry ++;
if(u8Retry == 200)
{
*AT91C_PIOA_CODR = LED1;
return (0);
}
}
while(temp != 1);
CMD[0] = 0x41;
CMD[5] = 0xff;
u8Retry = 0;
do
{
temp = vMmcWriteCommand(CMD);
u8Retry ++;
if(u8Retry == 100)
{
*AT91C_PIOA_CODR = LED1;
return (0);
}
}
while(temp != 0);
return (1);
}
//-------------------------------------------------------------------------
void VS1003_SCI_Write(INT8U u8RegNumber, INT16U u16Data)
{
VS1003_DS_HIGH();
VS1003_CS_LOW();
vMmcWriteByte(0x02); //write opcode
vMmcWriteByte(u8RegNumber); //reg id
vMmcWriteByte((u16Data & 0xff00) >> 8); //high byte
vMmcWriteByte(u16Data & 0x00ff); //low byte
VS1003_CS_HIGH();
}
//-------------------------------------------------------------------------
INT16U VS1003_SCI_Read(INT8U u8RegNumber)
{
INT16U temp;
VS1003_DS_HIGH();
VS1003_CS_LOW();
vMmcWriteByte(0x03); //write opcode
vMmcWriteByte(u8RegNumber); //reg id
temp = vMmcReadByte(); //high byte
temp = (temp << 8) + vMmcReadByte(); //low byte
VS1003_CS_HIGH();
return (temp);
}
//-------------------------------------------------------------------------
INT16U VS1003_SDI_Write(INT8U* pData, INT16U u16DataNumber)
{
INT16U i;
VS1003_DS_LOW();
for(i=0; i<u16DataNumber; i++)
{
vMmcWriteByte(*pData ++);
}
VS1003_DS_HIGH();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -