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.

TM4C123GH6PM: Unable to create CAN FIFO

Part Number: TM4C123GH6PM

In my application I am facing a data loss. So I tried to create a FIFO using 7 message objects.
But the data are receiving only in the lowest object. Given below is my code

void CAN_Config(void)
{
// enable the PORT-E for CAN TX & RX
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // enable the PORTE
GPIOPinConfigure(GPIO_PE4_CAN0RX); // configure the PE4 for CAN receiving function
GPIOPinConfigure(GPIO_PE5_CAN0TX); // configure the PE5 for CAN transmitting function
GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5); // enable the pin types for CAN
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);

// initialize the CAN0
CANInit(CAN0_BASE);
IntEnable(INT_CAN0);

// enable the interrupt on the CAN peripheral
CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
CANEnable(CAN0_BASE);

}
*****************************************************************************

void can_info(uint32_t baudRate,uint8_t samplingPoint)
{
// assigning the CAN bit timing structure values for CAN transmit and receive
// ToDo:Currently bit_time_q is constant in all baudRates;Need to validate it.
if (baudRate == 1000)
{
GetBittime.ui32SyncPropPhase1Seg=15;
GetBittime.ui32Phase2Seg=4;
GetBittime.ui32SJW=3;
GetBittime.ui32QuantumPrescaler=4;
}
else
{
// ToDo:baudrate is not supported;Handle this as an error.
}

// set that assigning values to that CAN
CANBitTimingSet(CAN0_BASE, &GetBittime);

// assign the CAN message object structure members for receving the data
sMsgObjectRx.ui32MsgIDMask = 0Xffff;

// The first 5 message objects have the MSG_OBJ_FIFO set to indicate
// that they are part of a FIFO.
sMsgObjectRx.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_EXTENDED_ID | MSG_OBJ_FIFO );
sMsgObjectRx.pui8MsgData = pui8MsgData;
sMsgObjectRx.ui32MsgLen = 8;


// The first three message objects have the MSG_OBJ_FIFO set to indicate
// that they are part of a FIFO.
CANMessageSet(CAN0_BASE, 2, &sMsgObjectRx, MSG_OBJ_TYPE_RX);
CANMessageSet(CAN0_BASE, 3, &sMsgObjectRx, MSG_OBJ_TYPE_RX);
CANMessageSet(CAN0_BASE, 4, &sMsgObjectRx, MSG_OBJ_TYPE_RX);
CANMessageSet(CAN0_BASE, 5, &sMsgObjectRx, MSG_OBJ_TYPE_RX);
CANMessageSet(CAN0_BASE, 6, &sMsgObjectRx, MSG_OBJ_TYPE_RX);

// Last message object does not have the MSG_OBJ_FIFO set to indicate that
// this is the last message.
sMsgObjectRx.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
CANMessageSet(CAN0_BASE, 7, &sMsgObjectRx, MSG_OBJ_TYPE_RX);

}

void CANIntHandler(void)
{
uint32_t ui32Status;

// Read the CAN interrupt status to find the cause of the interrupt
ui32Status = CANIntStatus(CAN0_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
ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
// set the error flag
g_bErrFlag = 1;

}

// Check if the cause is message object 1, which what we are using for
// sending messages.

else if(ui32Status == 1)
{
//-----------Transmit Interrupt-----------//
// If this condition is true, then the TX interrupt occurred on
// message object 1, and the message TX is complete. Clear the
// message object interrupt.

CANIntClear(CAN0_BASE, 1);

g_ui32MsgCount_Tx++;

// clear the error flag
g_bErrFlag = 0;

}

//-------------Receive Interrupt-----------//
// If this condition is true, then the RX interrupt occurred on
// message object 2, and the message RX is complete.

else if(ui32Status == 2)
{
g_ui32MsgCount_Rx++;
CANMessageGet(CAN0_BASE, 2, &sMsgObjectRx, 1);
// clear the error flag
g_bErrFlag = 0;
}
else if(ui32Status == 3)
{
g_ui32MsgCount3_Rx++;
CANMessageGet(CAN0_BASE, 3, &sMsgObjectRx, 1);
// clear the error flag
g_bErrFlag = 0;
}
else if(ui32Status == 4)
{
g_ui32MsgCount4_Rx++;
CANMessageGet(CAN0_BASE, 4, &sMsgObjectRx, 1);
// clear the error flag
g_bErrFlag = 0;
}
else if(ui32Status == 5)
{
g_ui32MsgCount5_Rx++;
CANMessageGet(CAN0_BASE, 5, &sMsgObjectRx, 1);
// clear the error flag
g_bErrFlag = 0;
}
else if(ui32Status == 6)
{
g_ui32MsgCount6_Rx++;
CANMessageGet(CAN0_BASE, 6, &sMsgObjectRx, 1);
// clear the error flag
g_bErrFlag = 0;
}
else if(ui32Status == 7)
{
g_ui32MsgCount7_Rx++;
CANMessageGet(CAN0_BASE, 7, &sMsgObjectRx, 1);
// clear the error flag
g_bErrFlag = 0;
}
}

  • Hi Jithin,
    First of all I only see six msg objects being setup for FIFO instead of 7 as you indicated in the subject title. Secondly, I wonder why you want to enable interrupt for the first 5 msg objects. I will suggest that you enable interrupt for the last msg object in the FIFO. So when the FIFO receives the last msg into msg object #7 it will generate interrupt. In the ISR you will then read from msg object starting from 2 to 7. Thirdly, I wonder why you didn't start your FIFO with msg object 1. You start with msg object 2.
  • One word of caution using the CAN FIFO mode. If you are continually receiving and reading from the FIFO and the order of the data is important, this may not work. In FIFO mode the order of the data frames is not guaranteed if you read a mailbox in the FIFO while receiving a frame that goes into the FIFO. The FIFO works when you receive a burst of frames where they all fit in the FIFO and can all be read before the next burst comes, or where the order in which the frames were received is not important. If this is not the case in your application, then you may be better off minimizing the time spent in your interrupt routines such that you will always be able to respond and read the data before the next frame comes in.
  • Just for clarification, even after implementing the FIFO you are missing FRAMES? I did not see in your code where you set the message ID, however since you initialize each mailbox with a structure, it will be the same for all 6 mailboxes (2-7). Are the CAN frames you want to receive all with the same ID? You set the MSG_OBJ_USE_ID_FILTER flag but then set the mask to all 1's, meaning that no bits of the ID are masked out.

    I notice that for mailbox 7 you did not set the MSG_OBJ_EXTENDED_ID flag. I don't think that is the cause of not getting messages in mailbox 3, but all mailboxes in the FIFO should have the same length ID's.