Skip to main content
xpp07
Associate III
September 21, 2018
Solved

Reading current sensor via SPI (Solved)

  • September 21, 2018
  • 12 replies
  • 2823 views

I'm having problems to read my current sensor, which is located at the source leg of a power transistor. 

I'm using the sensor TLI4970

This is my routine every 10ms:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); //Bring slave select low
 
HAL_SPI_Receive(&hspi1, (uint8_t *)&SPIRx, 2, 10); //Receive data
 
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); //Bring slave select high

However, I get random values even when the current is zero. I'm getting values like:

0x8800

0x8803

0x8801

0xA7FF

0x87FC

0x97FE

0xA802

0xA801

0x97FD

0x87FD

0xA800

0xA7FE

According to the datasheet, these are sensor status messages, but none of them are Sensor Current Messages. The hardware seems okay. This sensor is not so common I think. I haven't found much help. Am I doing something wrong in software?

    This topic has been closed for replies.
    Best answer by xpp07

    Fixed. My clock phase was wrong. I had SP1 mode 0 , but the right one is the Mode 1.

    12 replies

    T J
    Senior III
    September 21, 2018

    I checked the datasheet.

    firstly, I havn't seen the need for 100k pullup on SPI before, it is unusual, but necessary I guess.

    I am not sure if you can enable the stm32pin-pullup whilst the pin is in AF(alt function) mode as SPI.

    The TLI4970-D050T4 has a 3-pin serial peripheral interface (SPI). A standard unidirectional 16-bit SPI protocol is
    used.

    that's different to your snippet, its not an issue but I believe the Indians run backward...

    otherwise you would use a 16bit buffer,

    (uint16_t *)&SPIRx

    its a nice datasheet,

    did you see the 16bit frame has a parity bit ?

    All SPI frames are based on a 16-bit word. A parity bit in each SPI frame allows the detection of transmission errors and increases the reliability of the measured data. 
    The transmission of the data is triggered by the CS-pin.

    and there is a timing issue: so, not too fast ...

    the CS-pin has to return to the high state for at least the time tCSON before pulling it to low again in order to trigger the next sample readout.

    I see ... you are reading close to zero current...

    ignoring the first two bits, you have

    0800

    0803

    0801

    07FF

    07FC

    17FE ????

    0802

    0801

    17FD ???

    07FD

    0800

    07FE

    Not sure why you have noise in the MSB position...otherwise the data looks good...

    xpp07
    xpp07Author
    Associate III
    September 21, 2018

    That's the point. I'm getting always either 8 or A in the MSB position. I don't understand why.

    T J
    Senior III
    September 21, 2018

    its not 8 or A, its the 9 that is the issue.

    the top 3 bits are not part of the reading, and must be removed.

    the ADC is 13bit

    ADC= result &0x1FFF ;

    hence my question when you recive a '9' in the top nibble.. that seems incorrect.

    xpp07
    xpp07Author
    Associate III
    September 21, 2018

    I've captured a new pattern of received data and all of them start at either 8 or A. Not 9 anymore. But according to the datasheet, the first bit should be 0 in order to be a current message.

    T J
    Senior III
    September 21, 2018

    I already showed you in my first responce in the datasheet the top 3 bit are used for different purposes.

    You should decode those top 3 bits for your code.

    and remove them for the data.

    without any '9's, the bottom 13 bits of your data looks good.

    xpp07
    xpp07Author
    Associate III
    September 21, 2018

    Thanks for your patience. I will assume I can ignore the top 3 bits. I just was confused because the datasheet says that:

    The “Sensor Status Message�? and the “Sensor Value Message�?. The two types are distinguished by the STATUS Bit.

    So the status bit is the first bit, which should be 0.

    T J
    Senior III
    September 21, 2018

    Yes, sorry I didn't read so in.

    if bit 15 is 0 then

    value = SPI_16 &1FFF

    else{

    Pstatus = SPI_16 & 0x4000;

    HWstatus = ....

    }

    xpp07
    xpp07Author
    Associate III
    September 21, 2018

    The problem is that.. I'm never getting 0 in bit 15.

    T J
    Senior III
    September 21, 2018

    did you adjust to reading 16bit data ?

    you may have a little indian problem...

    did you check CPOL in the datasheets ?

    xpp07
    xpp07Author
    Associate III
    September 21, 2018

    This is how my SPI is set:

    /* SPI1 init function */
    static void MX_SPI1_Init(void)
    {
     
     /* SPI1 parameter configuration*/
     hspi1.Instance = SPI1;
     hspi1.Init.Mode = SPI_MODE_MASTER;
     hspi1.Init.Direction = SPI_DIRECTION_2LINES;
     hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
     hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
     hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
     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 = 7;
     hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
     hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
     if (HAL_SPI_Init(&hspi1) != HAL_OK)
     {
     _Error_Handler(__FILE__, __LINE__);
     }
     
    }