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.

TMS320F28377S: Can cannot enter the CAN receiving interrupt.

Part Number: TMS320F28377S

Dear Sir

When the CAN port is used to send and receive data, there is a rare probability that the CAN receiving data of DSP itself is abnormal. At this time, the CAN sending data of DSP itself is normal. When the software is checked in detail, it is found that the software cannot enter the CAN receiving interrupt.

What are the possible causes of this situation and what are the solutions you can try?

  • Are you saying the data is transmitted correctly by the transmitter but the data copied into the message object is not correct? How did you verify the data was transmitted correctly? Did you monitor the bus with a bus-analyzer? This is very unlikely to happen since the message RAM is protected with parity. If there was indeed some corruption of the message RAM, a parity error would have been flagged. The fact that the receive interrupt was not triggered suggests that the frame was actually not received.

  • Gabriel,

    Can you also look at the contents of CAN_ES register when received data is abnormal?  CAN_ES will report the last error that occurred.

    Regards,

    Joseph

  • Dear Joseph

    1.Data sent by DCAN CAN be read by CAN analyzer. When DCAN cannot receive data, the upper function can normally receive data frames sent by DCAN to prove that the transmission function is still normal.
    2, the test is to use two DSP circuit boards, hanging on a bus at the same time, the upper computer sends broadcast frames, DSP 1 can not receive the data when DSP 2 can receive, in order to prove that the external has to the bus normal transmission of data;
    3. When the faulty DCAN fails to receive data, all the fault flags of the DCAN are 0. For unknown reasons, the relevant operation functions are as follows:

    4. At the same time, adding the following DCAN peripheral reset function can not solve the problem:

  • Hi Gabriel,

    From you set up description, it seems like there are multiple nodes in the CAN bus and two of them are DSPs.  One main node is sending the CAN messages while the other two nodes (DSP1 and DSP2) are supposed to be receiving the CAN frames.  Are DSP1 and DSP2 both F28377S devices and are there differences in the HW on both DSPs?  Are both DSPs using the same CAN configuration?  I just basically want to understand the differences between DSP1 and DSP2.

    Thanks,

    Joseph

  • Dear Joseph

    DSP1 and DSP2 are both F28377D devices. DSP1 and DSP2 are configured with different node IDs. In addition, the software configuration is the same without any difference. The attachment is my code. I hope you can help me see if there are any errors.

    /*******************************************************************************************************
    
    	                                 ��Ȩ(c) 	2022 �� 2025		�����Ŵ����¿Ƽ����޹�˾
    
                                                �����:   ��       ��
    
                                         ���:   BspECan.c.c
    
                                         ��   ��:   ECan�
    
    *******************************************************************************************************/
    
    //======================================================================================================
    // ����ͷ�ļ�
    //======================================================================================================
    #include "F2837xS_device.h"
    #include "F28x_Project.h"
    #include "../Task\header\BspECan.h"
    #include "../Task\header\BspGpio.h"
    #include "../Task\header\BspLibDependence.h"
    #include "../Task\header\BspLibConfig.h"
    #include "../Task\header\BspConfig.h"
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_can.h"
    #include "driverlib/can.h"
    
    //*****************************************************************************
    // A��B counter that keeps track of the number of times the TX interrupt has
    // occurred, which should match the number of TX messages that were sent.
    //*****************************************************************************
    volatile unsigned long g_CANATxMsgCount = 0;
    volatile unsigned long g_CANARxMsgCount = 0;
    volatile unsigned long g_CANAErrCount = 0;
    volatile unsigned long g_CANAErrFlag = 0;
    
    volatile unsigned long g_CANBTxMsgCount = 0;
    volatile unsigned long g_CANBRxMsgCount = 0;
    volatile unsigned long g_CANBErrCount = 0;
    volatile unsigned long g_CANBErrFlag = 0;
    //*****************************************************************************
    // A��B flag to indicate that some transmission error occurred.
    //*****************************************************************************
    //tCANMsgObject sTXCANAMessage[24];
    tCANMsgObject sRXCANAMessage[8];
    
    //tCANMsgObject sTXCANBMessage[24];
    tCANMsgObject sRXCANBMessage[8];
    
    //unsigned char ucTXCANAMsgData[192];
    unsigned char ucRXCANAMsgData[64];
    
    //unsigned char ucTXCANBMsgData[192];
    unsigned char ucRXCANBMsgData[64];
    
    volatile struct  CAN_REG  CAN[2];
    
    volatile unsigned int CAN_RX_INT_Judge[2] = {0, 0};
    
    // �۲����ݵ�ȫ�ֱ���
    int gCanSend1 = 0xFF;           // CANSEND1~16
    int gCanSend2 = 0xFF;
    int gCanSend3 = 0xFF;
    int gCanSend4 = 0xFF;
    int gCanSend5 = 0xFF;
    int gCanSend6 = 0xFF;
    int gCanSend7 = 0xFF;
    int gCanSend8 = 0xFF;
    int gCanSend9 = 0xFF;
    int gCanSend10 = 0xFF;
    int gCanSend11 = 0xFF;
    int gCanSend12 = 0xFF;
    int gCanSend13 = 0xFF;
    int gCanSend14 = 0xFF;
    int gCanSend15 = 0xFF;
    int gCanSend16 = 0xFF;
    
    //======================================================================================================
    // ��������: interrupt void canaISR(void)
    // ��������: CANA������жϴ������,����жϲ�����ԭ��,�������Ѵ����������Ϣ�ļ���
    // �������: ��
    // �������: ��
    // ����˵��: ��
    //======================================================================================================
    volatile unsigned int ulStatusA = 0;
    volatile unsigned int ulStatus_A = 0;
    volatile unsigned int CANA_INT_Flag = 0;
    volatile unsigned long MDLA = 0, MDHA = 0;
    
    #pragma CODE_SECTION(canaISR, ".TI.ramfunc");
    interrupt void canaISR(void)//CANA receive interrupt
    {
        unsigned long ulStatus;
    
        ulStatusA++;
    
        CAN_RX_INT_Judge[1] = 0;
    
        // Read the CAN interrupt status to find the cause of the interrupt
        ulStatus = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE);//��ȡCAN�ж�״̬�Ĵ�����ֵ
    
        // If the cause is a controller status interrupt, then get the status
        if(ulStatus == CAN_INT_INT0ID_STATUS)//0x8000 ������״̬�ж�
        {
            ulStatus = CANStatusGet(CANA_BASE, CAN_STS_CONTROL);//��ȡ�����״̬�Ĵ���
    
            //Check to see if an error occurred.
            if(((ulStatus  & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 7)
            && ((ulStatus  & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 0))
            {
            	g_CANAErrCount++;
    
            	g_CANAErrFlag = 1;
            }
        }
        else if(ulStatus == 1)//��������1�ж�
        {
            CANIntClear(CANA_BASE, 1);//�������1�ж�
    
            g_CANATxMsgCount++;
    
            g_CANAErrFlag = 0;
        }
        else if((ulStatus >= 25) && (ulStatus <= 32))//A ��������25��32�ж�
        {
            //��������ʱ637 * 5ns = 3.185US
            CANMessageGet(CANA_BASE, ulStatus, (void *)&sRXCANAMessage[ulStatus - 25], true);//��ȡ����25��32��Ϣ
    
            ulStatus_A = ulStatus;
            CANA_INT_Flag = 1;
    
            CANIntClear(CANA_BASE, ulStatus);//�������25��32�ж�
    
            g_CANARxMsgCount++;
    
            g_CANAErrFlag = 0;
        }
        else//������Խ�������жϴ���
        {
    
        }
    
        //canaRegs.CAN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1;
        CANGlobalIntClear(CANA_BASE, CAN_GLB_INT_CANINT0);//CANA INT0 ȫ���жϱ�־���
    
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    }
    
    
    #pragma CODE_SECTION(BSPCAN0RxDataTask, ".TI.ramfunc");
    void BSPCAN0RxDataTask(void)//CANA 500US task execution cycle
    {
        if(CANA_INT_Flag == 1)
        {
            CANA_INT_Flag = 0;
            MDLA  = (unsigned long)sRXCANAMessage[ulStatus_A - 25].pucMsgData[0];
            MDLA += ((unsigned long)sRXCANAMessage[ulStatus_A - 25].pucMsgData[1] << 8);
            MDLA += ((unsigned long)sRXCANAMessage[ulStatus_A - 25].pucMsgData[2] << 16);
            MDLA += ((unsigned long)sRXCANAMessage[ulStatus_A - 25].pucMsgData[3] << 24);
    
            MDHA  = (unsigned long)sRXCANAMessage[ulStatus_A - 25].pucMsgData[4];
            MDHA += ((unsigned long)sRXCANAMessage[ulStatus_A - 25].pucMsgData[5] << 8);
            MDHA += ((unsigned long)sRXCANAMessage[ulStatus_A - 25].pucMsgData[6] << 16);
            MDHA += ((unsigned long)sRXCANAMessage[ulStatus_A - 25].pucMsgData[7] << 24);
    
            //��������ʱ273 * 5ns = 1.365US  273 303 493 523 1430  1430 * 5ns = 7.15US
            //BSPCAN0RxDataHook(sRXCANAMessage[ulStatus - 25].ui32MsgLen, sRXCANAMessage[ulStatus - 25].ui32MsgID, MDLA, MDHA);
            BSPCAN1RxDataHook(sRXCANAMessage[ulStatus_A - 25].ui32MsgLen, sRXCANAMessage[ulStatus_A - 25].ui32MsgID, MDLA, MDHA);
        }
    }
    
    /*
    #pragma CODE_SECTION(BSPCAN0RxDataTask, ".TI.ramfunc");
    void BSPCAN0RxDataTask(void)
    {
        u16 i;
        Uint32 cmd_regdata = 0;
    
        //A ��Ϣ�������ڽ���,�ȴ�����
        while(HWREG(CANA_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
        //IF2 Command Register
        cmd_regdata = CAN_IF1CMD_ARB | CAN_IF1CMD_MASK | CAN_IF1CMD_CONTROL | CAN_IF1CMD_DATA_A | CAN_IF1CMD_DATA_B;
        HWREGH(CANA_BASE + CAN_O_IF1CMD + 2) = cmd_regdata >> 16;
    
        for(i = 25; i <= 32; i++)
        {
            HWREGH(CANA_BASE + CAN_O_IF1CMD) = i;//д�������Ϣ����
    
            while(HWREG(CANA_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
            //1,��Ϣ��������CPU�ѽ�������д�����Ϣ��������ݲ���
            if((HWREG(CANA_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_NEWDAT) != 0)
            {
                break;
            }
        }
    
        if(i >= 33){return;}//����ʧ��
        if((HWREG(CANA_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_MSGLST) != 0)//��Ϣ��ʧ,����Ϣ��ʧ
        {
            return;
        }
    
        CANMessageGet(CANA_BASE, i, (void *)&sRXCANAMessage[i - 25], true);//��ȡ����25��32��Ϣ
    
        MDLA  = (unsigned long)sRXCANAMessage[i - 25].pucMsgData[0];
        MDLA += ((unsigned long)sRXCANAMessage[i - 25].pucMsgData[1] << 8);
        MDLA += ((unsigned long)sRXCANAMessage[i - 25].pucMsgData[2] << 16);
        MDLA += ((unsigned long)sRXCANAMessage[i - 25].pucMsgData[3] << 24);
    
        MDHA  = (unsigned long)sRXCANAMessage[i - 25].pucMsgData[4];
        MDHA += ((unsigned long)sRXCANAMessage[i - 25].pucMsgData[5] << 8);
        MDHA += ((unsigned long)sRXCANAMessage[i - 25].pucMsgData[6] << 16);
        MDHA += ((unsigned long)sRXCANAMessage[i - 25].pucMsgData[7] << 24);
    
        //��������ʱ273 * 5ns = 1.365US  273 303 493 523 1430  1430 * 5ns = 7.15US
        BSPCAN1RxDataHook(sRXCANAMessage[i - 25].ui32MsgLen, sRXCANAMessage[i - 25].ui32MsgID, MDLA, MDHA);
    }
    */
    //======================================================================================================
    // ��������: interrupt void canbISR(void)
    // ��������: CANB������жϴ������,����жϲ�����ԭ��,�������Ѵ����������Ϣ�ļ���
    // �������: ��
    // �������: ��
    // ����˵��: ��
    //======================================================================================================
    volatile unsigned int ulStatusB = 0;
    volatile unsigned int ulStatus_B = 0;
    volatile unsigned int CANB_INT_Flag = 0;
    volatile unsigned long MDLB = 0, MDHB = 0;
    
    #pragma CODE_SECTION(canbISR, ".TI.ramfunc");
    interrupt void canbISR(void)//CANB receive interrupt
    {
        unsigned long ulStatus;
    
        ulStatusB++;
    
        CAN_RX_INT_Judge[0] = 0;
    
        // Read the CAN interrupt status to find the cause of the interrupt
        ulStatus = CANIntStatus(CANB_BASE, CAN_INT_STS_CAUSE);//��ȡCAN�ж�״̬�Ĵ�����ֵ
    
        // If the cause is a controller status interrupt, then get the status
        if(ulStatus == CAN_INT_INT0ID_STATUS)//0x8000 ������״̬�ж�
        {
            ulStatus = CANStatusGet(CANB_BASE, CAN_STS_CONTROL);//��ȡ�����״̬�Ĵ���CAN_ES
    
            //Check to see if an error occurred.
            //Parity Error Detected��Bus-off Status Bit��Warning State Bit��Error Passive State
            if(((ulStatus  & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 7)
            && ((ulStatus  & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 0))
            {
            	g_CANBErrCount++;
    
            	g_CANBErrFlag = 1;
            }
        }
        else if(ulStatus == 1)//��������1�ж�
        {
            CANIntClear(CANB_BASE, 1);//�������1�ж�
    
            g_CANBTxMsgCount++;
    
            g_CANBErrFlag = 0;
        }
        else if((ulStatus >= 25) && (ulStatus <= 32))//A ��������25��32�ж�
        {
            CANMessageGet(CANB_BASE, ulStatus, (void *)&sRXCANBMessage[ulStatus - 25], true);//��ȡ����25��32��Ϣ
    
            ulStatus_B = ulStatus;
            CANB_INT_Flag = 1;
    
            CANIntClear(CANB_BASE, ulStatus);//�������25��32�ж�
    
            g_CANBRxMsgCount++;
    
            g_CANBErrFlag = 0;
        }
        else//������Խ�������жϴ���
        {
    
        }
    
        //canaRegs.CAN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1;
        CANGlobalIntClear(CANB_BASE, CAN_GLB_INT_CANINT0);//CANA INT0 ȫ���жϱ�־���
    
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    }
    
    
    #pragma CODE_SECTION(BSPCAN1RxDataTask, ".TI.ramfunc");
    void BSPCAN1RxDataTask(void)//CANB 500US task execution cycle
    {
        if(CANB_INT_Flag == 1)
        {
            CANB_INT_Flag = 0;
            MDLB  = (unsigned long)sRXCANBMessage[ulStatus_B - 25].pucMsgData[0];
            MDLB += ((unsigned long)sRXCANBMessage[ulStatus_B - 25].pucMsgData[1] << 8);
            MDLB += ((unsigned long)sRXCANBMessage[ulStatus_B - 25].pucMsgData[2] << 16);
            MDLB += ((unsigned long)sRXCANBMessage[ulStatus_B - 25].pucMsgData[3] << 24);
    
            MDHB  = (unsigned long)sRXCANBMessage[ulStatus_B - 25].pucMsgData[4];
            MDHB += ((unsigned long)sRXCANBMessage[ulStatus_B - 25].pucMsgData[5] << 8);
            MDHB += ((unsigned long)sRXCANBMessage[ulStatus_B - 25].pucMsgData[6] << 16);
            MDHB += ((unsigned long)sRXCANBMessage[ulStatus_B - 25].pucMsgData[7] << 24);
    
            //BSPCAN1RxDataHook(sRXCANBMessage[ulStatus - 25].ui32MsgLen, sRXCANBMessage[ulStatus - 25].ui32MsgID, MDLB, MDHB);
            BSPCAN0RxDataHook(sRXCANBMessage[ulStatus_B - 25].ui32MsgLen, sRXCANBMessage[ulStatus_B - 25].ui32MsgID, MDLB, MDHB);
        }
    }
    
    /*
    #pragma CODE_SECTION(BSPCAN1RxDataTask, ".TI.ramfunc");
    void BSPCAN1RxDataTask(void)
    {
        u16 i;
        Uint32 cmd_regdata = 0;
    
        while(HWREG(CANB_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
        //IF2 Command Register
        cmd_regdata = CAN_IF1CMD_ARB | CAN_IF1CMD_MASK | CAN_IF1CMD_CONTROL | CAN_IF1CMD_DATA_A | CAN_IF1CMD_DATA_B;
        HWREGH(CANB_BASE + CAN_O_IF1CMD + 2) = cmd_regdata >> 16;
    
        for(i = 25; i <= 32; i++)
        {
            HWREGH(CANB_BASE + CAN_O_IF1CMD) = i;//д�������Ϣ����
    
            while(HWREG(CANB_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
            //1,��Ϣ��������CPU�ѽ�������д�����Ϣ��������ݲ���
            if((HWREG(CANB_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_NEWDAT) != 0)
            {
                break;
            }
        }
    
        if(i >= 33){return;}//����ʧ��
        if((HWREG(CANB_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_MSGLST) != 0)//��Ϣ��ʧ,����Ϣ��ʧ
        {
            return;
        }
    
        CANMessageGet(CANB_BASE, i, (void *)&sRXCANBMessage[i - 25], true);//��ȡ����25��32��Ϣ
    
        MDLB  = (unsigned long)sRXCANBMessage[i - 25].pucMsgData[0];
        MDLB += ((unsigned long)sRXCANBMessage[i - 25].pucMsgData[1] << 8);
        MDLB += ((unsigned long)sRXCANBMessage[i - 25].pucMsgData[2] << 16);
        MDLB += ((unsigned long)sRXCANBMessage[i - 25].pucMsgData[3] << 24);
    
        MDHB  = (unsigned long)sRXCANBMessage[i - 25].pucMsgData[4];
        MDHB += ((unsigned long)sRXCANBMessage[i - 25].pucMsgData[5] << 8);
        MDHB += ((unsigned long)sRXCANBMessage[i - 25].pucMsgData[6] << 16);
        MDHB += ((unsigned long)sRXCANBMessage[i - 25].pucMsgData[7] << 24);
    
        BSPCAN0RxDataHook(sRXCANBMessage[i - 25].ui32MsgLen, sRXCANBMessage[i - 25].ui32MsgID, MDLB, MDHB);
    }
    */
    //======================================================================================================
    // ��������:void BSPCANAInitGpio(void)
    // ��������:initialize the GPIO of eCAN-A module
    // �������:void
    // �������:void
    // ����˵��:
    //======================================================================================================
    void BSPCANAInitGpio(void)//CANA initialization functions
    {
    	#if(ECANAENABLE == 1)//initialize the eCAN-A module
    
    	EALLOW; //GpioCtrlRegs.GPAGMUX2.bit.GPIO30
    
    	//GpioCtrlRegs.GPBMUX2.bit.GPIO62  = 2;
    	//GpioCtrlRegs.GPBMUX2.bit.GPIO63  = 2;
    	//GpioCtrlRegs.GPBGMUX2.bit.GPIO62 = 1;
    	//GpioCtrlRegs.GPBGMUX2.bit.GPIO63 = 1;
    
        //GPIO_SetupPinMux(62, GPIO_MUX_CPU1, 6);//GPIO62 - CANRXA
        //GPIO_SetupPinMux(63, GPIO_MUX_CPU1, 6);//GPIO63 - CANTXA
    	GPIO_SetupPinMux(30, GPIO_MUX_CPU1, 1);//GPIO30 - CANRXA
    	GPIO_SetupPinMux(31, GPIO_MUX_CPU1, 1);//GPIO31 - CANTXA
    
    	EDIS;
    
    	//GPIO_SetupPinOptions(62, GPIO_INPUT, GPIO_ASYNC);    //CANRXA
    	//GPIO_SetupPinOptions(63, GPIO_OUTPUT, GPIO_PUSHPULL);//CANTXA
        GPIO_SetupPinOptions(30, GPIO_INPUT, GPIO_ASYNC);    //CANRXA
        GPIO_SetupPinOptions(31, GPIO_OUTPUT, GPIO_PUSHPULL);//CANTXA
    
        #endif
    }
    
    //======================================================================================================
    // ��������:void BSPCANAInit(void)
    // ��������:��ʼ��CAN-A ģ��
    // �������:void
    // �������:void
    // ����˵��:��
    //======================================================================================================
    void BSPCANAInit(void)//CANA initialization peripheral functions
    {
    	Uint16  i, Length;
    	Uint16  *Ptr_Obj;
    
    	#if(ECANAENABLE == 1)//initialize the eCAN-A module
    
        CANInit(CANA_BASE);//��ʼ��CAN������
    
        CANClkSourceSelect(CANA_BASE, 0);//����CAN�Դ�PLL���ʱ�Ӽ�ʱ,�ڲ�COUʱ��
    
        CANBitRateSet(CANA_BASE, 200000000, (unsigned long)gBSPConfig.CanaBaudRate * 1000);//������,250kbps
    
        //                         �ж���0�ж�        �����ж�            ״̬�ж�
        CANIntEnable(CANA_BASE, CAN_INT_MASTER /*| CAN_INT_ERROR | CAN_INT_STATUS*/);//CAN�����ж�ʹ��
    
        //���ò���ģʽ��ѡ���ⲿ����
        //HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_TEST;//����ģʽ
        //HWREG(CANA_BASE + CAN_O_TEST) = CAN_TEST_EXL;//�����ⲿ����ģʽ
    
        //����������״̬��,����⵽128*11������λ��,ģ�齫�Զ��ָ����ߵ�����״̬
        HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_ABO; //Auto-Bus-On Enable
        //�ڼ�⵽�κ����߻��,ģ���˳��͹���ģʽ(�Զ�����)
        HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_WUBA;//Wake Up on Bus Activity
        //�ر��Զ��ӷ�����
        HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_DAR;//Disable Automatic Retransmission
    
        CANEnable(CANA_BASE);//ʹ��CAN
    
        //A                  ��ַ                   Ҫ���õ��ж�Դ��λ����
        CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0);//CAN INT0ȫ���ж�ʹ��
    
    	//A ��������
    	Length = sizeof(sRXCANAMessage);
    	Ptr_Obj = (void *)sRXCANAMessage;
    	for(i = 0; i < Length; i++){*Ptr_Obj++ = 0;}
    
    	/*
        //���÷�������
    	for(i = 0; i < 24; i++)//��ʼ�������ڷ���CAN����Ϣ����      ��ȫ��ƥ��
    	{
    	    sTXCANAMessage[i].ui32MsgID = 0x08FFF100 | i;              // CAN message ID - use
    	    sTXCANAMessage[i].ui32MsgIDMask = 0;                       // no mask needed for TX
    	    sTXCANAMessage[i].ui32Flags = MSG_OBJ_EXTENDED_ID;         // an extended identifier
    	    sTXCANAMessage[i].ui32MsgLen = 8;                          // size of message is 8
    	    sTXCANAMessage[i].pucMsgData = (void *)&ucTXCANAMsgData[i * 8];// ptr to message content
    	}
    	*/
    
    	//���ý�������  Configure receiving message object,receive using message object ID:25-32
    	for(i = 24; i < 32; i++)//��ʼ�������ڽ���CAN��Ϣ����Ϣ����   ���������б�ʶ��,����������ֵ
    	{
    		sRXCANAMessage[i - 24].ui32MsgID = 0x08FFF100 | i;                     // CAN message ID - use 1
    		sRXCANAMessage[i - 24].ui32MsgIDMask = 0;                              // no mask needed for TX
    		sRXCANAMessage[i - 24].ui32Flags =  MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_EXT_FILTER;// enable interrupt on RX
    		sRXCANAMessage[i - 24].ui32MsgLen = 8;                                 // size of message is 8
    	    sRXCANAMessage[i - 24].pucMsgData = (void *)&ucRXCANAMsgData[(i - 24) * 8];// ptr to message content
    
    	    //A �������ڽ�����Ϣ����Ϣ����  ʹ������25-32����CAN��Ϣ
    	    CANMessageSet(CANA_BASE, (i + 1), (void *)&sRXCANAMessage[i - 24], MSG_OBJ_TYPE_RX);
    	}
    
    	#endif
    }
    
    //======================================================================================================
    // ��������:void BSPCANBInitGpio(void)
    // ��������:initialize the GPIO of eCAN-B module
    // �������:void
    // �������:void
    // ����˵��:
    //======================================================================================================
    void BSPCANBInitGpio(void)
    {
    	#if(ECANAENABLE == 1)//initialize the eCAN-A module
    
    	EALLOW;
    
    	//GpioCtrlRegs.GPAMUX1.bit.GPIO7  = 2;
    	//GpioCtrlRegs.GPAMUX1.bit.GPIO6  = 2;
    	//GpioCtrlRegs.GPAGMUX1.bit.GPIO7 = 1;
    	//GpioCtrlRegs.GPAGMUX1.bit.GPIO6 = 1;
        GPIO_SetupPinMux(7, GPIO_MUX_CPU1, 6);//GPIO7 - CANRXB
        GPIO_SetupPinMux(6, GPIO_MUX_CPU1, 6);//GPIO6 - CANTXB
    
    	EDIS;
    
    	GPIO_SetupPinOptions(7, GPIO_INPUT, GPIO_ASYNC);    //CANRXB
    	GPIO_SetupPinOptions(6, GPIO_OUTPUT, GPIO_PUSHPULL);//CANTXB
    
        #endif
    }
    
    //======================================================================================================
    // ��������:void BSPCANBInit(void)
    // ��������:��ʼ��CAN-B ģ��
    // �������:void
    // �������:void
    // ����˵��:��
    //======================================================================================================
    void BSPCANBInit(void)
    {
    	Uint16  i, Length;
    	Uint16  *Ptr_Obj;
    
    	#if(ECANBENABLE == 1)//initialize the eCAN-B module
    
        CANInit(CANB_BASE);//��ʼ��CAN������
    
        CANClkSourceSelect(CANB_BASE, 0);//����CAN�Դ�PLL���ʱ�Ӽ�ʱ,�ڲ�COUʱ��
    
        CANBitRateSet(CANB_BASE, 200000000, (unsigned long)gBSPConfig.CanbBaudRate * 1000);//������,250kbps
    
        //                         �ж���0�ж�         �����ж�          ״̬�ж�
        CANIntEnable(CANB_BASE, CAN_INT_MASTER /*| CAN_INT_ERROR | CAN_INT_STATUS*/);//CAN�����ж�ʹ��
    
        //���ò���ģʽ��ѡ���ⲿ����
        //HWREG(CANB_BASE + CAN_O_CTL) |= CAN_CTL_TEST;//����ģʽ
        //HWREG(CANB_BASE + CAN_O_TEST) = CAN_TEST_EXL;//�����ⲿ����ģʽ
    
        //����������״̬��,����⵽128*11������λ��,ģ�齫�Զ��ָ����ߵ�����״̬
        HWREG(CANB_BASE + CAN_O_CTL) |= CAN_CTL_ABO; //Auto-Bus-On Enable
        //�ڼ�⵽�κ����߻��,ģ���˳��͹���ģʽ(�Զ�����)
        HWREG(CANB_BASE + CAN_O_CTL) |= CAN_CTL_WUBA;//Wake Up on Bus Activity
        //�ر��Զ��ӷ�����
        HWREG(CANB_BASE + CAN_O_CTL) |= CAN_CTL_DAR;//Disable Automatic Retransmission
    
        CANEnable(CANB_BASE);//ʹ��CAN
    
        //                   ��ַ                   Ҫ���õ��ж�Դ��λ����
        CANGlobalIntEnable(CANB_BASE, CAN_GLB_INT_CANINT0);//CAN INT0ȫ���ж�ʹ��
    
    	//��������
    	Length = sizeof(sRXCANBMessage);
    	Ptr_Obj = (void *)sRXCANBMessage;
    	for(i = 0; i < Length; i++){*Ptr_Obj++ = 0;}
    
    	/*
        //���÷�������
    	for(i = 0; i < 24; i++)//��ʼ�������ڷ���CAN����Ϣ����      ��ȫ��ƥ��
    	{
    	    sTXCANBMessage[i].ui32MsgID = 0x08FFF100 | i;              // CAN message ID - use
    	    sTXCANBMessage[i].ui32MsgIDMask = 0;                       // no mask needed for TX
    	    sTXCANBMessage[i].ui32Flags = MSG_OBJ_EXTENDED_ID;         // an extended identifier
    	    sTXCANBMessage[i].ui32MsgLen = 8;                          // size of message is 8
    	    sTXCANBMessage[i].pucMsgData = (void *)&ucTXCANBMsgData[i * 8];// ptr to message content
    	}
    	*/
    
    	//���ý�������
    	for(i = 24; i < 32; i++)//��ʼ�������ڽ���CAN��Ϣ����Ϣ����   ���������б�ʶ��,����������ֵ
    	{
    		sRXCANBMessage[i - 24].ui32MsgID = 0x08FFF100 | i;                     // CAN message ID - use 1
    		sRXCANBMessage[i - 24].ui32MsgIDMask = 0;                              // no mask needed for TX
    		sRXCANBMessage[i - 24].ui32Flags =  MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_EXT_FILTER;// enable interrupt on RX
    		sRXCANBMessage[i - 24].ui32MsgLen = 8;                                 // size of message is 8
    	    sRXCANBMessage[i - 24].pucMsgData = (void *)&ucRXCANBMsgData[(i - 24) * 8];// ptr to message content
    
    	    //�������ڽ�����Ϣ����Ϣ����  ʹ������25-32����CAN��Ϣ
    	    CANMessageSet(CANB_BASE, (i + 1), (void *)&sRXCANBMessage[i - 24], MSG_OBJ_TYPE_RX);
    	}
    
    	#endif
    }
    
    //======================================================================================================
    // ��������:void BSPCANSInit(void)
    // ��������:initialize the eCAN-A/B module
    // �������:void
    // �������:void
    // ����˵��:none
    //======================================================================================================
    void BSPCANSInit(void)
    {
    	BSPCANAInitGpio();
    	BSPCANAInit();
    
    	BSPCANBInitGpio();
    	BSPCANBInit();
    }
    
    //======================================================================================================
    // ��������:void BSPCANS_WARN_Protect(u8 CANNum)
    // ��������:CANA/CANBģ�����ʱ���Իָ�
    // �������:CANNum,CAN·��:ȡֵ��Χ:[0,1], 1:��ʾCANA; 0:��ʾCANB
    // �������:void
    // ����˵��:none
    //======================================================================================================
    u8 CAN_WARN_Flag[2] = {0, 0};
    void BSPCANS_WARN_Protect(u8 CANNum)//100MS task execution cycle
    {
        Uint32 regbase;
    
        if(CANNum == 0){regbase = CANB_BASE;}
        else           {regbase = CANA_BASE;}
    
        if(HWREG(regbase + CAN_O_ES) & CAN_ES_EWARN)//�澯״̬λ,1,������һ������������Ѵﵽ���󾯸�����96
        {
            EALLOW;
            HWREG(regbase + CAN_O_CTL) = CAN_CTL_INIT;//��ʼ��ģ��
    
            HWREG(regbase + CAN_O_CTL) |= CAN_CTL_SWR;//���ǿ�Ƹ�λ
            HWREG(regbase + CAN_O_CTL) |= CAN_CTL_DAR;//�ر��Զ��ش�
            HWREG(regbase + CAN_O_CTL) |= CAN_CTL_ABO;//ʹ���Զ����߽�ͨ����
            HWREG(regbase + CAN_O_CTL) |= CAN_CTL_WUBA;
    
            if(CANNum == 0){BSPCANBInit();}
            else           {BSPCANAInit();}
    
            HWREG(regbase + CAN_O_CTL) &= ~CAN_CTL_INIT;//CANģ�������ʼ������������Ϣ
            EDIS;
    
            CAN_WARN_Flag[CANNum] = 1;
        }
        else
        {
            CAN_WARN_Flag[CANNum] = 0;
        }
    }
    
    //======================================================================================================
    // ��������:void BSPCANS_Err_Counter(u8 CANNum)
    // ��������:����ͳ��CANA/CANBģ��Ľ��ա����ʹ������
    // �������:CANNum,CAN·��:ȡֵ��Χ:[0,1], 1:��ʾCANA; 0:��ʾCANB
    // �������:void
    // ����˵��:none
    //======================================================================================================
    void BSPCANS_Err_Counter(u8 CANNum)//100MS task execution cycle
    {
        Uint32 regbase;
    
        if(CANNum == 0){regbase = CANB_BASE;}
        else           {regbase = CANA_BASE;}
    
        CAN[CANNum].CAN_Err.bit.TEC = (HWREG(regbase + CAN_O_ERRC) >> 0)  & 0xff;
        CAN[CANNum].CAN_Err.bit.REC = (HWREG(regbase + CAN_O_ERRC) >> 8)  & 0x7f;
        CAN[CANNum].CAN_Err.bit.RP  = (HWREG(regbase + CAN_O_ERRC) >> 15) & 0x01;
    
        CAN[CANNum].CAN_Sta.bit.LEC   = (HWREG(regbase + CAN_O_ES) >> 0) & 0x07;
        CAN[CANNum].CAN_Sta.bit.TxOk  = (HWREG(regbase + CAN_O_ES) >> 3) & 0x01;
        CAN[CANNum].CAN_Sta.bit.RxOk  = (HWREG(regbase + CAN_O_ES) >> 4) & 0x01;
        CAN[CANNum].CAN_Sta.bit.EPass = (HWREG(regbase + CAN_O_ES) >> 5) & 0x01;
        CAN[CANNum].CAN_Sta.bit.EWarn = (HWREG(regbase + CAN_O_ES) >> 6) & 0x01;
        CAN[CANNum].CAN_Sta.bit.BOff  = (HWREG(regbase + CAN_O_ES) >> 7) & 0x01;
        CAN[CANNum].CAN_Sta.bit.PER   = (HWREG(regbase + CAN_O_ES) >> 8) & 0x01;
    }
    
    //======================================================================================================
    // ��������:	void BSPCANTxDataBuffInByteAlterDlc(u8 CANNum, u8 DLC, u32 ID, u8* Data)
    // ��������:	����������д�뷢�ͻ���(8 λ����)
    // �������:1:CANNum,CAN·��:ȡֵ��Χ:[0,1], 0:��ʾCANA; 1:��ʾCANB
    //				2.DLC, �������ݳ���
    //				3.ID, CAN ֡ID
    //				4.Data[], 8�������
    // �������:	void
    // ����˵��:    1.������˵��Ĭ��ֵ, ��ָ������ȡֵ����ʱ������������ֵ
    //				2.DLC ȡֵ��Χ: [0,8], Ĭ����Ϊ8
    //				3.ID ȡֵ��Χ:[0,0x1FFFFFFF]
    //				4.IDE=1, RTR=0, TPL=4.
    //				5.����Data ��Ԫ�ظ���Ϊ8
    //======================================================================================================
    u8 ObjID0 = 0, ObjID1 = 0;
    void BSPCANTxDataBuffInByteAlterDlc(u8 CANNum, u8 DLC, u32 ID, u8* Data)//Send task function 1
    {
        tCANMsgObject sTXCANMessage;
        u16 i;
        Uint32 cmd_regdata = 0;
    
        if(CANNum >= 2){CANNum = 0;}//CAN·������,��Ϊ0
        if(DLC > 8){DLC = 8;}       //dlcȡֵ����, ��Ϊ8
    
        //BSPCANS_WARN_Protect(CANNum);
        //if(CAN_WARN_Flag[CANNum] == 1){return;}
    
        sTXCANMessage.ui32MsgID = ID;                 // CAN message ID - use
        sTXCANMessage.ui32MsgIDMask = 0;              // no mask needed for TX
        sTXCANMessage.ui32Flags = /*MSG_OBJ_EXTENDED_ID*/MSG_OBJ_NO_FLAGS;// an extended identifier
        sTXCANMessage.ui32MsgLen = DLC;               // size of message is 8
        sTXCANMessage.pucMsgData = Data;              // ptr to message content
    
        /*
        if(CANNum == 0)
        {
            ObjID0++;
            if(ObjID0 > 24){ObjID0 = 1;}
    
            CANMessageSet(CANB_BASE, ObjID0, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
        }
        else
        {
            ObjID1++;
            if(ObjID1 > 24){ObjID1 = 1;}
    
            CANMessageSet(CANA_BASE, ObjID1, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
        }
        */
    
    
        if(CANNum == 0)
        {
            //��Ϣ�������ڽ���,�ȴ�����
            while(HWREG(CANB_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
            //IF1 Command Register
            cmd_regdata = CAN_IF1CMD_ARB | CAN_IF1CMD_MASK | CAN_IF1CMD_CONTROL;
            HWREGH(CANB_BASE + CAN_O_IF1CMD + 2) = cmd_regdata >> 16;
    
            //��1-24��Ѱ�ҿ��Է��͵�����
            for(i = 1; i <= 24; i++)//send using message object ID:1-24
            {
                HWREGH(CANB_BASE + CAN_O_IF1CMD) = i;//д�������Ϣ����
    
                while(HWREG(CANB_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
                //0,����Ϣ����δ�ȴ�����,���Է�������Ϣ
                if((HWREG(CANB_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_TXRQST) == 0){break;}
            }
            if(i >= 25){return;}
    
            CANMessageSet(CANB_BASE, i, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
        }
        else
        {
            //��Ϣ�������ڽ���,�ȴ�����
            while(HWREG(CANA_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
            //IF1 Command Register
            cmd_regdata = CAN_IF1CMD_ARB | CAN_IF1CMD_MASK | CAN_IF1CMD_CONTROL;
            HWREGH(CANA_BASE + CAN_O_IF1CMD + 2) = cmd_regdata >> 16;
    
            //��1-24��Ѱ�ҿ��Է��͵�����
            for(i = 1; i <= 24; i++)//send using message object ID:1-24
            {
                HWREGH(CANA_BASE + CAN_O_IF1CMD) = i;//д�������Ϣ����
    
                while(HWREG(CANA_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
                //0,����Ϣ����δ�ȴ�����,���Է�������Ϣ
                if((HWREG(CANA_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_TXRQST) == 0){break;}
            }
            if(i >= 25){return;}
    
            CANMessageSet(CANA_BASE, i, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
        }
    
    }
    //======================================================================================================
    // ��������:	void BSPCANTxDataBuffInDWordAlterDlc(u8 dlc, u8 id, u32 DWord0, u32 DWord1)
    // ��������:	����CAN����(32 ���)
    // �������:	1:CANNum,CAN·��:ȡֵ��Χ:[0,1], 0:��ʾCANA; 1:��ʾCANB
    //				2.DLC, �������ݳ���
    //				3.ID, CAN ֡ID
    //				4.DWord0~DWord1, 32 ���
    // �������:	void
    // ����˵��:	1.BSPCANTxDataBuffInDWordAlterDlc() ��BSPCANTxDataBuffInDWord() �򻯰汾
    // 				2.������˵��Ĭ��ֵ, ��ָ������ȡֵ����ʱ������������ֵ
    //				3.DLC ȡֵ��Χ: [0,8], Ĭ����8
    //				4.IDE=1, RTR=0, TPL=4.
    //				5.ID ȡֵ��Χ:[0,0x1FFFFFFF]
    //======================================================================================================
    void BSPCANTxDataBuffInDWordAlterDlc(u8 CANNum, u8 DLC, u32 ID, u32 DWord0, u32 DWord1)//Send task function 2
    {
        u8 TXMsgData[8];
        tCANMsgObject sTXCANMessage;
        u16 i;
        Uint32 cmd_regdata = 0;
    
        if(CANNum >= 2){CANNum = 0;}//CAN·������,��Ϊ0
        if(DLC > 8){DLC = 8;}       //dlcȡֵ����, ��Ϊ8
    
        //BSPCANS_WARN_Protect(CANNum);
        //if(CAN_WARN_Flag[CANNum] == 1){return;}
    
        TXMsgData[0] = DWord0 & 0x000000ff;
        TXMsgData[1] = (DWord0 & 0x0000ff00) >> 8;
        TXMsgData[2] = (DWord0 & 0x00ff0000) >> 16;
        TXMsgData[3] = (DWord0 & 0xff000000) >> 24;
    
        TXMsgData[4] = DWord1 & 0x000000ff;
        TXMsgData[5] = (DWord1 & 0x0000ff00) >> 8;
        TXMsgData[6] = (DWord1 & 0x00ff0000) >> 16;
        TXMsgData[7] = (DWord1 & 0xff000000) >> 24;
    
        sTXCANMessage.ui32MsgID = ID;                 // CAN message ID - use
        sTXCANMessage.ui32MsgIDMask = 0;              // no mask needed for TX
        sTXCANMessage.ui32Flags = /*MSG_OBJ_EXTENDED_ID*/MSG_OBJ_NO_FLAGS;// an extended identifier
        sTXCANMessage.ui32MsgLen = DLC;               // size of message is 8
        sTXCANMessage.pucMsgData = TXMsgData;         // ptr to message content
    
        /*
        if(CANNum == 0)
        {
            ObjID0++;
            if(ObjID0 > 24){ObjID0 = 1;}
    
            CANMessageSet(CANB_BASE, ObjID0, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
        }
        else
        {
            ObjID1++;
            if(ObjID1 > 24){ObjID1 = 1;}
    
            CANMessageSet(CANA_BASE, ObjID1, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
        }
        */
    
    
        if(CANNum == 0)
        {
            //��Ϣ�������ڽ���,�ȴ�����
            while(HWREG(CANB_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
            //IF1 Command Register
            cmd_regdata = CAN_IF1CMD_ARB | CAN_IF1CMD_MASK | CAN_IF1CMD_CONTROL;
            HWREGH(CANB_BASE + CAN_O_IF1CMD + 2) = cmd_regdata >> 16;
    
            //��1-24��Ѱ�ҿ��Է��͵�����
            for(i = 1; i <= 24; i++)//send using message object ID:1-24
            {
                HWREGH(CANB_BASE + CAN_O_IF1CMD) = i;//д�������Ϣ����
    
                while(HWREG(CANB_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
                //0,����Ϣ����δ�ȴ�����,���Է�������Ϣ
                if((HWREG(CANB_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_TXRQST) == 0){break;}
            }
            if(i >= 25){return;}
    
            CANMessageSet(CANB_BASE, i, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
        }
        else
        {
            //��Ϣ�������ڽ���,�ȴ�����
            while(HWREG(CANA_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
            //IF1 Command Register
            cmd_regdata = CAN_IF1CMD_ARB | CAN_IF1CMD_MASK | CAN_IF1CMD_CONTROL;
            HWREGH(CANA_BASE + CAN_O_IF1CMD + 2) = cmd_regdata >> 16;
    
            //��1-24��Ѱ�ҿ��Է��͵�����
            for(i = 1; i <= 24; i++)//send using message object ID:1-24
            {
                HWREGH(CANA_BASE + CAN_O_IF1CMD) = i;//д�������Ϣ����
    
                while(HWREG(CANA_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);
    
                //0,����Ϣ����δ�ȴ�����,���Է�������Ϣ
                if((HWREG(CANA_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_TXRQST) == 0){break;}
            }
            if(i >= 25){return;}
    
            CANMessageSet(CANA_BASE, i, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
        }
    
    }
    
    //=======================================================================================================
    // No more
    //=======================================================================================================
    
    

  • Hi Gabriel,

    It would be difficult to debug the issue you are seeing just by looking at the codes but maybe you can do a some changes to isolate what is causing one of the nodes to not recevie the frames.  See if you can try the following:

         1.) Remove the DSP that can receive the CAN frames.  Will the remaining DSP be able to receive the CAN frame? 

         2.) Swap the node IDs of the 2 DSPs.  Does the original node that cannot receive the CAN frame still not able to receive messages?

    Also, what is the CAN clock setup and what is the source of SYSCLK (external crystal, others...etc...)

    Thanks,

    Joseph

  • Dear Joseph

    1、The source of SYSCLK is external crystal, as shown in the following function:

    InitSysPll(XTAL_OSC,IMULT_20,FMULT_0,PLLCLK_BY_2);

    2、The CAN clock is CPU SYSCLKOUT, as shown in the following function:

    CANClkSourceSelect(CANB_BASE, 0);//0 - Selected CPU SYSCLKOUT (CPU1.Sysclk or CPU2.Sysclk)

    3、After swapping the node IDs of two DSPs, I found that the node ID that could not enter receive interrupts was still the previous node ID number, node 61. Node 44  is still normal after swapping the DSP circuit board. This can prove that it is not related to hardware, the problem lies in software.

    4、After I removing the DSP node (node number: 44) that was able to enter receive interrupts normally all the time, leaving only the DSP node (node number: 61) that was sometimes unable to enter receive interrupts, I found that after doing this, node 61 was able to enter receive interrupts normally all the time, and there was no occurrence of being unable to enter receive interrupts afterwards.

    5、Through the above operation, I speculate that node 44 sent too many frames to the bus, which affected the reception of node 61. To verify this speculation, I deleted some messages sent by node 44 to the bus, and still connected nodes 44 and 61 to the bus. After powering on, the probability of node 61 being unable to enter the receive interrupt was greatly reduced.

    6、Through the above operation, I speculate that node 44 sent too many frames to the bus, which affected the reception of node 61. To verify this speculation, I deleted some messages sent by node 44 to the bus, and still connected nodes 44 and 61 to the bus. After powering on, the probability of node 61 being unable to enter the receive interrupt was greatly reduced. I highly suspect that there is a problem with the configuration of the receiving mailboxes or the code for polling idle sending mailboxes, but I don't know where it is. I hope you can help me check if there are any issues with the receiving and sending mailbox operation codes.

     Thanks!

  • Hi Gabriel,

    In CAN, if the transmitting node does not receive an ACK from a receiving node, it will attempt to retransmit the frame unless automatic data retransmission is disabled.  Maybe this is the issue.  Here is the snippet taken from your code:

     

        //在总线脱离状态下,当检测到128*11个隐性位后,模块将自动恢复总线的连接状态
        HWREG(CANB_BASE + CAN_O_CTL) |= CAN_CTL_ABO; //Auto-Bus-On Enable
        //在检测到任何总线活动后,模块退出低功耗模式(自动唤醒)
        HWREG(CANB_BASE + CAN_O_CTL) |= CAN_CTL_WUBA;//Wake Up on Bus Activity
        //关闭自动从发功能
        HWREG(CANB_BASE + CAN_O_CTL) |= CAN_CTL_DAR;//Disable Automatic Retransmission
    
    

    Try to enable enable retransmission by clearing the DAR bit to '0'.

    Regards,

    Joseph

  • Dear Joseph

    Today, I did as you said, as follows:

    HWREG(CANB_BASE + CAN_O_CTL) &= ~CAN_CTL_DAR;//Enable Automatic Retransmission

    But it didn't have any effect.

    Can you help me check if there are any errors in using the sending email, as shown below:

  • Hi Gabriel,

    I don't understand the purpose of the for loop in your code.  It seems that code is attempting to copy the message object number to the IF1CMD register for objects 1-24 and polling for busy bit and TXRQST afterwards, then after the for loop the frame is transmitted with function CANMessageSet().  This means that there is only one frame transmitted.  The code inside the for loop is already accomplished inside CANMessageSet.  Can you just put the loop around function CANMessageSet() as below?

    for(i=1;i<=24;i++)
    {
        
        CANMessageSet(CAN_BASE, i, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
        
        // add some delay here if needed
    
    }

    Regards,

    Joseph

  • Dear Joseph

    1、The function "void BSPCANTxDataBuffInByteAlterDlc(u8 CANNum, u8 DLC, u32 ID, u8* Data)" and "void BSPCANTxDataBuffInDWordAlterDlc(u8 CANNum, u8 DLC, u32 ID, u32 DWord0, u32 DWord1)" are interface functions used by two CAN channels to send a frame of message externally.

    2、The reason why I use this for loop is because I have configured message object 1-24 for sending messages, but each mailbox may be busy or idle at different time periods. Therefore, I need to search for idle mailboxes to send, busy mailboxes can not be used at this time. The purpose of doing so is to maximize the use of 24 message objects, avoiding wasting time and delaying transmission efficiency.According to what you just said, there is a problem with the code, but according to my design philosophy, how should the code be corrected?

    3、If I follow your instructions to add some delay  after function "CANMessageSet(CAN_BASE, i, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);". This may affect the overall operation of the project, as my current project is running in a time slot manner. Adding a delay here will affect the execution timing of other tasks.

     

    Thanks.

  • Hi Gabriel,

    Thanks for the explanation.  Now i understand what you are trying to accomplish in the for loop.  You could also try polling register CAN_TXRQ_21 to see which object(s) is not busy with transmit request.

    Some more questions - what speed have you set for the baud rate and how often are functions  BSPCANTxDataBuffInByteAlterDlc()/ BSPCANTxDataBuffInDWordAlterDlc() called?

    Thanks,

    Joseph

  • Dear Joseph

    1、The baud rate is set to 250Kbps.

    2、In most cases, one frame of data is sent every 1ms, but in some cases, two or three frames of data may be sent in one place.

     

    3、Can you provide me with a normal routine for sending and receiving data through multiple message objects for my reference? If possible, I would be very grateful.

     

    Thanks

  • Hi Gabriel,

    At 250kbps,  an average frame (with 8 bytes of data, control bits, node ID and CRC and stuffing bits - in total would have approximately 125bit) will take at least 0.5ms to send.  This might be fine with the CAN bus with one frame every 1ms sent but if the receving node(s) is having issues receiving the frame or successive frames.  It might cause some issues.  CAN protocol would still try to resend a frame that has not been acknowledged or if the current sent frame is pending due to an arbitration won by another node that is currently sending a frame to the bus.

    Can you try increasing the baud rate to 500kbps to see if this helps with better frame reception?

    Thanks,

    Joseph 

  • Dear Joseph

    Today, I tried increasing the baud rate to 500kbps  for testing, which can better receive frames, but the issue of not being able to enter the receive interrupt still occasionally occurs.

     

    Thanks

  • Hi Gabriel,

    It looks like some messages are either not transmitted, or lost due to the frequency at which they are sent/received.  First makes sure not to disable the automatic retransmission so that if there is no acknowledgement that a frame has been received by a node, CAN will keep retransmitting the frame.

    It would probably help with debug if you use a CAN analyzer (PEAK Can or any CAN analysis tool) that monitors the CAN bus for any sent frames.   Put the CAN analyzer in listening mode so there will not be any acknowledgement.  You would want to see that any frame sent out by the node is indeed being transmitted to the CAN bus.  If you can confirm that every frame sent makes it to the CAN bus, then we can start to debug why frame is not received.

    There is a bit in the CAN_IFxMCTL that you can check after the contents of the message RAM is transferred to the interface registers to see if the message was lost.  You can monitor this register in the receiving node and the bit is MsgLst (bit 14).

    See if you can trace where the issue is coming from first (during transmission or during reception) with the suggested steps above.

    Thanks,

    Joseph