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.

[参考译文] TMS320F2800157:MCAN

Guru**** 2539500 points
Other Parts Discussed in Thread: C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1270896/tms320f2800157-mcan

器件型号:TMS320F2800157
主题中讨论的其他器件:C2000WARE

您好、E2E 团队:

我正在使用 LUNCHXL-F2800157进行 MCAN 通信。我的环回 TX 和 Rx 面临问题。

在将示波器连接到 CAN 总线时、Rx 缓冲区中也传输唯一的标识符数据包比预期的小

我在代码块中附加了 main.c。  

请帮助了解我操作错误的地方、我已将寄存器与典型 TX 和环回的给定示例进行了比较

/* Author by : Ram singh
 * Date :09/11/2023
 * File : main.c
 */

//MCU specific includes
#include "f28x_project.h"
//#include "mcan.h"


//USER INCLUDE FILES


//User define Macros
#define MCAN_MAX_PAYLOAD_BYTES  8U ;

//
// Defines
//
#define MCAN_STD_ID_FILTER_NUM          (0U)
#define MCAN_EXT_ID_FILTER_NUM          (0U)
#define MCAN_FIFO_0_NUM                 (0U)
#define MCAN_FIFO_0_ELEM_SIZE           (MCAN_ELEM_SIZE_8BYTES)
#define MCAN_FIFO_1_NUM                 (10U)
#define MCAN_FIFO_1_ELEM_SIZE           (MCAN_ELEM_SIZE_8BYTES)
#define MCAN_RX_BUFF_NUM                (10U)
#define MCAN_RX_BUFF_ELEM_SIZE          (MCAN_ELEM_SIZE_8BYTES)
#define MCAN_TX_BUFF_SIZE               (1U)
#define MCAN_TX_BUFF_ELEM_SIZE          (MCAN_ELEM_SIZE_8BYTES)
#define MCAN_TX_EVENT_SIZE              (10U)
#define MCAN_EXT_ID_AND_MASK            (0x1FFFFFFFU)
//#define MCAN_MSG_INT                    (0x81200)

/**
 * \brief  Macro for standard Message ID filter.
 */
#define MCANSS_STD_ID_FILTER_SIZE_WORDS                          (1U)

/**
 * \brief  Macro for extended Message ID filter.
 */
#define MCANSS_EXT_ID_FILTER_SIZE_WORDS                          (2U)

//
//  Defining Starting Addresses for Message RAM Sections,
//  (Calculated from Macros based on User defined configuration above)
//
#define MCAN_STD_ID_FILT_START_ADDR     (0x0U)
#define MCAN_EXT_ID_FILT_START_ADDR     (MCAN_STD_ID_FILT_START_ADDR + ((MCAN_STD_ID_FILTER_NUM * MCANSS_STD_ID_FILTER_SIZE_WORDS * 4U)))
#define MCAN_FIFO_0_START_ADDR          (MCAN_EXT_ID_FILT_START_ADDR + ((MCAN_EXT_ID_FILTER_NUM * MCANSS_EXT_ID_FILTER_SIZE_WORDS * 4U)))
#define MCAN_FIFO_1_START_ADDR          (MCAN_FIFO_0_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_0_ELEM_SIZE) * 4U * MCAN_FIFO_0_NUM))
#define MCAN_RX_BUFF_START_ADDR         (MCAN_FIFO_1_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_1_ELEM_SIZE) * 4U * MCAN_FIFO_1_NUM))
#define MCAN_TX_BUFF_START_ADDR         (MCAN_RX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_RX_BUFF_ELEM_SIZE) * 4U * MCAN_RX_BUFF_NUM))
#define MCAN_TX_EVENT_START_ADDR        (MCAN_TX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_TX_BUFF_ELEM_SIZE) * 4U * MCAN_TX_BUFF_SIZE))

//User function Prototypes
void MCANInit(void);
int GpioInit(void);

//Global variable

int32_t     error = 0;
int32_t loopCnt = 0U;
static uint32_t objSize[8] = {4, 5, 6, 7, 8, 10, 14, 18};

/**
 *  \brief    Enum to represent FIFO/Buffer element Size
 */
typedef enum
{
    MCAN_ELEM_SIZE_8BYTES = 0U,
    /**< 8 byte data field */
    MCAN_ELEM_SIZE_12BYTES = 1U,
    /**< 12 byte data field */
    MCAN_ELEM_SIZE_16BYTES = 2U,
    /**< 16 byte data field */
    MCAN_ELEM_SIZE_20BYTES = 3U,
    /**< 20 byte data field */
    MCAN_ELEM_SIZE_24BYTES = 4U,
    /**< 24 byte data field */
    MCAN_ELEM_SIZE_32BYTES = 5U,
    /**< 32 byte data field */
    MCAN_ELEM_SIZE_48BYTES = 6U,
    /**< 48 byte data field */
    MCAN_ELEM_SIZE_64BYTES = 7U
                             /**< 64 byte data field */
}MCAN_ElemSize;


//Global struct
typedef struct
{
    uint32_t id;
    /**< Identifier */
    uint32_t rtr;
    /**< Remote Transmission Request
     *   0 = Transmit data frame
     *   1 = Transmit remote frame
     */
    uint32_t xtd;
    /**< Extended Identifier
     *   0 = 11-bit standard identifier
     *   1 = 29-bit extended identifier
     */
    uint32_t esi;
    /**< Error State Indicator
     *   0 = ESI bit in CAN FD format depends only on error passive flag
     *   1 = ESI bit in CAN FD format transmitted recessive
     */
    uint32_t dlc;
    /**< Data Length Code
     *   0-8  = CAN + CAN FD: transmit frame has 0-8 data bytes
     *   9-15 = CAN: transmit frame has 8 data bytes
     *   9-15 = CAN FD: transmit frame has 12/16/20/24/32/48/64 data bytes
     */
    uint32_t brs;
    /**< Bit Rat Switching
     *   0 = CAN FD frames transmitted without bit rate switching
     *   1 = CAN FD frames transmitted with bit rate switching
     */
    uint32_t fdf;
    /**< FD Format
     *   0 = Frame transmitted in Classic CAN format
     *   1 = Frame transmitted in CAN FD format
     */
    uint32_t efc;
    /**< Event FIFO Control
     *   0 = Donâ€Tmt store Tx events
     *   1 = Store Tx events
     */
    uint32_t mm;
    /**< Message Marker */
    uint16_t  data[8];
    /**< Data bytes.
     *   Only first dlc number of bytes are valid.
     */
}MCAN_TxBufElement;

typedef struct
{
    uint32_t id;
    /**< Identifier */
    uint32_t rtr;
    /**< Remote Transmission Request
     *   0 = Received frame is a data frame
     *   1 = Received frame is a remote frame
     */
    uint32_t xtd;
    /**< Extended Identifier
     *   0 = 11-bit standard identifier
     *   1 = 29-bit extended identifier
     */
    uint32_t esi;
    /**< Error State Indicator
     *   0 = Transmitting node is error active
     *   1 = Transmitting node is error passive
     */
    uint32_t rxts;
    /**< Rx Timestamp */
    uint32_t dlc;
    /**< Data Length Code
     *   0-8  = CAN + CAN FD: received frame has 0-8 data bytes
     *   9-15 = CAN: received frame has 8 data bytes
     *   9-15 = CAN FD: received frame has 12/16/20/24/32/48/64 data bytes
     */
    uint32_t brs;
    /**< Bit Rat Switching
     *   0 = Frame received without bit rate switching
     *   1 = Frame received with bit rate switching
     */
    uint32_t fdf;
    /**< FD Format
     *   0 = Standard frame format
     *   1 = CAN FD frame format (new DLC-coding and CRC)
     */
    uint32_t fidx;
    /**< Filter Index */
    uint32_t anmf;
    /**< Accepted Non-matching Frame
     *   0 = Received frame matching filter index FIDX
     *   1 = Received frame did not match any Rx filter element
     */
    uint16_t  data[8];
    /**< Data bytes.
     *   Only first dlc number of bytes are valid.
     */
}MCAN_RxBufElement;

MCAN_RxBufElement rxMsg;

MCAN_TxBufElement txMsg;



void LoadingTXFIFO(const MCAN_TxBufElement *txMsg)
{
    // DATA COPY TO Massage RAM base Address 0X58000
    uint32_t *baseAddr;
    uint32_t reg_val = 0;
    uint16_t adressOffset = 0;
    baseAddr = (MCAN_TX_BUFF_START_ADDR + 0x58000U);
    //TX element E0
    reg_val = ((txMsg->id << 0) | (txMsg->rtr << 29) | (txMsg->xtd << 30)
            | (txMsg->esi << 31));
    *baseAddr = reg_val;
    reg_val = 0;
    adressOffset += 4U;
    //TX element E1
    baseAddr = (baseAddr + adressOffset);
    reg_val = ((txMsg->dlc << 16) | (txMsg->brs << 20) | (txMsg->fdf << 21)
            | (txMsg->efc << 23) | txMsg->fdf << 24);
    *baseAddr = reg_val;
    reg_val = 0;
    adressOffset += 4U;
    //DATA ELEMENT 0
    baseAddr = (baseAddr + adressOffset);
    reg_val = ((txMsg->data[0] << 0) | (txMsg->data[1] << 8)
            | (txMsg->data[2] << 16) | (txMsg->data[3] << 24));
    *baseAddr = reg_val;
    reg_val = 0;
    adressOffset += 4U;
    //DATA ELEMENT 1
    baseAddr = (baseAddr + adressOffset);
    reg_val = ((txMsg->data[4] << 0) | (txMsg->data[5] << 8)
            | (txMsg->data[6] << 16) | (txMsg->data[7] << 24));
    *baseAddr = reg_val;
    reg_val = 0;
}

void CanMassageFrame(MCAN_TxBufElement *txMsg)
{
    int i = 0;
    volatile uint32_t mode = 0U;
    uint32_t dataBytes = 4;
    // Initialize message to transmit.
    //
    txMsg->id = ((uint32_t) (0x111));
    txMsg->rtr = 0U;
    txMsg->xtd = 0U;
    txMsg->esi = 0U;
    txMsg->dlc = 8U;
    txMsg->brs = 0U;
    txMsg->fdf = 0U;
    txMsg->efc = 1U;
    txMsg->mm = 0xAAU;

//    txMsg->data[0]  = 0x12;
//    txMsg->data[1]  = 0x34;
//    txMsg->data[2]  = 0x56;
//    txMsg->data[3]  = 0x78;



    txMsg->data[i] = 0x1;
    for (i = 1; i < dataBytes; i++)
    {
        txMsg->data[i] = txMsg->data[i - 1] + 1;
    }
    i = 0;
}

void DataReadFromRxfifo(MCAN_RxBufElement *rxMsg)
{
    //Data Read from RX FIFO Address
    uint32_t *baseAddr;
    uint32_t reg_val = 0;
    uint16_t adressOffset = 0;
    baseAddr = (MCAN_FIFO_0_START_ADDR + 0x58000U); //0x000002EC;
    //RX element E0
    reg_val = *baseAddr;
    rxMsg->id = reg_val & 0x1FFFFFFF;
    rxMsg->rtr = reg_val & 0x20000000;
    rxMsg->xtd = reg_val & 0x40000000;
    rxMsg->esi = reg_val & 0x80000000;
    reg_val = 0;
    adressOffset += 4U;
    //RX element E1
    baseAddr = (baseAddr + adressOffset);
    reg_val = *baseAddr;
    rxMsg->rxts = reg_val & 0x000000FF;
    rxMsg->dlc = reg_val & 0x000F0000;
    rxMsg->brs = reg_val & 0x00100000;
    rxMsg->fdf = reg_val & 0x00200000;
    rxMsg->fidx = reg_val & 0x7F000000;
    rxMsg->anmf = reg_val & 0x80000000;
    reg_val = 0;
    //RX element E1
    baseAddr = (baseAddr + adressOffset);
    reg_val = *baseAddr;
    rxMsg->data[0] = reg_val & 0x000000FF;
    rxMsg->data[1] = ((reg_val & 0x0000FF00) >> 8);
    rxMsg->data[2] = ((reg_val & 0x00FF0000) >> 16);
    rxMsg->data[3] = ((reg_val & 0xFF000000) >> 24);
    reg_val = 0;
    //RX element E1
    baseAddr = (baseAddr + adressOffset);
    reg_val = *baseAddr;
    rxMsg->data[4] = (reg_val & 0x000000FF);
    rxMsg->data[5] = ((reg_val & 0x0000FF00) >> 8);
    rxMsg->data[6] = ((reg_val & 0x00FF0000) >> 16);
    rxMsg->data[7] = ((reg_val & 0xFF000000) >> 24);
    reg_val = 0;
}

void DataReadFromRxbuffer(MCAN_RxBufElement *rxMsg)
{
    // DATA Read From Rx Buffer start address
    uint32_t *baseAddr;
    uint32_t reg_val = 0;
    uint16_t adressOffset = 0;
    baseAddr = (MCAN_RX_BUFF_START_ADDR + 0x58000U);
    //RX element E0
    reg_val = *baseAddr;
    rxMsg->id = reg_val & 0x1FFFFFFF;
    rxMsg->rtr = reg_val & 0x20000000;
    rxMsg->xtd = reg_val & 0x40000000;
    rxMsg->esi = reg_val & 0x80000000;
    reg_val = 0;
    adressOffset += 4U;
    //RX element E1
    baseAddr = (baseAddr + adressOffset);
    reg_val = *baseAddr;
    rxMsg->rxts = reg_val & 0x000000FF;
    rxMsg->dlc = reg_val & 0x000F0000;
    rxMsg->brs = reg_val & 0x00100000;
    rxMsg->fdf = reg_val & 0x00200000;
    rxMsg->fidx = reg_val & 0x7F000000;
    rxMsg->anmf = reg_val & 0x80000000;
    reg_val = 0;
    //RX element E1
    baseAddr = (baseAddr + adressOffset);
    reg_val = *baseAddr;
    rxMsg->data[0] = reg_val & 0x000000FF;
    rxMsg->data[1] = ((reg_val & 0x0000FF00) >> 8);
    rxMsg->data[2] = ((reg_val & 0x00FF0000) >> 16);
    rxMsg->data[3] = ((reg_val & 0xFF000000) >> 24);
    reg_val = 0;
    //RX element E1
    baseAddr = (baseAddr + adressOffset);
    reg_val = *baseAddr;
    rxMsg->data[4] = (reg_val & 0x000000FF);
    rxMsg->data[5] = ((reg_val & 0x0000FF00) >> 8);
    rxMsg->data[6] = ((reg_val & 0x00FF0000) >> 16);
    rxMsg->data[7] = ((reg_val & 0xFF000000) >> 24);
    reg_val = 0;
}

void ReadRXFIFO0(MCAN_RxBufElement *rxMsg)
{

    //Data Read from RX FIFO Address
    DataReadFromRxfifo(rxMsg);
    // DATA Read From Rx Buffer start address
    DataReadFromRxbuffer(rxMsg);
}

int main(void)
{
    InitSysCtrl();

    GpioInit();   // Gpio init
    MCANInit();   //CAN init
    CanMassageFrame(&txMsg);
    LoadingTXFIFO(&txMsg); // DATA COPY TO Massage RAM base Address 0X58000
    int i = 0;

    uint32_t dataBytes = 8;
    // Initialize message to receive
    //
    rxMsg.id = 0U;
    rxMsg.rtr = 0U;
    rxMsg.xtd = 0U;
    rxMsg.esi = 0U;
    rxMsg.rxts = 0U;   // Rx Timestamp
    rxMsg.dlc = 0U;
    rxMsg.brs = 0U;
    rxMsg.fdf = 0U;
    rxMsg.fidx = 0U;   // Filter Index
    // (of matching Rx acceptance filter element)
    rxMsg.anmf = 0U;   // Accepted Non-matching Frame

    for(i = 0; i < dataBytes; i++)  // Initialize receive buffer to 0
    {
        rxMsg.data[i]  = 0;
    }

    while (1)
      {

          // Add request for all transmission.
          McanaRegs.MCAN_TXBAR.bit.AR0 = 1;
          DELAY_US(10000);
          ReadRXFIFO0(&rxMsg);
          if(McanaRegs.MCAN_RXF0S.bit.F0F == 1)
          {
    //          while(1)
              {

              }
          }
      }




    return 0;
}

void MCANInit(void)
{
    EALLOW;
    McanaRegs.MCAN_CCCR.bit.INIT=1;                 // MCAN Initialization enable bit. Setting this bit high does not mean that the mcan module is initialized

    while(McanaRegs.MCAN_CCCR.bit.INIT==0);
    McanaRegs.MCAN_CCCR.bit.CCE=1;                  // protection bit disable
    McanaRegs.MCAN_CCCR.bit.TEST=1;
    McanaRegs.MCAN_TEST.bit.LBCK = 1;                // Loop Back Mode
    McanaRegs.MCAN_CCCR.bit.FDOE=0;                 // CANFD disable
    McanaRegs.MCAN_CCCR.bit.BRSE=0;                 // Bit rate switch disable
    // Bit Nominal bit Rate 1 Mbps as  this value is calculated as per DATA sheet
    McanaRegs.MCAN_NBTP.bit.NBRP=5;                 //Nominal Bit Rate Prescaler
    McanaRegs.MCAN_NBTP.bit.NTSEG1=12;              //Nominal Time Segment Before Sample Point
    McanaRegs.MCAN_NBTP.bit.NTSEG2=5;               //Nominal Time Segment After Sample Point
    McanaRegs.MCAN_NBTP.bit.NSJW=0;                 //Nominal (Re)Synchronization Jump Width
    ;
    // RX FIFO configuration
    McanaRegs.MCAN_RXF0C.bit.F0OM =1;               // F0OM = 0: blocking mode enable / F0OM= 1 overwrite mode enable
    McanaRegs.MCAN_RXF0C.bit.F0WM =0;               // F0WM = 0: water mark interrupt disable / F0WM = 1 to 64 : level for RXFIFO water mark interrupt (IR.RF0W)
    McanaRegs.MCAN_RXF0C.bit.F0S  =9;               // F0S  = 0: NO RXFIFO0 / F0S= 1 to 64 RX FIFO Element : TOTAL RX ELEMENT (FOS-1)
    McanaRegs.MCAN_RXF0C.bit.F0SA = (MCAN_FIFO_0_START_ADDR>>2);            //0x00058006;     //MCAN_FIFO_0_START_ADDR ;  // START ADDRESS OF RxFIFO RAM : this value should be change
    McanaRegs.MCAN_RXESC.bit.F0DS =5;            // Rx FIFO 0 Data Field Size
    McanaRegs.MCAN_RXBC.bit.RBSA  = (MCAN_RX_BUFF_START_ADDR>>2);           //0x0005800C;

    // TX FIFO configuration
    McanaRegs.MCAN_TXBC.bit.TFQM = 0;               //TX FIFO MODE (TX FIFO = 0/Queue Mode =1)
    McanaRegs.MCAN_TXBC.bit.TBSA = (MCAN_TX_BUFF_START_ADDR>>2); //0x00058000;      //TX Buffers Start Address
    McanaRegs.MCAN_TXBC.bit.NDTB = 10;               //Number of Dedicated Transmit Buffers
    McanaRegs.MCAN_TXBC.bit.TFQS = 8;               //Number Tx buffer is used as Transmit FIFO/Queue   there is waring (NDTB +TFQS!>32)



    McanaRegs.MCAN_CCCR.bit.CCE=0;                  // protection bit disable
    McanaRegs.MCAN_CCCR.bit.INIT=0;                 // Init Mode disable
    EDIS;
}

int GpioInit(void)
{
    EALLOW;
    GpioCtrlRegs.GPALOCK.all = 0;                    //unlock all GPIO pin
    ClkCfgRegs.CLKCFGLOCK1.bit.AUXCLKDIVSEL = 0;     //MCAN Clock prescaler enable set to 1
    ClkCfgRegs.AUXCLKDIVSEL.bit.MCANCLKDIV = 0;      //MCAN Clock prescaler value
    //GPIO MUX for MCAN GPIO4 CAN TX and MCAN GPIO5 CANRX
    GpioCtrlRegs.GPAGMUX1.bit.GPIO4 = 0;
    GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0x3;
    GpioCtrlRegs.GPAGMUX1.bit.GPIO5 = 0b01;
    GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 0b01;
    EDIS;
    return 0;
}

uint32_t MCAN_getMsgObjSize(uint32_t elemSize)
{
  //  ASSERT(elemSize < 8U);
    return(objSize[elemSize]);
}

提前感谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    RAM、

    不使用/引用 C2000Ware 中现有的 mcan_loopback 示例的任何原因、该示例已在 F280015x 上得到验证和证明?  这可能对您的调试有所帮助。

    此致、

    约瑟夫

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Joseph:

    我参考了典型的 TX 和环回示例、但我必须对它们进行修改、以便与自定义应用 协议配合使用。 目前、我尚未实现协议、仅复制示例以了解外设工作原理、并且无法获取预期的数据。  

    001:RAM

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、RAM:

    建议首先从 MCAN 环回示例开始。  遗憾的是、我们没有太多带宽来调试定制应用。

    此致、

    约瑟夫