SPI_MODE_0 and SPI_MODE_1 assumed swapped in lib_spi

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
User avatar
aclassifier
Respected Member
Posts: 483
Joined: Wed Apr 25, 2012 8:52 pm
Contact:

SPI_MODE_0 and SPI_MODE_1 assumed swapped in lib_spi

Post by aclassifier »

By careful examination to the best of my ability I have come to the assumption that lib_spi 3.0.2 [1] has got SPI_MODE_0 and SPI_MODE_1 swapped all over. In the documentation and in the code.

Disclaimer: Since it is beyond my comprehension that this error may have survived so long, I have thought that I may be wrong in my interpretations. I may be having some cognitive short here. Even built this case! If I am wrong nothing is better for XMOS, and I must just lip my wounds..

The headings of SPI modes show the two first wrongly. The correct is in green (and Mode 0 is SPI_MODE_0 etc.):
  • “1.1.1 Mode 0 – CPOL: 0 CPHA 1” → Mode 1 in heading and figure description
  • “1.1.2 Mode 1 – CPOL: 0 CPHA 0” → Mode 0 i in heading and figure description
I have run the code with all four SPI modes and scoped the result, and then compared that to the Wikipedia SPI mode curve example picture there. My document is attached, but there is a high-res version at [2]

Some examples from the code. The typedef in spi.h also has its comments wrong:

Code: Select all

/** This type indicates what mode an SPI component should use */
typedef enum spi_mode_t {
  SPI_MODE_0, /**< SPI Mode 0 - Polarity = 0, Clock Edge = 1 CORRECT: Clock Edge = 0*/
  SPI_MODE_1, /**< SPI Mode 1 - Polarity = 0, Clock Edge = 0 CORRECT: Clock Edge = 1*/
  SPI_MODE_2, /**< SPI Mode 2 - Polarity = 1, Clock Edge = 0 */
  SPI_MODE_3, /**< SPI Mode 3 - Polarity = 1, Clock Edge = 1 */
} spi_mode_t;
And here is another example. I assume the code has to be modified to get it correct. For now I can just swap the one for the other.

Code: Select all

static void get_mode_bits(spi_mode_t mode, unsigned &cpol, unsigned &cpha){
    switch(mode){
        case SPI_MODE_0:cpol = 0; cpha= 1; break;
        case SPI_MODE_1:cpol = 0; cpha= 0; break;
        case SPI_MODE_2:cpol = 1; cpha= 0; break;
        case SPI_MODE_3:cpol = 1; cpha= 1; break;
    }
}
[1] https://www.xmos.com/support/libraries/lib_spi
[2] http://www.teigfam.net/oyvind/home/wp-c ... wapped.pdf,
as used in http://www.teigfam.net/oyvind/home/tech ... s/#lib_spi
Attachments
2018 02 22 E spi_lib MODE_0 and MODE_1 swapped.pdf
have run the code with all four SPI modes and scoped the result, and then compared that the the Wikipedia SPI mode curve example picture
(959.6 KiB) Downloaded 196 times
2018 02 22 E spi_lib MODE_0 and MODE_1 swapped.pdf
have run the code with all four SPI modes and scoped the result, and then compared that the the Wikipedia SPI mode curve example picture
(959.6 KiB) Downloaded 196 times


--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
User avatar
aclassifier
Respected Member
Posts: 483
Joined: Wed Apr 25, 2012 8:52 pm
Contact:

Post by aclassifier »

By the way, the comment "The data will be transmitted least-significant bit first. " in spi.h is also wrong. The code shows MSB first, and the figures in spi.pdf are also showing MSB first.

Code: Select all

// uint8_t data is the data to be output by transfer8_sync_zero_clkblk
for(unsigned i=0;i<8;i++){ 
    // Code omitted 
    if(!isnull(mosi)){ 
        partout_timed(mosi, 1, data>>7, time); 
            data<=1;
    }
    // Code omitted
}
The first bit to output is data>>7 which is BIT7 or MSB. Then BIT6 is shifted left into BIT7 and output next. There is no doubt: MSB first!
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
User avatar
aclassifier
Respected Member
Posts: 483
Joined: Wed Apr 25, 2012 8:52 pm
Contact:

Post by aclassifier »

I'd certainly like some response on this! Please..

I have a working SPI link as it should. However I have not concluded that the above comments are not correct.
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
Post Reply