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.

EK-TM4C1294XL: Issue with CAN bus transmitter code

Part Number: EK-TM4C1294XL

I am trying to dubug the following code for CAN Tx side. I have connected the EK-TM4C1294XL board to PC using USB and using putty to view the results though the UART.

The code I am running is the following:

//*****************************************************************************

#include <stdbool.h>

#include <stdint.h>

#include "inc/hw_can.h"

#include "inc/hw_ints.h"

#include "inc/hw_memmap.h"

#include "driverlib/can.h"

#include "driverlib/gpio.h"

#include "driverlib/interrupt.h"

#include "driverlib/pin_map.h"

#include "driverlib/sysctl.h"

#include "driverlib/uart.h"

#include "utils/uartstdio.h"

#include "utils/uartstdio.c"

//*****************************************************************************

//

//! \addtogroup can_examples_list

//! <h1>Multiple CAN TX (multi_tx)</h1>

//!

//! This example shows how to set up the CAN to send multiple messages.  The

//! CAN peripheral is configured to send messages with 4 different CAN IDs.

//! Two of the messages (with different CAN IDs) are sent using a shared

//! message object.  This shows how to reuse a message object for multiple

//! messages.  The other two messages are sent using their own message objects.

//! All four messages are transmitted once per second.  The content of each

//! message is a test pattern.  A CAN interrupt handler is used to confirm

//! message transmission and count the number of messages that have been sent.

//!

//! This example uses the following peripherals and I/O signals.  You must

//! review these and change as needed for your own board:

//! - CAN1 peripheral

//! - GPIO Port B peripheral (for CAN1 pins)

//! - CAN1RX - PB0

//! - CAN1TX - PB1

//!

//! The following UART signals are configured only for displaying console

//! messages for this example.  These are not required for operation of CAN.

//! - GPIO port A peripheral (for UART0 pins)

//! - UART0RX - PA0

//! - UART0TX - PA1

//!

//! This example uses the following interrupt handlers.  To use this example

//! in your own application you must add these interrupt handlers to your

//! vector table.

//! - INT_CAN1 - CANIntHandler

//

//*****************************************************************************

//*****************************************************************************

//

// A counter that keeps track of the number of times the TX interrupt has

// occurred, which should match the number of TX messages that were sent.

//

//*****************************************************************************

volatile uint32_t g_ui32IntCount = 0;

//*****************************************************************************

//

// Counters that are used to count the number of messages on each of the

// three message objects that are used in this example.

//

//*****************************************************************************

volatile uint32_t g_ui32Msg1Count = 0;

volatile uint32_t g_ui32Msg2Count = 0;

volatile uint32_t g_ui32Msg3Count = 0;

//*****************************************************************************

//

// A flag to indicate that CAN controller message object 3 has sent a message.

//

//*****************************************************************************

volatile bool g_bMsgObj3Sent = 0;

//*****************************************************************************

//

// A flag to indicate that some transmission error occurred.

//

//*****************************************************************************

volatile bool g_bErrFlag = 0;

//*****************************************************************************

//

// CAN message objects that will hold the separate CAN messages.  These could

// also be allocated on the stack but be careful because these structures

// each take about 20 bytes.

//

//*****************************************************************************

tCANMsgObject g_sCANMsgObject1;

tCANMsgObject g_sCANMsgObject2;

tCANMsgObject g_sCANMsgObject3;

//*****************************************************************************

//

// Message buffers that hold the contents of the 4 different messages that

// are being transmitted.  Each one is a different length.

//

//*****************************************************************************

uint8_t g_pui8Msg1[4] = { 1, 3, 5, 7 };

uint8_t g_pui8Msg2[5] = { 2, 4, 6, 8, 10 };

uint8_t g_pui8Msg3[6] = { 3, 6, 9, 12, 15, 18 };

uint8_t g_pui8Msg4[8] = { 4, 8, 12, 16, 20, 24, 28, 32 };

//*****************************************************************************

//

// This function sets up UART0 to be used for a console to display information

// as the example is running.

//

//*****************************************************************************

void

InitConsole(void)

{

    //

    // Enable GPIO port A which is used for UART0 pins.

    // TODO: change this to whichever GPIO port you are using.

    //

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //

    // Configure the pin muxing for UART0 functions on port A0 and A1.

    // This step is not necessary if your part does not support pin muxing.

    // TODO: change this to select the port/pin you are using.

    //

    GPIOPinConfigure(GPIO_PA0_U0RX);

    GPIOPinConfigure(GPIO_PA1_U0TX);

    //

    // Enable UART0 so that we can configure the clock.

    //

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    //

    // Use the internal 16MHz oscillator as the UART clock source.

    //

    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    //

    // Select the alternate (UART) function for these pins.

    // TODO: change this to select the port/pin you are using.

    //

    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //

    // Initialize the UART for console I/O.

    //

    UARTStdioConfig(0, 115200, 16000000);

}

//*****************************************************************************

//

// This function prints some information about the CAN message to the

// serial port for information purposes only.

//

//*****************************************************************************

void

PrintCANMessageInfo(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj)

{

    unsigned int uIdx;

    UARTprintf("Sending msg: obj=%d ID=0x%04X msg=0x", ui32MsgObj,

               psCANMsg->ui32MsgID);

    for(uIdx = 0; uIdx < psCANMsg->ui32MsgLen; uIdx++)

    {

        UARTprintf("%02X ", psCANMsg->pui8MsgData[uIdx]);

    }

    UARTprintf("\n");

}

//*****************************************************************************

//

// This function provides a 1 second delay using a simple polling method.

//

//*****************************************************************************

void

SimpleDelay(void)

{

    //

    // Delay cycles for 1 second

    //

    SysCtlDelay(16000000 / 3);

}

//*****************************************************************************

//

// This function is the interrupt handler for the CAN peripheral.  It checks

// for the cause of the interrupt, and maintains a count of all messages that

// have been transmitted.

//

//*****************************************************************************

void

CANIntHandler(void)

{

    uint32_t ui32Status;

    //

    // Read the CAN interrupt status to find the cause of the interrupt

    //

    ui32Status = CANIntStatus(CAN1_BASE, CAN_INT_STS_CAUSE);

    //

    // If the cause is a controller status interrupt, then get the status

    //

    if(ui32Status == CAN_INT_INTID_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.  If the

        // CAN peripheral is not connected to a CAN bus with other CAN devices

        // present, then errors will occur and will be indicated in the

        // controller status.

        //

        ui32Status = CANStatusGet(CAN1_BASE, CAN_STS_CONTROL);

        //

        // Set a flag to indicate some errors may have occurred.

        //

        g_bErrFlag = 1;

    }

    //

    // Check if the cause is message object 1, which is used for sending

    // message 1.

    //

    else if(ui32Status == 1)

    {

        //

        // Getting to this point means that the TX interrupt occurred on

        // message object 1, and the message TX is complete.  Clear the

        // message object interrupt.

        //

        CANIntClear(CAN1_BASE, 1);

        //

        // Increment a counter to keep track of how many messages have been

        // sent.  In a real application this could be used to set flags to

        // indicate when a message is sent.

        //

        g_ui32Msg1Count++;

        //

        // Since the message was sent, clear any error flags.

        //

        g_bErrFlag = 0;

    }

    //

    // Check if the cause is message object 2, which is used for sending

    // message 2.

    //

    else if(ui32Status == 2)

    {

        //

        // Getting to this point means that the TX interrupt occurred on

        // message object 2, and the message TX is complete.  Clear the

        // message object interrupt.

        //

        CANIntClear(CAN1_BASE, 2);

        //

        // Increment a counter to keep track of how many messages have been

        // sent.  In a real application this could be used to set flags to

        // indicate when a message is sent.

        //

        g_ui32Msg2Count++;

        //

        // Since the message was sent, clear any error flags.

        //

        g_bErrFlag = 0;

    }

    //

    // Check if the cause is message object 3, which is used for sending

    // messages 3 and 4.

    //

    else if(ui32Status == 3)

    {

        //

        // Getting to this point means that the TX interrupt occurred on

        // message object 3, and a message TX is complete.  Clear the

        // message object interrupt.

        //

        CANIntClear(CAN1_BASE, 3);

        //

        // Increment a counter to keep track of how many messages have been

        // sent.  In a real application this could be used to set flags to

        // indicate when a message is sent.

        //

        g_ui32Msg3Count++;

        //

        // Set the flag indicating that a message was sent using message

        // object 3.  The program main loop uses this to know when to send

        // another message using message object 3.

        //

        g_bMsgObj3Sent = 1;

        //

        // Since the message was sent, clear any error flags.

        //

        g_bErrFlag = 0;

    }

    //

    // Otherwise, something unexpected caused the interrupt.  This should

    // never happen.

    //

    else

    {

        //

        // Spurious interrupt handling can go here.

        //

    }

}

//*****************************************************************************

//

// Configure the CAN and enter a loop to transmit periodic CAN messages.

//

//*****************************************************************************

int

main(void)

{

    uint32_t ui32SysClock;

    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_16MHZ |

                                                 SYSCTL_OSC_INT |

                                                 SYSCTL_USE_PLL |

                                                 SYSCTL_CFG_VCO_480), 120000000);

    //

    // Set up the serial console to use for displaying messages.  This is

    // just for this example program and is not needed for CAN operation.

    //

    InitConsole();

    //

    // For this example CAN1 is used with RX and TX pins on port B4 and B5.

    // The actual port and pins used may be different on your part, consult

    // the data sheet for more information.

    // GPIO port B needs to be enabled so these pins can be used.

    // TODO: change this to whichever GPIO port you are using

    //

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //

    // Configure the GPIO pin muxing to select CAN1 functions for these pins.

    // This step selects which alternate function is available for these pins.

    // This is necessary if your part supports GPIO pin function muxing.

    // Consult the data sheet to see which functions are allocated per pin.

    // TODO: change this to select the port/pin you are using

    //

    GPIOPinConfigure(GPIO_PB0_CAN1RX);

    GPIOPinConfigure(GPIO_PB1_CAN1TX);

    //

    // Enable the alternate function on the GPIO pins.  The above step selects

    // which alternate function is available.  This step actually enables the

    // alternate function instead of GPIO for these pins.

    // TODO: change this to match the port/pin you are using

    //

    GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //

    // The GPIO port and pins have been set up for CAN.  The CAN peripheral

    // must be enabled.

    //

    SysCtlPeripheralDisable(SYSCTL_PERIPH_CAN1);

    SysCtlPeripheralReset(SYSCTL_PERIPH_CAN1);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN1);

    //

    // Initialize the CAN controller

    //

    CANInit(CAN1_BASE);

    //

    // Set up the bit rate for the CAN bus.  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.

    // In this example, the CAN bus is set to 500 kHz.  In the function below,

    // the call to SysCtlClockGet() is used to determine the clock rate that

    // is used for clocking the CAN peripheral.  This can be replaced with a

    // fixed value if you know the value of the system clock, saving the extra

    // function call.  For some parts, the CAN peripheral is clocked by a fixed

    // 8 MHz regardless of the system clock in which case the call to

    // SysCtlClockGet() should be replaced with 8000000.  Consult the data

    // sheet for more information about CAN peripheral clocking.

    //

    CANBitRateSet(CAN1_BASE, ui32SysClock, 500000);

    //

    // Enable interrupts on the CAN peripheral.  This example uses static

    // allocation of interrupt handlers which means the name of the handler

    // is in the vector table of startup code.  If you want to use dynamic

    // allocation of the vector table, then you must also call CANIntRegister()

    // here.

    //

    CANIntRegister(CAN1_BASE, CANIntHandler); // if using dynamic vectors

    //

    CANIntEnable(CAN1_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

    //

    // Enable the CAN interrupt on the processor (NVIC).

    //

    IntEnable(INT_CAN1);

    //

    // Enable the CAN for operation.

    //

    CANEnable(CAN1_BASE);

    //

    // Initialize the message object that will be used for sending CAN

    // messages.  The message will be 4 bytes that will contain an incrementing

    // value.  Initially it will be set to 0.

    //

    //

    // Initialize message object 1 to be able to send CAN message 1.  This

    // message object is not shared so it only needs to be initialized one

    // time, and can be used for repeatedly sending the same message ID.

    //

    g_sCANMsgObject1.ui32MsgID = 0x1001;

    g_sCANMsgObject1.ui32MsgIDMask = 0;

    g_sCANMsgObject1.ui32Flags = MSG_OBJ_TX_INT_ENABLE;

    g_sCANMsgObject1.ui32MsgLen = sizeof(g_pui8Msg1);

    g_sCANMsgObject1.pui8MsgData = g_pui8Msg1;

    //

    // Initialize message object 2 to be able to send CAN message 2.  This

    // message object is not shared so it only needs to be initialized one

    // time, and can be used for repeatedly sending the same message ID.

    //

    g_sCANMsgObject2.ui32MsgID = 0x2001;

    g_sCANMsgObject2.ui32MsgIDMask = 0;

    g_sCANMsgObject2.ui32Flags = MSG_OBJ_TX_INT_ENABLE;

    g_sCANMsgObject2.ui32MsgLen = sizeof(g_pui8Msg2);

    g_sCANMsgObject2.pui8MsgData = g_pui8Msg2;

    //

    // Enter loop to send messages.  Four messages will be sent once per

    // second.  The contents of each message will be changed each time.

    //

    for(;;)

    {

        //

        // Send message 1 using CAN controller message object 1.  This is

        // the only message sent using this message object.  The

        // CANMessageSet() function will cause the message to be sent right

        // away.

        //

        PrintCANMessageInfo(&g_sCANMsgObject1, 1);

        CANMessageSet(CAN1_BASE, 1, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);

        UARTprintf("%d\n",g_ui32Msg1Count);

        //

        // Send message 2 using CAN controller message object 2.  This is

        // the only message sent using this message object.  The

        // CANMessageSet() function will cause the message to be sent right

        // away.

        //

        PrintCANMessageInfo(&g_sCANMsgObject2, 2);

        CANMessageSet(CAN1_BASE, 2, &g_sCANMsgObject2, MSG_OBJ_TYPE_TX);

        UARTprintf("%d\n",g_ui32Msg2Count);

        //

        // Load message object 3 with message 3.  This is needs to be done each

        // time because message object 3 is being shared for two different

        // messages.

        //

        g_sCANMsgObject3.ui32MsgID = 0x3001;

        g_sCANMsgObject3.ui32MsgIDMask = 0;

        g_sCANMsgObject3.ui32Flags = MSG_OBJ_TX_INT_ENABLE;

        g_sCANMsgObject3.ui32MsgLen = sizeof(g_pui8Msg3);

        g_sCANMsgObject3.pui8MsgData = g_pui8Msg3;

        //

        // Clear the flag that indicates that message 3 has been sent.  This

        // flag will be set in the interrupt handler when a message has been

        // sent using message object 3.

        //

        g_bMsgObj3Sent = 0;

        //

        // Now send message 3 using CAN controller message object 3.  This is

        // the first message sent using this message object.  The

        // CANMessageSet() function will cause the message to be sent right

        // away.

        //

        PrintCANMessageInfo(&g_sCANMsgObject3, 3);

        CANMessageSet(CAN1_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);

        //

        // Wait for the indication from the interrupt handler that message

        // object 3 is done, because we are re-using it for another message.

        //

        while(!g_bMsgObj3Sent)

        {

        }

        UARTprintf("%d\n",g_ui32Msg3Count); 

        //

        // Load message object 3 with message 4.  This is needed because

        // message object 3 is being shared for two different messages.

        //

        g_sCANMsgObject3.ui32MsgID = 0x3002;

        g_sCANMsgObject3.ui32MsgIDMask = 0;

        g_sCANMsgObject3.ui32Flags = MSG_OBJ_TX_INT_ENABLE;

        g_sCANMsgObject3.ui32MsgLen = sizeof(g_pui8Msg4);

        g_sCANMsgObject3.pui8MsgData = g_pui8Msg4;

        //

        // Now send message 4 using CAN controller message object 3.  This is

        // the second message sent using this message object.  The

        // CANMessageSet() function will cause the message to be sent right

        // away.

        //

        PrintCANMessageInfo(&g_sCANMsgObject3, 3);

        CANMessageSet(CAN1_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);

    }

    //

    // Return no errors

    //

    //return(0);

}

The result of the above code is: 

Please note the lines in red coloured font in the code.

The above in putty is received when the UARTprintf("%d\n",g_ui32Msg3Count); is included after while(!g_bMsgObj3Sent) {  } 

But if I include the UARTprintf("%d\n",g_ui32Msg3Count) before while(!g_bMsgObj3Sent) {  }  I am getting the below shown result in putty: 

So the program execution seems to be stuck in the while loop: while(!g_bMsgObj3Sent) {  }

The program is designed to reuse the message object to send multiple data.

Is there any remedy ?

//*****************************************************************************//// multi_tx.c - Peripheral example demonstrating multiple CAN message//              transmission.//// Copyright (c) 2010-2014 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.//// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.////*****************************************************************************
#include <stdbool.h>#include <stdint.h>#include "inc/hw_can.h"#include "inc/hw_ints.h"#include "inc/hw_memmap.h"#include "driverlib/can.h"#include "driverlib/gpio.h"#include "driverlib/interrupt.h"#include "driverlib/pin_map.h"#include "driverlib/sysctl.h"#include "driverlib/uart.h"#include "utils/uartstdio.h"#include "utils/uartstdio.c"
//*****************************************************************************////! \addtogroup can_examples_list//! <h1>Multiple CAN TX (multi_tx)</h1>//!//! This example shows how to set up the CAN to send multiple messages.  The//! CAN peripheral is configured to send messages with 4 different CAN IDs.//! Two of the messages (with different CAN IDs) are sent using a shared//! message object.  This shows how to reuse a message object for multiple//! messages.  The other two messages are sent using their own message objects.//! All four messages are transmitted once per second.  The content of each//! message is a test pattern.  A CAN interrupt handler is used to confirm//! message transmission and count the number of messages that have been sent.//!//! This example uses the following peripherals and I/O signals.  You must//! review these and change as needed for your own board://! - CAN1 peripheral//! - GPIO Port B peripheral (for CAN1 pins)//! - CAN1RX - PB0//! - CAN1TX - PB1//!//! The following UART signals are configured only for displaying console//! messages for this example.  These are not required for operation of CAN.//! - GPIO port A peripheral (for UART0 pins)//! - UART0RX - PA0//! - UART0TX - PA1//!//! This example uses the following interrupt handlers.  To use this example//! in your own application you must add these interrupt handlers to your//! vector table.//! - INT_CAN1 - CANIntHandler////*****************************************************************************
//*****************************************************************************//// A counter that keeps track of the number of times the TX interrupt has// occurred, which should match the number of TX messages that were sent.////*****************************************************************************volatile uint32_t g_ui32IntCount = 0;
//*****************************************************************************//// Counters that are used to count the number of messages on each of the// three message objects that are used in this example.////*****************************************************************************volatile uint32_t g_ui32Msg1Count = 0;volatile uint32_t g_ui32Msg2Count = 0;volatile uint32_t g_ui32Msg3Count = 0;
//*****************************************************************************//// A flag to indicate that CAN controller message object 3 has sent a message.////*****************************************************************************volatile bool g_bMsgObj3Sent = 0;
//*****************************************************************************//// A flag to indicate that some transmission error occurred.////*****************************************************************************volatile bool g_bErrFlag = 0;
//*****************************************************************************//// CAN message objects that will hold the separate CAN messages.  These could// also be allocated on the stack but be careful because these structures// each take about 20 bytes.////*****************************************************************************tCANMsgObject g_sCANMsgObject1;tCANMsgObject g_sCANMsgObject2;tCANMsgObject g_sCANMsgObject3;
//*****************************************************************************//// Message buffers that hold the contents of the 4 different messages that// are being transmitted.  Each one is a different length.////*****************************************************************************uint8_t g_pui8Msg1[4] = { 1, 3, 5, 7 };uint8_t g_pui8Msg2[5] = { 2, 4, 6, 8, 10 };uint8_t g_pui8Msg3[6] = { 3, 6, 9, 12, 15, 18 };uint8_t g_pui8Msg4[8] = { 4, 8, 12, 16, 20, 24, 28, 32 };
//*****************************************************************************//// This function sets up UART0 to be used for a console to display information// as the example is running.////*****************************************************************************voidInitConsole(void){    //    // Enable GPIO port A which is used for UART0 pins.    // TODO: change this to whichever GPIO port you are using.    //    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    //    // Configure the pin muxing for UART0 functions on port A0 and A1.    // This step is not necessary if your part does not support pin muxing.    // TODO: change this to select the port/pin you are using.    //    GPIOPinConfigure(GPIO_PA0_U0RX);    GPIOPinConfigure(GPIO_PA1_U0TX);
    //    // Enable UART0 so that we can configure the clock.    //    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    //    // Use the internal 16MHz oscillator as the UART clock source.    //    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    //    // Select the alternate (UART) function for these pins.    // TODO: change this to select the port/pin you are using.    //    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    //    // Initialize the UART for console I/O.    //    UARTStdioConfig(0, 115200, 16000000);}
//*****************************************************************************//// This function prints some information about the CAN message to the// serial port for information purposes only.////*****************************************************************************voidPrintCANMessageInfo(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj){    unsigned int uIdx;
    UARTprintf("Sending msg: obj=%d ID=0x%04X msg=0x", ui32MsgObj,               psCANMsg->ui32MsgID);    for(uIdx = 0; uIdx < psCANMsg->ui32MsgLen; uIdx++)    {        UARTprintf("%02X ", psCANMsg->pui8MsgData[uIdx]);    }    UARTprintf("\n");}
//*****************************************************************************//// This function provides a 1 second delay using a simple polling method.////*****************************************************************************voidSimpleDelay(void){    //    // Delay cycles for 1 second    //    SysCtlDelay(16000000 / 3);}
//*****************************************************************************//// This function is the interrupt handler for the CAN peripheral.  It checks// for the cause of the interrupt, and maintains a count of all messages that// have been transmitted.////*****************************************************************************voidCANIntHandler(void){    uint32_t ui32Status;
    //    // Read the CAN interrupt status to find the cause of the interrupt    //    ui32Status = CANIntStatus(CAN1_BASE, CAN_INT_STS_CAUSE);
    //    // If the cause is a controller status interrupt, then get the status    //    if(ui32Status == CAN_INT_INTID_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.  If the        // CAN peripheral is not connected to a CAN bus with other CAN devices        // present, then errors will occur and will be indicated in the        // controller status.        //        ui32Status = CANStatusGet(CAN1_BASE, CAN_STS_CONTROL);
        //        // Set a flag to indicate some errors may have occurred.        //        g_bErrFlag = 1;    }
    //    // Check if the cause is message object 1, which is used for sending    // message 1.    //    else if(ui32Status == 1)    {        //        // Getting to this point means that the TX interrupt occurred on        // message object 1, and the message TX is complete.  Clear the        // message object interrupt.        //        CANIntClear(CAN1_BASE, 1);
        //        // Increment a counter to keep track of how many messages have been        // sent.  In a real application this could be used to set flags to        // indicate when a message is sent.        //        g_ui32Msg1Count++;
        //        // Since the message was sent, clear any error flags.        //        g_bErrFlag = 0;    }
    //    // Check if the cause is message object 2, which is used for sending    // message 2.    //    else if(ui32Status == 2)    {        //        // Getting to this point means that the TX interrupt occurred on        // message object 2, and the message TX is complete.  Clear the        // message object interrupt.        //        CANIntClear(CAN1_BASE, 2);
        //        // Increment a counter to keep track of how many messages have been        // sent.  In a real application this could be used to set flags to        // indicate when a message is sent.        //        g_ui32Msg2Count++;
        //        // Since the message was sent, clear any error flags.        //        g_bErrFlag = 0;    }
    //    // Check if the cause is message object 3, which is used for sending    // messages 3 and 4.    //    else if(ui32Status == 3)    {        //        // Getting to this point means that the TX interrupt occurred on        // message object 3, and a message TX is complete.  Clear the        // message object interrupt.        //        CANIntClear(CAN1_BASE, 3);
        //        // Increment a counter to keep track of how many messages have been        // sent.  In a real application this could be used to set flags to        // indicate when a message is sent.        //        g_ui32Msg3Count++;
        //        // Set the flag indicating that a message was sent using message        // object 3.  The program main loop uses this to know when to send        // another message using message object 3.        //        g_bMsgObj3Sent = 1;
        //        // Since the message was sent, clear any error flags.        //        g_bErrFlag = 0;    }
    //    // Otherwise, something unexpected caused the interrupt.  This should    // never happen.    //    else    {        //        // Spurious interrupt handling can go here.        //    }}
//*****************************************************************************//// Configure the CAN and enter a loop to transmit periodic CAN messages.////*****************************************************************************intmain(void){    uint32_t ui32SysClock;
    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_16MHZ |                                                 SYSCTL_OSC_INT |                                                 SYSCTL_USE_PLL |                                                 SYSCTL_CFG_VCO_480), 120000000);    //    // Set up the serial console to use for displaying messages.  This is    // just for this example program and is not needed for CAN operation.    //    InitConsole();
    //    // For this example CAN1 is used with RX and TX pins on port B4 and B5.    // The actual port and pins used may be different on your part, consult    // the data sheet for more information.    // GPIO port B needs to be enabled so these pins can be used.    // TODO: change this to whichever GPIO port you are using    //    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    //    // Configure the GPIO pin muxing to select CAN1 functions for these pins.    // This step selects which alternate function is available for these pins.    // This is necessary if your part supports GPIO pin function muxing.    // Consult the data sheet to see which functions are allocated per pin.    // TODO: change this to select the port/pin you are using    //    GPIOPinConfigure(GPIO_PB0_CAN1RX);    GPIOPinConfigure(GPIO_PB1_CAN1TX);
    //    // Enable the alternate function on the GPIO pins.  The above step selects    // which alternate function is available.  This step actually enables the    // alternate function instead of GPIO for these pins.    // TODO: change this to match the port/pin you are using    //    GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    //    // The GPIO port and pins have been set up for CAN.  The CAN peripheral    // must be enabled.    //    SysCtlPeripheralDisable(SYSCTL_PERIPH_CAN1);    SysCtlPeripheralReset(SYSCTL_PERIPH_CAN1);    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN1);
    //    // Initialize the CAN controller    //    CANInit(CAN1_BASE);
    //    // Set up the bit rate for the CAN bus.  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.    // In this example, the CAN bus is set to 500 kHz.  In the function below,    // the call to SysCtlClockGet() is used to determine the clock rate that    // is used for clocking the CAN peripheral.  This can be replaced with a    // fixed value if you know the value of the system clock, saving the extra    // function call.  For some parts, the CAN peripheral is clocked by a fixed    // 8 MHz regardless of the system clock in which case the call to    // SysCtlClockGet() should be replaced with 8000000.  Consult the data    // sheet for more information about CAN peripheral clocking.    //    CANBitRateSet(CAN1_BASE, ui32SysClock, 500000);
    //    // Enable interrupts on the CAN peripheral.  This example uses static    // allocation of interrupt handlers which means the name of the handler    // is in the vector table of startup code.  If you want to use dynamic    // allocation of the vector table, then you must also call CANIntRegister()    // here.    //    CANIntRegister(CAN1_BASE, CANIntHandler); // if using dynamic vectors    //    CANIntEnable(CAN1_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
    //    // Enable the CAN interrupt on the processor (NVIC).    //    IntEnable(INT_CAN1);
    //    // Enable the CAN for operation.    //    CANEnable(CAN1_BASE);
    //    // Initialize the message object that will be used for sending CAN    // messages.  The message will be 4 bytes that will contain an incrementing    // value.  Initially it will be set to 0.    //
    //    // Initialize message object 1 to be able to send CAN message 1.  This    // message object is not shared so it only needs to be initialized one    // time, and can be used for repeatedly sending the same message ID.    //    g_sCANMsgObject1.ui32MsgID = 0x1001;    g_sCANMsgObject1.ui32MsgIDMask = 0;    g_sCANMsgObject1.ui32Flags = MSG_OBJ_TX_INT_ENABLE;    g_sCANMsgObject1.ui32MsgLen = sizeof(g_pui8Msg1);    g_sCANMsgObject1.pui8MsgData = g_pui8Msg1;


    //    // Initialize message object 2 to be able to send CAN message 2.  This    // message object is not shared so it only needs to be initialized one    // time, and can be used for repeatedly sending the same message ID.    //    g_sCANMsgObject2.ui32MsgID = 0x2001;    g_sCANMsgObject2.ui32MsgIDMask = 0;    g_sCANMsgObject2.ui32Flags = MSG_OBJ_TX_INT_ENABLE;    g_sCANMsgObject2.ui32MsgLen = sizeof(g_pui8Msg2);    g_sCANMsgObject2.pui8MsgData = g_pui8Msg2;
    //    // Enter loop to send messages.  Four messages will be sent once per    // second.  The contents of each message will be changed each time.    //    for(;;)    {        //        // Send message 1 using CAN controller message object 1.  This is        // the only message sent using this message object.  The        // CANMessageSet() function will cause the message to be sent right        // away.        //        PrintCANMessageInfo(&g_sCANMsgObject1, 1);        CANMessageSet(CAN1_BASE, 1, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);
        //        // Send message 2 using CAN controller message object 2.  This is        // the only message sent using this message object.  The        // CANMessageSet() function will cause the message to be sent right        // away.        //        PrintCANMessageInfo(&g_sCANMsgObject2, 2);        CANMessageSet(CAN1_BASE, 2, &g_sCANMsgObject2, MSG_OBJ_TYPE_TX);
        //        // Load message object 3 with message 3.  This is needs to be done each        // time because message object 3 is being shared for two different        // messages.        //        g_sCANMsgObject3.ui32MsgID = 0x3001;        g_sCANMsgObject3.ui32MsgIDMask = 0;        g_sCANMsgObject3.ui32Flags = MSG_OBJ_TX_INT_ENABLE;        g_sCANMsgObject3.ui32MsgLen = sizeof(g_pui8Msg3);        g_sCANMsgObject3.pui8MsgData = g_pui8Msg3;
        //        // Clear the flag that indicates that message 3 has been sent.  This        // flag will be set in the interrupt handler when a message has been        // sent using message object 3.        //        g_bMsgObj3Sent = 0;
        //        // Now send message 3 using CAN controller message object 3.  This is        // the first message sent using this message object.  The        // CANMessageSet() function will cause the message to be sent right        // away.        //        PrintCANMessageInfo(&g_sCANMsgObject3, 3);        CANMessageSet(CAN1_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);
        //        // Wait for the indication from the interrupt handler that message        // object 3 is done, because we are re-using it for another message.        //        while(!g_bMsgObj3Sent)        {        }
        //        // Load message object 3 with message 4.  This is needed because        // message object 3 is being shared for two different messages.        //        g_sCANMsgObject3.ui32MsgID = 0x3002;        g_sCANMsgObject3.ui32MsgIDMask = 0;        g_sCANMsgObject3.ui32Flags = MSG_OBJ_TX_INT_ENABLE;        g_sCANMsgObject3.ui32MsgLen = sizeof(g_pui8Msg4);        g_sCANMsgObject3.pui8MsgData = g_pui8Msg4;
        //        // Now send message 4 using CAN controller message object 3.  This is        // the second message sent using this message object.  The        // CANMessageSet() function will cause the message to be sent right        // away.        //
        PrintCANMessageInfo(&g_sCANMsgObject3, 3);        CANMessageSet(CAN1_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);



    }


    //    // Return no errors    //    //return(0);}

  • Dear Sir,

    Please edit your original post to make it more clear and avoid the risk of being ignored. It is almost impossible to even find a question in it.

    - Cut the code, past it using the </> button of the formatting bar.

    - Erase the hundreds of continuous code lines after the graphics

    - Maybe consider posting only the relevant part of the code

    Thank you

    Bruno

  • I am trying to dubug the following code for CAN Tx side. I have connected the EK-TM4C1294XL board to PC using USB and using putty to view the results though the UART.

    The code I am running is the following:

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_can.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/can.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "utils/uartstdio.c"
    
    volatile uint32_t g_ui32IntCount = 0;
    volatile uint32_t g_ui32Msg1Count = 0;
    volatile uint32_t g_ui32Msg2Count = 0;
    volatile uint32_t g_ui32Msg3Count = 0;
    
    volatile bool g_bMsgObj3Sent = 0;
    volatile bool g_bErrFlag = 0;
    
    
    tCANMsgObject g_sCANMsgObject1;
    tCANMsgObject g_sCANMsgObject2;
    tCANMsgObject g_sCANMsgObject3;
    
    uint8_t g_pui8Msg1[4] = { 1, 3, 5, 7 };
    uint8_t g_pui8Msg2[5] = { 2, 4, 6, 8, 10 };
    uint8_t g_pui8Msg3[6] = { 3, 6, 9, 12, 15, 18 };
    uint8_t g_pui8Msg4[8] = { 4, 8, 12, 16, 20, 24, 28, 32 };
    
    void InitConsole(void)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        UARTStdioConfig(0, 115200, 16000000);
    }
    
    
    void PrintCANMessageInfo(tCANMsgObject *psCANMsg, uint32_t ui32MsgObj)
    {
        unsigned int uIdx;
        UARTprintf("Sending msg: obj=%d ID=0x%04X msg=0x", ui32MsgObj,psCANMsg->ui32MsgID);
                 
        for(uIdx = 0; uIdx < psCANMsg->ui32MsgLen; uIdx++)
        {
        	UARTprintf("%02X ", psCANMsg->pui8MsgData[uIdx]);
        }
        UARTprintf("\n");
    }
    
    
    void SimpleDelay(void)
    {
        SysCtlDelay(16000000 / 3);
    
    }
    
    void CANIntHandler(void)
    {
    
        uint32_t ui32Status;
      
        ui32Status = CANIntStatus(CAN1_BASE, CAN_INT_STS_CAUSE);
    
        if(ui32Status == CAN_INT_INTID_STATUS)
        {
    
        	ui32Status = CANStatusGet(CAN1_BASE, CAN_STS_CONTROL);
            g_bErrFlag = 1;
        }
    
        else if(ui32Status == 1)
        {
        	CANIntClear(CAN1_BASE, 1);
            g_ui32Msg1Count++;
            g_bErrFlag = 0;
        }
    
        else if(ui32Status == 2)
        {
    	CANIntClear(CAN1_BASE, 2);
            g_ui32Msg2Count++;
            g_bErrFlag = 0;
        }
    
        else if(ui32Status == 3)
        {
    
            CANIntClear(CAN1_BASE, 3);
            g_ui32Msg3Count++;
            g_bMsgObj3Sent = 1;
            g_bErrFlag = 0;
        }
    
    }
    
    
    int main(void)
    {
    
        uint32_t ui32SysClock;
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_16MHZ | SYSCTL_OSC_INT | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
       
        InitConsole();
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB0_CAN1RX);
        GPIOPinConfigure(GPIO_PB1_CAN1TX);
        GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        SysCtlPeripheralDisable(SYSCTL_PERIPH_CAN1);
        SysCtlPeripheralReset(SYSCTL_PERIPH_CAN1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN1);
        CANInit(CAN1_BASE);
        CANBitRateSet(CAN1_BASE, ui32SysClock, 500000);
        CANIntRegister(CAN1_BASE, CANIntHandler); 
        CANIntEnable(CAN1_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
        IntEnable(INT_CAN1);
        CANEnable(CAN1_BASE);
    
        g_sCANMsgObject1.ui32MsgID = 0x1001;
        g_sCANMsgObject1.ui32MsgIDMask = 0;
        g_sCANMsgObject1.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        g_sCANMsgObject1.ui32MsgLen = sizeof(g_pui8Msg1);
        g_sCANMsgObject1.pui8MsgData = g_pui8Msg1;
    
        g_sCANMsgObject2.ui32MsgID = 0x2001;
        g_sCANMsgObject2.ui32MsgIDMask = 0;
        g_sCANMsgObject2.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        g_sCANMsgObject2.ui32MsgLen = sizeof(g_pui8Msg2);
        g_sCANMsgObject2.pui8MsgData = g_pui8Msg2;
    
        for(;;)
        {
            PrintCANMessageInfo(&g_sCANMsgObject1, 1);
            CANMessageSet(CAN1_BASE, 1, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);
            UARTprintf("%d\n",g_ui32Msg1Count);
    
            PrintCANMessageInfo(&g_sCANMsgObject2, 2);
            CANMessageSet(CAN1_BASE, 2, &g_sCANMsgObject2, MSG_OBJ_TYPE_TX);
            UARTprintf("%d\n",g_ui32Msg2Count);
    
            g_sCANMsgObject3.ui32MsgID = 0x3001;
            g_sCANMsgObject3.ui32MsgIDMask = 0;
            g_sCANMsgObject3.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
            g_sCANMsgObject3.ui32MsgLen = sizeof(g_pui8Msg3);
            g_sCANMsgObject3.pui8MsgData = g_pui8Msg3;
           
            g_bMsgObj3Sent = 0;
    
            PrintCANMessageInfo(&g_sCANMsgObject3, 3);
            CANMessageSet(CAN1_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);
    
            while(!g_bMsgObj3Sent) 
    	{
    	}
    
            UARTprintf("%d\n",g_ui32Msg3Count); 
    
            g_sCANMsgObject3.ui32MsgID = 0x3002;
            g_sCANMsgObject3.ui32MsgIDMask = 0;
            g_sCANMsgObject3.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
            g_sCANMsgObject3.ui32MsgLen = sizeof(g_pui8Msg4);
            g_sCANMsgObject3.pui8MsgData = g_pui8Msg4;
    
            PrintCANMessageInfo(&g_sCANMsgObject3, 3);
    
            CANMessageSet(CAN1_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);
        }
    
    }

    The above in Putty is received when the UARTprintf("%d\n",g_ui32Msg3Count); is included after while(!g_bMsgObj3Sent) {  } .

    But if I include the UARTprintf("%d\n",g_ui32Msg3Count) before while(!g_bMsgObj3Sent) {  }  I am getting the below shown result in Putty: 

    So the program execution seems to be stuck in the while loop: while(!g_bMsgObj3Sent) {  }

    The for loop is not getting executed infinitely. What is the remedy ?

  • Both of your screen caps  provide (ONLY) ~10% usable data (of very poor contrast!) - rest is useless.     (which obscures your key findings - that's NOT good!) You may remedy that by performing a "2nd operation" upon the screen cap - (editing it to just the essentials - that vast dead/"black" space provides NO value!)     And choose more contrasting/brighter (i.e. readable) screen colors.

    Recall that (many) posters arrive here "seeking help" - you must make (some) effort to "Sell your post" so that it receives adequate attention...    (legibility really counts!)

    Jayakrishnan Krishna Prasad said:

    So the program execution seems to be stuck in the while loop: while(!g_bMsgObj3Sent) {  }

    The for loop is not getting executed infinitely.     What is the remedy ?

    As to your code review - I find that "while loop" - yet no (included) "for loop" - which you suggest is present and NOT (fully) executed!