cancel
Showing results for 
Search instead for 
Did you mean: 

Problems writing to SD card in SPI mode

nelegalus
Associate
Posted on August 11, 2011 at 16:58

I'm trying to comunicate with SD card with  STM32F100RB controller via SPI.

I am able to erase blocks on card, and to read them. The problem is about writing blocks to card. I am able to write something to card, and i can read it, but i cant get correct response after writing bytes to card. Maybe anyone can tell me what i am doing wrong?

My code:

void SPI_SD_Init(void) 

{

GPIO_InitTypeDef gpio;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

gpio.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

gpio.GPIO_Speed = GPIO_Speed_50MHz;

gpio.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOA, &gpio);

gpio.GPIO_Pin = GPIO_Pin_4;

gpio.GPIO_Speed = GPIO_Speed_50MHz;

gpio.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &gpio);

SPI_SetSpeed(SD_SPEED_400KHZ);

void SPI_SetSpeed(SD_Speed_TypeDef speed)

{

SPI_InitTypeDef spi;

  int prescaler = SPI_BaudRatePrescaler_64;

  

  if(speed == SD_SPEED_400KHZ){

prescaler = SPI_BaudRatePrescaler_64;

}

else if (speed == SD_SPEED_25MHZ){

prescaler = SPI_BaudRatePrescaler_2;

}

// 6 mhz / 187khz  ; 100<x<400khz, and <25mhz

SPI_Cmd(SPI_SD, DISABLE);

spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

spi.SPI_Mode = SPI_Mode_Master;

spi.SPI_DataSize = SPI_DataSize_8b;

spi.SPI_CPOL = SPI_CPOL_Low;

spi.SPI_CPHA = SPI_CPHA_1Edge;

spi.SPI_NSS = SPI_NSS_Soft;

spi.SPI_BaudRatePrescaler = prescaler;

spi.SPI_FirstBit = SPI_FirstBit_MSB;

spi.SPI_CRCPolynomial = 7;

SPI_Init(SPI_SD, &spi);

SPI_Cmd(SPI_SD, ENABLE);

}

unsigned char SPI_WriteByte(unsigned char data)   

{   

    u8 Data = 0;   

   

    /* Wait until the transmit buffer is empty */   

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);   

    /* Send the byte */   

    SPI_I2S_SendData(SPI1, data);   

       

    /* Wait until a data is received */   

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);   

    /* Get the received data */   

    Data = SPI_I2S_ReceiveData(SPI1);   

       

    /* Return the shifted data */   

    return Data;   

}   

u8 SD_Init(void)

{

u8 retry;

u8 response=0;

u8 i;

retry = 0x00;

SD_CS_LOW();

do   

    {

for(i = 0; i < 10; i++)

{

SPI_WriteByte(0xff);

}   

        response = SD_sendCommand(GO_IDLE_STATE, 0);   //send idle command 

printf(''Idle cmd - '');

printfResponse(response);

 

        retry++;   

        if(retry > 100)

{

printf(''SD init fail...\n\r'');

return 1;       //time out

}   

    } while(response != 0x01);

SD_CS_HIGH();

SPI_WriteByte(0xff);

SPI_WriteByte(0xff);

retry = 0;

do

{

response = SD_sendCommand(SEND_OP_COND, 0); //activate card's initialization process

response = SD_sendCommand(SEND_OP_COND, 0); //same command sent again for compatibility with some cards

retry++;

if(retry > 100)

{

printf(''SD init fail..\n\r'');

return 1;       //time out

}   

}

while(response);

response = SD_sendCommand(CRC_ON_OFF, OFF); //disable CRC; deafault - CRC disabled in SPI mode

response = SD_sendCommand(SET_BLOCK_LEN, 512); //

SPI_SetSpeed(SD_SPEED_25MHZ);

    return 0;    //normal return       

}

u8 SD_writeSingleBlock(u32 startBlock, u8* buffer)

{

u8 response = 0x04;

u8 retry = 0;

int i;

SD_CS_LOW();

response = SD_sendCommand(WRITE_SINGLE_BLOCK, startBlock<<9); //write a Block command

if(response != 0x00) //check for SD status: 0x00 - OK (No flags set)

return response;

response = SPI_WriteByte(0xfe); //Send start block token 0xfe (0x11111110)

for(i=0; i<512; i++)    //send 512 bytes data

  {

SPI_WriteByte(buffer[i]);

}

printf(''512 Bytes transfered!!\r\n'');

SPI_WriteByte(0xFF);     //transmit dummy CRC (16-bit), CRC is ignored here

SPI_WriteByte(0xFF);

response = SPI_WriteByte(0xFF);

printf(''%#04x \r\n'',response);

if( (response & 0x1f) != 0x05) //response= 0xXXX0AAA1 ; AAA='010' - data accepted

{                              //AAA='101'-data rejected due to CRC error

  SD_CS_HIGH();              //AAA='110'-data rejected due to write error

 

printf(''BAD RESPONSE!!\r\n'');

  return response;

}

printf(''GOOD!!\r\n'');

while(!SPI_WriteByte(0xff)) //wait for SD card to complete writing and get idle

{

if(retry++ > 0xfffe)

{

SD_CS_HIGH(); 

return 1;

}

}

SD_CS_HIGH(); 

SPI_WriteByte(0xff);

SD_CS_LOW(); 

while(!SPI_WriteByte(0xff)) //wait for SD card to complete writing and get idle

   

if(retry++ > 0xfffe)

{

SD_CS_HIGH(); 

return 1;

}

SD_CS_HIGH();

 

return 0;

}

int main(void)

{

u8 buf[512];

  // HW configuration 

  RCC_Configuration();

  GPIO_Configuration();

NVIC_Configuration();

// Peripherials configuration

USART_Configuration();

BLUE_LED_ON();

SPI_SD_Init();

SD_Init();

buf[0] = 0x99;

buf[1] = 0x99;

SD_writeSingleBlock(0, buf);

  

while(1);

}   

0 REPLIES 0