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.

TMS320F280049: F280049 CAN issue

Part Number: TMS320F280049

HI Champ,

Customer met issue for CAN transmit, the CAN transmit be execute in main loop, if not disable the interrupt (by DINT), the CAN mailbox transmit message ID and Data will mismatch sometime. if disable the interrupt like following way , the CAN transmit will always correct.

Could you help to advise the reason?

  • Hi Johnson,

    I suspect that there could be an ongoing transmission or pending interrupts while the IF1 register values are being modified in main loop.  You can advise to poll INT1ID or INT10D in the CAN_INT register to see if there are pending interrupts or check on register CAN_TXRQ_21 to see if there are pending  transmissions.

    Regards,

    Joseph

  • HI Joseph,

    Sorry, i cannot catch you!

    The CAN transmit just use polling didn't enable  interrupt.

    if there have ongoing transmission or pending interrupts , why disable the interrupt could settle the issue?

  • HI Joseph,

    Attached is customer CAN transmit code.

    Could you  help to advise the possible reason.

    // ============================================================================
    // º¯ÊýÃû³Æ: CANMessageSend()
    // º¯Êý¹¦ÄÜ: CAN·¢Ëͺ¯Êý
    // Êä    Èë: ui32Base is the base address of the CAN controller
    //!       ui32ObjID is the object number to configure (1-32).
    //!       pMsgObject is a pointer to a structure containing message object settings.
    //!       eMsgType indicates the type of message for this object.
    // Êä    ³ö: ÎÞ
    // ÉÈ    Èë: BspCan_CanTx             // CAN³õʼ»¯
    // ÉÈ    ³ö: ÎÞ
    // ÆäËü˵Ã÷: ÎÞ
    // ===========================================================================
    int16 CANMessageSend(Uint32 ui32Base, Uint32 ui32ObjID, tCANMsgObject *pMsgObject, tMsgObjType eMsgType)
    {
        Uint32 ui32CmdMaskReg = 0;
        Uint32 ui32MaskReg = 0;
        Uint32 ui32ArbReg = 0;
        Uint32 ui32MsgCtrl = 0;
        bool bTransferData = FALSE;
        bool bUseExtendedID = FALSE;
        Uint16 S_Temp = 0;
        int16 Rtv = SYS_CAN_OP_OK;
    
        bTransferData = 0;
    
        while(((CAN_ADDR16(ui32Base + CAN_O_IF1CMD) & \
                CAN_IF1CMD_BUSY) != 0) && (S_Temp < 1000))                     // ¼ì²éÊÇ·ñ´¦ÓÚ¿ÕÏÐ״̬,Èç¹ûÕâÀïͨ²»¹ý£¬ÄÇÏÂÃæµÄ¼Ä´æÆ÷¶¼ÎÞ·¨²Ù×÷£¬ÒòΪ¼Ä´æÆ÷¶¼ÊÜbusy±£»¤
        {
            DELAY_US(1);                                                 // ×î¶àµÈ´ý1msºóÍ˳ö
            S_Temp++;                                                    // ͨ¹ý×öʵÑ飬ÕâÀïÔÚ³õʼ»¯µÄʱºò²»»á½øÈë
        }
    
        if (S_Temp >= 1000)
        {
            S_Temp = 0;                                                  // Í˳öºó½«µÈ´ý¼ÆÊýÇåÀí´¦Àí
            Rtv = SYS_CAN_OP_ERROR;                                      // ·µ»ØCAN·¢ËÍ´íÎó
        }
        else
        {
            S_Temp = 0;
        }
    
        if((pMsgObject->ui32MsgID > CAN_MAX_11BIT_MSG_ID) || ((pMsgObject->ui32Flags & MSG_OBJ_EXTENDED_ID) != 0))    // ÅжÏÊÇ·ñΪ±ê×¼Ö¡»¹ÊÇÀ©Õ¹Ö¡
        {
            bUseExtendedID = 1;
        }
        else
        {
            bUseExtendedID = 0;
        }
    
        ui32CmdMaskReg = (CAN_IF1CMD_DIR | CAN_IF1CMD_DATA_A | CAN_IF1CMD_DATA_B | CAN_IF1CMD_CONTROL);        // This is always a write to the Message object as this call is setting a message object.  This call will also always set all size bits so it sets both data bits.  The call will use the CONTROL register to set control bits so this bit needs to be set as well.
    
        ui32ArbReg = 0;                                                                                        // Initialize the values to a known state before filling them in based on the type of message object that is being configured.
        ui32MsgCtrl = 0;
        ui32MaskReg = 0;
    
        switch(eMsgType)
        {
            case MSG_OBJ_TYPE_TX:                                                                              // Transmit message object.
            {
                ui32MsgCtrl |= CAN_IF1MCTL_TXRQST;                                                             // Set the TXRQST bit and the reset the rest of the register.
                ui32ArbReg = CAN_IF1ARB_DIR;
                bTransferData = 1;
                break;
            }
    
            case MSG_OBJ_TYPE_TX_REMOTE:                                                                       // Transmit remote request message object
            {
                ui32MsgCtrl |= CAN_IF1MCTL_TXRQST;                                                             // Set the TXRQST bit and the reset the rest of the register.
                ui32ArbReg = 0;
                break;
            }
    
            case MSG_OBJ_TYPE_RX:                                                                              // Receive message object.
            {
                ui32ArbReg = 0;                                                                                // This clears the DIR bit along with everything else.  The TXRQST bit was cleared by defaulting ui32MsgCtrl to 0.
                break;
            }
    
            case MSG_OBJ_TYPE_RX_REMOTE:                                                                       // Receive remote request message object.
            {
                ui32ArbReg = CAN_IF1ARB_DIR;                                                                   // The DIR bit is set to one for remote receivers.  The TXRQST bit was cleared by defaulting ui32MsgCtrl to 0.
                ui32MsgCtrl = CAN_IF1MCTL_UMASK;                                                               // Set this object so that it only indicates that a remote frame was received and allow for software to handle it by sending back a data frame.
                ui32MaskReg = CAN_IF1MSK_MSK_M;                                                                // Use the full Identifier by default.
                ui32CmdMaskReg |= CAN_IF1CMD_MASK;                                                             // Make sure to send the mask to the message object.
                break;
            }
    
            case MSG_OBJ_TYPE_RXTX_REMOTE:                                                                     // Remote frame receive remote, with auto-transmit message object.
            {
                ui32ArbReg = CAN_IF1ARB_DIR;                                                                   // Oddly the DIR bit is set to one for remote receivers.
                ui32MsgCtrl = CAN_IF1MCTL_RMTEN | CAN_IF1MCTL_UMASK;                                           // Set this object to auto answer if a matching identifier is seen.
                bTransferData = 1;                                                                             // The data to be returned needs to be filled in.
                break;
            }
    
            default:                                                                                           // This case should never happen due to the ASSERT statement at the beginning of this function.
            {
                Rtv = SYS_CAN_OP_ERROR;
                break;
            }
        }
    
        if ((pMsgObject->ui32Flags & MSG_OBJ_USE_ID_FILTER) != 0)                                                      // Configure the Mask Registers.
        {
            if(bUseExtendedID)
            {
                ui32MaskReg = pMsgObject->ui32MsgIDMask & CAN_IF1MSK_MSK_M;                                    // Set the 29 bits of Identifier mask that were requested.
            }
            else
            {
                ui32MaskReg = ((pMsgObject->ui32MsgIDMask << CAN_IF1ARB_STD_ID_S) & CAN_IF1ARB_STD_ID_M);      // Put the 11 bit Mask Identifier into the upper bits of the field in the register.
            }
        }
        else
        {
            ;
        }
    
        if ((pMsgObject->ui32Flags & MSG_OBJ_USE_EXT_FILTER) == MSG_OBJ_USE_EXT_FILTER)                         // If the caller wants to filter on the extended ID bit then set it.
        {
            ui32MaskReg |= CAN_IF1MSK_MXTD;
        }
        else
        {
            ;
        }
    
        if ((pMsgObject->ui32Flags & MSG_OBJ_USE_DIR_FILTER) == MSG_OBJ_USE_DIR_FILTER)                         // The caller wants to filter on the message direction field.
        {
            ui32MaskReg |= CAN_IF1MSK_MDIR;
        }
        else
        {
            ;
        }
    
        if ((pMsgObject->ui32Flags & (MSG_OBJ_USE_ID_FILTER | MSG_OBJ_USE_DIR_FILTER | MSG_OBJ_USE_EXT_FILTER)) != 0)
        {
            ui32MsgCtrl |= CAN_IF1MCTL_UMASK;                                                                  // Set the UMASK bit to enable using the mask register.
            ui32CmdMaskReg |= CAN_IF1CMD_MASK;                                                                 // Set the MASK bit so that this gets transferred to the Message Object.
        }
        else
        {
            ;
        }
    
        ui32CmdMaskReg |= CAN_IF1CMD_ARB;                                                                      // Set the Arb bit so that this gets transferred to the Message object.
    
        if (bUseExtendedID)                                                                                     // Configure the Arbitration registers.
        {
            ui32ArbReg |= (pMsgObject->ui32MsgID & CAN_IF1ARB_ID_M) | CAN_IF1ARB_MSGVAL | CAN_IF1ARB_XTD;      // Set the 29 bit version of the Identifier for this message object.Mark the message as valid and set the extended ID bit.
        }
        else
        {
            ui32ArbReg |= ((pMsgObject->ui32MsgID << CAN_IF1ARB_STD_ID_S) & CAN_IF1ARB_STD_ID_M) | CAN_IF1ARB_MSGVAL;   // Set the 11 bit version of the Identifier for this message object.The lower 18 bits are set to zero.Mark the message as valid.
        }
    
        ui32MsgCtrl |= (pMsgObject->ui32MsgLen & CAN_IF1MCTL_DLC_M);                                                    // Set the data length since this is set for all transfers.  This is also a single transfer and not a FIFO transfer so set EOB bit.
    
        if ((pMsgObject->ui32Flags & MSG_OBJ_FIFO) == 0)                                                                 // Mark this as the last entry if this is not the last entry in a FIFO.
        {
            ui32MsgCtrl |= CAN_IF1MCTL_EOB;
        }
        else
        {
            ;
        }
    
        if ((pMsgObject->ui32Flags & MSG_OBJ_TX_INT_ENABLE) != 0)                                                               // Enable transmit interrupts if they should be enabled.
        {
            ui32MsgCtrl |= CAN_IF1MCTL_TXIE;
        }
        else
        {
            ;
        }
    
        if ((pMsgObject->ui32Flags & MSG_OBJ_RX_INT_ENABLE) != 0)                                                               // Enable receive interrupts if they should be enabled.
        {
            ui32MsgCtrl |= CAN_IF1MCTL_RXIE;
        }
        else
        {
            ;
        }
    
        if (bTransferData)                                                                                               // Write the data out to the CAN Data registers if needed.
        {
            CANDataRegWrite(pMsgObject->pucMsgData, (Uint32 *)(ui32Base + CAN_O_IF1DATA), pMsgObject->ui32MsgLen);
        }
        else
        {
            ;
        }
    
        CAN_ADDR16(ui32Base + CAN_O_IF1CMD + 2) = ui32CmdMaskReg >> 16;                                                 // Write out the registers to program the message object.
        CAN_ADDR16(ui32Base + CAN_O_IF1MSK)     = ui32MaskReg & CAN_REG_WORD_MASK;
        CAN_ADDR16(ui32Base + CAN_O_IF1MSK + 2) = ui32MaskReg >> 16;
        CAN_ADDR16(ui32Base + CAN_O_IF1ARB)     = ui32ArbReg & CAN_REG_WORD_MASK;
        CAN_ADDR16(ui32Base + CAN_O_IF1ARB + 2) = ui32ArbReg >> 16;
        CAN_ADDR16(ui32Base + CAN_O_IF1MCTL)    = ui32MsgCtrl & CAN_REG_WORD_MASK;
        CAN_ADDR16(ui32Base + CAN_O_IF1CMD)     = ui32ObjID & CAN_IF1CMD_MSG_NUM_M;                                     // Transfer the message object to the message object specific by ui32ObjID.
    
        return (Rtv);
    }

  • Hi Johnson,

          The code snippet only shows the transmit function (CANMessageSend).   I do not see the CAN set up functions so I really cannot say if interrupt is anabled or not.  Anyway, modifying the data bytes of the message object before a pending transmission starts will not take effect.  This may be what is happening so it will be good to check for pending transmissions before modifying the data.

    Regards,

    Joseph

  • HI Joseph,

    Customer system has CPUTIMER  interrupt and PWM interrupt.

    CAN Transmit used IF1 and didn't enable the CANTX interrupt.

    CAN receive use IF2  and enabled the interrupt.the receive handling as attached.

    // ============================================================================
    // ��������: CANMessageReceive()
    // ��������: CAN���պ���
    // ��    ��: ui32Base is the base address of the CAN controller
    //!       ui32ObjID is the object number to configure (1-32).
    //!       pMsgObject is a pointer to a structure containing message object settings.
    //!       eMsgType indicates the type of message for this object.
    // ��    ��: ��
    // ��    ��: BspCan_CanRx             // CAN��ʼ��
    // ��    ��: ��
    // ����˵��: ��
    // ===========================================================================
    int16 CANMessageReceive(Uint32 ui32Base, Uint32 ui32ObjID, tCANMsgObject *pMsgObject, bool bClrPendingInt)
    {
        Uint32 ui32CmdMaskReg = 0;
        Uint32 ui32MaskReg = 0;
        Uint32 ui32ArbReg = 0;
        Uint32 ui32MsgCtrl = 0;
        Uint16 S_Temp = 0;
        int16 Rtv = SYS_CAN_OP_OK;
    
        ui32CmdMaskReg = (CAN_IF2CMD_DATA_A | CAN_IF2CMD_DATA_B | CAN_IF2CMD_CONTROL | CAN_IF2CMD_MASK | CAN_IF2CMD_ARB);   // This is always a read to the Message object as this call is setting a message object.
    
        if(bClrPendingInt)                                                                                                  // Clear a pending interrupt and new data in a message object.
        {
            ui32CmdMaskReg |= CAN_IF2CMD_CLRINTPND | CAN_IF2CMD_TXRQST;
        }
        else
        {
            ;
        }
    
        CAN_ADDR16(ui32Base + CAN_O_IF2CMD + 2) =  ui32CmdMaskReg >> 16;                                                    // Set up the request for data from the message object.
        CAN_ADDR16(ui32Base + CAN_O_IF2CMD) = ui32ObjID & CAN_IF2CMD_MSG_NUM_M;                                             // Transfer the message object to the message object specified by ui32ObjID.
    
        while(((CAN_ADDR16(ui32Base + CAN_O_IF2CMD) & \
                CAN_IF2CMD_BUSY) != 0) && (S_Temp < 1000))                                                                        // ����Ƿ��ڿ���״̬,�������ͨ������������ļĴ������޷���������Ϊ�Ĵ�������busy����
        {
            DELAY_US(1);                                                                                                    // ���ȴ�1ms���˳�
            S_Temp++;                                                                                                       // ͨ����ʵ�飬�����ڳ�ʼ����ʱ�򲻻����
        }
    
        if (S_Temp >= 1000)
        {
            S_Temp = 0;                                                                                                     // �˳��󽫵ȴ������������
            Rtv = SYS_CAN_OP_ERROR;                                                                                           // ����CAN���մ���
        }
        else
        {
            S_Temp = 0;
        }
    
        ui32MaskReg = CAN_ADDR32(ui32Base + CAN_O_IF2MSK);                                                                  // Read out the IF Registers.
        ui32ArbReg  = CAN_ADDR32(ui32Base + CAN_O_IF2ARB);
        ui32MsgCtrl = CAN_ADDR32(ui32Base + CAN_O_IF2MCTL);
        pMsgObject->ui32Flags = MSG_OBJ_NO_FLAGS;
    
        if((((!(ui32MsgCtrl & CAN_IF2MCTL_TXRQST)) != 0) && ((ui32ArbReg & CAN_IF2ARB_DIR) != 0)) \
                || (((ui32MsgCtrl & CAN_IF2MCTL_TXRQST) != 0) && ((!(ui32ArbReg & CAN_IF2ARB_DIR)) != 0)))  // Determine if this is a remote frame by checking the TXRQST and DIR bits.
        {
            pMsgObject->ui32Flags |= MSG_OBJ_REMOTE_FRAME;
        }
        else
        {
            ;
        }
    
        if((ui32ArbReg & CAN_IF2ARB_XTD) == CAN_IF2ARB_XTD)                                     // Get the identifier out of the register, the format depends on size of the mask.
        {
            pMsgObject->ui32MsgID = ui32ArbReg & CAN_IF2ARB_ID_M;                               // Set the 29 bit version of the Identifier for this message object.
            pMsgObject->ui32Flags |= MSG_OBJ_EXTENDED_ID;
        }
        else
        {
            pMsgObject->ui32MsgID = (ui32ArbReg & CAN_IF2ARB_STD_ID_M) >> CAN_IF2ARB_STD_ID_S;  // The Identifier is an 11 bit value.
        }
    
        if((ui32MsgCtrl & CAN_IF2MCTL_MSGLST) == CAN_IF2MCTL_MSGLST)                            // Indicate that we lost some data.
        {
            pMsgObject->ui32Flags |= MSG_OBJ_DATA_LOST;
        }
        else
        {
            ;
        }
    
        if((ui32MsgCtrl & CAN_IF2MCTL_UMASK) == CAN_IF2MCTL_UMASK)                              // Set the flag to indicate if ID masking was used.
        {
            if((ui32ArbReg & CAN_IF2ARB_XTD) == CAN_IF2ARB_XTD)
            {
                pMsgObject->ui32MsgIDMask = (ui32MaskReg & CAN_IF2MSK_MSK_M);                                           // The Identifier Mask is assumed to also be a 29 bit value.
    
                if((pMsgObject->ui32MsgIDMask != 0x1fffffff) || ((pMsgObject->ui32Flags & MSG_OBJ_REMOTE_FRAME) == 0))  // If this is a fully specified Mask and a remote frame then don't set the MSG_OBJ_USE_ID_FILTER because the ID was not really filtered.
                {
                    pMsgObject->ui32Flags |= MSG_OBJ_USE_ID_FILTER;
                }
                else
                {
                    ;
                }
            }
            else
            {
                pMsgObject->ui32MsgIDMask = ((ui32MaskReg & CAN_IF2MSK_MSK_M) >> 18);                                   // The Identifier Mask is assumed to also be an 11 bit value.
    
                if((pMsgObject->ui32MsgIDMask != 0x7ff) || ((pMsgObject->ui32Flags & MSG_OBJ_REMOTE_FRAME) == 0))       // If this is a fully specified Mask and a remote frame then don't set the MSG_OBJ_USE_ID_FILTER because the ID was not really filtered.
                {
                    pMsgObject->ui32Flags |= MSG_OBJ_USE_ID_FILTER;
                }
                else
                {
                    ;
                }
            }
    
            if((ui32MaskReg & CAN_IF2MSK_MXTD) == CAN_IF2MSK_MXTD)                                                      // Indicate if the extended bit was used in filtering.
            {
                pMsgObject->ui32Flags |= MSG_OBJ_USE_EXT_FILTER;
            }
            else
            {
                ;
            }
    
            if((ui32MaskReg & CAN_IF2MSK_MDIR) == CAN_IF2MSK_MDIR)                                                      // Indicate if direction filtering was enabled.
            {
                pMsgObject->ui32Flags |= MSG_OBJ_USE_DIR_FILTER;
            }
            else
            {
                ;
            }
        }
        else
        {
            ;
        }
    
        if ((ui32MsgCtrl & CAN_IF2MCTL_TXIE) == CAN_IF2MCTL_TXIE)                                                       // Set the interrupt flags.
        {
            pMsgObject->ui32Flags |= MSG_OBJ_TX_INT_ENABLE;
        }
        else
        {
            ;
        }
    
        if ((ui32MsgCtrl & CAN_IF2MCTL_RXIE) == CAN_IF2MCTL_RXIE)
        {
            pMsgObject->ui32Flags |= MSG_OBJ_RX_INT_ENABLE;
        }
        else
        {
            ;
        }
    
        if ((ui32MsgCtrl & CAN_IF2MCTL_NEWDAT) == CAN_IF2MCTL_NEWDAT)                                                     // See if there is new data available.
        {
            pMsgObject->ui32MsgLen = (ui32MsgCtrl & CAN_IF2MCTL_DLC_M);                                                  // Get the amount of data needed to be read.
    
            if ((pMsgObject->ui32Flags & MSG_OBJ_REMOTE_FRAME) == 0)                                                      // Don't read any data for a remote frame, there is nothing valid in that buffer anyway.
            {
                CANDataRegRead(pMsgObject->pucMsgData, (Uint32 *)(ui32Base + CAN_O_IF2DATA), pMsgObject->ui32MsgLen);  // Read out the data from the CAN registers.
            }
            else
            {
                ;
            }
    
            CAN_ADDR16(ui32Base + CAN_O_IF2CMD + 2) = CAN_IF2CMD_TXRQST >> 16;                                           // Now clear out the new data flag.
            CAN_ADDR16(ui32Base + CAN_O_IF2CMD) = ui32ObjID & CAN_IF2CMD_MSG_NUM_M;                                      // Transfer the message object to the message object specified by ui32ObjID.
    
            while(((CAN_ADDR16(ui32Base + CAN_O_IF2CMD) & \
                    CAN_IF2CMD_BUSY) != 0) && (S_Temp < 1000))                                                           // ����Ƿ��ڿ���״̬,�������ͨ������������ļĴ������޷���������Ϊ�Ĵ�������busy����
            {
                DELAY_US(1);                                                                                             // ���ȴ�1ms���˳�
                S_Temp++;                                                                                                // ͨ����ʵ�飬�����ڳ�ʼ����ʱ�򲻻����
            }
    
            if (S_Temp >= 1000)
            {
                S_Temp = 0;                                                                                              // �˳��󽫵ȴ������������
                Rtv = SYS_CAN_OP_ERROR;                                                                                    // ����CAN���մ���
            }
            else
            {
                S_Temp = 0;
            }
    
            pMsgObject->ui32Flags |= MSG_OBJ_NEW_DATA;                                                                   // Indicate that there is new data in this message.
        }
        else
        {
    //        pMsgObject->ui32MsgLen = 0;                                                                                  // Along with the MSG_OBJ_NEW_DATA not being set the amount of data needs to be set to zero if none was available.
        }
        return (Rtv);                                                                                               // �����ɹ�
    }

    My concern is  if  following code be interrupt by other interrupt  like CPUTIMER or PWM interrupt,  what will happen?

    obviously just disable the interrupt by DINT be execute following code , the issue be closed.

    below function used 16-bit accesses, does it possible have 16-bit accesses cased this issue?

    CAN_ADDR16(ui32Base + CAN_O_IF1CMD + 2) = ui32CmdMaskReg >> 16; // Write out the registers to program the message object.
    CAN_ADDR16(ui32Base + CAN_O_IF1MSK) = ui32MaskReg & CAN_REG_WORD_MASK;
    CAN_ADDR16(ui32Base + CAN_O_IF1MSK + 2) = ui32MaskReg >> 16;
    CAN_ADDR16(ui32Base + CAN_O_IF1ARB) = ui32ArbReg & CAN_REG_WORD_MASK;
    CAN_ADDR16(ui32Base + CAN_O_IF1ARB + 2) = ui32ArbReg >> 16;
    CAN_ADDR16(ui32Base + CAN_O_IF1MCTL) = ui32MsgCtrl & CAN_REG_WORD_MASK;
    CAN_ADDR16(ui32Base + CAN_O_IF1CMD) = ui32ObjID & CAN_IF1CMD_MSG_NUM_M;

  • Hi Johnson,

    I do not have that macro for CAN_ADDR16 available so i cannot comment on how the writes are happening.  What we have in driverlib for CAN register writes are HWREGH and HWREG_BP but to be sure that writes are happening properly on the IF1 registers (transmit in this case), you probably can step through the code and see if writes are happening while using registers view in CCS.  It will be good to step through the code while looking at registers view with and without DINT.  Maybe something in the current ISR is overwriting the IF1 contents or preventing it from updating. 

    Regards,

    Joseph

  • HI Joseph,

    The issue happened randomly, most time without issue.if CAN BUS loading very high,  maybe 1 failed at total 100 time transmit.

    It is impossible to step through the code to found the issue.

    I hope  you could  advise  the possible reason.

    Could you advise 16-bit accesses may cased issue or not?

  • Hi Johnson,

    No, the 16-bit writes would not cause such an issue the fact that this is occurring randomly.  If CAN register update is not happening correctly then CAN will not function.  I still think that there is something in the Timer and PWM ISR routines that interferes with CAN register writes.  Maybe need to check what codes are in these ISRs.

    Regards,

    Joseph

  • HI Joseph,

    Please noted!

    In the Timer and PWM ISR routines never handling  CAN  related register. 

  • Hi Johnson,

    If it is not possible to step through the code, would an evaluation to comment out the Timer and PWM codes in the ISR (except for PIE acknowledgement) just as a quick debug to see if CAN transmission happens without the DINT statement?  The purpose of doing this is to see if there are codes in the ISR that affect the CAN.

    Thanks,

    Joseph

  • HI Joseph,

    if no code in Timer and PWM ISR, there will be no issue.

    This issue will happened  when the CPU loading is very high.

    the CAN_ADD16() as  following, please advise the possible reason。

    Thanks!

  • Hi Johnson,

    No, the 16-bit register writes is not an issue.  There are probably too many tasks happening in the Timer and EPWM ISRs in the background that prevents the updates on the CAN registers from happening at the intended time prior to transmission.

    Regards,

    Joseph

  • HI Joseph,

    The failure is not lost CAN transmit,  the issue is  CAN send out ID and Data not match sometimes.

    Need you help to analysis the root cause why below code be interrupt by some ISR will cause this issue!

    Please advise the solution to settle this issue, customer  cannot accept disable the interrupt to settle this issue,  or if we could tell customer below code has some issue.

  • Hi Johnson,

    Is it possible to see the Timer and EPWM ISR codes?  Wanted to understand what the routines are in the ISR that takes up CPU processing time and do you know how often these ISRs happen?  Issue might not be with the CAN but maybe what the ISRs are doing.

    Regards,

    Joseph

  • HI Joseph,

    The CPUTIMER  is 100us interrupt , PWM is 10us interrupt. PWM interrupt running motor control algorithm.

    As i mentioned before, it is very hard to repeat issue, it is happened randonly!  maybe 10min happened one time.

    We need you help analysis the potential risk if following code without disable interrupt.

  • Hi Johnson,

    Without knowing what the codes are inside the timer and PWM ISR, I can only suggest the following:

         - Create a flag inside the ISR and set it only to true if CAN data is valid ready to be updated

         - At the main program where the IFx registers (CMD,MSK,ARB and MCTL) are updated, only execute when flag is set to true.  For example

    if(flag==true)
    {
         CAN_ADDR16(ui32Base + CAN_O_IF1CMD + 2) = ui32CmdMaskReg >> 16;
         CAN_ADDR16(ui32Base + CAN_O_IF1ARB)…
          :
          :
         flag = false;
    }

    See if this will work without disabling the interrupts.

    Regards,

    Joseph

  • Joseph,

    It is no meaning to try this testing, we already know the CAN transmit  issue be caused by the ISR happened during the IFx registers (CMD,MSK,ARB and MCTL) are updated.

    By setting this flag  function is same as DINT.