Skip to main content
ljuarez
Associate
July 26, 2018
Question

L9663-1 PSI5 Transceiver not communicating through SPI

  • July 26, 2018
  • 26 replies
  • 9241 views

We want to use the L9663 PSI5 Transceiver to interface a sensor. A STM32 Discovery board is being used as the SPI master, in mode 1 (CPOL = 0, CPHA = 1). The SPI clock speed is set to 10MHz.

The module configuration is:

/* SPI1 parameter configuration*/

 hspi1.Instance = SPI1;

 hspi1.Init.Mode = SPI_MODE_MASTER;

 hspi1.Init.Direction = SPI_DIRECTION_2LINES;

 hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

 hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;

 hspi1.Init.NSS = SPI_NSS_SOFT;

 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;

 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

 hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

 hspi1.Init.CRCPolynomial = 11;

We are sending 32 bit frames to the device formatted as specified on the datasheet (Frame definition section, pages 84-85) .

However, the IC is not responding to any SPI commands, and the MISO line stays always high. We have verified that the SPI module of the STM32 board functions properly, by interfacing a MCP2515 SPI CAN controller successfully. i.e. getting an SPI response and activity on the MISO line.

We have also verified that the number of clock cycles for each SPI transaction is correct (32 clock cycles as specified on the datasheet, page 87).

The transceiver has been supplied with one of the configurations described in the documentation (page 15), with the following values (all within the operational range):

VB = 12V - Including a 75nF capacitor between the pin and GND

VDD = 5V - Including a 75nF capacitor between the pin and GND

VASSUP = 0V (Charge pump off)

VAS = 7.6V (Using an external regulated voltage)

Included a 75nF capacitor across the pins VINTD and DGND.

Since we are using the exposed pad TQFP32 package, the pad is soldered to a GND plane. All the grounds have been kept electrically shorted, as specified on the datasheet (page 11). The TM pin is also connected to GND.

We have also confirmed that the device is switched on, by measuring the output voltage on the VINTD pin, which is 3.3V when the device is enabled, consuming around 19mA when powered up.

The question:

Could someone please describe why the device is not communicating back on the MISO line?

    This topic has been closed for replies.

    26 replies

    Tesla DeLorean
    Guru
    August 8, 2018

    @ST Community​  Please move to an appropriate forum and flag for staff engagement.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Pasquale D'Argenio
    ST Employee
    August 28, 2018

    Hello,

    the reported behavior on MISO could be due to incomplete power up sequence of L9663; please ensure Figure 6 of DS (Doc ID028693 Rev 3, Mar 17) is followed (a part from the necessary change because of different VAS configuration). You may have a look also to paragraph 2.1 and 2.6 .

    Regards,

    Pasquale

    ljuarez
    ljuarezAuthor
    Associate
    August 29, 2018

    Thank you @Community member​ for directing attention to this post.

    Thank you @Pasquale D'Argenio​ for your answer. We have followed the power up sequence, as specified on figure 6, and now we have some activity on the MISO line.

    However, we are sending frames as specified on the following figure of the datasheet (page 85), but the MISO response is always of incorrect SPI operation.

    See figure 27 attached.

    As an example, if we wanted to write 0x0443 to the register CHCNT with address 0x02, we are sending the frame:

    0x02 0x80 0x88 0x68 (as per formatting rules).

    Could you please clarify if this frame formatting is correct, or which format should we follow in order to write the device's registers successfully?

    We very much appreciate your help.

    umit.sharip
    Visitor II
    September 20, 2018

    Hi @ljuarez​ 

    Were you able to figure out the issue?

    I'm having the same problem, SPI fault register is always set, initially I suspected crc but after after verifying that is correct, still no luck. Any insight/experience?

    Thank you!

    Pasquale D'Argenio
    ST Employee
    October 4, 2018

    Hello,

    in attach you can find the algo for L9663 SPI CRC plus status register frame reading as example.

    Regards,

    Pasquale

    TEvan.3
    Visitor II
    February 7, 2019

    Thank you for posting the L9663 SPI CRC Algorithm. It was impossible to work out from the Data Sheet, which only states:

    5.2.4 Communication frames
     
    CRC on MOSI is calculated over bits 31:5. CRC on MISO is:
     a) CRC from the sensor
     b) CRC calculated over bits 26:3
    depending on GCR1[1].
     
    CRC generation is based on the same calculation scheme used for PSI5 sensor data
    (generator polynomial g(x)=1+x+x3, initialization value "111") with MSB passed first.
     
    Register Address out on MISO is checked internally with the register decoded address; a
    CRC error is generated in case of mismatch (last two bits are inverted)

    There are a lot of problems with the above. As shown in your posting the CRC on MOSI is calculated over bits 31:2 and not 31:5. The calculation is over 31:5 with three zero-bits appended. It won't work otherwise. This may be obvious to people familiar with the specific details of CRC calculation in this chip, but I had to see your post to get it working.

    The CRC on MISO is validated by performing the CRC over bits 26:3 WITH THREE ZEROS APPENDED in place of the received CRC bits, meaning over bits 26:0. The resulting calculated CRC is then compared with the one received. Alternately, the CRC can be run over bits 26:0 as received, and the expected result is ZERO if there are no errors.

    The CRC on MOSI can't be be the "CRC from the sensor" when reading or writing the internal registers. This section can only apply to the "Sensor Data Reading" frames, but it doesn't say that.

    It would help if an example of the calculation was given rather than just referring to the polynomial and to PSI5. Especially since PSI5 checks starting at the LSB and this starts at the MSB. That excludes the use of common code.

    The condition that causes the "Last two bits inverted" on MISO is not explained. What does "Register Address out on MISO is checked internally with the register decoded address" mean?

    It seems to mean that if you try to read Register 60 (which doesn't exist) then it returns the "last two bits inverted". Reading Register 49 (110000) which also doesn't exist doesn't give this error though.

    There's a minor bug on Pages 62 and 63 of the current Rev 3 L9663 Manual. It has the same address for two different registers. The second one should be "010100":

    CH1_CR3 (PROG): Address: 010011

    CH1_CR4 (PROG): Address: 010011

    Tom

    mahshid.ghaemi
    Visitor II
    February 15, 2019

    hello,

    Thanks for the observations about the datasheet. ​Regarding your questions:

    1. As you mentioned the CRC on MOSI is calculated over bits 31:5 with three zeros appended after LSB.
    2. The CRC on MOSI is calculated over bits 26:3 with three zeros appended after LSB instead of received CRC. you can find an example in the following picture: 0690X000006DcgyQAC.jpg
    3. "Last two bits inverted" means: if we have a out of range register address on MOSI, the address bits are decoded by IC and recognized as invalid address. then in this case the last two bits (CRC bits) on MISO are flipped.
    4. You don't get "last two bits inverted" for reading register 49 because is not a out range address. as reported in datasheet, 110000 is the address for register "ADVSET3".
    5. The address of register CH1_CR4(PROG) should be 010100.

    Mahshid

    TEvan.3
    Visitor II
    February 18, 2019

    Thank you for the clarification.

    The reason this is so confusing is that there are three different ways to calculate CRCs in software. There's the "Augmented Method" where the data has to have zero bits appended. That version derives directly from the basic theory of CRC generation, so it is the version given in educational material showing the derivation.

    It is possible to rearrange the "software shift register" so that the "appending" can be skipped. This gives the "Direct Method". As it is more efficient, that's the way most people do it, and how most sample code is written.

    So the "Direct Method" can be implemented on 31:5 or the "Augmented Method" can be implemented on "31:5 plus three zeros". Searching for code examples turns up a lot of "Direct" examples, without any explanation that they're different to the other method, which is the one assumed in the L9663 Manual.

    The next problem is that ST's routine requires an "Initializer" of "7". Using "Direct Method" code with "7" gives the wrong result. For "Direct", the value "2" has to be used instead.

    I said there were three methods. The most common is the "Table Driven" one that operates 8 bits at a time on large amounts of data. That's the most common example code out there, but you can't use one of them on 27 BITS of data.

    The image you've included in your reply seems to be of a software tool that calculates the CRC and other parameters. Is that available for developers?

    Tom

    FRoub
    Associate
    May 29, 2019

    Hello,

    Is it possible to have the routine chosen for the CRC calculation in a programming language which everybody is able to understand (like c for exemple).

    I made this routine, and I think this is working.

    #include<stdio.h>

    int main() {

      char data_packet[30]={0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};// (MOSI{31:5}+000)

      char CRC[3]={1,1,1}; //MSB first

      char CRCnext[3];

       

      for(int i=0; i<=29 ; i=i+1){

        CRCnext[2]= CRC[1];

        CRCnext[1]= CRC[0]^CRC[2];

        CRCnext[0] = CRC[2]^data_packet[i];

         

        CRC[0] = CRCnext[0];

        CRC[1] = CRCnext[1];

        CRC[2] = CRCnext[2];

      }

      printf("CRC[2:0]=%d%d%d",CRC[2],CRC[1],CRC[0]);

    }

    thank you ST for the waste of time

    TEvan.3
    Visitor II
    May 30, 2019

    Fabrice included an example CRC function, but it isn't practical. The message to be summed has to be converted from a 32-bit integer to one-bit-per-byte, and then the resulting checksum has to be packed back from bytes into bits. I think that code was derived from the code on this site:

    http://www.ghsi.de/pages/subpages/Online%20CRC%20Calculation/

    If you want to learn about CRCs you're better off reading:

    http://www.ross.net/crc/download/crc_v3.txt

    These are the ones that helped me to get a reliable CRC function for the L9663 chip and for the PSI5 Devices:

    http://www.zorc.breitbandkatze.de/crc.html

    http://www.zorc.breitbandkatze.de/crctester.c

    Here's what I wrote for the ST L9663 SPI transfers. Note that the value to be summed has to be LEFT justified in the passed-in integer for this to work:

    /* CRC parameters.
     *
     * Augmented to Direct Initialisation calculations:
     * CRC tester v1.1 written on 13/01/2003 by Sven Reifegerste (zorc/reflex)
     * -----------------------------------------------------------------------
     * 
     * Parameters:
     * 
     * polynom : 0x3
     * order : 3
     * crcinit : 0x2 direct, 0x7 nondirect
     * crcxor : 0x0
     */
     
    #define CRC_ORDER	3		/* Bits in CRC. */
    #define CRC_POLYNOM	0x3		/* 1011 without top bit. */
    #define CRC_DIRECT_INIT	0x02		/* Augmented "7" is "2" direct. */
    #define CRC_CRCXOR	0
    #define CRC_CRCMASK	(((((unsigned long)1 << (CRC_ORDER - 1)) - 1) << 1) | 1)
    #define CRC_CRCHIGHBIT	((unsigned long)1 << (CRC_ORDER - 1))
     
    /* Big-endian (non reflected) only at the moment. Message must be left justified. */
     
    unsigned long l9663_crc_3(unsigned long msg, unsigned long bitlen)
    {
    	// fast bit by bit algorithm without augmented zero bytes.
    	// does not use lookup table, suited for polynom orders between 1...32.
     
    	unsigned long c, bit;
    	unsigned long crc = CRC_DIRECT_INIT;
     
    	c = msg;
     
    	while (bitlen-- > 0) {
    		bit = crc & CRC_CRCHIGHBIT;
    		crc <<= 1;
    		if (c & 0x80000000) bit ^= CRC_CRCHIGHBIT;
    		if (bit) crc ^= CRC_POLYNOM;
    		c <<= 1;
    	}
     
    	crc ^= CRC_CRCXOR;
    	crc &= CRC_CRCMASK;
     
    	return(crc);
    }
     
    #define L9663_SPI_COMMAND_LEN		(1 + 31 - 5)
    #define L9663_SPI_COMMAND_CRC_LEN	(3)
    #define L9663_SPI_COMMAND_LSHIFT	(31 - 31)
     
    /* Sum the command without the CRC field. */
    uint32_t l9663_crc_3_gen(uint32_t a_nData)
    {
    	return l9663_crc_3(a_nData << L9663_SPI_COMMAND_LSHIFT,
    		L9663_SPI_COMMAND_LEN);
    }

    The above returns the CRC bits that are then added in the correct place in the SPI message that is to be sent.

    There's also an "l9883_crc_3_check()" function that is used to check the CRC returned from the L9663 - which is of course a bit different.

    Then there has to be a similar-but-different one to generate the standard PSI5 CRC. It is different to the above as the bits are processed "least significant bit first" where the above is the other way around. Then the CRC bits have to be end-around swapped as well.

    Tom

    VChan.1
    Visitor II
    January 16, 2020

    Can't we use the same function by changing L9663_SPI_COMMAND_LSHIFT and L9663_SPI_COMMAND_LEN for the CRC check from the L9663?

    FRoub
    Associate
    June 3, 2019

    Hi Tom,

    Thanks for the CRC calculation ! It work easier with your method !

    I have now the following problem :

    I write the following trame on the MOSI line and receive the following trame on the MISO : (those trames are given by pasquale from ST with the CRC calculation)

    SR1 MOSI: 0x04 0x00 0x00 0x08

    MISO: 0x1C 0x20 0x10 0x07 SR1[9] over voltage on VAS MISO[28] RSTB =1always on reset

    SR2 MOSI: 0x05 0x00 0x00 0x00

    MISO: 0x1C 0x28 0x08 0x0A MISO[28] RSTB =1 always on reset

    SR3 MOSI: 0x06 0x00 0x00 0x18

    MISO: 0x1C 0x31 0x00 0x0A SR3[0] reset occured MISO[28] RSTB =1 ialways on reset

    Does anyone know why my RSTB bit is always set ?

    I set the RESETN pin

    It's only a prototype so I try to put the frequency to 100KHz but it still don't work.

    I try to connect my sensor to the PSI5 first line to see if it work better but no.

    The transceiver has been supplied with one of the configurations described in the documentation (page 15), with the following values (all within the operational range):

    VB = 12V - Including a 100nF capacitor between the pin and GND

    VDD = 5V - Including a 100nF capacitor between the pin and GND

    VASSUP = 0V (Charge pump off)

    VAS = 7.6V (Using an external regulated voltage)

    Included a 100nF capacitor across the pins VINTD and DGND.

    The TM pin is also connected to GND.

    We have also confirmed that the device is switched on, by measuring the output voltage on the VINTD pin, which is 3.3V when the device is enabled, consuming around 19mA when powered up.

    Thanks you in advance for the answer.

    Fabrice