My TM4C1230H6PM system has a CAN bus , I am setup CAN bus on Loopback mode ,The following program only TX once, but will continue to receive a continuous repeated "ABC" CAN message , What is the problem?
compiler option : -mv7M4 --code_state=16 --float_support=FPv4SPD16 --abi=eabi -me --include_path="C:/ti/ccsv6/tools/compiler/ti-cgt-arm_5.2.2/include" --include_path="C:/ti/TivaWare_C_Series-2.1.3.156" -g --gcc --define=ccs="ccs" --define=TARGET_IS_TM4C123_RB2 --define=PART_TM4C1230H6PM --display_error_number --diag_warning=225 --diag_wrap=off
link option :-mv7M4 --code_state=16 --float_support=FPv4SPD16 --abi=eabi -me -g --gcc --define=ccs="ccs" --define=TARGET_IS_TM4C123_RB2 --define=PART_TM4C1230H6PM --display_error_number --diag_warning=225 --diag_wrap=off -z -m"HM-HSMARTS8Z.map" --heap_size=0 --stack_size=512 -i"C:/ti/ccsv6/tools/compiler/ti-cgt-arm_5.2.2/lib" -i"C:/ti/ccsv6/tools/compiler/ti-cgt-arm_5.2.2/include" --reread_libs --warn_sections --display_error_number --diag_wrap=off --xml_link_info="HM-HSMARTS8Z_linkInfo.xml" --rom_model
//*****************************************************************************
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "driverlib/fpu.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "inc/hw_can.h"
#include "driverlib/can.h"
#include "inc/hw_ints.h"
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "driverlib/watchdog.h"
int nCANAddr;
volatile uint32_t g_ui32RXMsgCount = 0;
volatile uint32_t g_ui32TXMsgCount = 0;
volatile bool g_bRXFlag = 0;
volatile uint32_t g_ui32ErrFlag = 0;
tCANMsgObject g_sCAN0RxMessage;
tCANMsgObject g_sCAN0TxMessage;
#define CAN_TRA_SIZE 8
#define CAN_REC_SIZE 8
uint8_t g_nTXMsgData[CAN_TRA_SIZE];
uint8_t g_nRXMsgData[CAN_REC_SIZE];
#define RXOBJECT 1
#define TXOBJECT 2
void CAN0_IntHandler(void);
void CANErrorLED(bool state)
{
if(state)
GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_0, 0x0);
else
GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_0, GPIO_PIN_0);
}
void CAN0_Init(void)
{
//CAN 0 config
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTF_BASE + GPIO_O_CR) = 0x1;
// For this example CAN0 is used with RX and TX pins on port F0 and F3.
// GPIO port E needs to be enabled so these pins can be used.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF));
// Configure the GPIO pin muxing to select CAN0 functions for these pins.
// This step selects which alternate function is available for these pins.
GPIOPinConfigure(GPIO_PF0_CAN0RX);
GPIOPinConfigure(GPIO_PF3_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 GPIO for these pins.
GPIOPinTypeCAN(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_3);
// The GPIO port and pins have been set up for CAN. The CAN peripheral
// must be enabled.
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
// Initialize the CAN controller
CANInit(CAN0_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.
CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 250000);
//lopback
HWREG(CAN0_BASE + CAN_O_CTL) = HWREG(CAN0_BASE + CAN_O_CTL) | CAN_CTL_TEST;
HWREG(CAN0_BASE + CAN_O_TST) = HWREG(CAN0_BASE + CAN_O_TST) | CAN_TST_LBACK;
///
IntMasterEnable();
CANIntRegister(CAN0_BASE, CAN0_IntHandler);
// 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);
g_sCAN0RxMessage.ui32MsgID = nCANAddr;
g_sCAN0RxMessage.ui32MsgIDMask = 0xFFFF;
g_sCAN0RxMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
g_sCAN0RxMessage.ui32MsgLen = CAN_REC_SIZE ;
g_sCAN0RxMessage.pui8MsgData = g_nRXMsgData;
CANMessageSet(CAN0_BASE, RXOBJECT, &g_sCAN0RxMessage, MSG_OBJ_TYPE_RX);
}
void CAN0_IntHandler(void)
{
uint32_t ui32Status;
// Read the CAN 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 caused the interrupt
// 0x8000 = Status interrupt
// all other numbers are reserved and have no meaning in this system
ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
if(ui32Status == CAN_INT_INTID_STATUS)
{
ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
g_ui32ErrFlag |= ui32Status;
}
else if(ui32Status == RXOBJECT)
{
//CANIntClear(CAN0_BASE, RXOBJECT);
g_sCAN0RxMessage.pui8MsgData = g_nRXMsgData;
CANMessageGet(CAN0_BASE, RXOBJECT, &g_sCAN0RxMessage, 1);
g_ui32RXMsgCount++;
g_bRXFlag = true;
g_ui32ErrFlag = 0;
CANErrorLED(false);
}
else if(ui32Status == TXOBJECT)
{
CANIntClear(CAN0_BASE, TXOBJECT);
g_ui32TXMsgCount++;
g_ui32ErrFlag = 0;
CANErrorLED(false);
}
else
{
// Spurious interrupt handling can go here.
}
}
//*****************************************************************************
void CAN0_ErrorCheck(void)
{
// CAN controller has entered a Bus Off state.
if(g_ui32ErrFlag & CAN_STATUS_BUS_OFF)
{
g_ui32ErrFlag &= ~(CAN_STATUS_BUS_OFF);
CANErrorLED(true);
}
// CAN controller error level has reached warning level.
if(g_ui32ErrFlag & CAN_STATUS_EWARN)
{
g_ui32ErrFlag &= ~(CAN_STATUS_EWARN);
CANErrorLED(true);
}
// CAN controller error level has reached error passive level.
if(g_ui32ErrFlag & CAN_STATUS_EPASS)
{
g_ui32ErrFlag &= ~(CAN_STATUS_EPASS);
CANErrorLED(true);
}
// A message was received successfully since the last read of this status.
if(g_ui32ErrFlag & CAN_STATUS_RXOK)
{
g_ui32ErrFlag &= ~(CAN_STATUS_RXOK);
CANErrorLED(true);
}
// A message was transmitted successfully since the last read of this status.
if(g_ui32ErrFlag & CAN_STATUS_TXOK)
{
g_ui32ErrFlag &= ~(CAN_STATUS_TXOK);
CANErrorLED(true);
}
// This is the mask for the last error code field.
if(g_ui32ErrFlag & CAN_STATUS_LEC_MSK)
{
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_MSK);
CANErrorLED(true);
}
// A bit stuffing error has occurred.
if(g_ui32ErrFlag & CAN_STATUS_LEC_STUFF)
{
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_STUFF);
CANErrorLED(true);
}
// A formatting error has occurred.
if(g_ui32ErrFlag & CAN_STATUS_LEC_FORM)
{
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_FORM);
CANErrorLED(true);
}
// An acknowledge error has occurred.
if(g_ui32ErrFlag & CAN_STATUS_LEC_ACK)
{
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_ACK);
CANErrorLED(true);
}
// The bus remained a bit level of 1 for longer than is allowed.
if(g_ui32ErrFlag & CAN_STATUS_LEC_BIT1)
{
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_BIT1);
CANErrorLED(true);
}
// The bus remained a bit level of 0 for longer than is allowed.
if(g_ui32ErrFlag & CAN_STATUS_LEC_BIT0)
{
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_BIT0);
CANErrorLED(true);
}
// A CRC error has occurred.
if(g_ui32ErrFlag & CAN_STATUS_LEC_CRC)
{
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_CRC);
CANErrorLED(true);
}
// This is the mask for the CAN Last Error Code (LEC).
if(g_ui32ErrFlag & CAN_STATUS_LEC_MASK)
{
g_ui32ErrFlag &= ~(CAN_STATUS_LEC_MASK);
CANErrorLED(true);
}
// If there are any bits still set in g_ui32ErrFlag then something unhandled
// has happened. Print the value of g_ui32ErrFlag.
if(g_ui32ErrFlag !=0)
{
CANErrorLED(true);
}
}
bool CAN0_send(int nTxId,uint8_t *dptr, int len)
{
if(len >8)
return false;
memcpy(g_nTXMsgData,dptr,len);
g_sCAN0TxMessage.ui32MsgID = nTxId;
g_sCAN0TxMessage.ui32MsgIDMask = 0;
g_sCAN0TxMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
g_sCAN0TxMessage.ui32MsgLen = len ;
g_sCAN0TxMessage.pui8MsgData = (uint8_t *)g_nTXMsgData;
CANMessageSet(CAN0_BASE, TXOBJECT, &g_sCAN0TxMessage, MSG_OBJ_TYPE_TX);
return true;
}
int32_t CAN0_rec(uint8_t *dptr)
{
if(!g_bRXFlag)
return 0;
g_bRXFlag = 0;
if(g_sCAN0RxMessage.ui32Flags & MSG_OBJ_DATA_LOST)
{
}
memcpy(dptr,g_nRXMsgData,CAN_REC_SIZE);
return g_sCAN0RxMessage.ui32MsgLen;
}
void HSMARTS8Z_init()
{
FPUEnable();
FPULazyStackingEnable();
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
//
// Check if the peripheral access is enabled.
//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA));
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB));
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD));
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE));
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOG));
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF));
}
int main(void)
{
volatile uint32_t ui32Loop;
uint32_t ret;
uint8_t str[8];
int32_t len;
int nRecCount=0;
HSMARTS8Z_init();
nCANAddr=0x06;
CAN0_Init();
strcpy(str,"ABC");
CAN0_send(6,str, 3);
while(1)
{
CAN0_ErrorCheck();
len=CAN0_rec(str);
if(len!=0)
{
if(str[0]=='A' && str[1]=='B' && str[2]=='C')
{
nRecCount++;
}
}
}
}