Other Parts Discussed in Thread: TCAN4550, BOOSTXL-CANFD-LIN
Tool/software: Code Composer Studio
Hello~!.
I’m Alex.Kim, And I’m in problem with TCAN4550-Q1.
Now, I’m developing product using TCAN4550 for CAN-FD.
And, I have made TCAN4550 SPI Drv. But I think It’s not working now.
I referred datasheet came from TI like below while developing a SPI Drv.
As a result, I’ve made result like below. (Read mode register(0x800) frequently.)
Yellow: nCS, Blue: SCK, Green: SDO (based on MCU), Red: SDI (based on MCU)
At the first time, I thought, It worked very well.
But all of sudden I realized that there were some troubles like below.
First problem is that sometime I can’t read correct data came from TCAN4550 through SDI.
Second problem is that some minute later MCU can’t any data unless TCAN4550 IC gets H/W reset. I mean, I just can read 0xFFFFFFFF like below picture before
I have made driver by referring to example code “Code_sllc469a”. And My SPI Driver consist of 8bit communication. To be honest I can’t understand why SPI communication failed. So that’s why I need help by you guys.
Please, If you have any opinion which can solve it. Don't hesitate notice me.
--- source code --
#1. TCAN4x5x_SPI.c code
/*
* TCAN4x5x_SPI.c
* Description: This file is responsible for abstracting the lower-level microcontroller SPI read and write functions
*
*
*
* Copyright (c) 2019 Texas Instruments Incorporated. All rights reserved.
* Software License Agreement
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "TCAN4x5x_SPI.h"
#include "Spi_Driver.h"
/*
* @brief Single word write
*
* @param address A 16-bit address of the destination register
* @param data A 32-bit word of data to write to the destination register
*/
void
AHB_WRITE_32(uint16_t address, uint32_t data)
{
AHB_WRITE_BURST_START(address, 1);
AHB_WRITE_BURST_WRITE(data);
AHB_WRITE_BURST_END();
}
/*
* @brief Single word read
*
* @param address A 16-bit address of the source register
*
* @return Returns 32-bit word of data from source register
*/
uint32_t
AHB_READ_32(uint16_t address)
{
uint32_t returnData;
AHB_READ_BURST_START(address, 1);
returnData = AHB_READ_BURST_READ();
AHB_READ_BURST_END();
return returnData;
}
/*
* @brief Burst write start
*
* The SPI transaction contains 3 parts: the header (start), the payload, and the end of data (end)
* This function is the start, where the register address and number of words are transmitted
*
* @param address A 16-bit address of the destination register
* @param words The number of 4-byte words that will be transferred. 0 = 256 words
*/
void
AHB_WRITE_BURST_START(uint16_t address, uint8_t words)
{
//set the CS low to start the transaction
Spi_ManualCsOn_8Bit(SpiObjectConfigId_TCAN4550);
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, AHB_WRITE_OPCODE);
// Send the 16-bit address
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((address >> 8) & 0x00FF));
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((address >> 0) & 0x00FF));
// Send the number of words to read
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((uint16_t)words & 0x00FF));
}
/*
* @brief Burst write
*
* The SPI transaction contains 3 parts: the header (start), the payload, and the end of data (end)
* This function writes a single word at a time
*
* @param data A 32-bit word of data to write to the destination register
*/
void
AHB_WRITE_BURST_WRITE(uint32_t data)
{
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((data >> 24) & 0x000000FF));
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((data >> 16) & 0x000000FF));
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((data >> 8) & 0x000000FF));
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((data >> 0) & 0x000000FF));
}
/*
* @brief Burst write end
*
* The SPI transaction contains 3 parts: the header (start), the payload, and the end of data (end)
* This function ends the burst transaction by pulling nCS high
*/
void
AHB_WRITE_BURST_END(void)
{
Spi_ManualCsOff_8Bit(SpiObjectConfigId_TCAN4550);
}
/*
* @brief Burst read start
*
* The SPI transaction contains 3 parts: the header (start), the payload, and the end of data (end)
* This function is the start, where the register address and number of words are transmitted
*
* @param address A 16-bit start address to begin the burst read
* @param words The number of 4-byte words that will be transferred. 0 = 256 words
*/
void
AHB_READ_BURST_START(uint16_t address, uint8_t words)
{
// Set the CS low to start the transaction
Spi_ManualCsOn_8Bit(SpiObjectConfigId_TCAN4550);
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, AHB_READ_OPCODE);
// Send the 16-bit address
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((address >> 8) & 0x00FF));
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((address >> 0) & 0x00FF));
// Send the number of words to read
Spi_TransmitData_8Bit(SpiObjectConfigId_TCAN4550, (uint8_t)((uint16_t)words & 0x00FF));
}
/*
* @brief Burst read start
*
* The SPI transaction contains 3 parts: the header (start), the payload, and the end of data (end)
* This function where each word of data is read from the TCAN4x5x
*
* @return A 32-bit single data word that is read at a time
*/
uint32_t
AHB_READ_BURST_READ(void)
{
uint16_t readData;
uint8_t readData0;
uint8_t readData1;
uint8_t readData2;
uint8_t readData3;
uint32_t returnData;
Spi_ReceiveData_8Bit (SpiObjectConfigId_TCAN4550, 0x00, &readData);
readData0 = (uint8_t)readData;
Spi_ReceiveData_8Bit (SpiObjectConfigId_TCAN4550, 0x00, &readData);
readData1 = (uint8_t)readData;
Spi_ReceiveData_8Bit (SpiObjectConfigId_TCAN4550, 0x00, &readData);
readData2 = (uint8_t)readData;
Spi_ReceiveData_8Bit (SpiObjectConfigId_TCAN4550, 0x00, &readData);
readData3 = (uint8_t)readData;
returnData = (((uint32_t)readData0) << 24) | (((uint32_t)readData1 << 16)) | (((uint32_t)readData2) << 8) | readData3;
return returnData;
}
/*
* @brief Burst write end
*
* The SPI transaction contains 3 parts: the header (start), the payload, and the end of data (end)
* This function ends the burst transaction by pulling nCS high
*/
void
AHB_READ_BURST_END(void)
{
Spi_ManualCsOff_8Bit(SpiObjectConfigId_TCAN4550);
}
#2. Test code
//execute every 10ms
void TCAN4550_Test (void)
{
TCAN4550_AllReg.ModeOperationReg.word = AHB_READ_32(REG_DEV_MODES_AND_PINS); /* 0x0800 */
}
#3. Dev setting
devConfig.word = 0;
devConfig.SWE_DIS = 0; // Keep Sleep Wake Error Enabled (it's a disable bit, not an enable)
devConfig.DEVICE_RESET = 0; // Not requesting a software reset
devConfig.WD_EN = 0; // Watchdog disabled
devConfig.nWKRQ_CONFIG = 1; // Mirror INH function (default)
devConfig.INH_DIS = 1; // INH enabled (default)
devConfig.GPIO1_GPO_CONFIG = TCAN4x5x_DEV_CONFIG_GPO1_MCAN_INT1; // MCAN nINT 1 (default)
devConfig.FAIL_SAFE_EN = 0; // Failsafe disabled (default)
devConfig.GPIO1_CONFIG = TCAN4x5x_DEV_CONFIG_GPIO1_CONFIG_GPO; // GPIO set as GPO (Default)
devConfig.WD_ACTION = TCAN4x5x_DEV_CONFIG_WDT_ACTION_nINT; // Watchdog set an interrupt (default)
devConfig.WD_BIT_RESET = 0; // Don't reset the watchdog
devConfig.nWKRQ_VOLTAGE = 0; // Set nWKRQ to internal voltage rail (default)
devConfig.GPO2_CONFIG = TCAN4x5x_DEV_CONFIG_GPO2_NO_ACTION; // GPO2 has no behavior (default)
devConfig.CLK_REF = 1; // Input crystal is a 40 MHz crystal (default)
devConfig.WAKE_CONFIG = TCAN4x5x_DEV_CONFIG_WAKE_BOTH_EDGES;// Wake pin can be triggered by either edge (default)