Other Parts Discussed in Thread: EK-TM4C1294XL, TPS2052, TPS2052B
Hi All. I am very new to CAN Bus protocol and TM4C. I am given a task to transmit CAN messages from 1 TM4C129EXL to another TM4C129EXL launchpad. Since I am new to this and I need to start from somewhere, I have decided to adapt the code and the hardware from the link below : http://ohm.ninja/tiva-c-series-can-bus-with-mcp2551/ and also by refering to the sample code from C:\ti\TivaWare_C_Series-2.1.4.178\examples\peripherals\can.
I have added severel UARTprintf to the void CANIntHandler(void) to help my debugging. I have also used the oscilloscope to check CANH,CANL and TX but there are no output (hence, scope caps are not attached in this post). The JP4 and JP5 jumpers are in default configuration since CAN1 is used instead of CAN0. Please do assist.
Attached is my code for Master:
#include <stdbool.h> #include <stdint.h> #include <math.h> #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_can.h" #include "inc/hw_ints.h" #include "driverlib/can.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/gpio.h" #include "driverlib/uart.h" #include "driverlib/pin_map.h" #include "utils/uartstdio.h" #define PI 3.14159265359f volatile bool errFlag = 0; // transmission error flag unsigned int sysClock; // clockspeed in hz void delay(unsigned int milliseconds) { SysCtlDelay((sysClock / 3) * (milliseconds / 1000.0f)); } // CAN interrupt handler void CANIntHandler(void) { unsigned long status = CANIntStatus(CAN1_BASE, CAN_INT_STS_CAUSE); // read interrupt status UARTprintf("Triggered\n"); if(status == CAN_INT_INTID_STATUS) { // controller status interrupt status = CANStatusGet(CAN1_BASE, CAN_STS_CONTROL); // read back error bits, do something with them? errFlag = 1; UARTprintf("Triggered1\n"); } else if(status == 1) { // message object 1 CANIntClear(CAN1_BASE, 1); // clear interrupt errFlag = 0; // clear any error flags UARTprintf("Triggered2\n"); } else { // should never happen UARTprintf("Unexpected CAN bus interrupt\n"); UARTprintf("Error is-- %lu\n",status); } } int main(void) { tCANMsgObject msg; // the CAN message object unsigned int msgData; // the message data is four bytes long which we can allocate as an int32 unsigned char *msgDataPtr = (unsigned char *)&msgData; // make a pointer to msgData so we can access individual bytes // Run from the PLL at 120 MHz. sysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // Set up debugging UART SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // enable UART0 GPIO peripheral SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioConfig(0, 115200, sysClock); // 115200 baud // Set up CAN1 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // enable CAN1 GPIO peripheral GPIOPinConfigure(GPIO_PB0_CAN1RX); GPIOPinConfigure(GPIO_PB1_CAN1TX); GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN1); CANInit(CAN1_BASE); CANBitRateSet(CAN1_BASE, sysClock, 500000); CANIntRegister(CAN1_BASE, CANIntHandler); // use dynamic vector table allocation CANIntEnable(CAN1_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); IntEnable(INT_CAN1); CANEnable(CAN1_BASE); // Set up msg object msgData = 0; msg.ui32MsgID = 1; msg.ui32MsgIDMask = 0; msg.ui32Flags = MSG_OBJ_TX_INT_ENABLE; msg.ui32MsgLen = sizeof(msgDataPtr); msg.pui8MsgData = msgDataPtr; unsigned int t = 0; // loop counter float freq = 0.3; // frequency scaler while(1) { // set up next colour (scale sinf (0-1) to 0-255) msgDataPtr[0] = (0.5 + 0.5*sinf(t*freq)) * 0xFF; msgDataPtr[1] = (0.5 + 0.5*sinf(t*freq + (2*PI/3))) * 0xFF; // 120 degrees out of phase msgDataPtr[2] = (0.5 + 0.5*sinf(t*freq + (4*PI/3))) * 0xFF; // 240 degrees out of phase msgDataPtr[3] = 128; // 50% intensity UARTprintf("Sending colour\tr: %d\tg: %d\tb: %d\n", msgDataPtr[0], msgDataPtr[1], msgDataPtr[2]); // write colour to UART for debugging CANMessageSet(CAN1_BASE, 1, &msg, MSG_OBJ_TYPE_TX); // send as msg object 1 delay(100); // wait 100ms if(errFlag) { // check for errors UARTprintf("CAN Bus Error\n"); } t++; // overflow is fine } return 0; }
Attached is my circuit diagram:
Attached is the output from the terminal: