SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By dvukovic
#11865
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
By upand_at_them
#11867
If you're reading CID and CSD your setup should be fine. Are you sending a valid address with the read command?

Mike
By dvukovic
#11869
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
By dvukovic
#11874
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
By seema
#18309
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?