2011-05-25 12:15:04     Endian of SPI transfers mixed up for 16-bit

Document created by Aaronwu Employee on Aug 27, 2013
Version 1Show Document
  • View in full screen mode

2011-05-25 12:15:04     Endian of SPI transfers mixed up for 16-bit

Ciaran Watterson (IRELAND)

Message: 100837   

 

Just been testing IIO with the ad7298 a bit. It seems to endian order is wrong for 16bit SPI transfers. Example to read the temperature sensor, this section of code from ad7298_core.c

 

int tmp;

 

    tmp = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |

              AD7298_TAVG | st->ext_ref);

 

    mutex_lock(&dev_info->mlock);

    spi_write(st->spi, (u8 *)&tmp, 2);

 

The code written should be 0x8022 but appears on the SPI bus as 0x2280 (see attached output). 'cpu_to_be16' should do a byte order swap (defined in little_endian.h) - the question is, is there a second byte swap happening in spi_bfin5xx.c? Or somewhere else. I think I ran this test using spidev with wordsize 16 and passing in a u8 array - the last two bytes of the transfer should read F00D but are 0DF0. I'll re-run this to verify.

 

Is it possible a configuration is wrong somewhere and big_endian.h is being included instead - surely this would cause a fatal error pretty quick?

 

Endian issue.png

QuoteReplyEditDelete

 

 

2011-05-25 12:39:16     Re: Endian of SPI transfers mixed up for 16-bit

Ciaran Watterson (IRELAND)

Message: 100838   

 

Just to confirm this issue also with spidev, as I suggested above, output attached. test data is as per the spi test program.

 

static uint8_t tx[] = {

        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

        0x40, 0x00, 0x00, 0x00, 0x00, 0x95,

        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

        0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,

        0xF0, 0x0D,

    };

 

EndianIssueSPIDev.png

QuoteReplyEditDelete

 

 

2011-05-26 03:30:15     Endian of SPI transfers mixed up for 16-bit

Michael Hennerich (GERMANY)

Message: 100860    All IIO SPI drivers are written to work with bits_per_word = 8.

Only in case the driver sets spi->bits_per_word = 16 itself, then

the driver cares about the endianness. In all other cases the driver gets the

endianness right only if it is set to 8-bit transfers.

 

The feature to alter bits_per_word from the board file is a balckfin thing only.

So please don't set controller_data in struct spi_board_info.

The SPI bus core assumes bits_per_word = 8 by default.

 

-Michael

QuoteReplyEditDelete

 

 

2011-05-26 04:20:42     Re: Endian of SPI transfers mixed up for 16-bit

Ciaran Watterson (IRELAND)

Message: 100862   

 

I'm not sure how that works - how does the ad7298 work with an 8-bit wordsize? Isn't it supposed to use 16bits? Does it allow a pause/CS toggle in the middle of a transfer?

 

If I configure the wordsize with spidev is that different from setting the wordsize in the blackfin platform config?

 

Thanks for your help - I'll try it with the 8bit default. I've seen the screen shot so I assume it must work somehow.

QuoteReplyEditDelete

 

 

2011-05-26 04:31:45     Re: Endian of SPI transfers mixed up for 16-bit

Michael Hennerich (GERMANY)

Message: 100864    SPI is driven by clocks.

It doesn't matter if there is some pause between two successive transfers,

as long as the chip select behavior is right. The ad7298 IIO driver takes care of that.

 

However Blackfin SPI has some strange side effect on SPI_MODE_0 and SPI_MODE_2.

So please use SPI_MODE_3 instead of MODE_0. Or if the device requires MODE_0,

use GPIO controlled SPI select instead.

 

See more here:

 

  docs.blackfin.uclinux.org/doku.php?id=spi

 

SPI bits_per_word set in the balackfin board file, overwrites the default set by the SPI core.

However if the driver overwrites it again by setting spi->bits_per_word followed by a spi_setup(spi) it uses this instead.

QuoteReplyEditDelete

 

 

2011-05-26 04:56:34     Re: Endian of SPI transfers mixed up for 16-bit

Ciaran Watterson (IRELAND)

Message: 100865   

 

Yes - I've been through all that. However, I find that the SPI_MODE_0 and 2 are the ONLY modes that do the chip select right for the ad7298 when using it as a character device with spidev to get samples at the max sample rate of 1MSPS. The Chip select is used to activate conversion and set the sample timing in this case, and needs to toggle between each word, with a fixed period.

 

Using spidev I found unless GPIO was used for the other two modes, the chip select was very badly off. Obviously the GPIO mode works fine for (and only works) for the iio drivers as these are periodic short transfers. Also the sample period is large compared to the transfer time so the sampling mode for the ad7298 becomes irrelevant. So IIO intrinsically can't really do more than 10000SPS and the sample period might be variable depending on the SPI message queue...

QuoteReplyEditDelete

 

 

2011-05-31 05:12:06     Re: Endian of SPI transfers mixed up for 16-bit

Ciaran Watterson (IRELAND)

Message: 100953   

 

Thought I should clarify for anyone that reads this; the SPI driver is actually doing the right thing. If you are doing a 16-bit word SPI transfer and pass a u16 word array (little endian native) each word is flipped and becomes big endian.

 

If you pass a u8 array in 16-bit mode, this is cast to a u16 array, which means the bytes are also swapped (which is incorrect, but only because the parameter was of the incorrect format).

 

If you pass a u16 array, when the SPI transfers are in 8bit words, then no flipping is done, and the bytes are sent in little endian order. ie. LSB then MSB of the 16-bit array element (as it is cast directly to u8).

 

 

 

There is a slight issue here. Normally, to avoid complication due to wordsize differences between physical layers, one passes parameters as bytes. Here you HAVE to know the SPI wordsize in order to get it right. The soln is not to set the physical layer to 8-bit so you can make assumptions in all the higher layers about endianness and byte order.

 

IF the SPI driver "message" also contained an "input wordsize" it could handle all this automatically and potentially do endian order flips in software or reconfigure the hardware - getting rid of any ambiguity.

Attachments

Outcomes