[PATCH] SPI SD-Card: setup valid CRC-7 for STOP_TRANSMISSION command.

Pavel Pisa ppisa4lists at pikron.com
Fri Oct 4 11:42:27 UTC 2013


Hello Sebastian,

in the theory GCC could do such optimization sd_card_compute_crc7()
is static and code is better readable with the function call.
But I have checked generated code and direct use of 0x7a
would replace lot of the code. I can check if it works and
update patch. Other option is to prepare whole
command for sd_card_stop_multiple_block_read in memory

  const static uint8_t sd_card_stop_multiple_block_cmd[]

which would be even smaller. Separate read/flush of reply
would be required in such case.

It is possible that use of command without indicated CRC use 
(CRC7  bit 0 clear) is even accepted by (all?) cards in this
actual case even that CRCs are generally enabled. But it can
vary between cards. Actual code was against spec for sure, there
has been left CRC and arg from previous command left. But even
such broken read stop worked for original author and some cards.
We have found confirmation in some discussion that some cards
do not check CRC in this actual case.

The reason why I am considering such thing is, that this command
should ensure stop of read mode and CRC check contributes
for higher probability that card is left in incorrect state.

Anyway I think that there should be some mechanism to reset
card/stop read or other special modes when card is left in
incorrect state due to some fault. Check of response from stop
command could help too.

But send patch is minimum required to work with SD
card and checksums on our HW. If you agree I do update
and send it after check.

In the fact I use CRC enabled code on RTEMS 4.10.
I would be happy if such patch could be included in RTEMS 4.10,
but there is chance that it can break some other card/project
combination so I am not sure if it is RTEMS 4.10 matherial.

I have written even MXS/CSB336 RTEMS libi2c SPI driver for
SSI peripheral. SSI is intended mainly for audio but in MXS
case it can be reconfigured to SPI and with DMA the SD card
throughput is not so bad. The code is partially dependant
on our MX1 drivers support etc. preparation for mainlining
would require quite effort so if there is no one else who can
proffit (CSB336/MXS is not perspective platform) I do not
plan cleaning it now. For sure, I would send that code with many
more other stuff from our application if somebody has interrest
in that.

Best wishes,

             Pavel

On Friday 04 of October 2013 10:14:44 Sebastian Huber wrote:
> On 2013-10-04 09:34, Pavel Pisa wrote:
> > From: Pavel Pisa <ppisa at pikron.com>
> >
> > STOP_TRANSMISSION command is used to finish READ_MULTIPLE_BLOCK
> > command and its format is regular command format.
> > It requires valid CRC-7 to have effect at least on
> > some card brands else it is ignored and attempt
> > to issue next READ or WRITE commands results in
> > illegal command condition (0x04) preceded by strange
> > (0x3f) for tested card.
> >
> > Signed-off-by: Pavel Pisa <ppisa at pikron.com>
> > ---
> >   c/src/libchip/i2c/spi-sd-card.c |    4 ++++
> >   1 file changed, 4 insertions(+)
> >
> > diff --git a/c/src/libchip/i2c/spi-sd-card.c
> > b/c/src/libchip/i2c/spi-sd-card.c index 5a30451..89d5fb5 100644
> > --- a/c/src/libchip/i2c/spi-sd-card.c
> > +++ b/c/src/libchip/i2c/spi-sd-card.c
> > @@ -501,8 +501,12 @@ static int sd_card_send_register_command(
> > sd_card_driver_entry *e, uint32_t comm static int
> > sd_card_stop_multiple_block_read( sd_card_driver_entry *e) {
> >   	int rv = 0;
> > +	uint8_t crc7;
> >
> >   	SD_CARD_COMMAND_SET_COMMAND( e->command,
> > SD_CARD_CMD_STOP_TRANSMISSION); +	SD_CARD_COMMAND_SET_ARGUMENT(
> > e->command, 0);
> > +	crc7 = sd_card_compute_crc7( e->command + 1, 5);
> > +	SD_CARD_COMMAND_SET_CRC7( e->command, crc7);
> >   	rv = rtems_libi2c_write_bytes( e->bus, e->command,
> > SD_CARD_COMMAND_SIZE); RTEMS_CHECK_RV( rv, "Write stop transfer token");
>
> Since the command uses only constants is it sufficient to use
>
> SD_CARD_COMMAND_SET_ARGUMENT( e->command, 0);
> SD_CARD_COMMAND_SET_CRC7( e->command, 0x7a);



More information about the devel mailing list