سلام به دوستان.
کسی هست بتونه مثال مربوط به خواندن از mmc توی کتاب مظاهریانو (مرجع کامل avr) تحلیل کنه؟
با تشکر.
کسی هست بتونه مثال مربوط به خواندن از mmc توی کتاب مظاهریانو (مرجع کامل avr) تحلیل کنه؟
با تشکر.
#include <mega32.h>
#include <delay.h>
#define MMC_CS_PORT PORTB
#define MMC_CS_DDR DDRB
#define MMC_CS_PIN 4
// MMC commands (taken from sandisk MMC reference)
#define MMC_GO_IDLE_STATE 0 ///< initialize card to SPI-type access
#define MMC_SEND_OP_COND 1 ///< set card operational mode
#define MMC_SEND_CSD 9 ///< get card's CSD
#define MMC_SEND_CID 10 ///< get card's CID
#define MMC_SEND_STATUS 13
#define MMC_SET_BLOCKLEN 16 ///< Set number of bytes to transfer per block
#define MMC_READ_SINGLE_BLOCK 17 ///< read a block
#define MMC_WRITE_BLOCK 24 ///< write a block
#define MMC_PROGRAM_CSD 27
#define MMC_SET_WRITE_PROT 28
#define MMC_CLR_WRITE_PROT 29
#define MMC_SEND_WRITE_PROT 30
#define MMC_TAG_SECTOR_START 32
#define MMC_TAG_SECTOR_END 33
#define MMC_UNTAG_SECTOR 34
#define MMC_TAG_ERASE_GROUP_START 35 ///< Sets beginning of erase group (mass erase)
#define MMC_TAG_ERARE_GROUP_END 36 ///< Sets end of erase group (mass erase)
#define MMC_UNTAG_ERASE_GROUP 37 ///< Untag (unset) erase group (mass erase)
#define MMC_ERASE 38 ///< Perform block/mass erase
#define MMC_CRC_ON_OFF 59 ///< Turns CRC check on/off
// R1 Response bit-defines
#define MMC_R1_BUSY 0x80 ///< R1 response: bit indicates card is busy
#define MMC_R1_PARAMETER 0x40
#define MMC_R1_ADDRESS 0x20
#define MMC_R1_ERASE_SEQ 0x10
#define MMC_R1_COM_CRC 0x08
#define MMC_R1_ILLEGAL_COM 0x04
#define MMC_R1_ERASE_RESET 0x02
#define MMC_R1_IDLE_STATE 0x01
// Data Start tokens
#define MMC_STARTBLOCK_READ 0xFE ///< when received from card, indicates that a block of data will follow
#define MMC_STARTBLOCK_WRITE 0xFE ///< when sent to card, indicates that a block of data will follow
#define MMC_STARTBLOCK_MWRITE 0xFC
// Data Stop tokens
#define MMC_STOPTRAN_WRITE 0xFD
// Data Error Token values
#define MMC_DE_MASK 0x1F
#define MMC_DE_ERROR 0x01
#define MMC_DE_CC_ERROR 0x02
#define MMC_DE_ECC_FAIL 0x04
#define MMC_DE_OUT_OF_RANGE 0x04
#define MMC_DE_CARD_LOCKED 0x04
// Data Response Token values
#define MMC_DR_MASK 0x1F
#define MMC_DR_ACCEPT 0x05
#define MMC_DR_REJECT_CRC 0x0B
#define MMC_DR_REJECT_WRITE_ERROR 0x0D
void mmcInit(void);
unsigned char mmcReset(void);
unsigned char mmcSendCommand(unsigned char cmd, unsigned long int argument);
unsigned char mmcRead(unsigned long int sector, unsigned char* buffer);
unsigned char mmcWrite(unsigned long int sector, unsigned char* buffer);
unsigned char mmcCommand(unsigned char cmd, unsigned long int argument);
//----------------------------------------------
void spiInit()
{
PORTB.7=1; // set SCK hi
DDRB.7=1; // set SCK as output
DDRB.6=0; // set MISO as input
DDRB.5=1; // set MOSI as output
DDRB.4=1; // SS must be output for Master mode to work
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 250.000 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=0x52;
SPSR=0x00;
}
//----------------------------------------------
unsigned char spiTransferByte(unsigned char data)
{
unsigned char received = 0;
SPDR = data;
while(!(SPSR & (1<<7)));
received = SPDR;
return (received);
}
//-----------------------------------------------
void mmcInit(void)
{
// initialize SPI interface
spiInit();
// release chip select
MMC_CS_DDR.MMC_CS_PIN=1;
MMC_CS_PORT.MMC_CS_PIN=1;
}
//-------------------------------------------------
unsigned char mmcReset(void)
{
unsigned char i;
unsigned char retry;
unsigned char r1=0;
retry = 0;
do
{
// send dummy bytes with CS high before accessing
for(i=0;i<10;i++) spiTransferByte(0xFF);
// resetting card, go to SPI mode
r1 = mmcSendCommand(MMC_GO_IDLE_STATE, 0);
retry++;
if(retry>10) return -1;
} while(r1 != 0x01);
retry = 0;
do
{
// initializing card for operation
r1 = mmcSendCommand(MMC_SEND_OP_COND, 0);
retry++;
if(retry>100) return -1;
} while(r1);
// turn off CRC checking to simplify communication
r1 = mmcSendCommand(MMC_CRC_ON_OFF, 0);
// set block length to 512 bytes
r1 = mmcSendCommand(MMC_SET_BLOCKLEN, 512);
return 0;
}
//-------------------------------------------------
unsigned char mmcSendCommand(unsigned char cmd, unsigned long int argument)
{
unsigned char r1;
// assert chip select
MMC_CS_PORT.MMC_CS_PIN=0;
// issue the command
r1 = mmcCommand(cmd, argument);
// release chip select
MMC_CS_PORT.MMC_CS_PIN=1;
return r1;
}
//---------------------------------------------------
unsigned char mmcRead(unsigned long int sector, unsigned char* buffer)
{
unsigned char r1;
unsigned int i;
MMC_CS_PORT.MMC_CS_PIN=0;
r1 = mmcCommand(MMC_READ_SINGLE_BLOCK, sector<<9);
// check for valid response
if(r1 != 0x00)
return r1;
// wait for block start
while(spiTransferByte(0xFF) != MMC_STARTBLOCK_READ);
// read in data
for(i=0; i<0x200; i++)
{
*buffer++ = spiTransferByte(0xFF);
}
// read 16-bit CRC
spiTransferByte(0xFF);
spiTransferByte(0xFF);
MMC_CS_PORT.MMC_CS_PIN=1;
return 0;
}
//------------------------------------------------------------
unsigned char mmcWrite(unsigned long int sector, unsigned char* buffer)
{
unsigned char r1;
unsigned int i;
MMC_CS_PORT.MMC_CS_PIN=0;
// issue command
r1 = mmcCommand(MMC_WRITE_BLOCK, sector<<9);
if(r1 != 0x00)
return r1;
// send dummy
spiTransferByte(0xFF);
// send data start token
spiTransferByte(MMC_STARTBLOCK_WRITE);
// write data
for(i=0; i<512; i++)
spiTransferByte(*buffer++);
// write 16-bit CRC (dummy values)
spiTransferByte(0xFF);
spiTransferByte(0xFF);
// read data response token
r1 = spiTransferByte(0xFF);
if( (r1&MMC_DR_MASK) != MMC_DR_ACCEPT)
return r1;
while(!spiTransferByte(0xFF));
// release chip select
MMC_CS_PORT.MMC_CS_PIN=1;
// return success
return 0;
}
//------------------------------------------------------------
unsigned char mmcCommand(unsigned char cmd, unsigned long int argument)
{
unsigned char r1;
unsigned char retry=0;
//send command
spiTransferByte(cmd | 0x40);
spiTransferByte(argument>>24);
spiTransferByte(argument>>16);
spiTransferByte(argument>>8);
spiTransferByte(argument);
spiTransferByte(0x95); // crc valid only for MMC_GO_IDLE_STATE
// end command
// wait for response
// if more than 8 retries, card has timed-out
// return the received 0xFF
while((r1 = spiTransferByte(0xFF)) == 0xFF)
if(retry++ > 8) break;
// return response
return r1;
}
//-----------------------------------
char write_buf[512],read_buf[512];
void main(void)
{
unsigned int i;
unsigned long int sector;
mmcInit();
mmcReset();
for(i=0;i<512;i++)
write_buf[i]=i;
sector=5; //sector 5
mmcWrite(sector,write_buf); // write to sector 5
delay_ms(1);
mmcRead(sector,read_buf); // read of sector 5
while(1);
}

دیدگاه