Can't read Card Specific Data from SD Card (rtems-4.9.0) - RESOLVED

Robert S. Grimes rsg at alum.mit.edu
Thu Oct 9 17:28:47 UTC 2008


Hi Thomas and Sebastian,

Whew!  This was a tough one!

I finally figured it out.  The culprit was sd_card_wait(), and its helper:

    static inline int sd_card_query( sd_card_driver_entry *e, uint8_t
    *in, int n)
    {
        return rtems_libi2c_read_bytes( e->minor, in, n);
    }


Actually, it wasn't that these functions are wrong - it's really that 
your (Sebastian) driver is built on top of a newer low-level SPI 
driver.  Note that rtems_libi2c_read_bytes is being used to monitor when 
the SD card is no longer busy.  This function eventually calls the 
low-level SPI read_write function, which accepts optional read and write 
buffers to accommodate read, write, and read/write operations.  In my 
SPI driver, which is pre-4.8 in origin, this function sends zeros out if 
no write buffer is provided. 

It seems things have changed in the SPI driver of RTEMS since I grabbed 
your (Thomas) driver, and hence the idle_char field in the transfer mode 
structure!  And sure enough, Sebastian has this defined, which is 
assigned to the idle_char field:

    #define SD_CARD_IDLE_TOKEN 0xff


And of course, detecting a busy/non-busy card only works when CS is low, 
and the master is clocking the SPI bus while holding its output high.

So, a simple updating of my Virtex low-level SPI driver to the current 
(i.e. 4.9) model and the card data is easily read

    sd_card_driver_init: Ok: Send: SD_CARD_CMD_SEND_CSD
    sd_card_driver_init: Ok: Read: SD_CARD_CMD_SEND_CSD
    sd_card_driver_init: *** Card Specific Data ***
    sd_card_driver_init: CSD structure            : 0
    sd_card_driver_init: Spec version             : 0
    sd_card_driver_init: Access time [ns]         : 1500000
    sd_card_driver_init: Max access time [N]      : 4687
    sd_card_driver_init: Max read block size [B]  : 512
    sd_card_driver_init: Max write block size [B] : 512
    sd_card_driver_init: Block size [B]           : 512
    sd_card_driver_init: Block number             : 1984000
    sd_card_driver_init: Capacity [B]             : 1015808000
    sd_card_driver_init: Max transfer speed [b/s] : 25000000


Now for the next stages - getting the file system working - wish me luck!

Thanks,
-Bob


Robert S. Grimes wrote:
> Thomas Doerfler wrote:
>   
>> Can you monitor the SPI signals at the SDCard with an oscilloscope, I
>> think the proper relationship between SEL, CLK and Data lines is crucial.
>>
>>     
>  Yes, of course they are - that's why I love my four channel 'scope!
>   
>> - - Did you verify the baudrate is correct (not too high)?
>>
>>     
> Yes.  I had started with 6.25 MHz, but switched now to 391 kHz because
> of the MMC startup requirement - same results.  (While I'm at it, I will
> only be using SD cards, so can I run only at the higher 6.25 MHz clock?
> >From the SanDisk manual and other stuff I've read, the slower clock rate
> is needed to support MMC cards during initialization; do I need that
> rate even if I won't be using MMC cards?
>
>   
>> - - which is the real relationship between clock and the both data lines,
>> how much time is between the (de-)activation of SEL to the data transfers?
>>
>>     
> Hmm...  You know, up until right now, I didn't think you were onto
> anything I've already checked.  However, the whole CS (aka SEL) issue
> has popped front and center.  If you recall, the Virtex SPI IP provides
> manual and automatic CS modes; this is part of the purpose of the
> spi_sel_per_word parameter that's been added to the transfer mode
> structure.  At this point, it doesn't seem to matter which strategy I
> use.  However, the automatic mode is quite fast; the CS is de-activated
> for only a clock cycle between bytes, which could be entirely missed by
> the card.
>
> So, is the CS supposed to frame individual bytes, and if so, what is the
> timing needed?  How long must it be inactive between bytes?
>
> The real problem is that I haven't been able to find any real SPI timing
> information about these darn cards!  Can anyone point me to a suitable
> reference?
>
>   
>> - - did you check with different SDcards?
>>
>>     
> Yes, two different cards by two different manufacturers.
>
>   
>> maybe this will give some insights.
>>
>>     
> Thanks, Thomas,
> -Bob
>
>   
>> wkr,
>> Thomas.
>>
>>
>> Robert S. Grimes wrote:
>>
>>     
>>> I've firmed up my hardware, and things seem much better. I seem to be
>>> able to reliably set SPI mode, initialize the card, and read the CID
>>> information. However, I cannot get the card to send its CSD. In order to
>>> attempt some progress, I've intentionally ignored errors when sending
>>> the SD_CARD_CMD_SEND_CSD command, and attempt to interpret the
>>> information that is returned, but it is all nonsense. This is the
>>> results from the aforementioned command:
>>>
>>> sd_card_send_command: Error: Response: ff:ff 49:ff 00:ff 00:ff 00:ff
>>> 00:ff 95:82
>>> ff:[7f] ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff
>>>
>>> I don't understand the 82 and 7f that it seems to find in the response
>>> data; shouldn't I see something like {ff} 01 {ff} fe <CSD bytes>?
>>> By the way, it seems I need to set both clock_inv and clock_phs true in
>>> the rtems_libi2c_tfr_mode_t structure used to set the transfer mode.
>>> This surprised me a bit, but then again, the other three combinations
>>> didn't work - I brute-forced it and tried all four, because I couldn't
>>> find documentation specifying which to use, and because nothing was
>>> working at the time ;-). Anyway, does that sound right?
>>>
>>> Any ideas? Thanks,
>>> -Bob
>>>
>>> P.S. Here is the full output as it stands:
>>>
>>>     sd_card_driver_init: Ok: Get driver entry
>>>     sd_card_start: Ok: Send start
>>>     virtex_spi_ioctl
>>>     virtex_spi_set_tfr_mode
>>>     virtex_spi_char_mode
>>>     sd_card_start: Ok: Set transfer mode
>>>     sd_card_start: Ok: Send address
>>>     sd_card_driver_init: Ok: Start
>>>     sd_card_driver_init: Ok: Register disk IO driver
>>>     sd_card_wait: Ok: Busy
>>>     sd_card_driver_init: Ok: Wait
>>>     sd_card_driver_init: Ok: Active chip select delay
>>>     sd_card_stop: Ok: Send stop
>>>     sd_card_driver_init: Ok: Stop
>>>     sd_card_driver_init: Ok: Send start
>>>     virtex_spi_ioctl
>>>     virtex_spi_set_tfr_mode
>>>     virtex_spi_char_mode
>>>     sd_card_driver_init: Ok: Set transfer mode
>>>     sd_card_driver_init: Ok: Inactive chip select delay
>>>     sd_card_driver_init: Ok: Send address
>>>     sd_card_stop_multiple_block_write: Ok: Wait
>>>     sd_card_stop_multiple_block_write: Ok: Write stop transfer token
>>>     sd_card_wait: Ok: Busy
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>     sd_card_send_command: Token [08]: 0xff
>>>     sd_card_send_command: Token [09]: 0xff
>>>     sd_card_send_command: Token [10]: 0xff
>>>     sd_card_send_command: Token [11]: 0xff
>>>     sd_card_send_command: Token [12]: 0xff
>>>     sd_card_send_command: Token [13]: 0xff
>>>     sd_card_send_command: Token [14]: 0xff
>>>     sd_card_send_command: Token [15]: 0xff
>>>     sd_card_send_command: Token [16]: 0xff
>>>     sd_card_send_command: Token [17]: 0xff
>>>     sd_card_send_command: Error: Timeout
>>>     sd_card_send_command: Error: Response: ff:ff 4d:ff 00:ff 00:ff 00:ff
>>>     00:ff 95:ff
>>>     ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:[ff]
>>>     sd_card_stop_multiple_block_read: Ok: Write stop transfer token
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>     sd_card_send_command: Token [08]: 0x01
>>>     sd_card_driver_init: Ok: Send: SD_CARD_CMD_GO_IDLE_STATE
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>     sd_card_send_command: Token [08]: 0x01
>>>     sd_card_driver_init: Ok: Send: SD_CARD_CMD_APP_CMD
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>     sd_card_send_command: Token [08]: 0x01
>>>     sd_card_driver_init: Ok: Send: SD_CARD_ACMD_SD_SEND_OP_COND
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>     sd_card_send_command: Token [08]: 0x01
>>>     sd_card_driver_init: Ok: Send: SD_CARD_CMD_APP_CMD
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>     sd_card_send_command: Token [08]: 0x01
>>>     sd_card_driver_init: Ok: Send: SD_CARD_ACMD_SD_SEND_OP_COND
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>     sd_card_send_command: Token [08]: 0x01
>>>     sd_card_driver_init: Ok: Send: SD_CARD_CMD_APP_CMD
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>     sd_card_send_command: Token [08]: 0x00
>>>     sd_card_driver_init: Ok: Send: SD_CARD_ACMD_SD_SEND_OP_COND
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>     sd_card_send_command: Token [08]: 0xff
>>>     sd_card_send_command: Token [09]: 0x00
>>>     sd_card_driver_init: Ok: Send: SD_CARD_CMD_SEND_CID
>>>     sd_card_read: Search from 10 to 17
>>>     sd_card_read: Token [10]: 0xff
>>>     sd_card_read: Token [11]: 0xfe
>>>     sd_card_read: Ok: Read data
>>>     sd_card_read: Ok: Read CRC 16
>>>     sd_card_driver_init: Ok: Read: SD_CARD_CMD_SEND_CID
>>>     sd_card_driver_init: *** Card Identification ***
>>>     sd_card_driver_init: Manufacturer ID : 3
>>>     sd_card_driver_init: OEM/Application ID : 21316
>>>     sd_card_driver_init: Product name : SD01G€
>>>     sd_card_driver_init: Product revision : 0
>>>     sd_card_driver_init: Product serial number : 2696421888
>>>     sd_card_driver_init: Manufacturing date : 136
>>>     sd_card_driver_init: 7-bit CRC checksum : 27
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0x7f
>>>     sd_card_send_command: Error: Command error [07]: 0x7f
>>>     sd_card_send_command: Error: Response: ff:ff 49:ff 00:ff 00:ff 00:ff
>>>     00:ff 95:82
>>>     ff:[7f] ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff ff:ff
>>>     RSG: rv=-27
>>>     sd_card_driver_init: Ok: Send: SD_CARD_CMD_SEND_CSD
>>>     sd_card_read: Search from 8 to 17
>>>     sd_card_read: Token [08]: 0xff
>>>     sd_card_read: Token [09]: 0xff
>>>     sd_card_read: Token [10]: 0xff
>>>     sd_card_read: Token [11]: 0xff
>>>     sd_card_read: Token [12]: 0xff
>>>     sd_card_read: Token [13]: 0xff
>>>     sd_card_read: Token [14]: 0xff
>>>     sd_card_read: Token [15]: 0xff
>>>     sd_card_read: Token [16]: 0xff
>>>     sd_card_read: Error: Timeout
>>>     RSG: rv=-27
>>>     sd_card_driver_init: Ok: Read: SD_CARD_CMD_SEND_CSD
>>>     sd_card_driver_init: *** Card Specific Data ***
>>>     sd_card_driver_init: CSD structure : 0
>>>     sd_card_driver_init: Spec version : 0
>>>     sd_card_driver_init: Access time [ns] : 4500
>>>     sd_card_driver_init: Max access time [N] : 7053
>>>     sd_card_driver_init: Max read block size [B] : 1
>>>     sd_card_driver_init: Max write block size [B] : 1
>>>     sd_card_driver_init: Block size [B] : 1
>>>     sd_card_driver_init: Block number : 10488
>>>     sd_card_driver_init: Capacity [B] : 10488
>>>     sd_card_driver_init: Max transfer speed [b/s] : 450000000
>>>     sd_card_send_command: Ok: Wait
>>>     virtex_spi_ioctl
>>>     sd_card_send_command: Ok: Write command and read response
>>>     sd_card_send_command: Token [07]: 0xff
>>>
>>>
>>> _______________________________________________
>>> rtems-users mailing list
>>> rtems-users at rtems.com
>>> http://rtems.rtems.org/mailman/listinfo/rtems-users
>>>
>>>       
>> - --
>>
>> - --------------------------------------------
>> Embedded Brains GmbH
>> Thomas Doerfler        Obere Lagerstrasse 30
>> D-82178 Puchheim       Germany
>> email: Thomas.Doerfler at embedded-brains.de
>> Phone: +49-89-18908079-2
>> Fax:   +49-89-18908079-9
>> -----BEGIN PGP SIGNATURE-----
>> Version: GnuPG v1.4.3 (MingW32)
>> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>>
>> iD8DBQFI7Z5o7GwuYxrppv4RAknJAJ96MFZuI2Fi497xsgRTbBFXgAr2GgCcClyn
>> AyzYiY/xVk68NYw9owCgrW4=
>> =zSAr
>> -----END PGP SIGNATURE-----
>>
>>
>>     
>
> _______________________________________________
> rtems-users mailing list
> rtems-users at rtems.com
> http://rtems.rtems.org/mailman/listinfo/rtems-users
>
>   




More information about the users mailing list