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.

TMS320F28335: Transmit and receive interrupt issues with eCAN

Part Number: TMS320F28335

Hi Team,

There's an issue from the customer need your help:

主程序:
#include "eCAN.h"

//定义全局变量
Uint32 MessageSendCount = 0;
Uint32 MessageReceiveCount = 0;
Uint32 Rec_l;
Uint32 Rec_h;
Uint16 i = 0,j = 0,k = 0;
Uchar senddata[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};

__interrupt void ECAN0INTB_iSR(void);

void main(void)
{
    InitSysCtrl();
    DINT;
    IER = 0x0000;
    IFR = 0x0000;
    InitPieCtrl();
    InitPieVectTable();

    EALLOW;  // 写保护
    PieVectTable.ECAN0INTB = &ECAN0INTB_iSR;    //设置ECAN0INTB中断服务程序的入口地址为ECAN0INTB_iSR
    EDIS;    // 禁用写保护

    InitECan();
    //使能PIE中断
    PieCtrlRegs.PIEIER9.bit.INTx7 = 1;

    //使能CPU中断
    IER |= M_INT9;
    EINT;                         //开全局中断
    ERTM;                         //开实时中断

    for(;;)
    {
        //只使用接收的话,52行-65行注释掉即可
//        for(;k<20;)
//        {
            ECanbRegs.CANTRS.all = 0x00000001;     //1设置TRSn,发送该邮箱中的消息
            while(ECanbRegs.CANTA.all == 0){}      //等待TA被置位,邮箱消息发送成功则置位
            ECanbRegs.CANTA.all = 0x00000001;      //如果邮箱n的消息发送成功,则设置该寄存器的第n位
            MessageSendCount++;                    //设断点,观察
            ECanbMboxes.MBOX0.MDL.all = senddata[i];
            ECanbMboxes.MBOX0.MDH.all = senddata[i + 1];
            i = i + 2;
            if(i > 7)
            i = 0;
//            k++;
//        }
    }
}

__interrupt void ECAN0INTB_iSR(void)            //eCAN_B
{
    if(ECanbRegs.CANRMP.all != 0)               //判断是否有数据
    {
        while(ECanbRegs.CANRMP.all != 0x00010000);
        ECanbRegs.CANRMP.all = 0x00010000;      //复位RMP标志,同时也复位中断标志
        Rec_l = ECanbMboxes.MBOX16.MDL.all;     //接收到的数据在接收邮箱Mbox16
        Rec_h = ECanbMboxes.MBOX16.MDH.all;
        PieCtrlRegs.PIEACK.bit.ACK9 = 1;
        EINT;
    }
}



ecan.c

void InitECan(void)
{
    struct ECAN_REGS ECanbShadow;
    EALLOW;

    //配置GPIO引脚工作在eCAN功能
    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 1;     //禁止上拉GPIO16(CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;     //使能上拉GPIO17(CANRXB)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3;
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2;    //配置GPIO16为CANTXB
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2;    //配置GPIO17为CANRXB
    //配置eCAN的RX&TX分别为eCAN的接收和发送引脚

    ECanbShadow.CANTIOC.all = ECanbRegs.CANTIOC.all;
    ECanbShadow.CANTIOC.bit.TXFUNC = 1;
    ECanbRegs.CANTIOC.all = ECanbShadow.CANTIOC.all;
    ECanbShadow.CANRIOC.all = ECanbRegs.CANRIOC.all;
    ECanbShadow.CANRIOC.bit.RXFUNC = 1;
    ECanbRegs.CANRIOC.all = ECanbShadow.CANRIOC.all;
    ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
    ECanbShadow.CANMC.bit.STM = 0;          //工作在正常模式
    ECanbShadow.CANMC.bit.SCB = 1;
    ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;

    //初始化所有主设备控制区域为0,MCF所有的位都初始化为0
    ECanbMboxes.MBOX0.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX31.MSGCTRL.all = 0x00000000;
    ECanbShadow.CANTA.all = ECanbRegs.CANTA.all;
    ECanbShadow.CANTA.all = 0xFFFFFFFF;
    ECanbRegs.CANTA.all = ECanbShadow.CANTA.all;
    ECanbShadow.CANRMP.all = ECanbRegs.CANRMP.all;
    ECanbShadow.CANRMP.all = 0xFFFFFFFF;
    ECanbRegs.CANRMP.all = ECanbShadow.CANRMP.all;
    ECanbShadow.CANGIF0.all = ECanbRegs.CANGIF0.all;
    ECanbShadow.CANGIF0.all = 0xFFFFFFFF;
    ECanbRegs.CANGIF0.all = ECanbShadow.CANGIF0.all;
    ECanbShadow.CANGIF1.all = ECanbRegs.CANGIF1.all;
    ECanbShadow.CANGIF1.all = 0xFFFFFFFF;
    ECanbRegs.CANGIF1.all = ECanbShadow.CANGIF1.all;
    /*为eCAN配置位时间参数*/
    ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
    ECanbShadow.CANMC.bit.CCR = 1;             //设置CCR=1
    ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;

//    ECanbShadow.CANES.all = ECanbRegs.CANES.all;      //////////////////////

    do
    {ECanbShadow.CANES.all = ECanbRegs.CANES.all;
    }while(ECanbShadow.CANES.bit.CCE != 1);    //等待CCE位被清除
    ECanbShadow.CANBTC.all = ECanbRegs.CANBTC.all;
    ECanbShadow.CANBTC.bit.BRPREG = 9;         //数据传输速率
    //150/10 = 15
    ECanbShadow.CANBTC.bit.TSEG2REG = 2;
    ECanbShadow.CANBTC.bit.TSEG1REG = 10;
    ECanbRegs.CANBTC.all = ECanbShadow.CANBTC.all;
    ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
    ECanbShadow.CANMC.bit.CCR = 0;             //设置CCR=0
    ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
    do
    {ECanbShadow.CANES.all = ECanbRegs.CANES.all;
    }while(ECanbShadow.CANES.bit.CCE != 0);    //等待CCE位被置位
    ECanbShadow.CANME.all = ECanbRegs.CANME.all;
    ECanbShadow.CANME.all = 0;
    ECanbRegs.CANME.all = ECanbShadow.CANME.all;

    //接收邮箱的ID
    ECanbMboxes.MBOX0.MSGID.all = 0x80C80000;  //扩展帧         /////////////
    ECanbMboxes.MBOX16.MSGID.all = 0x80C20000;  //扩展帧

    //邮箱0为TX,16为RX
    ECanbShadow.CANMD.all = ECanbRegs.CANMD.all;
    ECanbShadow.CANMD.bit.MD0 = 0;              //邮箱0,发送    /////////////
    ECanbShadow.CANMD.bit.MD16 = 1;             //邮箱16,接收
    ECanbRegs.CANMD.all = ECanbShadow.CANMD.all;

    //数据长度为8个byte
    ECanbMboxes.MBOX0.MSGCTRL.bit.DLC = 8;      ////////////
    ECanbMboxes.MBOX16.MSGCTRL.bit.DLC = 8;

    //设置发送优先级 2009.3.15 Add
    ECanbMboxes.MBOX0.MSGCTRL.bit.TPL = 0;      ////////////
    ECanbMboxes.MBOX16.MSGCTRL.bit.TPL = 0;

    //没有远方应答帧被请求
    ECanbMboxes.MBOX0.MSGCTRL.bit.RTR = 0;      //////////////看手册弄懂
    ECanbMboxes.MBOX16.MSGCTRL.bit.RTR = 0;

    //向邮箱RAM区写数据
    ECanbMboxes.MBOX0.MDL.all = 0x00000000;                //0x01234567;     //////////////看手册弄懂
    ECanbMboxes.MBOX0.MDH.all = 0x00000000;                //0x89ABCDEF;
    //邮箱使能Mailbox0
    ECanbShadow.CANME.all = ECanbRegs.CANME.all;
    ECanbShadow.CANME.bit.ME0 = 1;              //////////////
    ECanbShadow.CANME.bit.ME16 = 1;
    ECanbRegs.CANME.all = ECanbShadow.CANME.all;
    ECanbRegs.CANMIM.all = 0xFFFFFFFF;          //邮箱中断使能(只需要测试发送的时候,注释掉该句即可)

    //邮箱中断将产生在ECAN0INT
    ECanbRegs.CANMIL.all = 0;
    ECanbRegs.CANGIF0.all = 0xFFFFFFFF;

    //ECAN0INT中断请求线被使能
    ECanbRegs.CANGIM.bit.I0EN = 1;
    EDIS;

}

 I'm now mailbox number 0 and my array will be sent normally. But I send CAN data to the DSP and I can't get into the receive interrupt. But if I comment out the few sentences sent by the 0 mailbox in the main function, I send CAN data to the DSP, and I can enter the interrupt, and the value is correct, I don't know why.

Thanks & Regards,

Ben

  • Ben,

        Please have customer look into the interrupt example in www.ti.com/lit/SPRA876

  • Hi Hareesh,

    I found that when ECAN is sending data, it is not only necessary to configure a sending mailbox. You also need to configure a receiving mailbox. My code was changed through a code that only has a sending function. Mailbox No. 0 sends, and Mailbox No. 16 receives. When writing the receiving code, I still use these two mailboxes. Shouldn't it be configuring a set of sending and receiving mailboxes. That way there should be no conflicts. I think the problem is out here?

    Best Regards,

    Ben

  • I found that when ECAN is sending data, it is not only necessary to configure a sending mailbox. You also need to configure a receiving mailbox. 

    That is not true in a normal application. I think you are using the CAN module in self-test mode. 

    Shouldn't it be configuring a set of sending and receiving mailboxes. 

    Nothing happens automatically. If you need a receive mailbox to receive the transmitted data, you need to configure it manually.

    I think the problem is out here?

    No, there is no problem. In self-test mode, if you want to generate receive interrupts, you need to configure the receive mailbox with the same MSGID as the transmitting mailbox. Once you do this, when the message is received, an interrupt will be generated.