- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @OddOwl,
Thanks for your patience!!
- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Hardware
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @OddOwl,
Adding to my previous response.
Could you please share the function definition of
SPI_receiveByte
Thank you
Best Regards
Raj Chaudhari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
//
//*****************************************************************************
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
spi.c:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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