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.

Wrong CAN data received

Other Parts Discussed in Thread: TM4C129DNCPDT

Hi all

I'm having some trouble receiving correct CAN messages when the bus is busy.

I am using the TM4C129DNCPDT on our own board. I have 2 boards communicating with a short cable between them.

To get to the bottom of my problem I am transmitting "123456789" over and over on one particular msg id. 

I have severeal msg id's doing various other tasks.

It seems that the can bus is sometimes receiving incorrect can messages where the first 2 bytes of the message is changed - usually into 0x03 0x00.

If I disable all other can communication the problem disappears.

I have posted my interrupt function below - Is there anything that can trigger this behaviour?

void HalCanInterruptHandler(uint8_t ucModule)
{
    tCANMsgObject sMsgObj;
    tMsgObjType   eMsgObjType = MSG_OBJ_TYPE_TX;
    uint32_t      usStatus    = 0;
    uint16_t      usMsgIdx    = 0;
    uint32_t      base = HalCanModule[ucModule].ulCanBase;
    HalCanResult  msg_stat = HAL_CAN_RESULT_NO_ERROR;
    HalCanMessage_t *message;

    // Read the CAN interrupt status to find the cause of the interrupt

    do
    {
        usStatus = CANIntStatus(base, CAN_INT_STS_CAUSE);

        // If the cause is a controller status interrupt, then get the status
        if (usStatus == CAN_INT_INTID_STATUS)
        {
            // Read the controller status. Also clears the status interrupt
            uint32_t canStatus = CANStatusGet(base, CAN_STS_CONTROL);// & HAL_CAN_STATUS_MASK;

            canStatus = canStatus & HAL_CAN_STATUS_MASK; //Filter out RX_OK and TX_OK flags

            // Only interested in status messages if it is related to an error
            if (canStatus != CAN_STATUS_LEC_NONE)
            {
                int j;

                // Now see which errors are present
                switch (canStatus & CAN_STATUS_LEC_MASK)
                {
                    case CAN_STATUS_LEC_STUFF: msg_stat |= HAL_CAN_RESULT_LEC_STUFF; break;
                    case CAN_STATUS_LEC_FORM:  msg_stat |= HAL_CAN_RESULT_LEC_FORM;  break;
                    case CAN_STATUS_LEC_ACK:   msg_stat |= HAL_CAN_RESULT_LEC_ACK;   break;
                    case CAN_STATUS_LEC_BIT1:  msg_stat |= HAL_CAN_RESULT_LEC_BIT1;  break;
                    case CAN_STATUS_LEC_BIT0:  msg_stat |= HAL_CAN_RESULT_LEC_BIT0;  break;
                    case CAN_STATUS_LEC_CRC:   msg_stat |= HAL_CAN_RESULT_LEC_CRC;   break;
                }

                if (canStatus & CAN_STATUS_BUS_OFF)
                {
                    msg_stat |= HAL_CAN_RESULT_BUS_OFF;
                    // Bus-off disables the module. To recover we must re-enable the module
                    CANEnable(base);
                }

                if (canStatus & CAN_STATUS_EWARN)
                {
                    msg_stat |= HAL_CAN_RESULT_EWARN;
                }

                if (canStatus & CAN_STATUS_EPASS)
                {
                    msg_stat |= HAL_CAN_RESULT_EPASS;
                }

                // Can't rely on getting information from CAN module about what TX/RX object was behind interrupt
                // when error case. Need to call back to all with status information
                for (j = 0; j < HAL_CAN_NO_OF_MSG_OBJS; j++)
                {
                    XHalCanCallBack cb = HalCanMessage[ucModule][j].can_call_back;
                    eMsgObjType = HalCanMessage[ucModule][j].eObjType;
                    HalCanMessage[ucModule][j].ulStatus = msg_stat;

                    // Don't bother telling listeners that the interface is down or running with errors
                    if ((cb != NULL) && ((eMsgObjType == MSG_OBJ_TYPE_TX) || (eMsgObjType == MSG_OBJ_TYPE_TX_REMOTE)))
                    {
                        cb(&HalCanMessage[ucModule][j]);
                    }
                }
            }
        }
        else if ((usStatus > 0) && (usStatus <= 32))
        {

            message = &HalCanMessage[ucModule][usStatus - 1]; //usStatus is from 1-32

            // What was the original message type?
            eMsgObjType = message->eObjType;

            // In case of reception, go get the message
            if ((eMsgObjType == MSG_OBJ_TYPE_RX) || (eMsgObjType == MSG_OBJ_TYPE_RX_REMOTE))
            {
                // Tell where to store received data (no matter if it is a remote reception)
                sMsgObj.pui8MsgData = message->aucData;
                // Go get the message
                CANMessageGet(base, usStatus, &sMsgObj, true);
                // Get the length of the message (only valid for data message)
                message->ucLength = sMsgObj.ui32MsgLen;
                if ((sMsgObj.ui32Flags & MSG_OBJ_NEW_DATA) != 0)
                {
                    message->ulStatus = HAL_CAN_RESULT_NO_ERROR;

                    // If a call-back function was given, do call it now
                    if (message->can_call_back != NULL)
                    {
                        message->can_call_back(message);
                    }
                }
            }
            else
            {
                // Clear processed message interrupt.
                CANIntClear(base, usStatus);
                message->ulStatus = HAL_CAN_RESULT_NO_ERROR;

                // If a call-back function was given, do call it now
                if (message->can_call_back != NULL)
                {
                    message->can_call_back(message);
                }
            }


        }
        else if (usStatus != 0)
        {
            //undefined!!!!
            ASSERT(FALSE);
        }
    } while (usStatus != 0);
}

  • Hi,

    It is not obvious from your snippet code how you transmit nine bytes in a message - at least i used always a maximum of eight.

    Petrei

  • Mads Andreasen said:
    can bus is sometimes receiving incorrect can messages where the first 2 bytes of the message is changed

    Your post is so well constructed/detailed - but for (dreaded) "sometimes!"

    Diagnosis is hugely dependent upon whether issue reveals 1/100,000, 1/1,000 or 1/100 can transactions!  (of course you know this - but you've given us no clue.)   Recall that we're savants - not psychics...

    And - like poster Petrei - I've always past sent (& received) messages up to 8 bytes...

    Devil in such detail...

  • Hi Petrei 

    I'm sorry that I wasn't clear on this point. I do only transmit 8 bytes, so the packets will be "12345678" - "91234567" ...

    -Mads

  • The issue pops up seemingly at random intervals. There can be perhaps 50,000 bytes with no errors and then have a period where there are 5-10 errors in the next 20,000 bytes. Sometimes just 1 error in 50,0000

    I know this isn't much to go on, but wondering if anyone has had weird experiences with this CAN controller. Or if my receive routine has some weak spots.

    -Mads

  • Mads Andreasen said:
    trouble receiving correct CAN messages when the bus is busy.

    Your latest post brings some definition/clarity to the verbage, "bus is busy." 

    Unknown & unstated is just, "how you add load to the CAN bus so that it becomes, "busy."  Suspect that extra CAN remotes come on-line - might this impact your bus termination?  Might one of these added CAN devices introduce some line defect which you (mistakenly) note as a bus busy condition?

    Does the error present consistently among different CAN locations?  (such may provide an added clue)

    When all else fails - lowering the CAN bus rate often adds robustness...

  • Hi again

    After some experimenting I got hold of a CAN analyzer. I could see that some bytes from other messages was transmitted copied into the transmission.

    It ended up being a problem with calling CanMessageSet inside an interrupt routine. This corrupted the message.

    One problem remains; it seems that sometimes messages are not being transmitted. I have implemented a timeout to look for this situation and to re-transmit the message. Solves the problem but it's not the root.

    Thanks for pitching in with ideas!

    regards,

    -Mads