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.

TMS320F28384D: Transmissions not observed when BRS is enabled.

Part Number: TMS320F28384D

Tool/software:

Hey,

Similar to this question... I don't observe any transmissions (using a CAN FD Bus Analyzer) occurring between two nodes on my bus when I enable MCAN_TxBufElement.brs & MCAN_InitParams.brsEnable. My setup was working OK when MCAN_InitParams.brsEnable was 0 and MCAN_TxBufElement.brs was 1 but that means my data is also being transmitted at the speed of arbitration. 

I was also checking the example code mcan_config_c28x with mcan_ex2_external_loopback in CM core, and my MCAN_CLK being 25 MHz. When I enable BRS in both MCAN_CCCR and in Tx Buffer Element, I get errors and the program stops at the error breakpoint for the most part but also at the Interrupt ISR error breakpoint a few times. Below is the code I'm working with for your reference:

//#############################################################################
//
// FILE:   mcan_ex2_external_loopback.c
//
// TITLE:  MCAN External Loopback with Interrupt
//
//! \addtogroup driver_example_cm_list
//! <h1> MCAN External Loopback with Interrupt </h1>
//!
//! This example shows the MCAN External Loopback functionality. The external
//! loopback is done between two MCAN Controllers. As there is only one MCAN
//! that exist this example can be changed to make MCAN Transmit or Receive
//! based on define selected. The GPIOs of MCAN should be connected to a CAN
//! Transceiver
//! 
//! Before running this example, please run the mcan_config_c28x example
//! It will initialize the clock, configure the GPIOs.
//!
//! Selection of Mode : A define has to be selected to make the MCAN to
//! transmit or receive.
//!  - TRANSMIT - MCAN to Transmit messages.
//!  - RECEIVE  - MCAN to Receive Messages.
//!
//! Run the example as with RECEIVE Define on one MCAN Controller before
//! running it as Transmit.  
//!
//! \b Hardware \b Required \n
//!  - A C2000 board with CAN transceiver
//!
//! \b External \b Connections \n
//!  - MCAN is on GPIO30 (MCANRXA) and GPIO31 (MCANTXA)
//!
//! \b Watch \b Variables \n
//!  - isrIntr0Flag - The flag has initial value as no. of messages to be
//!                   transmitted and its value decrements after a message is
//!                   transmitted. 
//!  - isrIntr1Flag - The flag has initial value as no. of messages that are
//!                   received and its value decrements after a message is
//!                   successfully received.
//!  - error - Checks if there is an error that occurred when the data was
//!            sent using internal loopback
//!
//
//#############################################################################
//
//
// $Copyright:
// Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

//
// Include Files
//
#include "cm.h"
#include "inc/stw_types.h"
#include "inc/stw_dataTypes.h"

//
// Select one of the Modes.
//
#define TRANSMIT
//#define RECEIVE

//
// Defines.
//
#define NUM_OF_MSG                    (10U)
#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)

//
// Global Variables.
//
volatile uint32_t isrIntr0Flag = NUM_OF_MSG;
volatile uint32_t isrIntr1Flag = NUM_OF_MSG;
volatile uint32_t isrIntrTSFlag = 1U;
int32_t     error = 0;
MCAN_TxBufElement txMsg[NUM_OF_MSG];
MCAN_RxBufElement rxMsg[NUM_OF_MSG], rxMsg1;
int32_t loopCnt = 0U;


//
// Function Prototype.
//
static void MCANConfig(void);
static void MCANIntrConfig(void);
static void MCANIntr0ISR(void);
static void MCANIntr1ISR(void);

void main()
{
#ifdef RECEIVE
    int32_t dataCnt;
#endif
    int i = 0;
    uint32_t numOfMsg = NUM_OF_MSG;
    volatile uint32_t mode = 0U;
    uint32_t dataBytes = 8;
    
    //
    // Switching on the peripheral.
    //
    CM_init();

    //
    // Reset the peripheral.
    //
    SysCtl_resetPeripheral(SYSCTL_PERIPH_RES_MCAN_A);

    //
    // CrossBar and ISR Configuration.
    //
    MCANIntrConfig();
    
    //
    // Initialize message to transmit.
    //
    for(loopCnt = 0U ; loopCnt < numOfMsg ; loopCnt++)
    {
        txMsg[loopCnt].id       = (0x0);
        txMsg[loopCnt].id       = (loopCnt) << 16U;
        txMsg[loopCnt].id       |= (0xFF);
        txMsg[loopCnt].rtr      = 0U;
        txMsg[loopCnt].xtd      = 1U;
        txMsg[loopCnt].esi      = 0U;
        txMsg[loopCnt].dlc      = 15U;
        txMsg[loopCnt].brs      = 1U;
        txMsg[loopCnt].fdf      = 1U;
        txMsg[loopCnt].efc      = 1U;
        txMsg[loopCnt].mm       = 0xAAU;
        txMsg[loopCnt].data[i]  = 0x1;
        for(i = 1; i < dataBytes; i++)
        {
            txMsg[loopCnt].data[i]  = txMsg[loopCnt].data[i-1] + 1;
        }
        i = 0;
    }
    for(loopCnt = 0U ; loopCnt < numOfMsg ; loopCnt++)
    {
        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;
        }
    }

    //
    // Configure the MCAN Module.
    //
    MCANConfig();
    
#ifdef TRANSMIT
    //
    // This is transmitter side application.
    //
     
    // 
    // 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);
    
    //
    // Select Interrupt Line.
    //
    MCAN_selectIntrLine(MCAN0_BASE, MCAN_INTR_MASK_ALL,
                        MCAN_INTR_LINE_NUM_0);
    
    //
    // Enable Interrupt Line.
    //
    MCAN_enableIntrLine(MCAN0_BASE, MCAN_INTR_LINE_NUM_0, 1U);
    
    //
    // Enable Transmission interrupt.
    //
    for(loopCnt = 0U ; loopCnt < numOfMsg ; loopCnt++)
    {
        MCAN_txBufTransIntrEnable(MCAN0_BASE, loopCnt,1);
    
        //
        // Write message to Message RAM.
        //
        MCAN_writeMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_BUF, loopCnt,
                         &txMsg[loopCnt]);
    }
    
    //
    // Add request for all transmission.
    //
    HWREG(MCAN0_BASE + MCAN_TXBAR) = 0x000003FF;
                
    //
    // Wait till the flag becomes zero and all the messages are transmitted.
    //
    while(isrIntr0Flag)
    {
    }
#endif
#ifdef RECEIVE
    //
    // This is receiver side application.
    // 

    //
    // 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);
    
    //
    // Select Interrupt Line.
    //
    MCAN_selectIntrLine(MCAN0_BASE, MCAN_INTR_MASK_ALL,
                        MCAN_INTR_LINE_NUM_1);
    //
    // Enable Interrupt Line.
    //
    MCAN_enableIntrLine(MCAN0_BASE, MCAN_INTR_LINE_NUM_1, 1U);
    
    while(1)
    {

    //
    // Wait till the interrupt flag becomes zero.
    //
    while(isrIntr1Flag)
    {
    }

    for(loopCnt = 0U ; loopCnt < numOfMsg;loopCnt++)
    {
        MCAN_readMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_FIFO, 0U,
                        MCAN_RX_FIFO_NUM_1, &rxMsg1);
        MCAN_writeRxFIFOAck(MCAN0_BASE, MCAN_RX_FIFO_NUM_1,
                            loopCnt);
        rxMsg[loopCnt] = rxMsg1;
    }
                
    for(loopCnt = 0U ; loopCnt < numOfMsg ; loopCnt++)
    {

        if (rxMsg[loopCnt].id  != txMsg[loopCnt].id)
        {
            error++;
        }
        if (rxMsg[loopCnt].rtr != txMsg[loopCnt].rtr)
        {
            error++;
        }
        if (rxMsg[loopCnt].xtd != txMsg[loopCnt].xtd)
        {
            error++;
        }
        if (rxMsg[loopCnt].esi != txMsg[loopCnt].esi)
        {
            error++;
        }
        if (rxMsg[loopCnt].dlc != txMsg[loopCnt].dlc)
        {
            error++;
        }
        if (rxMsg[loopCnt].brs != txMsg[loopCnt].brs)
        {
            error++;
        }
        if (rxMsg[loopCnt].fdf != txMsg[loopCnt].fdf)
        {
            error++;
        }
        
        if (loopCnt > 0)
        {
            if (rxMsg[loopCnt].rxts > rxMsg[loopCnt-1].rxts)
            {
            }
            else
            {
                error++;
            }
        }

        for (dataCnt = 0U ; dataCnt < dataBytes ; dataCnt++)
        {
            if (rxMsg[loopCnt].data[dataCnt]!=
                txMsg[loopCnt].data[dataCnt])
            {
                error++;
            }
        }
    }
#endif
    if (error != 0)
    {
        //
        // Stop if there is an error.
        //
        __asm("   bkpt #0");
    }
    
    //
    // Stop Application.
    //
    __asm("   bkpt #0");
}
}
static void MCANIntrConfig(void)
{
    Interrupt_registerHandler(INT_MCANSS_0,&MCANIntr0ISR);
    Interrupt_enable(INT_MCANSS_0);
    Interrupt_registerHandler(INT_MCANSS_1,&MCANIntr1ISR);
    Interrupt_enable(INT_MCANSS_1);
    Interrupt_enableInProcessor();
}
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; // Enable automatic retransmission of messages
                                         // that were not transmitted successfully.
    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  = (0x9U << 16U);
    extFiltelem.efid2 |= 0xFFU;
    extFiltelem.efid1  = (0x0U << 16U);
    extFiltelem.efid1 |= 0xFFU;
    extFiltelem.efec   = 0x6U;
    extFiltelem.eft    = 0x0U;

    //
    // Initialize bit timings.
    //
    bitTimes.nomRatePrescalar   = 0x9U; // Nominal Baud Rate Pre-scaler.
    bitTimes.nomTimeSeg1        = 0x1U; // Nominal Time segment before sample point.
    bitTimes.nomTimeSeg2        = 0x1U; // Nominal Time segment after sample point.
    bitTimes.nomSynchJumpWidth  = 0x1U; // Nominal (Re)Synchronization Jump Width Range.
    bitTimes.dataRatePrescalar  = 0x0U; // Data Baud Rate Pre-scaler.
    bitTimes.dataTimeSeg1       = 0x1U; // Data Time segment before sample point.
    bitTimes.dataTimeSeg2       = 0x1U; // Data Time segment after sample point.
    bitTimes.dataSynchJumpWidth = 0x1U; // 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))
    {
        
    }
}

static void MCANIntr0ISR(void)
{
    uint32_t intrStatus;

    intrStatus = MCAN_getIntrStatus(MCAN0_BASE);
    MCAN_clearIntrStatus(MCAN0_BASE, intrStatus);
    
    if (MCAN_INTR_SRC_TRANS_COMPLETE == (intrStatus &
         MCAN_INTR_SRC_TRANS_COMPLETE))
    {
        //
        // Decrement the flag after each message is transmitted.
        //
        isrIntr0Flag--;
    }
    else
    {
        //
        // Stop the application if error occurs.
        //
        __asm("   bkpt #0");
    }

}

static void MCANIntr1ISR(void)
{
    uint32_t intrStatus;

    intrStatus = MCAN_getIntrStatus(MCAN0_BASE);
    MCAN_clearIntrStatus(MCAN0_BASE, intrStatus);
    if(MCAN_INTR_SRC_RX_FIFO1_NEW_MSG ==
            (intrStatus & MCAN_INTR_SRC_RX_FIFO1_NEW_MSG))
    {
        //
        // Decrement the flag after each message is received.
        //
        isrIntr1Flag--;
    }
    else
    {
        //
        // Stop the application if error occurs.
        //
        __asm("   bkpt #0");
    }
}
 

This is configured for 500 Kbps Nominal and 5 Mbps Data Bit Rate.

The previous issues I had with my setup are here for any reference. Thanks in advance.

Best,

Nalin

  • Hi Nalin,

    Have you tried using 1Mbps data rate first to see if bit switching works?  Can you also check that the transceiver used with the F28384D is CAN-FD compatible?

    Thanks,

    Joseph

  • Hi Joseph,

    I have tried with 1Mbps under the assumption that 5Mbps was too fast for the setup, and with 500kbps as well (if BRS was disabled all this time, that would mean that the setup ran at nominal bit rate which was 500kbps) but there was no transmission in both these cases.

    We're using the Microchip ATA6561-GAQW-N which does support CAN-FD up to 5Mbps.

    Best,

    Nalin

  • Hi Nalin,

    Thanks for checking.  I'm assuming that you have also set the CAN FD bus analyzer to recognize CAN-FD frames with switching nom and data rates.  In Peak CAN, there is a dialog box where bit switching can be disabled or enabled.

    Regards,

    Joseph

  • Hi Joseph,

    I appreciate the quick response. I have enabled the CAN FD bus analyzer to capture CAN-FD frames. I have a Waveshare CAN FD analyzer that, as you mentioned, has a pop-up that asks for nominal and data bit-rate input.

    Otherwise, I also have a few parameters in my firmware that get updated when there's a successful transmission and reception, so we can rule this case out.

    Thank you,

    Nalin 

  • Hi Nalin,

    Ok, thanks for checking.  Would you have access to an oscilloscope where you can probe the CAN TX pin to capture a CAN frame will the two nodes are communicating?  Wanted to see a capture of the CAN frame from start of frame to the CRC.  Does not have to be accurate but good enough to show the different regions if the CAN frame.  Would be good to have this with 500kbps arb rate and 5Mbps data rate.

    Regards,

    Joseph

  • Hi Joseph,

    I updated my CM clock from 125 MHz to 120 MHz (changed dividers in DEVICE_AUXSETCLOCK_CFG)... With the previous 25 MHz MCAN_CLK, the only configuration for 5 Mbps data bitrate that was possible gave a 60% sample point that I assumed was not too good. With the now 40 MHz MCAN_CLK, and a sample point of 75% ... I see the Tx and Rx between 1 Main and 1 Local node occurred faster.

    Below is my bitrate calculation (previous and current)

    SYS Clock  125 MHz   120 MHz
    CAN Clock Prescaler 5     3
    MCAN CLOCK 25 MHz   40 MHz
         
    NTSEG1 20     15
    NTSEG2 2     2
    SJW 2     2
    Nom PSC 1     3
    Nom Bit Rate 0.5 Mbps 0.5 Mbps
         
    DTSEG1 1     4
    DTSEG2 1     1
    SJW 1     1
    Data PSC 0     0
    Data Bit Rate 5 Mbps 5 Mbps
         
    Nom sample point 88 %   85 %
    Data sample point 60 %   75 %


    and also a few snapshots from the scope of CAN_H for your reference:


    First frame is from the main node requesting data and the consequent 4 frames are from the local node responding with data.


    All the frames with 64 bytes of data are about 200 microsec wide. 

    I wanted to know if the disturbance/noise that you see there is too much (noise at the end of frame and the consistent noise below the axis).
    One other thing I wanted to ask is about TDC. Now that my prescaler is 1 (0+1) and DTSEG1 is 2 (1+1), what should my TDCO and TDCF be?
    I read in a thread here on the forum that both TDCO = TDCF = DTSEG1 (here, 2). 

    All the captures above are with the default TDCO and TDCF from the example codes (TDCO = 0x6 and TDCF = 0xA). If there's any more data that you could use for your conclusion, please let me know.

    Best, 

    Nalin

  • Hi Nalin,

    Thanks for getting the overall plot but really hard to see or focus on the data phase when bitrate switched to 5Mbps.  Can you take a snap from where BRS starts up to where the ACK is received (the last bit that overshoots at the end of frame)?  May be tricky to locate the BRS bit especially if the scope does not have a CAN-FD decoding capability but just start the capture to a few cycles prior when the data periods start to shrink.  Data for one frame should be good.

    Regards,

    Joseph

  • Hi Joseph,

    Apologies for the late reply and also for the unclear images attached, 

    This is the request frame with the ID A231.

    This is the response frame with the ID 1A31 (in response to Master unit's request A131) with the same configuration as the above structure. 

    The frame is a little skewed because I hadn't connected this control card's Isolated Ground to the scope when I captured. 


    This is a zoomed-in capture. I hadn't noted down what the ID for this is but the configuration is the same as the two above.

    I also changed my RXFIFO1 size because there was a mismatch in the number of frames received in the main unit but it has been fixed now.

    I appreciate your time and feedback regarding my issue over the past month or so, Joseph. Thank you very much! It appears I have the system running as per my teams constraints. I'm OK with closing this thread.

    Best regards,

    Nalin

  • Hi Nalin,

    You're welcome.  Having scope shots of data streams in debugging communications issues is a good visual aid on what is happening in transmission lines.  There are few clues offered by inspecting the register status and contents but a capture of the transmitted frame would provide more information.  In this case, you can clearly point out where BRS bit is and soon after that, the bit timing switched to higher rate up until the ACK bit is received, which is the last pulse in the frame with longer period and higher level.

    Glad that you were able to solve your issues and happy to have helped.

    Regards,

    Joseph