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.

TMS320F28377S: CAN FIFO issues

Part Number: TMS320F28377S
Other Parts Discussed in Thread: C2000WARE

Hi,

These days we are configuring f28377S CAN FIFO to receive message objects, with these issues:

1) IF3 is the only one, which can be used for FIFO. Is that right?

2) What's is the relationship between FIFO and interrupt? If 6 objects are formed as one FIFO buffer, when will be interrupt happen? 6 objects received, then an interrupt? Or each object received, one interrupt initiated? 

3) How to achieve customer request: check when 6 objects arrived, then read. During this progress, there's some other issues:

    - How long does it need to read all of the 6 objects? The read is in CAN_ISR, customer would like to minimize the time;

    - During reading, if another object arrived, what will happen? Another CAN interrupt will be handling? Before go out of the CAN_ISR, do they need to clear the interrupt bit INT0_FLG_CLR? 

4) Is there any detailed doc for a reference? 

Thanks a lot.

Br, Jordan

  • Hi Jordan,

    Please find my response below:

    1) No IF3 is not the only one that can be used for FIFO but IF1 and IF2 can also be used. IF3 has only read access.
    2) If there is an interrupt enabled it will occur on each object receive.
    3) The time to read the data in the ISR depends on your requirements and the code. If another interrupt comes it will occur after the previous message object is read.
    4) You can refer to the Technical Reference Manual for more details. Link www.ti.com/.../spruhx5e.pdf


    Please let me know if there are any more queries.

    Thanks and Regards
    Harshmeet Singh
  • Singh,
    Thanks for your reply.
    Actually customer and I did several test, but still very confused.
    1) If not using IF3, FIFO doesn't work.
    2) From user guide, we can't understand FIFO very well.
    Customer's request is to use interrupt and FIFO to receive 6 objects.
    But we don't know how to handle the interrupt, to make sure there's no objects lost.
    Can you provide a demo code for us?
    Or, can we plan a con-call to understand better how it works.
    Thanks a lot.
    Br, Jordan
  • Hi Jordan,

    Did you try running the C2000Ware examples?

    Can you tell me in detail of what you are trying to do? So that i can understand better and help you with it.

    Thanks and Regards
    Harshmeet Singh
  • Singh,
    Yes, the code is from C2000ware.
    Customer's request is that: use CAN FIFO to receive 1+3 objects. The first object will be sent firstly. After 3ms, the 3 objects will be sent together without any delay between each other. If FIFO is not used, some objects will be lost. The frequency of 1+3 objects receiving is about 10ms.
    In their application, there are some other interrupts, like timer1 0.1ms. PWM 50ms, timer2 2ms, SCI receive/transmit. We'd like to know, which is the best way to check 1+3 objects and read them in a shortest time.

    Thanks a lot.
    Br, Jordan
  • Hi,
    Any feedback?
    Thanks a lot.
    Br, Jordan
  • Hi Jordan,

    Sorry i wasn't able to work on this.

    As far as i understood what you are trying to do is send first object and then after a delay of 3ms send three objects together without any delay.
    You are trying to use FIFO.

    Is the configuration done properly?

    Are you using the same driverlib example code and what changes have you made to it? Can you share the details.

    Can you provide some more details.

    I can try replicating the same way as you described and make an example for you?

    Regards
    Harshmeet

  • Harshmeet,
    Thanks for your reply.

    Actually, customer's request is that: use CAN FIFO to receive 1+3 (total) objects. The first object will be received firstly. After 3ms, the other 3 objects will be received, without any delay between each other. If FIFO is not used, some objects will be lost. The frequency of 1+3 objects receiving is about 10ms.
    In their application, there are some other interrupts, like timer1 0.1ms. PWM 50ms, timer2 2ms, SCI receive/transmit. We'd like to know, which is the best way to check 1+3 objects received and read them in a shortest time.

    Br, Jordan
  • Jordon i understood your problem statement.

    Can you share the details of which C2000Ware example you are referring and if you have made any change.

    Regards
    Harshmeet
  • Harshmeet,
    The code is not based on any C2000ware, as customer did the project when F2837x was only in sample.
    But their code is very familiar to the last version of C2000ware.
    Br, Jordan
  • Harshmeet,
    Any feedback?
    Thanks. Br, Jordan
  • Hi Jordan,

    Sorry for the late reply.

    So i tried to replicate the scenario you just mentioned. I am sending a message object then i wait for 3ms and send the next three message objects.

    Yes if FIFO is not used the objects will be lost. As per my understanding of CAN and my work i tried this:

    I broke the C2000Ware Example (can_ex3_external_transmit) into two different examples: one for transmitting the data and one for receiving the data. I am using two F2837XS Launchpads.

    In the first example i transmit the data configuring the message box according and providing a 3ms delay after the first data is received.

    In the second example I receive the data after configuring the message objects and go into a while(1) loop. So whenever data is received it will go into ISR.

    If i use the same Message ID the message might be lost. So i use different message ID's for the data and I am able to receive the data correctly.

    If you want to use the same message ID you need a delay to wait for the data to be successfully received.

    I need to understand more about how FIFO is implemented in hardware. Hope this information helps


    Thanks and Regards
    Harshmeet Singh

  • Hi Jordan,

    Did you have time to look at this?

    Regards
    Harshmeet
  • Harshmeet,
    Customer is working on your previous suggestion.
    Currently, customer has the question on how to judge if data are received successfully. In their application, it's not possible to just wait to check if received. There are several interrupts. What they can do is, each 2ms they can check if received. This is their code structure, just like a RTOS. In this case, what can they do?
    Thanks a lot.
    Br, Jordan
  • Harshmeet,
    CAN interrupt is used to receive the data.
    Now, customer needs:
    1) How many objects in CAN FIFO will trigger the CAN ISR? That's, how many objects can be read?
    2) In CAN ISR, how to reset the ISR flag?
    Do you have a demo on this, based our example in C2000ware?
    Thanks a lot.
    Br, Jordan
  • Hi Jordan,

    Every CAN Data will trigger an interrupt.

    Can you please refer to the c2000ware example for CAN : can_ex3_external_transmit

    In this example data is sent from CAN A to CAN B. There are interrupts and interrupts are cleared.

    Thanks and Regards

    Harshmeet

  • Harshmeet,
    Today, customer asked again for a demo of CAN FIFO.
    Will you prepare a demo based on "can_ex3_external_transmit", please?
    I introduced the logic to them, but they don't accept. This is their first to use C2000. M3/M4 are very familiar to them.
    Thanks a lot.
    Br, Jordan
  • Hi Jordan,

    Is it okay if i can share the two c files?

    I hope that helps.

    Regards

    Harshmeet

  • Harshmeet,
    Let me try with these two C files and then give you the feedback.
    Thanks a lot.
    Br, Jordan
  • Hi Jordan,

    Please find the two files below.

    As per the information you provided i tried to replicate it.

    I am using two Launchpads as they have an On Board CAN Transceivers. You can copy this in the can_ex3_external_receive project replacing the original project file,

    Just change the GPIO Configurations in the device.h file as below and select the define _LAUNCHXL_F28377S in the project.

    //
    // CANA
    //
    #define DEVICE_GPIO_PIN_CANTXA 71U // GPIO number for CANTXA
    #define DEVICE_GPIO_PIN_CANRXA 70U // GPIO number for CANRXA

    //
    // CAN External Loopback
    //
    #define DEVICE_GPIO_CFG_CANRXA GPIO_70_CANRXA // "pinConfig" for CANA RX
    #define DEVICE_GPIO_CFG_CANTXA GPIO_71_CANTXA // "pinConfig" for CANA TX

    You will have to have two lauchpads and two ccs instances where you can run on both the c files in the project and then run the receive c file containing project and then run the transmit project. You should see the rxMsgCount as 4 in the end.

    //#############################################################################
    //
    // FILE:   can_ex3_external_receive.c
    //
    // TITLE:   CAN External Transmit Example
    //
    //! \addtogroup driver_example_list
    //! <h1> CAN-A to CAN-B External Transmit </h1>
    //!
    //! This example initializes CAN module A to receive data.
    //!
    //
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    //
    // Defines
    //
    #define MSG_DATA_LENGTH    4
    #define RX_MSG_OBJ_ID    1
    
    //
    // Globals
    //
    volatile unsigned long i;
    volatile uint32_t rxMsgCount = 0;
    volatile uint32_t errorFlag = 0;
    uint16_t rxMsgData[4];
    
    //
    // Function Prototypes
    //
    __interrupt void canaISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Initialize GPIO and configure GPIO pins for CANTX/CANRX
        // on module A and B
        //
        Device_initGPIO();
        GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
        GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
    
        //
        // Initialize the CAN controllers
        //
        CAN_initModule(CANA_BASE);
    
        //
        // Set up the CAN bus bit rate to 500kHz for each module
        // Refer to the Driver Library User Guide for information on how to set
        // tighter timing control. Additionally, consult the device data sheet
        // for more information about the CAN module clocking.
        //
        CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);
    
        //
        // Enable interrupts on the CAN B peripheral.
        //
        CAN_enableInterrupt(CANA_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
                            CAN_INT_STATUS);
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
        // This registers the interrupt handler in PIE vector table.
        //
        Interrupt_register(INT_CANA0, &canaISR);
    
        //
        // Enable the CAN-B interrupt signal
        //
        Interrupt_enable(INT_CANA0);
    
        CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    
        //
        // Initialize the transmit message object used for sending CAN messages.
        // Message Object Parameters:
        //      CAN Module: A
        //      Message Object ID Number: 1
        //      Message Identifier: 0x95555555
        //      Message Frame: Extended
        //      Message Type: Transmit
        //      Message ID Mask: 0x0
        //      Message Object Flags: None
        //      Message Data Length: 4 Bytes
        //
        CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x95555555,
                               CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                               CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);
    
        //
        // Start CAN module A operations
        //
        CAN_startModule(CANA_BASE);
    
        while(1);
    }
    
    //
    // CAN B ISR - The interrupt service routine called when a CAN interrupt is
    //             triggered on CAN module B.
    //
    __interrupt void
    canaISR(void)
    {
        uint32_t status;
    
        //
        // Read the CAN-B interrupt status to find the cause of the interrupt
        //
        status = CAN_getInterruptCause(CANA_BASE);
    
        //
        // If the cause is a controller status interrupt, then get the status
        //
        if(status == CAN_INT_INT0ID_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.
            //
            status = CAN_getStatus(CANA_BASE);
    
            //
            // Check to see if an error occurred.
            //
            if(((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) &&
               ((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE))
            {
                //
                // Set a flag to indicate some errors may have occurred.
                //
                errorFlag = 1;
            }
        }
        //
        // Check if the cause is the CAN-B receive message object 1
        //
        else if(status == RX_MSG_OBJ_ID)
        {
            //
            // Get the received message
            //
            CAN_readMessage(CANA_BASE, RX_MSG_OBJ_ID, rxMsgData);
    
            //
            // Getting to this point means that the RX interrupt occurred on
            // message object 1, and the message RX is complete.  Clear the
            // message object interrupt.
            //
            CAN_clearInterruptStatus(CANA_BASE, RX_MSG_OBJ_ID);
    
            //
            // Increment a counter to keep track of how many messages have been
            // received. In a real application this could be used to set flags to
            // indicate when a message is received.
            //
            rxMsgCount++;
    
            //
            // Since the message was received, clear any error flags.
            //
            errorFlag = 0;
        }
        //
        // If something unexpected caused the interrupt, this would handle it.
        //
        else
        {
            //
            // Spurious interrupt handling can go here.
            //
        }
    
        //
        // Clear the global interrupt flag for the CAN interrupt line
        //
        CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    
        //
        // Acknowledge this interrupt located in group 9
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    //
    // End of File
    //
    
    //#############################################################################
    //
    // FILE:   can_ex3_external_transmit.c
    //
    // TITLE:   CAN External Transmit Example
    //
    //! \addtogroup driver_example_list
    //! <h1> CAN-A External Transmit </h1>
    //!
    //! This example initializes CAN module A to transmit data.
    //!
    //
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    //
    // Defines
    //
    #define MSG_DATA_LENGTH    4
    #define TX_MSG_OBJ_ID    1
    
    //
    // Globals
    //
    volatile unsigned long i;
    volatile uint32_t txMsgCount = 0;
    volatile uint32_t errorFlag = 0;
    uint16_t txMsgData[4];
    
    //
    // Function Prototypes
    //
    __interrupt void canaISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Initialize GPIO and configure GPIO pins for CANTX/CANRX
        // on module A and B
        //
        Device_initGPIO();
        GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
        GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
    
        //
        // Initialize the CAN controllers
        //
        CAN_initModule(CANA_BASE);
    
        //
        // Set up the CAN bus bit rate to 500kHz for each module
        // Refer to the Driver Library User Guide for information on how to set
        // tighter timing control. Additionally, consult the device data sheet
        // for more information about the CAN module clocking.
        //
        CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);
    
        //
        // Enable interrupts on the CAN B peripheral.
        //
        CAN_enableInterrupt(CANA_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
                            CAN_INT_STATUS);
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
        // This registers the interrupt handler in PIE vector table.
        //
        Interrupt_register(INT_CANA0, &canaISR);
    
        //
        // Enable the CAN-B interrupt signal
        //
        Interrupt_enable(INT_CANA0);
        CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    
        //
        // Initialize the transmit message object used for sending CAN messages.
        // Message Object Parameters:
        //      CAN Module: A
        //      Message Object ID Number: 1
        //      Message Identifier: 0x95555555
        //      Message Frame: Extended
        //      Message Type: Transmit
        //      Message ID Mask: 0x0
        //      Message Object Flags: None
        //      Message Data Length: 4 Bytes
        //
        CAN_setupMessageObject(CANA_BASE, TX_MSG_OBJ_ID, 0x95555555,
                               CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,
                               CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);
    
        CAN_setupMessageObject(CANA_BASE, 2U, 0x95555555,
                               CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,
                               CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);   //
    
        CAN_setupMessageObject(CANA_BASE, 3, 0x95555555,
                               CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,
                               CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);
    
        //
        // Initialize the transmit message object data buffer to be sent
        //
        txMsgData[0] = 0x12;
        txMsgData[1] = 0x34;
        txMsgData[2] = 0x56;
        txMsgData[3] = 0x78;
    
        //
        // Start CAN module A and B operations
        //
        CAN_startModule(CANA_BASE);
    
        CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
                                txMsgData);
    
        txMsgCount++;
    
        //
        // Delay 0.25 second before continuing
        //
        DEVICE_DELAY_US(3000);
    
        txMsgData[0] += 0x01;
        txMsgData[1] += 0x01;
        txMsgData[2] += 0x01;
        txMsgData[3] += 0x01;
        txMsgCount++;
    
        CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
                        txMsgData);
        txMsgData[0] += 0x01;
        txMsgData[1] += 0x01;
        txMsgData[2] += 0x01;
        txMsgData[3] += 0x01;
        txMsgCount++;
    
        CAN_sendMessage(CANA_BASE, 2U, MSG_DATA_LENGTH,
                        txMsgData);
        txMsgData[0] += 0x01;
        txMsgData[1] += 0x01;
        txMsgData[2] += 0x01;
        txMsgData[3] += 0x01;
        txMsgCount++;
    
        CAN_sendMessage(CANA_BASE, 3U, MSG_DATA_LENGTH,
                            txMsgData);
        DEVICE_DELAY_US(3000);
    
        asm("   ESTOP0");
    }
    
    //
    // CAN A ISR - The interrupt service routine called when a CAN interrupt is
    //             triggered on CAN module A.
    //
    __interrupt void
    canaISR(void)
    {
        uint32_t status;
    
        //
        // Read the CAN-B interrupt status to find the cause of the interrupt
        //
        status = CAN_getInterruptCause(CANA_BASE);
    
        //
        // If the cause is a controller status interrupt, then get the status
        //
        if(status == CAN_INT_INT0ID_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.
            //
            status = CAN_getStatus(CANA_BASE);
    
            //
            // Check to see if an error occurred.
            //
            if(((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) &&
               ((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE))
            {
                //
                // Set a flag to indicate some errors may have occurred.
                //
                errorFlag = 1;
            }
        }
        //
        // Check if the cause is the CAN-B receive message object 1
        //
        else if(status == TX_MSG_OBJ_ID)
        {
    
    //
    //        //
    //        // Getting to this point means that the RX interrupt occurred on
    //        // message object 1, and the message RX is complete.  Clear the
    //        // message object interrupt.
    //        //
    //        CAN_clearInterruptStatus(CANA_BASE, RX_MSG_OBJ_ID);
    //
    //        //
    //        // Increment a counter to keep track of how many messages have been
    //        // received. In a real application this could be used to set flags to
    //        // indicate when a message is received.
    //        //
    //        rxMsgCount++;
    //
    //        //
    //        // Since the message was received, clear any error flags.
    //        //
    //        errorFlag = 0;
        }
        //
        // If something unexpected caused the interrupt, this would handle it.
        //
        else
        {
            //
            // Spurious interrupt handling can go here.
            //
        }
    
        //
        // Clear the global interrupt flag for the CAN interrupt line
        //
        CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    
        //
        // Acknowledge this interrupt located in group 9
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    //
    // End of File
    //
    

    Thanks and Regards

    Harshmeet Singh

  • Hi,
    I check the code, especially the receive. It's not the one customer needs.
    They just need a demo code:
    1) Receive, not transmit
    2) FIFO receive, to save all the objects (with different ID)
    3) Receive with interrupt
    Thanks a lot.
    Br, Jordan
  • Hi Jordan,

    There are two files the receive file has a while(1); which waits for the data to be received and upon receiving data an interrupt is there.

    There is an ISR in the code in the receive code. you will receive objects with different IDs as transmitted by the transmit code.

    Regards

    Harshmeet

  • Harshmeet,
    Another doubt about the CAN FIFO: customer combined 4 objects as FIFO. Which CAN interrupt should they use to receive all of the objects (identify mask is not used, which means all of the objects will be received). Do they need to enable all of the four objects interrupt, or just enable one object interrupt?
    Our target is to enable only one CAN interrupt, to receive all of the objects. Inside the CAN ISR, code checks NewDat and Eob to save all of the objects.
    Thanks a lot.
    Br, Jordan
  • Any feedback?
    Thanks.
    Br Jordan
  • Hi Jordan,

    Sorry i was on leave so couldn't reply.

    Message object Interrupt is needed to be enabled. You need to configure the message box objects.

    I didn't clearly get what you meant by enabling all of the four message object interrupts. Can you explain this question and let me know if this is the answer to your question.

    Thanks and Regards
    Harshmeet Singh
  • Hi, currently only one interrupt is enabled. That object interrupt can happen. But customer said it was not possible to get other objects by NewDat and Eob. My question is, which interrupt should customer use to get the fifo CAN object?
    Br Jordan
  • Hi Jordan,

    There are three interrupts supported by CAN. Message Object, Error and Status Interrupts. The customer needs to enable the Message Object Interrupt.
    The customer needs to configure mailbox in order to get data or wait for some time before sending another data while using the same mailbox.
    Is the customer doing one of the above?

    Regards
    Harshmeet Singh
  • Hi Jordan,

    Was it of any help?

    Regards
    Harshmeet
  • Hi, Harshmeet
    I informed customer the solution, but they failed to receive with FIFO and interrupt.
    Customer is outside for a long time business trip (in Germany). I'm waiting for their back and work with them in the lab.
    This is their first time to work with C2000. Also, I don't have two boards to do the test. If you can provide a code with test, it will be better.
    Thanks a lot.
    Br, Jordan
  • Jordan,

    I use two Launchpads that have transceivers on board. Where one acts as the transmitter and the other as receiver.
    I modified the code a bit to make the transmission reception i can provide you with that code.

    Can you let me know the hardware you are using? Do you have external CAN Transceivers.?

    Regards
    Harshmeet
  • I have no CAN transceivers.
    But customer they have. You can provide me the code and then I send to customer.
    Actually, the key points will be like:
    1) Configure 4 FIFO objects, to receive all of the ID objects
    2) Interrupt to receive and clear the interrupt flag.
    Thanks a lot.
    Br, Jordan
  • Hi Jordan,

    You can't communicate between two CAN controllers without CAN Transceivers.

    1) There are four FIFO objects being configured in the can_external_transmit. These four message objects send data to the second CAN Controller which receives the data. I have done this so that there is no delay between sending data.

    Note: There has to be some delay between two data transmissions if you are using the same message object.

    2) In the can_external_receive there is while(1) which waits for the message object to be received. It goes into the ISR "canaISR()" in the code. There is code to clear the interrupt in the ISR.  After the message is read there is an API CAN_clearInterruptStatus that clears the Interrupt Status so that the next message object can trigger an interrupt. CAN_clearGlobalInterruptStatus and Interrupt_clearACKGroup APIs clear the global interrupt status and the ACKGroup APIs.

    I have two F2837xS Launchpads. There are On chip CAN Transceivers on the control card for CAN A Controller. I connect the CAN H, CAN L and Ground. I run both the codes having two instances of CCS. Now i run the can_external_receive which goes into a wait state to receive data. Then i run the can_external_transmit code and send data. 

    Pointers : The clock configuration and GPIO Configurations have to be correct. Check the message RAM to see that the configuration is done properly and when data is receive checked if it is received in the correct object in the message RAM.

    Thanks and Regards,

    Harshmeet


    Transmit Side Code :

    /cfs-file/__key/communityserver-discussions-components-files/171/can_5F00_external_5F00_transmit.c

    Receive Side Code :

    /cfs-file/__key/communityserver-discussions-components-files/171/can_5F00_external_5F00_receive.c

  • Harshmeet,
    Thanks for your code. I'll pass the code and explain to them.

    Actually I have no CAN transceiver, and I can't write any code to try and test.
    Customer, all of the team are on trip and they also can't provide me the platform to work together.
    Br, Jordan
  • Harshmeet,
    Based on customer's board, we fixed the code and now CAN FIFO works.
    Another two doubts:
    1) The time for data transfer from Message RAM to Interface Registers, in the UG, it says 4~14 clocks. How is it calculated? In customer's application, 1Mbps, external 10MHz clock input, 8 bytes application data. How long does it need for the transfer. What's the max delay time?
    // Wait for busy bit to clear
    while(HWREGH(ui32Base + CAN_O_IF2CMD) & CAN_IF2CMD_BUSY)

    2) In the receive interrupt, how the interrupt works if 3 objects in the FIFO? I mean that, in the ISR, it will only read and clear one object status, and then clear these two. After exiting ISR, other 2 objects still in FIFO. If no new objects received, will the CAN ISR be triggered again, because of the left 2 objects in FIFO?
    //
    // Clear the global interrupt flag for the CAN interrupt line
    //
    CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    //
    // Acknowledge this interrupt located in group 9
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    Thanks a lot.
    Br, Jordan
  • Hi Jordan,

    Sorry for the late reply.

    What was the issue with the code and how did you fix it.

    1) I am not sure but some time back when i did it i used the profiled the API when it came back to the interrupt to get the clock cycles. I am not sure how it is done and the data given in the UG. I can check with someone if you want.

    2) It will read one and clear one object status and then receive the other two.

    Regards
    Harshmeet
  • 2) It will read one and clear one object status and then receive the other two.
    Do you mean that, the other two will still trigger CAN interrupt?
    Br, Jordan
  • Yes Jordan.

    Can you please let me know how you resolved the issue? I am curious about it.

    Regards
    Harshmeet
  • Harshmeet,
    About the issue, first there's configuration error, "EoB" are asked to use to setup the FIFO. Customer used but ISR receive failed, then they changed the config of "EoB". Finally, only one object's FIFO was created. In the ISR, they didn't check "NewDat" for new objects in a loop. They also misunderstand "NewDat" in register CAN_NDAT_21.
    Br, Jordan