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.

TMS320F280037-Q1: Do we have the MCAN demo code based on sysconifg

Part Number: TMS320F280037-Q1
Other Parts Discussed in Thread: SYSCONFIG, C2000WARE

Hi team,

I ask this for my customer.

1.Do we have the MCAN demo based on sysconfig to realize the range filter, disable CAN-FD, Bit rate switching, bit rate is 500kbps. use FIFO to receive the message(range filter), blocking mode

2.In our sysconfig it seems it isn't have extend filter

3.If customer use RX buffer, they can't realize the range filter?
image.png 

4. Customer try to use sysconfig to realize the CAN range filter

And they set below:

image.png

image.png

image.png

image.png

image.png

they use filter element 14 to realize the range fliter and store the data to FIFO, but they finds if they set the opreation mode to overwrite mode, it can receive the data; but if they change it to blocking mode, they just can receive one message frame. Could you help to check this? Is any other opreation needed to do if they use blocking mode? I compare the ISR operation between their code and mcan_ex8_range_filter_receive demo ISR code, don't find any difference

 

BRs

Shuqing

 

  • Hi Shuqing,

    No, I don't have other MCAN example than in the SDK.

    2.In our sysconfig it seems it isn't have extend filter

    I also noticed there is no extend ID filter configuration.

    3.If customer use RX buffer, they can't realize the range filter?

    The range filter is only for FIFOs.

    To store the message to a dedicated RX buffer, SPEC=0x7 and SFID2[10:9]=0x0 should be configured. The SFID[5:0] is the offset of the RX buffer start address

    Could you help to check this? Is any other opreation needed to do if they use blocking mode?

    If the RX FIFO is full (put index = get index), no further message is written to the FIFO. You need to read out at least one message from the FIFO, then program F0AI register to update the Get Index of RXF0S register.

  • Hi Qingjun

    I want to develop a demo based on sysconfig, that is use data bit switching, standard filter: mcan_ex8_range_filter_receive_syscfg.zip

    But I just can receive the first two frame, and can't receive the correct frame ID, could you help to check this?

    BRs

    Shuqing

  • Hi Shuqing,

    I will take a look, then give you my comments tomorrow. 

  • Hi Shuqing,

    I noticed that the SDK API MCAN_readMsgRam() can not be used directly to read FIFO. You need to write another function to check the index and fill level, then use this API to read all the buffers from the FIFO.

  • Hi,

    I re-wrote the function for MCAN FIFO read. I haven't got chance to test it. Please try it. 

    //
    // Include Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    #include "inc/stw_types.h"
    #include "inc/stw_dataTypes.h"
    #include <string.h>
    
    // Global Variables.
    int32_t     error = 0;
    MCAN_RxBufElement rxMsg[myMCAN0_MCAN_FIFO_1_NUM], rxMsg1;
    MCAN_RxFIFOStatus RxFS;
    int32_t loopCnt = 0U;
    
    // Function Prototype.
    static void MCANIntrConfig(void);
    static void MCAN_ReadRxFIFO(uint32_t baseAddr, uint32_t fifoNum, MCAN_RxBufElement *rxMsg);
    
    void main()
     {
        int i = 0;
        volatile uint32_t mode = 0U;
        uint32_t dataBytes = 64;
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Initialize GPIO and unlock the GPIO configuration registers
        //
        Device_initGPIO();
    
        //
        // Configure the divisor for the MCAN bit-clock
        //
        SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_3);
    
        //
        // ISR Configuration.
        //
        MCANIntrConfig();
    
        Board_init();
    
        //
        // Initialize receive data structure
        // (not to be confused with RX Buffer inside the MCAN module)
        //
        rxMsg[loopCnt].id = 0U;
        rxMsg[loopCnt].rtr = 0U;
        rxMsg[loopCnt].xtd = 0U;
        rxMsg[loopCnt].esi = 0U;
        rxMsg[loopCnt].rxts = 0U;
        rxMsg[loopCnt].dlc = 0U;
        rxMsg[loopCnt].brs = 0U;
        rxMsg[loopCnt].fdf = 0U;
        rxMsg[loopCnt].fidx = 0U;
        rxMsg[loopCnt].anmf = 0U;
        for(i = 0; i < dataBytes; i++)
        {
            rxMsg[loopCnt].data[i]  = 0;
        }
    
        while(1)
        {
            //  Adding delay of 1 second
            DEVICE_DELAY_US(1000000);
    
            //  Message Handling Code goes here
        }
    
        // Stop Application.
        asm("   ESTOP0");
    }
    
    // This function will configure X-BAR for MCAN interrupts.
    static void MCANIntrConfig(void)
    {
        Interrupt_initModule();
        Interrupt_initVectorTable();
        Interrupt_enableGlobal();
    }
    
    // This is Interrupt Service Routine for MCAN interrupt 1.
    void INT_myMCAN0_1_ISR(void)
    {
        uint32_t intrStatus;
    
        intrStatus = MCAN_getIntrStatus(myMCAN0_BASE);
    
        // Clear the interrupt Status.
        MCAN_clearIntrStatus(myMCAN0_BASE, intrStatus);
    
        //  Clearing the interrupt lineNum
        MCAN_clearInterrupt(myMCAN0_BASE, 0x2);
    
        //  Check to see if the interrupt is caused by a new message being
        //  received in RX FIFO 1
        if((MCAN_INTR_SRC_RX_FIFO1_NEW_MSG & intrStatus) == MCAN_INTR_SRC_RX_FIFO1_NEW_MSG)
        {
            MCAN_ReadRxFIFO(myMCAN0_BASE, MCAN_RX_FIFO_NUM_1, &rxMsg);
        }
        else
        {
            error++;
            //  Interrupt handling for other interrupt sources goes here
        }
    
        // Acknowledge this interrupt located in group 9
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    #define CAN_ID_STD                        (0x0U)
    #define CAN_ID_XTD                        (0x1U)
    #define CAN_XTD_MSGID_MASK                ((uint32_t)0x1fffffffU)
    #define CAN_STD_MSGID_MASK                ((uint32_t)0x7ffU)
    #define CAN_STD_MSGID_SHIFT               ((uint32_t)18U)
    #define CAN_MSG_TYPE_MASK                 ((uint32_t)0x40000000U)
    #define CAN_MSG_ID_TYPE_EXT               ((uint32_t)0x80000000U)
    
    static void MCAN_ReadRxFIFO(uint32_t baseAddr, uint32_t fifoNum, MCAN_RxBufElement *rxMsg)
    {
       uint32_t fillLvl = (uint32_t)0;
       uint32_t loopCnt = (uint32_t)0;
       uint8_t canDataLength = (uint8_t)0;
       uint32_t canIdentifier = (uint32_t)0;
       uint32_t byteCnt = (uint32_t)0;
       MCAN_RxFIFOStatus fifoStatus = {0};
       MCAN_RxBufElement elem = {0};
    
     //  baseAddr = controllerObj->canControllerConfig.CntrAddr;
       fifoStatus.num = fifoNum;
    
       /* Get Rx FIFO status */
       MCAN_getRxFIFOStatus(baseAddr, &fifoStatus);
       fillLvl = fifoStatus.fillLvl;
    
       for (loopCnt = 0; loopCnt < fillLvl; loopCnt++)
       {
           MCAN_getRxFIFOStatus(baseAddr, &fifoStatus);
           MCAN_readMsgRam(baseAddr,
                           MCAN_MEM_TYPE_FIFO,
                           fifoStatus.getIdx, /*buff number*/
                           fifoNum,
                           &elem);
    
          MCAN_writeRxFIFOAck(baseAddr, fifoNum, fifoStatus.getIdx);
    
          canDataLength = MCAN_getMsgObjSize(elem.dlc);
    
          if ((uint8_t)CAN_ID_XTD == elem.xtd)
          {
             /* Received frame with Extended ID - set MSB to '1' */
             canIdentifier = ((uint32_t)elem.id | CAN_MSG_ID_TYPE_EXT);
          }
          else
          {
             /* Received frame with Standard ID */
             canIdentifier = (((uint32_t)elem.id >> CAN_STD_MSGID_SHIFT) & CAN_STD_MSGID_MASK);
          }
    
          /* Set CAN-FD bit (30th bit) to '1' if CAN-FD frame is received */
          canIdentifier = (canIdentifier | ((uint32_t)elem.fdf << 30U));
    
          for (byteCnt = 0; byteCnt < canDataLength; byteCnt++)
          {
              rxMsg[loopCnt].data[byteCnt] = (uint8_t)elem.data[byteCnt];
          }
    
          rxMsg[loopCnt].id = canIdentifier;
          rxMsg[loopCnt].xtd = elem.xtd;
          rxMsg[loopCnt].dlc = elem.dlc;
          rxMsg[loopCnt].fdf = elem.fdf;
       }
    }
    

  • Hi Qingjun,

    I don't think this is the ISR code problem

    In our demo: mcan_ex8_range_filter_receive, it isn't use the syscfg and can run normally

    Because customer don't use CAN-FD and extend ID filter, I change the demo to configurate the CAN is classic CAN, use standard ID filter: mcan_ex8_range_filter_receive.zip

    This demo can work normally and receive the frame when the ID in the range of 0x12~0x17 consecutively

    But when I use the sysconfig to do the mcan configuration, I can't receive the data frame: 1616.mcan_ex8_range_filter_receive_syscfg.zip

    I compare the register when the code run, just below register value is difference:

    1. MCAN_HPMS, if use syscofig, the value is 0x000000C0; If I don't use, the value is 0x00000000

    2.MCAN_RXBC, but I don't use RX buffer, so I think is not matter

    3. MCAN_TDCR, but I don't enable the TDC, so I think is no matter

    4. MCAN_RXESC

    And some register value will change when I send the frame to c2000

    when I load the code to chip and run, and isn't send the data to c2000, use sysconfig and not use sysconfig project code PSR_LEC is 111

    Then I send the first data frame to c2000, the PSR_LEC will change to 000 in sysconfig project and not using sysconfig project

    but if i don't use sysconfig, the IR will change to 0x00000070

    the I send the data frame to c2000 again, the IR will change to 0x000000F0. In this process, the IR will always 0 if I don't use sysconfig to configurate the MCAN

    BRs

    Shuqing

  • In our demo: mcan_ex8_range_filter_receive, it isn't use the syscfg and can run normally

    If number of buffers in the FIFO is one, original demo works. Otherwise, it won't be able to read all the message from the FIFO correctly. There is no such example in C2000ware.

    1. MCAN_HPMS, if use syscofig, the value is 0x000000C0; If I don't use, the value is 0x00000000

    Sysconfig: 0xC --> MSI=b11 which means that the message is stored in FIFO 1. It is expected.

    No sysconfig: 0x00, no FIFO is used

    2.MCAN_RXBC, but I don't use RX buffer, so I think is not matter

    doesn't matter because the dedicated RX buffer is not used

    3. MCAN_TDCR, but I don't enable the TDC, so I think is no matter

    It does matter CAN-FD. It is for TX delay compensation. Is TDC enabled in DBTP register?

    4. MCAN_RXESC

    FIFO1 is 64 bytes data field, and FIFO0 is 8 bytes data field. Both are fine

    I send the data frame to c2000 again, the IR will change to 0x000000F0

    The RX FIFO1 new message, watermark, and Full (only one buffer in your config) flags are set. This means you have received a new message. it is expected, right?

  • Hi Qingjun,

    1. Below value in sysconfig is not correct, right? Is it caused by sysconfig bug?

    Sysconfig: 0xC --> MSI=b11 which means that the message is stored in FIFO 1. It is expected.

    No sysconfig: 0x00, no FIFO is used

    2. This is because the new message is received but lost, but why this happen?

    The RX FIFO1 new message, watermark, and Full (only one buffer in your config) flags are set. This means you have received a new message. it is expected, right?

    BRs

    Shuqing

  • The FIFO size is 1 in your config. Have you tried 2 or 3 of FIFO size? 

    am not sure if it is a bug or not, MSI=b11 is not used anyway.