This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320F28377D: The USBCAN analyzer cannot receive sent data

Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE, CCSTUDIO

Tool/software: Code Composer Studio

In the development board (containing the CAN transceiver and 120 Ω resistance) are connected to the usbcan analyzer using CANA, program is sending data 100 times, modified from the can_external_transmit, analyzer cannot show the received data .I measured the GPIO71 with a multimeter showing 3.27V whether the program was running or not, and the CANH and CANL of the transceiver were always 0V.

By the way,the can_loopback program works fine. 

 

CODE:

#include "F28x_Project.h" // Device Headerfile and Examples Include File
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_can.h"
#include "driverlib/can.h"

//
// Defines
//
#define TXCOUNT 100
#define MSG_DATA_LENGTH 8
#define TX_MSG_OBJ_ID 15
#define RX_MSG_OBJ_ID 1

//
// Globals
//
volatile unsigned long i;
volatile uint32_t txMsgCount = 0;
volatile uint32_t rxMsgCount = 0;
volatile uint32_t errorFlag = 0;
unsigned char txMsgData[4];
unsigned char rxMsgData[4];
tCANMsgObject sTXCANMessage;
tCANMsgObject sRXCANMessage;

//
// Function Prototypes
//
__interrupt void canaISR(void);

//
// Main
//
void main(void)
{
//
// Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
//
InitSysCtrl();

//
// Initialize GPIO and configure GPIO pins for CANTX/CANRX
// on module A and B
//
InitGpio();

//
// Setup GPIO pin mux for CAN-A TX/RX and CAN-B TX/RX
//
GPIO_SetupPinMux(70, GPIO_MUX_CPU1, 5); //GPIO30 - CANRXA
GPIO_SetupPinOptions(70, GPIO_INPUT, GPIO_ASYNC);
GPIO_SetupPinMux(71, GPIO_MUX_CPU1, 5); //GPIO31 - CANTXA
GPIO_SetupPinOptions(71, GPIO_OUTPUT, GPIO_PUSHPULL);

// Initialize the CAN controllers
//
CANInit(CANA_BASE);
//CANInit(CANB_BASE);

//
// Setup CAN to be clocked off the PLL output clock
//
CANClkSourceSelect(CANA_BASE, 0); // 500kHz CAN-Clock
//CANClkSourceSelect(CANB_BASE, 0); // 500kHz CAN-Clock

//
// Set up the CAN bus bit rate to 500kHz for each module
// This function sets up the CAN bus timing for a nominal configuration.
// You can achieve more control over the CAN bus timing by using the
// function CANBitTimingSet() instead of this one, if needed.
// Additionally, consult the device data sheet for more information about
// the CAN module clocking.
//
CANBitRateSet(CANA_BASE, 200000000, 250000);
//CANBitRateSet(CANB_BASE, 200000000, 500000);

//
// Enable interrupts on the CAN B peripheral.
//
CANIntEnable(CANA_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

//
// Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
//
DINT;

//
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
//
InitPieCtrl();

//
// Disable CPU interrupts and clear all CPU interrupt flags
//
IER = 0x0000;
IFR = 0x0000;

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
//
InitPieVectTable();

//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
// This registers the interrupt handler in PIE vector table.
//
EALLOW;
PieVectTable.CANA0_INT = canaISR;
EDIS;

//
// Enable the CAN-B interrupt on the processor (PIE).
//
PieCtrlRegs.PIEIER9.bit.INTx5 = 1;
IER |= M_INT9;
EINT;

//
// Enable the CAN-B interrupt signal
//
CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0);

//
// Initialize the transmit message object used for sending CAN messages.
// Message Object Parameters:
// Message Identifier: 0x5555
// Message ID Mask: 0x0
// Message Object Flags: None
// Message Data Length: 4 Bytes
// Message Transmit data: txMsgData
//
sTXCANMessage.ui32MsgID = 0x5555;
sTXCANMessage.ui32MsgIDMask = 0;
sTXCANMessage.ui32Flags = 0;
sTXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
sTXCANMessage.pucMsgData = txMsgData;

//
// Initialize the receive message object used for receiving CAN messages.
// Message Object Parameters:
// Message Identifier: 0x5555
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 4 Bytes
// Message Receive data: rxMsgData
//
sRXCANMessage.ui32MsgID = 0x0;
sRXCANMessage.ui32MsgIDMask = 0;
sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE;
sRXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
sRXCANMessage.pucMsgData = rxMsgData;
CANMessageSet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage,MSG_OBJ_TYPE_RX);

//
// Initialize the transmit message object data buffer to be sent
//
txMsgData[0] = 0x12;
txMsgData[1] = 0x34;
txMsgData[2] = 0x56;
txMsgData[3] = 0x78;

//
// Start CAN module A and B operations
//
CANEnable(CANA_BASE);
//CANEnable(CANB_BASE);

//
// Transmit messages from CAN-A to CAN-B
//
while(1)
{
//
// Check the error flag to see if errors occurred
//
if(errorFlag)
{
//asm(" ESTOP0");
}

//
// Verify that the number of transmitted messages equal the number of
// messages received before sending a new message
//
//
// Transmit Message
//
CANMessageSet(CANA_BASE, TX_MSG_OBJ_ID, &sTXCANMessage, MSG_OBJ_TYPE_TX);

//txMsgCount++;


//
// Delay 0.25 second before continuing
//
DELAY_US(1000 * 250);

//
// Increment the value in the transmitted message data.
//
txMsgData[0] += 0x01;
txMsgData[1] += 0x01;
txMsgData[2] += 0x01;
txMsgData[3] += 0x01;

//
// Reset data if exceeds a byte
//
if(txMsgData[0] > 0xFF)
{
txMsgData[0] = 0;
}
if(txMsgData[1] > 0xFF)
{
txMsgData[1] = 0;
}
if(txMsgData[2] > 0xFF)
{
txMsgData[2] = 0;
}
if(txMsgData[3] > 0xFF)
{
txMsgData[3] = 0;
}
}

//
// Stop application
//
asm(" ESTOP0");
}

//
// CAN B ISR - The interrupt service routine called when a CAN interrupt is
// triggered on CAN module B.
//
__interrupt void canaISR(void)
{
uint32_t status;

//
// Read the CAN-B interrupt status to find the cause of the interrupt
//
status = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE);

//
// If the cause is a controller status interrupt, then get the status
//
if(status == CAN_INT_INT0ID_STATUS)
{
//
// Read the controller status. This will return a field of status
// error bits that can indicate various errors. Error processing
// is not done in this example for simplicity. Refer to the
// API documentation for details about the error status bits.
// The act of reading this status will clear the interrupt.
//
status = CANStatusGet(CANA_BASE, CAN_STS_CONTROL);

//
// Check to see if an error occurred.
//
if(((status & ~(CAN_ES_RXOK)) != 7) &&
((status & ~(CAN_ES_RXOK)) != 0))
{
//
// Set a flag to indicate some errors may have occurred.
//
errorFlag = 1;
}else
{
CANMessageGet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage, true);

//
// Getting to this point means that the RX interrupt occurred on
// message object 1, and the message RX is complete. Clear the
// message object interrupt.
//
CANIntClear(CANA_BASE, RX_MSG_OBJ_ID);
}
}
//
// Check if the cause is the CAN-B receive message object 1
//
else if(status == RX_MSG_OBJ_ID)
{
//
// Get the received message
//
CANMessageGet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage, true);

//
// Getting to this point means that the RX interrupt occurred on
// message object 1, and the message RX is complete. Clear the
// message object interrupt.
//
CANIntClear(CANA_BASE, RX_MSG_OBJ_ID);

//
// Increment a counter to keep track of how many messages have been
// received. In a real application this could be used to set flags to
// indicate when a message is received.
//
rxMsgCount++;

//
// Since the message was received, clear any error flags.
//
errorFlag = 0;
}
//
// If something unexpected caused the interrupt, this would handle it.
//
else
{
//
// Spurious interrupt handling can go here.
//
}

//
// Clear the global interrupt flag for the CAN interrupt line
//
CANGlobalIntClear(CANA_BASE, CAN_GLB_INT_CANINT0);

//
// Acknowledge this interrupt located in group 9
//
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}

//
// End of File
//

 

  • Hello,

                  Code debug is not something we can support on the e2e forum. However, I can offer the following suggestions: 

    Please download my Application report http://www.ti.com/lit/sprace5. It has many tested examples. I also urge you to look at the Debug tips provided. 

    Make sure you have the most recent version of C2000Ware (3_02_00_00) and CCS (CCSTUDIO_10.1.0.00010) 

    What development board are you using? Is it a board sold by TI or is it your own design? 

    If you run the C2000ware example "as is" (that is, without any changes), do you see any data on the CAN analyzer software on the PC? 

    I measured the GPIO71 with a multimeter showing 3.27V whether the program was running or not,

    A multimeter is not a reliable instrument to check for CAN traffic. You need an oscilloscope. 

    and the CANH and CANL of the transceiver were always 0V.

    Even when there is no activity on the bus, CANH & CANL levels should never be zero. Can you share the design of your board (just the connection from MCU to the transceiver)? 

    If you want to insert a small piece of code in your post (not the entire program), please do so using the code formatting tool. This would make the code easier to read . See attached image.


  • Hello,

      Any update on this issue?

    Did you ensure the below matches the actual CAN pins used in your hardware?

    //
    // Setup GPIO pin mux for CAN-A TX/RX and CAN-B TX/RX
    //
    GPIO_SetupPinMux(70, GPIO_MUX_CPU1, 5); //GPIO30 - CANRXA
    GPIO_SetupPinOptions(70, GPIO_INPUT, GPIO_ASYNC);
    GPIO_SetupPinMux(71, GPIO_MUX_CPU1, 5); //GPIO31 - CANTXA
    GPIO_SetupPinOptions(71, GPIO_OUTPUT, GPIO_PUSHPULL);

    Did you ensure bit rate on the USB CAN analyzer was set to match the MCU?