TLE9201SG SPI Message Repeat

Announcements

From sunburn to sun earn – we’ve got the power! Watch our #poweringgreen videos now.

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
OddOwl
Level 1
Level 1
5 sign-ins First like given First reply posted

Hello,

I am using TLE9201SG to drive a window motor with TMS320. When I sent a diagnostic read signal (0x00), it returned me the default diagnostic signal (0xDF), but after that things got messy and I only started getting repeated messages, for example when I sent 0xC0 it sent back 0xC0, when I sent 0xA0 it returned 0xA0. Things start to go smoothly if I just use the WR_CTRL_RD_DIA command, but when I send a RD_DIA command or a wrong command, it gets stuck in this repeated message hell. How can I solve this.

0 Likes
1 Solution
Raj_C
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi @OddOwl,

Thanks for your patience!!

I tested H-BRIDGE KIT 2GO for the above issue and it is working as expected. For your reference:

Please checkout the example project "H-Bridge 2Go – Simple Motor Control DAVE4" for correct implementation.

  •  Check the SPI configuration
  •  Implementation of SPI algorithm to write and read the data

 

Please let us know how the data is being sent in your application as well as hardware setup.

 

Thank you

Best Regards

Raj Chaudhari

View solution in original post

10 Replies
Raj_C
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi @OddOwl,

 Thanks for your patience!!

  1. Could you please check if the data is being transferred “MSB first”?

 As per the TLE9201SG datasheet: The first SPI response provided after power-up is the device revision number (RD_REV).

       2. Could you please confirm if the device revision number is received at the first instance?

For any unspecified commands, the device will respond with the content of the diagnosis register (RD_DIA).

       3. In your question the data 0xA0 is being sent which is an invalid command then it will return only the content of the diagnosis register. Could you please check if the command (0x00) and (0xA0) gives the same content without any other modification to the control register?

The short circuit and VS undervoltage diagnosis is coded in the DIA bits according to the following truth table. Together with transmission validation bit TV (always 0), it is ensured that there is always at least one 1->0 change at SO during a valid transmission. Therefore a “stuck at” failure of the SO pin can be detected.

       4. Could you please check this functionality with the 0xE0 to check “stuck at” failure?

 

For further reference please refer to section 4.12 Serial Peripheral Interface (SPI) of the TLE9201SG datasheet.

 

Thank you

Best Regards

Raj Chaudhari

0 Likes
OddOwl
Level 1
Level 1
5 sign-ins First like given First reply posted

Sory for the late response.

1- I am sure that I am sening msb first

2- The device give me "0x21" for the first response. Which I believe is the rev number.

3- That is my problem. Acording to datasheet I must get a diagonis response but it constantly send the same message. I checked again. When I send 0xa0 I get 0xa0. When I send 0x00 I just get 0x00.

4- When I send "0xe0" response is "0xe0"

When I send "0xc0",0xcd" and "0xcf" the chip responds correctly. After sending these messages I can turn on the motor and stop it. When I check the response it sends the diagnostic. But when I try to send 0x00 or any other wrong message, the chip start to response with the same message.

0 Likes
Raj_C
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi @OddOwl,

Thanks for your patience!!

I tested H-BRIDGE KIT 2GO for the above issue and it is working as expected. For your reference:

Please checkout the example project "H-Bridge 2Go – Simple Motor Control DAVE4" for correct implementation.

  •  Check the SPI configuration
  •  Implementation of SPI algorithm to write and read the data

 

Please let us know how the data is being sent in your application as well as hardware setup.

 

Thank you

Best Regards

Raj Chaudhari

OddOwl
Level 1
Level 1
5 sign-ins First like given First reply posted

Hello again;

I believe we are following the documents because we can turn motors with our setup. Here is our hardware and software setup. We are using TMS320F280025C-Q1.


Hardwareimage_2023-02-03_15-42-36.png
Software

tle9201.h

#ifndef LIB_TLE9201_H_
#define LIB_TLE9201_H_

#include <lib/utils.h>
#include "driverlib.h"
#include "device.h"
#include "board.h"


//###########################################################################
//
// x = don't care bits
// d = data bits
//
//###########################################################################
//
// Commands
//
#define TLE9201_CMD_RDDIA       0x00    // 0b000d dddd  Read Diagnosis Register
#define TLE9201_CMD_RESDIA      0x80    // 0b100d dddd  Reset Diagnosis Register
#define TLE9201_CMD_RDREV       0x20    // 0b001d dddd  Read Device Revision Number
#define TLE9201_CMD_RDCTRL      0x60    // 0b011d dddd  Read Control Register
#define TLE9201_CMD_WRCTRL      0xE0    // 0b111d dddd  Write Control - sets and returns Control Register values
#define TLE9201_CMD_WRCTRDDA    0xC0    // 0b110d dddd  Write Control and returns Diagnosis Register values

//
//Constants
//
#define DEFAULT_DATA            0x00
#define DATA_FORWARD            0x0f
#define DATA_REVERSE            0x0d
#define DATA_FREEWHEELHS1       0x0c
#define DATA_FREEWHEELHS2       0x0e
#define BASE                    SPIB_BASE

typedef struct
{
    uint8_t   inputBuffer;
    uint8_t   outputBuffer;
    uint16_t  CSB;
} tle9201_t;

typedef enum
{
    PASS_TLE = 0,   // DIA = 0bxxxx 1111 (0x0f) No failure
    DV_OT_FAIL, // DIA = 0bx0xx xxxx (0x00) Overtemperature Shutdown
    SP_VL_FAIL, // DIA = 0bxx1x xxxX (0x20) Transmission Validation Error in SPI
    O1_SG_FAIL, // DIA = 0bxxxx 1110 (0x0e) Short to GND at OUT1
    O1_SB_FAIL, // DIA = 0bxxxx 1101 (0x0d) Short to Battery at OUT1
    O2_SG_FAIL, // DIA = 0bxxxx 1011 (0x0b) Short to GND at OUT2
    O2_SB_FAIL, // DIA = 0bxxxx 0111 (0x07) Short to Battery at OUT2
    DB_SG_FAIL, // DIA = 0bxxxx 1010 (0x0a) Short to GND at OUT1 and OUT2
    DB_SB_FAIL, // DIA = 0bxxxx 0101 (0x05) Short to Battery at OUT1 and OUT2
    SG_SB_FAIL, // DIA = 0bxxxx 0110 (0x06) Short to GND at OUT1 and short to Bat. at OUT2
    SB_SG_FAIL, // DIA = 0bxxxx 1001 (0x09) Short to Bat. at OUT1 and short to GND at OUT2
    GN_OL_FAIL, // DIA = 0bxxxx 1100 (0x0c) Open Load
    VS_UV_FAIL  // DIA = 0bxxxx 0011 (0x03) VS Undervoltage

}tle9201_err;

//
// IC Functions
//
void tle9201_init();
void tle9201_setCSB();
void tle9201_reset();
void tle9201_sendAndRead(uint8_t cmd,uint8_t data);
tle9201_err tle9201_getDiagnosis();
void tle9201_getRevision();
void tle9201_getControl();
void tle9201_setControl(uint8_t data);
void tle9201_setCntrlGetDia(uint8_t data);
tle9201_err tle9201_checkError();

//
// Other Functions
//
uint8_t tle9201_getOutputBuffer();
tle9201_err tle9201_turnMotorForward();
tle9201_err tle9201_turnMotorBackward();
tle9201_err tle9201_stopMotor();


#endif /* LIB_TLE9201_H_ */

tle9201.c

#include <lib/tle9201.h>

static tle9201_t tle9201;

/**
 * @brief   Initialize input and output buffers.
 */
void tle9201_init()
{
    GPIO_writePin(HBridge1DIS, 0);
    GPIO_writePin(HBridge2DIS, 0);
    GPIO_writePin(HBridge3DIS, 0);
    GPIO_writePin(HBridge4DIS, 0);
    tle9201.inputBuffer  = 0x00;
    tle9201.outputBuffer = 0x00;
    tle9201.CSB = HBridge1CSB;
}

void tle9201_setCSB(uint8_t CSB)
{
    tle9201.CSB = CSB;
}

/**
 * @brief Reset diagnosis register through SPI
 */
void tle9201_reset()
{
    if(tle9201.CSB == HBridge1CSB)
    {
        GPIO_writePin(HBridge1DIS, 1);
        delayUs(100);
        GPIO_writePin(HBridge1DIS, 0);
        delayUs(100);

    }
    else
    {
        GPIO_writePin(HBridge2DIS, 1);
        delayUs(100);
        GPIO_writePin(HBridge2DIS, 0);
        delayUs(100);
    }

    tle9201_sendAndRead(TLE9201_CMD_RESDIA,DEFAULT_DATA);
}

/**
 * @brief   Send and receive SPI data
 *
 * @details Get 8 bit data in two parts as cmd and data. Combine them and send it via SPI
 *          Store the response in the output buffer.Then check response to decide device status.
 *
 * @param   cmd     8 bit command input defined in the documentation
 *
 * @param   data    8 bit data for the selected command
 */
void tle9201_sendAndRead(uint8_t cmd,uint8_t data)
{
    tle9201.inputBuffer = cmd | data;

    GPIO_writePin(tle9201.CSB, 0);
    DEVICE_DELAY_US(1);
    tle9201.outputBuffer = SPI_receiveByte(BASE, tle9201.inputBuffer);
    DEVICE_DELAY_US(3);
    GPIO_writePin(tle9201.CSB, 1);
    delayMs(10);
}

 /**
  * @brief Read diagnosis register through SPI
  */
tle9201_err tle9201_getDiagnosis()
{
    tle9201_err result = SP_VL_FAIL;
    tle9201_sendAndRead(TLE9201_CMD_RDDIA, DEFAULT_DATA);
    result = tle9201_checkError();
    return result;
}

/**
 * @brief Read revision register through SPI
 */
void tle9201_getRevision()
{
    tle9201_sendAndRead(TLE9201_CMD_RDREV, DEFAULT_DATA);
}

/**
 * @brief Read diagnosis register through SPI
 */
void tle9201_getControl()
{
    tle9201_sendAndRead(TLE9201_CMD_RDCTRL, DEFAULT_DATA);
}

/**
 * @brief   Set bits of the control register
 *
 * @details Assign given 8 bit input data to command register
 *
 * @param   data    data for the command register
 */
void tle9201_setControl(uint8_t data)
{
    tle9201_sendAndRead(TLE9201_CMD_WRCTRL, data);
}

/**
 * @brief   Set control register and get diagnosis register
 *
 * @param   data    data for the command register
 */
void tle9201_setCntrlGetDia(uint8_t data)
{
    tle9201_sendAndRead(TLE9201_CMD_WRCTRDDA, data);
}

/**
 * @brief   Check errors and return device status
 *
 * @details Read diagnosis register to decide current status of the device.
 *          Make sure that output buffer contains diagnosis register.
 *
 * @return  Device status according to diagnosis register
 */
tle9201_err tle9201_checkError()
{
    uint8_t dia = 0x00;

    if((tle9201.outputBuffer & 0x40) != 0x40) return DV_OT_FAIL;

    if((tle9201.outputBuffer & 0x20) == 0x20) return SP_VL_FAIL;

    dia = tle9201.outputBuffer & 0x0f;

    if(dia == 0x0e) return O1_SG_FAIL;
    if(dia == 0x0d) return O1_SB_FAIL;
    if(dia == 0x0b) return O2_SG_FAIL;
    if(dia == 0x07) return O2_SB_FAIL;
    if(dia == 0x0a) return DB_SG_FAIL;
    if(dia == 0x05) return DB_SB_FAIL;
    if(dia == 0x06) return SG_SB_FAIL;
    if(dia == 0x09) return SB_SG_FAIL;
    if(dia == 0x0c) return GN_OL_FAIL;
    if(dia == 0x03) return VS_UV_FAIL;
    if(dia == 0x0f) return PASS_TLE;

    return SP_VL_FAIL;
}

/**
 * @brief   Get current value of the output buffer
 *
 * @return  8 bit output buffer value
 */
uint8_t tle9201_getOutputBuffer()
{
    return tle9201.outputBuffer;
}

/**
 * @brief   Activate device forward mode
 *
 * @return  Device status according to diagnosis register
 */
tle9201_err tle9201_turnMotorForward()
{
    tle9201_err result = SP_VL_FAIL;
    tle9201_sendAndRead(TLE9201_CMD_WRCTRDDA, DATA_FORWARD);
    result = tle9201_checkError();
    return result;

}

/**
 * @brief   Activate device reverse mode
 *
 * @return  Device status according to diagnosis register
 */
tle9201_err tle9201_turnMotorBackward()
{
    tle9201_err result = SP_VL_FAIL;
    tle9201_sendAndRead(TLE9201_CMD_WRCTRDDA, DATA_REVERSE);
    result = tle9201_checkError();
    return result;
}

/**
 * @brief   Disable device SPI controlled outputs
 *
 * @return  Device status according to diagnosis register
 */
tle9201_err tle9201_stopMotor()
{
    tle9201_err result = SP_VL_FAIL;
    tle9201_sendAndRead(TLE9201_CMD_WRCTRDDA, DEFAULT_DATA);
    result = tle9201_checkError();
    return result;
}

SPI Settings

photo_2023-02-03_16-07-56.jpg

0 Likes
Raj_C
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi @OddOwl,

 

Could you please change the tle9201_sendAndRead function definition as follows and try again:

void tle9201_sendAndRead(uint8_t cmd,uint8_t data)
{
    tle9201.inputBuffer = cmd | data;

    GPIO_writePin(tle9201.CSB, 0);
    DEVICE_DELAY_US(1);
    tle9201.outputBuffer = SPI_receiveByte(BASE, tle9201.inputBuffer);
    DEVICE_DELAY_US(1);
    tle9201.outputBuffer = SPI_receiveByte(BASE, tle9201.inputBuffer); 
//Send Dummy data to recieve the reply
    DEVICE_DELAY_US(3);
    GPIO_writePin(tle9201.CSB, 1);
    delayMs(10);
}

Please let us know if this works.

Thank you

Best Regards

Raj Chaudhari

0 Likes
Raj_C
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi @OddOwl,

Adding to my previous response.

Could you please share the function definition of  

SPI_receiveByte

 

Thank you

Best Regards

Raj Chaudhari

0 Likes
OddOwl
Level 1
Level 1
5 sign-ins First like given First reply posted

Hello again,

Sadly the change did not work.  SPI_receiveByte is given by the microchip library. Here is the function explanation.

//*****************************************************************************
//
//! This macro definition is used to receive a byte of data
//!
//! \param base specifies the SPI module base address.
//! \param dummyData is the data which is transmitted to initiate
//! SPI transaction to receive SPI data
//!
//! This macro definition is to receive a byte of data.
//! This macro uses SPI_pollingNonFIFOTransaction function
//! SPI character length is hardcoded to 8 (1byte = 8bits) of character length
//!
//! \return the received byte.
//
//*****************************************************************************

0 Likes
Raj_C
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi @OddOwl,

Please let me know the MCU used as a Master device, and point out to the API functions for the SPI communication for the same device.

Thank you

Best Regards

Raj Chaudhari

0 Likes
OddOwl
Level 1
Level 1
5 sign-ins First like given First reply posted

Hello;

We are using  Texas Instruments TMS320F280025C-Q1.

Here is the link for the library API :
https://software-dl.ti.com/C2000/docs/C2000_driverlib_api_guide/f28002x/html/modules/spi.html#

I notice that the function I am using is not in the API so here are the SPI files I am using.
spi.h:

https://github.com/UOSupermileage/BLDC-F280049C/blob/dc10e99a24ac2d959789043f883f89eacefcd90d/ti-f28...

spi.c:

https://github.com/UOSupermileage/BLDC-F280049C/blob/dc10e99a24ac2d959789043f883f89eacefcd90d/ti-f28...

0 Likes
Raj_C
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi @OddOwl,

Thanks for the above information.

Could you please try to implement the SPI application in the known application? Where you can send and receive the data using the TMS320F280025C-Q1 by implementing the custom library.

It would give us clarity on whether there is an issue with TLE9201SG or the issue with the SPI implementation on the TMS320F280025C-Q1.

 

Thank  you

Best Regards

Raj Chaudhari

0 Likes