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.

TMDSCNCD28388D: CAN-FD RX interrupt

Part Number: TMDSCNCD28388D


Hi

It is connecting with PCANview and checking the communication operation.
From the perspective of PCANview, if the transmit operation is performed periodically, the CANFD receive interrupt on the board occurs only once for the first time, and no interrupt occurs after that.
If the CANFD_Rx_Control() function is called from the CPUTimer interrupt with a cycle of 100us instead of inside the CANFD receive interrupt, it was confirmed that the reception works normally.
When CANFD receive interrupt is used, I wonder why the interrupt occurs only once for the first time and the interrupt does not work after that.

Are there any registers related to rx that are not cleared? Please help.

#define NUM_OF_MSG                    (1U)
#define MCAN_STD_ID_FILT_START_ADDR   (0U)
#define MCAN_STD_ID_FILTER_NUM        (1U)
#define MCAN_EXT_ID_FILT_START_ADDR   (48U)
#define MCAN_EXT_ID_FILTER_NUM        (1U)
#define MCAN_TX_EVENT_START_ADDR      (100U)
#define MCAN_TX_EVENT_SIZE            (NUM_OF_MSG)
#define MCAN_TX_EVENT_WATERMARK       (NUM_OF_MSG/2)
#define MCAN_TX_BUFF_START_ADDR       (148U)
#define MCAN_TX_BUFF_SIZE             (NUM_OF_MSG)
#define MCAN_TX_FIFO_SIZE             (NUM_OF_MSG)
#define MCAN_FIFO_0_START_ADDR        (548U)
#define MCAN_FIFO_0_NUM               (NUM_OF_MSG)
#define MCAN_FIFO_0_WATERMARK         (NUM_OF_MSG)
#define MCAN_FIFO_1_START_ADDR        (748U)
#define MCAN_FIFO_1_NUM               (NUM_OF_MSG)
#define MCAN_FIFO_1_WATERMARK         (NUM_OF_MSG)
#define MCAN_RX_BUFF_START_ADDR       (948U)
#define MCAN_EXT_ID_AND_MASK          (0x1FFFFFFFU)
#define MCAN_TS_PRESCALAR             (0xB0)

#define MCAN_TX_BUFF_ELEM_SIZE       (MCAN_ELEM_SIZE_64Bytes)
#define MCAN_RX_BUFF_ELEM_SIZE       (MCAN_ELEM_SIZE_64Bytes)
#define MCAN_RX_FIFO0_ELEM_SIZE      (MCAN_ELEM_SIZE_64Bytes)
#define MCAN_RX_FIFO1_ELEM_SIZE      (MCAN_ELEM_SIZE_64Bytes)


void CANFD_Init(void);
static void MCANConfig(void);
void MCANIntrConfig(void);
__interrupt void MCANIntr1ISR(void);

MCAN_RxBufElement    CANFD_rxMsg;
MCAN_RxFIFOStatus    RxFS;

void CANFD_Rx_DATA()
{
    if(CANFD_rxMsg.id==0x100)
    {
        CANFD_DATA.Rx_Test[0] = CANFD_rxMsg.data[0];
        CANFD_DATA.Rx_Test[1] = CANFD_rxMsg.data[1];
        CANFD_DATA.Rx_Test[2] = CANFD_rxMsg.data[2];
        CANFD_DATA.Rx_Test[3] = CANFD_rxMsg.data[3];
        CANFD_DATA.Rx_Test[4] = CANFD_rxMsg.data[4];
        CANFD_DATA.Rx_Test[5] = CANFD_rxMsg.data[5];
        CANFD_DATA.Rx_Test[6] = CANFD_rxMsg.data[6];
        CANFD_DATA.Rx_Test[7] = CANFD_rxMsg.data[7];
    }
}
void CANFD_Rx_Control(void)
{
    // Read Message RAM.
    MCAN_readMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_FIFO, 0U, MCAN_RX_FIFO_NUM_1, &CANFD_rxMsg);
    RxFS.num = MCAN_RX_FIFO_NUM_1;
    MCAN_getRxFIFOStatus(MCAN0_BASE, &RxFS);
    MCAN_writeRxFIFOAck(MCAN0_BASE, MCAN_RX_FIFO_NUM_1, RxFS.getIdx);
    CANFD_Rx_DATA();
}

int canfd_rx_isr_fail1=0, isrIntr1Flag=0, canfdRxIsrCnt0=0, canfdRxIsrCnt1=0;
uint32_t intrStatus1;
__interrupt void MCANIntr1ISR(void)
{
    //uint32_t intrStatus;
    canfdRxIsrCnt1++;

    intrStatus1 = MCAN_getIntrStatus(MCAN0_BASE);
    if( MCAN_INTR_SRC_RX_FIFO1_NEW_MSG == (intrStatus1 & MCAN_INTR_SRC_RX_FIFO1_NEW_MSG) )
    {
        //
        // Decrement the flag after each message is received.
        //
        isrIntr1Flag++;
        CANFD_Rx_Control();
    }
    else
    {
        canfd_rx_isr_fail1++;
    }
    MCAN_clearIntrStatus(MCAN0_BASE, intrStatus1);

    // Acknowledge this interrupt located in group 9
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}


void CANFD_Init(void)
{
    int i = 0;

    //
    // Allocated MCAN shared peripheral to C28x
    //
    SysCtl_allocateSharedPeripheral(SYSCTL_PALLOCATE_MCAN_A,0x0U);
    //
    // Setting the MCAN Clock.
    //
    SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_10);
    //
    // Configuring the GPIOs for MCAN.
    //
    GPIO_setPinConfig(DEVICE_GPIO_CFG_MCANRXA);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_MCANTXA);

    // Initialize message to transmit.
    CANFD_txMsg.id       = ((uint32_t)(0x11)); // Identifier Value.
    CANFD_txMsg.rtr      = 0U;          // Transmit data frame.
    CANFD_txMsg.xtd      = 1U;          // extended identifier
    CANFD_txMsg.esi      = 0U;          // ESI bit in CAN FD format depends only on error
                                        // passive flag.
    CANFD_txMsg.dlc      = 15U;         // CAN FD: transmit frame has 12/16/20/24/32/48/64 data bytes
    CANFD_txMsg.brs      = 1U;          // CAN FD frames transmitted with bit rate
                                        // switching.
    CANFD_txMsg.fdf      = 1U;          // Frame transmitted in CAN FD format.
    CANFD_txMsg.efc      = 1U;          // Store Tx events.
    CANFD_txMsg.mm       = 0xAAU;       // Message Marker.

    // Data bytes.
    for(i=0;i<64;i++)
    {
        CANFD_txMsg.data[i]  = i;
    }

    // CrossBar and ISR Configuration.
    MCANIntrConfig();

    // Configure MCAN.
    MCANConfig();

    // Enable Interrupts.
    MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_MASK_ALL,1);
    MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_SRC_RES_ADDR_ACCESS|
                    MCAN_INTR_SRC_TIMESTAMP_WRAPAROUND,0);
    MCAN_selectIntrLine(MCAN0_BASE, MCAN_INTR_SRC_RX_FIFO1_NEW_MSG,
                        MCAN_INTR_LINE_NUM_1);
    MCAN_enableIntrLine(MCAN0_BASE, MCAN_INTR_LINE_NUM_1, 1U);
}


void MCANIntrConfig(void)
{
    Interrupt_register(INT_MCANSS1,&MCANIntr1ISR);
    Interrupt_enable(INT_MCANSS1);

    Interrupt_enableMaster();
}

// This function will configure MCAN module.
//
static void MCANConfig(void)
{
    MCAN_RevisionId revId;
    MCAN_InitParams initParams;
    MCAN_ConfigParams configParams;
    MCAN_MsgRAMConfigParams    msgRAMConfigParams;
    MCAN_StdMsgIDFilterElement stdFiltelem;
    MCAN_ExtMsgIDFilterElement extFiltelem;
    MCAN_BitTimingParams       bitTimes;

    //
    // Initialize MCAN Init parameters.
    //
    initParams.fdMode            = 0x1U; // FD operation disabled.
    initParams.brsEnable         = 0x1U; // Bit rate switching for
                                         // transmissions enabled.
    initParams.txpEnable         = 0x1U; // Transmit pause enabled.
    initParams.efbi              = 0x0U; // Edge filtering disabled.
    initParams.pxhddisable       = 0x0U; // Protocol exception handling enabled.
    initParams.darEnable         = 0x1U; // Automatic retransmission of messages
                                         // not transmitted successfully enabled.
    initParams.wkupReqEnable     = 0x1U; // Wakeup request is enabled.
    initParams.autoWkupEnable    = 0x1U; // Auto-Wakeup is enabled.
    initParams.emulationEnable   = 0x1U; // Emulation/Debug Suspend is enabled.
    initParams.tdcEnable         = 0x1U; // Transmitter Delay Compensation is
                                         // enabled.
    initParams.wdcPreload        = 0xFFU; // Start value of the Message RAM
                                          // Watchdog Counter preload.

    //
    // Transmitter Delay Compensation parameters.
    //
    initParams.tdcConfig.tdcf    = 0xAU;
    initParams.tdcConfig.tdco    = 0x6U;

    //
    // Initialize MCAN Config parameters.
    //
    configParams.monEnable       = 0x0U; // Bus Monitoring Mode is disabled.
    configParams.asmEnable       = 0x0U; // Normal CAN operation.
    configParams.tsPrescalar       = 0x2U; // Prescaler Value.
    configParams.tsSelect          = 0x2U; // Timestamp counter value.
    configParams.timeoutSelect     = MCAN_TIMEOUT_SELECT_CONT;
    // Time-out counter source select.
    configParams.timeoutPreload    = 0xFFFFU;// Start value of the Timeout
                                             // Counter.
    configParams.timeoutCntEnable  = 0x0U; // Time-out Counter is disabled.
    configParams.filterConfig.rrfs = 0x1U; // Reject all remote frames with
                                           // 29-bit extended IDs.
    configParams.filterConfig.rrfe = 0x1U; // Reject all remote frames with
                                           // 11-bit standard IDs.
    configParams.filterConfig.anfe = 0x1U; // Accept in Rx FIFO 1.
    configParams.filterConfig.anfs = 0x1U; // Accept in Rx FIFO 1.

    //
    // Initialize Message RAM Sections Configuration Parameters
    //
    msgRAMConfigParams.flssa                = MCAN_STD_ID_FILT_START_ADDR;
    // Standard ID Filter List Start Address.
    msgRAMConfigParams.lss                  = MCAN_STD_ID_FILTER_NUM;
    // List Size: Standard ID.
    msgRAMConfigParams.flesa                = MCAN_EXT_ID_FILT_START_ADDR;
    // Extended ID Filter List Start Address.
    msgRAMConfigParams.lse                  = MCAN_EXT_ID_FILTER_NUM;
    // List Size: Extended ID.
    msgRAMConfigParams.txStartAddr          = MCAN_TX_BUFF_START_ADDR;
    // Tx Buffers Start Address.
    msgRAMConfigParams.txBufNum             = MCAN_TX_BUFF_SIZE;
    // Number of Dedicated Transmit Buffers.
    msgRAMConfigParams.txFIFOSize           = MCAN_TX_FIFO_SIZE;
    // Tx FIFO/Queue.
    msgRAMConfigParams.txBufMode            = 0U;
    msgRAMConfigParams.txBufElemSize        = MCAN_ELEM_SIZE_64BYTES;
  // Tx Buffer Element Size.
    msgRAMConfigParams.txEventFIFOStartAddr = MCAN_TX_EVENT_START_ADDR;
    // Tx Event FIFO Start Address.
    msgRAMConfigParams.txEventFIFOSize      = MCAN_TX_BUFF_SIZE;
    // Event FIFO Size.
    msgRAMConfigParams.txEventFIFOWaterMark = MCAN_TX_EVENT_WATERMARK;
    // Level for Tx Event FIFO watermark interrupt.
    msgRAMConfigParams.rxFIFO0startAddr     = MCAN_FIFO_0_START_ADDR;
    // Rx FIFO0 Start Address.
    msgRAMConfigParams.rxFIFO0size          = MCAN_FIFO_0_NUM;
    // Number of Rx FIFO elements.
    msgRAMConfigParams.rxFIFO0waterMark     = MCAN_FIFO_0_WATERMARK;
    msgRAMConfigParams.rxFIFO0OpMode        = 0U;
    msgRAMConfigParams.rxFIFO1startAddr     = MCAN_FIFO_1_START_ADDR;
    // Rx FIFO1 Start Address.
    msgRAMConfigParams.rxFIFO1size          = MCAN_FIFO_1_NUM;
    // Number of Rx FIFO elements.
    msgRAMConfigParams.rxFIFO1waterMark     = MCAN_FIFO_1_WATERMARK;
    // Level for Rx FIFO 1 watermark interrupt.
    msgRAMConfigParams.rxFIFO1OpMode        = 0U; // FIFO blocking mode.
    msgRAMConfigParams.rxBufStartAddr       = MCAN_RX_BUFF_START_ADDR;
    // Rx Buffer Start Address.
    msgRAMConfigParams.rxBufElemSize        = MCAN_ELEM_SIZE_64BYTES;
    // Rx Buffer Element Size.
    msgRAMConfigParams.rxFIFO0ElemSize      = MCAN_ELEM_SIZE_64BYTES;
    // Rx FIFO0 Element Size.
    msgRAMConfigParams.rxFIFO1ElemSize      = MCAN_ELEM_SIZE_64BYTES;
    // Rx FIFO1 Element Size.

    //
    // Initialize Tx Buffer Configuration parameters.
    //
    stdFiltelem.sfid2              = 0x0U; // Standard Filter ID 2.
    stdFiltelem.sfid1              = 0x4U; // Standard Filter ID 1.
    stdFiltelem.sfec               = 0x7U; // Store into Rx Buffer or as
                           // debug message, configuration of SFT[1:0] ignored.
    stdFiltelem.sft                = 0x0U; // Range filter from SFID1 to SFID2.

    //
    // Initialize Tx Buffer Configuration parameters.
    //
    extFiltelem.efid2  = ((Uint32)0x9U << 16U);
    extFiltelem.efid2 |= 0xFFU;
    extFiltelem.efid1  = ((Uint32)0x0U << 16U);
    extFiltelem.efid1 |= 0xFFU;
    extFiltelem.efec   = 0x6U;
    extFiltelem.eft    = 0x0U;

    //
    // Initialize bit timings.
    //
    // Nominal = 1M  / Data = 2M
    bitTimes.nomRatePrescalar   = 0x4U; // Nominal Baud Rate Pre-scaler.
    bitTimes.nomTimeSeg1        = 0x1U; // Nominal Time segment before sample point.
    bitTimes.nomTimeSeg2        = 0x0U; // Nominal Time segment after sample point.
    bitTimes.nomSynchJumpWidth  = 0x0U; // Nominal (Re)Synchronization Jump Width Range.
    bitTimes.dataRatePrescalar  = 0x1U; // Data Baud Rate Pre-scaler.
    bitTimes.dataTimeSeg1       = 0x2U; // Data Time segment before sample point.
    bitTimes.dataTimeSeg2       = 0x0U; // Data Time segment after sample point.
    bitTimes.dataSynchJumpWidth = 0x0U; // Data (Re)Synchronization Jump Width.

    //
    // Get MCANSS Revision ID
    //
    MCAN_getRevisionId(MCAN0_BASE, &revId);

    //
    // Wait for memory initialization to happen.
    //
    while(FALSE == MCAN_isMemInitDone(MCAN0_BASE))
    {
    }

    //
    // Put MCAN in SW initialization mode.
    //
    MCAN_setOpMode(MCAN0_BASE, MCAN_OPERATION_MODE_SW_INIT);

    //
    // Wait till MCAN is not initialized.
    //
    while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(MCAN0_BASE))
    {}

    //
    // Initialize MCAN module.
    //
    MCAN_init(MCAN0_BASE, &initParams);

    //
    // Configure MCAN module.
    //
    MCAN_config(MCAN0_BASE, &configParams);

    //
    // Disable external timeStamp overflow interrupt.
    //
    MCAN_extTSEnableIntr(MCAN0_BASE,1);

    //
    // Configure TimeStamp Counter.
    //
    MCAN_extTSCounterConfig(MCAN0_BASE, MCAN_TS_PRESCALAR);

    //
    // Configure Bit timings.
    //
    MCAN_setBitTime(MCAN0_BASE, &bitTimes);

    //
    // Set Extended ID Mask.
    //
    MCAN_setExtIDAndMask(MCAN0_BASE, MCAN_EXT_ID_AND_MASK);

    //
    // Configure Message RAM Sections
    //
    MCAN_msgRAMConfig(MCAN0_BASE, &msgRAMConfigParams);

    //
    // Configure Standard ID filter element
    //
    MCAN_addStdMsgIDFilter(MCAN0_BASE, 0U, &stdFiltelem);

    //
    // Configure Extended ID filter element
    //
    MCAN_addExtMsgIDFilter(MCAN0_BASE, 0U, &extFiltelem);

    //
    // Enable external counter.
    //
    //MCAN_extTSCounterEnable(MCAN0_BASE, 1U);

    //
    // Take MCAN out of the SW initialization mode
    //
    MCAN_setOpMode(MCAN0_BASE, MCAN_OPERATION_MODE_NORMAL);

    while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(MCAN0_BASE))
    {

    }
}