Reading from SD card ??

I have wired a ATMEGA32 to an SD socket thru a 74hc125.

I have been able to read the CID and CSD registers.

Read CID Block FD0E894900C8A4040E003730353044000004

Read CSD Block FB40BF0060969F3FD9F6A583591F32007F00

These seem to be OK,

However, I can not read a data block.

I never see the READ TOKEN 0xFE.

I send the READ_CMD CMD17 to the card

I get the response = 0x00

I poll for the READ TOKEN but it never comes, nothing but 0xff.

Is there any other setup I need to do to get read data flowing ??

Thanks

If you’re reading CID and CSD your setup should be fine. Are you sending a valid address with the read command?

Mike

Opps,

Yes, I am trying to read block/sector 0x00000000.

I am unable to read the STATUS reg as well.

The string I am sending is:

CMD17,0,0,0,0,0xFF

Thanks

For those how have noticed this post.

I have found that ICCAVR does not handle long data type.

My function tries to pass the base address of the sector I am trying to read.

Debugging with AVRstudio I find that the value passed has garbage in the high order byte. This caused the SD chip to find the address out-of-range.

I have removed passing a long to passing a pointer.

Strange.

thanks

Hi

I am hacing the same problem…but I sstill can’t see whats going on! I can write to the SD Card…but can’t read it…i get the 0x00 response…here is some of my code:

/*-------------------------------------------------------------------------

SD Read Block

Reads 512 Byte Block from the SD card

Send READ_SINGLE_BLOCK command first, wait for response come back

0x00 followed by 0xFE. The call SPI_Receive() to read the data

block back followed by the checksum.

---------------------------------------------------------------------------*/

uint32_t SD_Read_Block(uint32_t block_number)

{

uint32_t Checksum;

uint32_t varh, varl;

SPI_IOSET = SPI_SS_PIN; // Set SPI SSEL

varl = ((block_number&0x003F)<<9);

varh = ((block_number&0xFFC0)>>7);

/* Send SD CMD17(READ_SINGLE_BLOCK) to read the data from the SD card. */

SDCmd[0] = 0x51; // 1010001

/* High block address bits, varh HIGH and LOW. */

SDCmd[1] = varh >> 0x08;

SDCmd[2] = varh & 0xFF;

/* low block address bits, varl HIGH and LOW. */

SDCmd[3] = varl >> 0x08;

SDCmd[4] = varl & 0xFF;

/* Checksum is no longer required but we always send 0xFF. */

SDCmd[5] = 0xFF;

SPI_Send(SDCmd, SD_CMD_SIZE);

/* If sd_response returns 1 when we failed to get a 0x00 response. */

if ((SD_Response(0x00)) == 1);

{

SDStatus = READ_BLOCK_TIMEOUT;

SPI_IOSET = SPI_SS_PIN; // Set SPI SSEL

return SDStatus;

}

/* Wait for data token. */

if ((SD_Response(0xFE)) == 1)

{

SDStatus = READ_BLOCK_DATA_TOKEN_MISSING;

SPI_IOSET = SPI_SS_PIN; // Set SPI SSEL

return SDStatus;

}

/* Get the block of data based on the length. */

SPI_Receive(SDRDData, SD_DATA_SIZE);

/* CRC bytes that are not needed. */

Checksum = SPI_ReceiveByte();

Checksum = Checksum << 0x08 | SPI_ReceiveByte();

SPI_IOSET = SPI_SS_PIN; // Set SPI SSEL

SPI_ReceiveByte();

return 0;

}

/*-----------------------------------------------------------

SD Get Response

Repeatedly reads the SD card until we get the response we want

or timeout.

-------------------------------------------------------------*/

uint32_t SD_Response(uint8_t response)

{

uint32_t count = 0xFFF;

while( (SPI_ReceiveByte() != response) && count)

{

count–;

}

if (count == 0)

return 1; // Failure, loop was exited due to timeout

else

return 0; // Normal, loop was exited before timeout

}

any ideas?