Hz2020
Member level 3
hello FVM, vinodstanur, doraemon, and mf1364.
i am doing the same project and i read all the posts >>>>>>>>>>> nice
i use ATmega8535 AVR controller
i send CMD0 to the SD and 1 returned, then, i send CMD1 and 0 returned, then i send CMD59 and 0 to turn off the CRC and 0 is returned, then i send CMD16 and 256 to adjust the block size to 256, then my problem occur. my problem is after that i send CMD24 and 5*256(sector five*number of bytes in each sector) to write in the fifth sector then 64 is returned. from r1 response, this means that it is an illegal command and there is an address error and parameter error
note : i use an lcd to show the r1 response of each command
note also that this code is the first code that mf1364 use, but i correct it
my code is:
my sd is as shown :
thanks in advance
i am doing the same project and i read all the posts >>>>>>>>>>> nice
i use ATmega8535 AVR controller
i send CMD0 to the SD and 1 returned, then, i send CMD1 and 0 returned, then i send CMD59 and 0 to turn off the CRC and 0 is returned, then i send CMD16 and 256 to adjust the block size to 256, then my problem occur. my problem is after that i send CMD24 and 5*256(sector five*number of bytes in each sector) to write in the fifth sector then 64 is returned. from r1 response, this means that it is an illegal command and there is an address error and parameter error
note : i use an lcd to show the r1 response of each command
note also that this code is the first code that mf1364 use, but i correct it
my code is:
Code:
#include <mega8535.h>
#include <stdio.h>
#include <delay.h>
#asm
.equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd.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_IF_COND 8 // For only SDC V2. Check voltage range.
#define MMC_SEND_CSD 9 // get card"s CSD
#define MMC_SEND_CID 10 // get card's CID
#define MMC_SEND_STATE 13
#define MMC_SET_BLOCKLEN 16 //set number of byte to transferblock
#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_PORT 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_ERASE_GROUP_END 36 //sets end of erase group (mass erase)
#define MMC_UNTAG_ERASE_GROUP 37
#define MMC_ERASE 38
#define MMC_CRC_ON_OFF 59
#define MMC_R1_BUSY 0X80
#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
#define MMC_STARTBLOCK_READ 0XFE
#define MMC_STARTBLOCK_WRITE 0XFE
#define MMC_STARTBLOCK_MWRITE 0XFC
#define MMC_STOPTRAN_WRITE 0XFD
#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
#define MMC_DR_MASK 0X1F
#define MMC_DR_ACCEPT 0X05
#define MMC_DR_REJECT_CRC 0X0B
#define MMC_DR_REJECT_WRITE_ERROR 0X0D
char c[10],y[10];
void spi_write(unsigned char data);
void mmclint(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 spilnit()
{
PORTB.7=1;
DDRB.7=1;
DDRB.6=0;
DDRB.5=1;
DDRB.4=1;
SPCR=0X52;
SPSR=0X00; //kan SPCR=0x00;
}
unsigned char spitransferbyte(unsigned char data)
{
unsigned char received =0;
SPDR = data;
while(!(SPSR&(1<<7)));
received = SPDR;
return (received);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mmclint(void)
{
spilnit();
MMC_CS_DDR.MMC_CS_PIN=1;
MMC_CS_PORT.MMC_CS_PIN=1;
lcd_clear();
lcd_putsf(" MMC initiated ");
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void spi_write(unsigned char data){
//MMC_CS_PORT.MMC_CS_PIN=0;
SPDR=data;
while(!(SPSR&(1<<7)));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char mmcreset(void){
unsigned char i;
unsigned char retry;
unsigned char r1=0;
retry=0;
do{
for(i=0;i<10;i++) spitransferbyte(0xff); // send dummy byte with CS high before accessing
r1= mmcsendcommand(MMC_GO_IDLE_STATE,0); //resetting card go to spi mode r1=????? 0x95
retry++;
if(retry>10) return-1;
}while(r1 != 0X01);
retry=0;
lcd_clear();
sprintf(y,"CMD0 r1= %d",r1);
lcd_puts(y);
spitransferbyte(0xff);
do
{
r1= mmcsendcommand(MMC_SEND_OP_COND,0); // initializing card for operation
retry++;
if(retry>10)return-1;
}while(r1);
sprintf(y,"\nCMD1 r1= %d",r1);
lcd_puts(y);
delay_ms(500);
r1= mmcsendcommand(MMC_CRC_ON_OFF,0); //turn off CRC checking to simplify communication
lcd_clear();
sprintf(y,"CMD59 r1= %d",r1);
lcd_puts(y);
r1=mmcsendcommand(MMC_SET_BLOCKLEN,256);
sprintf(y,"\nCMD16 r1= %d",r1);
lcd_puts(y);
delay_ms(500);
return 0;
}
//-------------------------------------------------
unsigned char mmcsendcommand(unsigned char cmd, unsigned long argument){
unsigned char r1;
MMC_CS_PORT.MMC_CS_PIN=0; //MMC_CS_DDR.MMC_CS_PIN=0; //assert chip select ??
r1= mmccommand(cmd,argument); //issue the command
MMC_CS_PORT.MMC_CS_PIN=1;
return r1;
}
//-----------------------------------------------
char mmcread(unsigned long int sector,unsigned char* buffer )
{
unsigned char r1;
unsigned i;
MMC_CS_DDR.MMC_CS_PIN=0;
r1= mmccommand(MMC_READ_SINGLE_BLOCK,sector<<9);
if (r1!=0X00)
return r1;
while(spitransferbyte(0xff)!=MMC_STARTBLOCK_READ);
for (i=0;i<0X200;i++)
*buffer++ = spitransferbyte(0xff);
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<<8); //multiply sector by 256
if(r1 != 0x00)
{/*lcd_clear();
sprintf(y,"CMD24 r1= %d",r1);
lcd_puts(y);*/
return r1;}
lcd_clear();
sprintf(y,"CMD24 r1= %d",r1);
lcd_puts(y);
spitransferbyte(0xff); // send dummy
spitransferbyte(MMC_STARTBLOCK_WRITE); //send data start token
for (i=0; i<256; i++)
spitransferbyte(*buffer++);
spitransferbyte(0xff);
spitransferbyte(0xff);
r1=spitransferbyte(0xff); // write 16-bit crc (dummy values)
// read data response token
if((r1&MMC_DR_MASK)!= MMC_DR_ACCEPT)
return r1;
while(!spitransferbyte(0xff)); //wait for busy period
sprintf(y,"\nDatares = %d",r1);
lcd_puts(y);
MMC_CS_PORT.MMC_CS_PIN=1; //CS
return 0; // return succes
}
//////////////////////////////////////////
unsigned char mmccommand(unsigned char cmd,unsigned long int argument){
char r1;
char retry=0;
//send command
spi_write(cmd |0x40);
spi_write(argument>>24);
spi_write(argument>>16);
spi_write(argument>>8);
spi_write(argument);
if(cmd==MMC_GO_IDLE_STATE)
spi_write(0x95); //crc valid only for mmc_go_idle_state
while((r1 = spitransferbyte(0xff))==0xff)
if(retry++ > 8) break;
return r1;
}
///-------------------------------------------------
char write_buf[256]; //read_buf[10];
void main(void) {
unsigned int i;
unsigned long int sector;
// LCD module initialization
lcd_init(16);
lcd_putsf(" wellcome ");
delay_ms(500);
mmclint();
delay_ms(10);
mmcreset();
for (i=0;i<256;i++)
write_buf[i]=i;
sector=5;
delay_ms(10);
mmcwrite(sector,write_buf); // write to sector 5
/*
delay_ms(1);
mmcread(sector,read_buf); */ // read of sector 5
while(1){}
}
my sd is as shown :
thanks in advance