SPI_MODE_0 and SPI_MODE_1 assumed swapped in lib_spi

Technical questions regarding the xTIMEcomposer, xSOFTip Explorer and Programming with XMOS.
User avatar
aclassifier
Respected Member
Posts: 319
Joined: Wed Apr 25, 2012 8:52 pm
Contact:

SPI_MODE_0 and SPI_MODE_1 assumed swapped in lib_spi

Postby aclassifier » Thu Feb 22, 2018 5:34 pm

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-content/uploads/2018/02/2018_02_22_E_spi_lib_MODE_0_and_MODE_1_swapped.pdf,
as used in http://www.teigfam.net/oyvind/home/technology/165-xc-code-examples/#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 78 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 78 times
User avatar
aclassifier
Respected Member
Posts: 319
Joined: Wed Apr 25, 2012 8:52 pm
Contact:

Postby aclassifier » Fri Mar 02, 2018 11:08 am

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!
User avatar
aclassifier
Respected Member
Posts: 319
Joined: Wed Apr 25, 2012 8:52 pm
Contact:

Postby aclassifier » Mon Mar 19, 2018 11:48 am

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.

Who is online

Users browsing this forum: No registered users and 68 guests