Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL
Hello
I'm basically trying to run the CAN bus example, I have verified the pins are correct and also the connection is set to be "Stellaris".
When I try to download into the launchpad, everything seems to be working correctly, I even get the pause and stop buttons but I cant seem to debug it.
Here is the code I am trying to run, plus the connection configuration. Can anybody please provide feedback, I am kind of new to the ARM processor universe.
Also, I'm using CCS 11.1


#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_can.h"
#include "driverlib/can.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/fpu.h"
#include "driverlib/can.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include <rom.h>
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "grlib/grlib.h"
#include "utils/uartstdio.h"
#include "driverlib/interrupt.h"
#include "inc/tm4c123gh6pm.h"
//Volatile variables
volatile uint32_t g_ui32RXMsgCount = 0; //Counter for interrupts so no data gets lost
volatile uint32_t g_ui32TXMsgCount = 0; //Counter for interrupts so no data gets lost
volatile bool g_bRXFlag = 0; //Flag to indicate data has been received
volatile uint32_t g_ui32ErrFlag = 0; //Global variable to keep track of the error so they are processed
//CAN objects for data tx and rx
tCANMsgObject g_sCAN0RxMessage;
tCANMsgObject g_sCAN0TxMessage;
//Message identifiers and objects
//RXID is set to 0 so all messages are received
#define CAN0RXID 0
#define RXOBJECT 1
#define CAN0TXID 2
#define TXOBJECT 2
//Variables to hold characters being sent / received
uint8_t g_ui8TXMsgData;
uint8_t g_ui8RXMsgData;
//CAN 0 Interrupt handler. Checks for the cause of the interrupt, and mantains
//a count of all messages that have been transmitted/received
void CAN0IntHandler(void)
{
uint32_t ui32Status;
//Read the interrupt status to find the cause of the interrupt
//CAN_INT_STS_CAUSE register values
//0x0000 = No interrupt pending
//0x0001-0x0020 = Number of message object that cause the interrupt
//0x8000 = Status interrupt
//all others numbers are reserved and have no meaning in this system
//Read the interrupt cause
ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
//If this was a status interrupt acknowledge it by reading the CAN
//status register
if(ui32Status == CAN_INT_INTID_STATUS)
{
//Read the controller status. This will return a field of status
//error bits that can indicate various errors. Refer to the
//API documentation for details about the error status bits.
//Just by reading the status will clear the interrupt.
ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
//Add ERROR flags to list of current errors. To be handled
//later, because it would take too much time here in the interrupt.
g_ui32ErrFlag |= ui32Status;
}
//Check if the cause is message object RXOBJECT, which we are using
//to receive messages
else if(ui32Status == RXOBJECT)
{
//Getting to this point means that the RX interrupt occurred
//on message object RXOBJECT, and the message reception is complete.
//Clear the message interrupt.
CANIntClear(CAN0_BASE, RXOBJECT);
//Increment a counter to keep track of how many messages have been
//received. In real application this could be used to set flags to
//indicate when a message is received
g_ui32RXMsgCount++;
//Set flag to indicate received message is pending
g_bRXFlag = true;
//Since a message was received, clear any error flags.
//This is done because before the message is received it triggers
//a Status interrupt for RX complete. By clearing the flag here
//we prevent unnecessary error handling from happening
g_ui32ErrFlag = 0;
}
//Check if the cause is message object TXOBJECT, which we are using
//for transmitting messages
else if(ui32Status == TXOBJECT)
{
//Getting to this point means that the TX interrupt occurred on
//message object TXOBJECT, and the message reception is complete
//Clear the message object interrupt.
CANIntClear(CAN0_BASE, TXOBJECT);
//Increment a counter to keep track of how many messages have been transmitted
//In real applications this could be used to set flags to indicate when a message
// is transmitted
g_ui32TXMsgCount++;
//Since a message was transmitted, clear any error flags.
//This is done because before the message is transmitted it
//triggers a Status interrupt for TX complete. By clearing the flag
//here we prevent unnecessary error handling from happening
g_ui32ErrFlag = 0;
}
else
{
//this code should never execute
return;
}
}
void ConfigureUART(void)
{
//Enable the GPIO peripheral used by UART.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//Enable UART0
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
//Configure GPIO pins for UART mode
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//Use internal 16MHz oscillator as the UART clock source
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
//Initialize the UART for console I/O
UARTStdioConfig(0, 115200, SysCtlClockGet());
}
//Setup CAN0 to both send and receive at 500KHz
void InitCAN0(void)
{
//For this example CAN0 is used with RX and TX on port E4 and E5
//GPIO port E needs to be enabled so these pins can be used
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
//Configure the GPIO muxing to select CAN0 functions for these pins
//this step selects which alternate function is available for these
//pins
GPIOPinConfigure(GPIO_PE4_CAN0RX);
GPIOPinConfigure(GPIO_PE5_CAN0TX);
//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 GPPIO for these pins
GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);
//The GPIO port and pins have been set up for CAN. THe CAN
//peripheral must be enabled
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
//Initialize CAN Controller
CANInit(CAN0_BASE);
//Setup 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.
//For this example, the CAN bus is set to 500kHz
CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 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
CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
//Enable the CAN interrupt on the processor NVIC
IntEnable(INT_CAN0);
//Enable the CAN for operation
CANEnable(CAN0_BASE);
//Initialize a message object to be used for receiving CAN messages
//with any CAN ID. In order to receive any CAN ID, the ID and mask
//must be both set to 0, and the ID filter enabled
g_sCAN0RxMessage.ui32MsgID = CAN0RXID;
g_sCAN0RxMessage.ui32MsgIDMask = 0;
g_sCAN0RxMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
g_sCAN0RxMessage.ui32MsgLen = sizeof(g_ui8RXMsgData);
//Now load the message object into the CAN peripheral. Once loaded
//the CAN will receive any message on the bus, and an interrupt will occur.
//Use message object RXOBJECT for receiving messages (this is not the
//same as the CAN ID which can be any value in this example)
CANMessageSet(CAN0_BASE, RXOBJECT, &g_sCAN0RxMessage, MSG_OBJ_TYPE_RX);
//Initialize the message object that will be used for sending CAN
//messages. The message will by 1 bytes that will contain the
//character received from the other controller. Initially it will be set to 0
g_ui8TXMsgData = 0;
g_sCAN0TxMessage.ui32MsgID = CAN0TXID;
g_sCAN0TxMessage.ui32MsgIDMask = 0;
g_sCAN0TxMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
g_sCAN0TxMessage.ui32MsgLen = sizeof(g_ui8TXMsgData);
g_sCAN0TxMessage.pui8MsgData = (uint8_t *)&g_ui8TXMsgData;
}
//CAN error handling. When a message a message is received if there is an error it is
//saved to g_ui32ErrFlag, the Error Flag set. Bellow the flags are checked
//and cleared. It is left up to the user to add handling functionality if
//so desired
void CANErrorHandler(void)
{
//CAN controller has entered a Bus off state
if(g_ui32ErrFlag & CAN_STATUS_BUS_OFF)
{
UARTprintf("ERROR: CAN STATUS BUS OFF\n");
//clear CAN_STATUS_BUS_OFF Flag
g_ui32ErrFlag &= ~(CAN_STATUS_BUS_OFF);
}
//CAN controller error level has reached warning level
if(g_ui32ErrFlag & CAN_STATUS_EWARN)
{
UARTprintf("ERROR: TOO MUCH ERRORS\n");
//clear CAN_STATUS_EWARN Flag
g_ui32ErrFlag &= ~(CAN_STATUS_EWARN);
}
//CAN controller error level has reached error pasive level
if(g_ui32ErrFlag & CAN_STATUS_EPASS)
{
//Clear CAN_STATUS_EPASS Flag
g_ui32ErrFlag &= ~(CAN_STATUS_EPASS);
}
//A message was received successfully since the last read of this status
if(g_ui32ErrFlag & CAN_STATUS_RXOK)
{
//Clear CAN_STATUS_RXOK Flag
g_ui32ErrFlag &= ~(CAN_STATUS_RXOK);
}
// A message was transmitted successfully since the last read of this status
if(g_ui32ErrFlag & CAN_STATUS_TXOK)
{
//Clear CAN_STATUS_TXOK Flag
g_ui32ErrFlag &= ~(CAN_STATUS_TXOK);
}
//This is the mask for the last error code field
if(g_ui32ErrFlag & CAN_STATUS_LEC_MSK)
{
//Clear CAN_STATUS_LEC_MSK Flag
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_MSK);
}
//A bit stuffing has occurred
if(g_ui32ErrFlag & CAN_STATUS_LEC_STUFF)
{
//Clear CAN_STATUS_LEC_STUFF Flag
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_STUFF);
}
//A formatting error has occurred
if(g_ui32ErrFlag & CAN_STATUS_LEC_FORM)
{
//Clear CAN_STATUS_LEC_FORM Flag
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_FORM);
}
//An acknowledge error has occurred
if(g_ui32ErrFlag & CAN_STATUS_LEC_ACK)
{
//Clear CAN_STATUS_LEC_ACK Flag
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_ACK);
}
//A bus remained a bit level of 1 for longer than is allowed
if(g_ui32ErrFlag & CAN_STATUS_LEC_BIT1)
{
//Clear CAN_STATUS_LEC_BIT1 Flag
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_BIT1);
}
//The bus remained a but level of 0 for longer than is allowed
if(g_ui32ErrFlag & CAN_STATUS_LEC_BIT0)
{
//Clear CAN_STATUS_LEC_BIT0 Flag
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_BIT0);
}
//A CRC error has occurred
if(g_ui32ErrFlag & CAN_STATUS_LEC_CRC)
{
//Important error to handle
//Clear CAN_STATUS_LEC_CRC Flag
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_CRC);
}
//This is the mask for the CAN Last Error Code (LEC)
if(g_ui32ErrFlag & CAN_STATUS_LEC_MASK)
{
//Clear CAN_STATUS_LEC_MASK Flag
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_MASK);
}
//At this point the error Flag container should be 0, make sure it is
if(g_ui32ErrFlag !=0)
{
UARTprintf("Unhandled ERROR: %x \n",g_ui32ErrFlag);
g_ui32ErrFlag &= 0x00;
}
}
int main(void)
{
volatile uint32_t ui32Loop; //Declare dummy variable
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOG))
{
}
//GPIODirModeSet(GPIO_PORTF_BASE, 0x04, GPIO_DIR_MODE_OUT);
GPIOPinTypeGPIOOutput(GPIO_PORTG_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, 1);
//Enable lazy stacking for interrupts handlers. This allows floating-point
//instructions to be used within interrupt handlers, but at the expense
//of extra stack usage
//FPULazyStackingEnable();
//Set the clocking to run directly from the crystal
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
//SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL| SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //Set 80Mhz
//SysCtlClockSet(SYSCTL_OSC_INT | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_320);
//Initialize the UART
ConfigureUART();
//Initialize CAN0
InitCAN0();
while(1)
{
//If this condition is true this means the RX interrupt occurred
//and there is a message ready to be read from the CAN
if(g_bRXFlag)
{
//Reuse the same message object that was used earlier to configure the CAN
//for receiving messages. A buffer for storing the received data must also
//be provided, so set the buffer pointer within the message
//object
g_sCAN0RxMessage.pui8MsgData = (uint8_t *) &g_ui8RXMsgData;
//Read the message from the CAN. Message object RXOBJECT is used
//(which is not the same thing as CAN ID). The interrupt clearing
//flag is not set because this interrupt was already cleared in the
//interrupt handler
CANMessageGet(CAN0_BASE, RXOBJECT, &g_sCAN0RxMessage, 0);
//Clear the pending message flag so that the interrupt handler can
//set it again when the next message arrives.
g_bRXFlag = 0;
//Check to see if there is an indication that some messages were lost
if(g_sCAN0RxMessage.ui32Flags & MSG_OBJ_DATA_LOST)
{
UARTprintf("\nCAN message loss detected\n");
}
//print the received char to the UART Terminal
//UARTprintf("%c", g_ui8RXMsgData);
}
else
{
//Error handling
if(g_ui32ErrFlag != 0)
CANErrorHandler();
while(UARTCharsAvail(UART0_BASE))
{
// Read the next character from the UART terminal
g_ui8TXMsgData = UARTCharGetNonBlocking(UART0_BASE);
char txdata = g_ui8TXMsgData;
UARTprintf("Sent data: ", txdata);
// Send the CAN message using object number TXOBJECT (not the
// same thing as CAN ID, which is also TXOBJECT in this
// example). This function will cause the message to be
// transmitted right away
CANMessageSet(CAN0_BASE, TXOBJECT, &g_sCAN0TxMessage, MSG_OBJ_TYPE_TX);
}
g_ui8TXMsgData = 0x33;
CANMessageSet(CAN0_BASE, TXOBJECT, &g_sCAN0TxMessage, MSG_OBJ_TYPE_TX);
}
}
return 0;
}

