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.

TM4C123GH6PM CAN MSG_OBJ_TYPE_RXTX_REMOTE

Other Parts Discussed in Thread: TM4C123GH6PM

Hey Everybody,

I need to configure some automatic mailboxes on the TM4C123GH6PM CAN micro.


Considering the following initialization, please correct me if I understand wrong:

    sCANMessage.ui32MsgID = (0x407);
    sCANMessage.ui32MsgIDMask = 0x7f8;
    sCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE   |
                                                MSG_OBJ_USE_ID_FILTER    |
                                                MSG_OBJ_EXTENDED_ID      |
                                                MSG_OBJ_USE_EXT_FILTER|
                                                MSG_OBJ_FIFO;
    sCANMessage.ui32MsgLen = 8;
    pui8MsgData[0] = 0x1;
    pui8MsgData[1] = 0xa;
    pui8MsgData[2] = 0x3;
    pui8MsgData[3] = 0xb;
    pui8MsgData[4] = 0x5;
    pui8MsgData[5] = 0xc;
    pui8MsgData[6] = 0x7;
    pui8MsgData[7] = 0xd;
    sCANMessage.pui8MsgData = &pui8MsgData;
    CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RXTX_REMOTE);

1.
??
"The MSG_OBJ_TYPE_RXTX_REMOTE option ALLOW ONLY RTR messages to be filtered(my particular example) and sent back over the bus with the SET LENGHT and PAYLOAD and the RECEIVED RTR ID."
??

2. What is the correct CAN driver procedure to modify the payload on a timer basis, for a MSG_OBJ_TYPE_RXTX_REMOTE mailbox?

3. Is there a way to set a different response ID for MSG_OBJ_TYPE_RXTX_REMOTE option?

4. Considering API example:

mask     0 0000 0000 0000 0000 0111 1111  1000    0x7f8
MSG1    0 0000 0000 0000 0000 0100 0000 0000   0x400
MSG2    0 0000 0000 0000 0000 0100 0000 0111    0x407

The mask should look to bits between 4 to 11, how come the 0x407 id valid?, can anywone details this mask filtering please?

Thank You.

  • Hello Liv,

    1. When the MSG_OBJ_TYPE_RXTX_REMOTE is used then if the identifier matches it is retransmitted over the bus

    2. For modification of the payload, you would need to change the type to MSG_OBJ_TYPE_RX_REMOTE so that the payload can be recieved, modified and then tranmsitted by CPU

    3. I am not sure what you mean a different response ID

    4. The filtering will allow for a group of MSG to be recieved. In this case both messages will be recieved and stored the MSG RAM

    Regards

    Amit

  • Hello Amit,

    Thanks for reply.

    Here is another question:

    5.

    CANDisable() = disable CAN controller for message processing. The controller can be restarted by calling  CANEnable().

    Can I use this restart method for changing BUSS OFF back to Error Active state?,

    or should  I use an external mechanism to power-off--power-on the controller?

    or, there is another way?

    Thanks

  • Hello Liv,

    When the CAN is disabled and re-enabled, the error counters will be frozen. So it will not allow for movement from BUSOFF to ERROR ACT state.

    Regards

    Amit

  • Hello Amit,

    Thanks again for fast rply.

    Here is question 6:

    So if the controller is not able to recover from bus-off for a time period (how many RX/TX packets?) using its internal mechanism, then I should use an external way to completely power of and on?, (hardware reset) ????


    Thanks

  • Hello Liv,

    You can use the SysCtlPeripheralReset API call to reset just the CAN controller instead of Reset of the entire device

    Regards

    Amit

  • Hello Amit,

    Thanks again for support here.

    Here is 7:

    I have set specific filter and mask id for mailbox 1 and 2 for CAN channel 0.

    Consider following Interrupt function:

    volatile bool TXFlag = 0;

    volatile bool RXFlag = 0;

    void
    CANIntHandlerA(void)
    {
        uint32_t ui32Status;

        ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

        if(ui32Status == CAN_INT_INTID_STATUS)
        {
            ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);

            switch (ui32Status)
            {
            case CAN_STATUS_BUS_OFF:
                UARTprintf(" CAN0_BASE CAN_STATUS_BUS_OFF ");
                break;

            case CAN_STATUS_EWARN:
                UARTprintf(" CAN0_BASE CAN_STATUS_EWARN ");
                break;

            case CAN_STATUS_LEC_ACK:
                UARTprintf(" CAN0_BASE CAN_STATUS_LEC_ACK ");
                break;

            case CAN_STATUS_LEC_BIT0:
                UARTprintf(" CAN0_BASE CAN_STATUS_LEC_BIT0 ");
                break;

            case CAN_STATUS_LEC_BIT1:
                UARTprintf(" CAN0_BASE CAN_STATUS_LEC_BIT1 ");
                break;

            case CAN_STATUS_LEC_CRC:
                UARTprintf(" CAN0_BASE CAN_STATUS_LEC_CRC ");
                break;

            case CAN_STATUS_LEC_FORM:
                UARTprintf(" CAN0_BASE CAN_STATUS_LEC_FORM ");
                break;

            case CAN_STATUS_LEC_MASK:
                UARTprintf(" CAN0_BASE CAN_STATUS_LEC_MASK ");
                break;

            case CAN_STATUS_LEC_NONE:
                UARTprintf(" CAN0_BASE CAN_STATUS_LEC_NONE ");
                break;

            case CAN_STATUS_LEC_STUFF:
                UARTprintf(" CAN0_BASE CAN_STATUS_LEC_STUFF ");
                break;

            case CAN_STATUS_RXOK:
                UARTprintf(" CAN0_BASE CAN_STATUS_RXOK "); // all 3 IDs

                RXFlag = 1;
                break;

            case CAN_STATUS_TXOK:
                UARTprintf(" CAN_STATUS_TXOK ");


                TXFlag = 1;
                break;

            default :

                UARTprintf(" default ");
                break;
            }
        }
        else if (TXFlag == 1)
        {
           TXFlag = 0;

            CANIntClear(CAN0_BASE, ui32Status);

            printf("Message Sent");

        }
        else if (RXFlag == 1)
        {
            RXFlag = 0;

            CANIntClear(CAN0_BASE, ui32Status);

            sCANMessage.pui8MsgData = pui8MsgData;

            CANMessageGet(CAN0_BASE, ui32Status, &sCANMessage, 0);

            printf("ID=0x%08X:", sCANMessage.ui32MsgID);  // only 2 mask IDs

        }
        else
        {
            UARTprintf("\n other ui32Status=%08X \n",ui32Status);

         }
    }

    Using an external device I am pushing 3 ID on the CAN bus:

    - one for feeding message mail box 1

    - one for feeding message mail box 2

    - one random that doesn't match either masks/filters.

    The behavior of the interrupt is that:

    - for each of the 3 different received messages I get the message: "CAN0_BASE CAN_STATUS_RXOK"

    - and only for the 2 masked ID's I get a "ID" print.

    My question is what happens with the interrupt function on the evaluation of:

    else if (RXFlag == 1) ????

    ...it simply gone after printing:

    "CAN0_BASE CAN_STATUS_RXOK" ...for the random ID, and doesn't print the RX ID.

    I think is convenient for me, but I need to understand the behavior.

    Thanks

  • Hello Liv

    Since the Random ID is not mapped to any message, the RXOK will only tell that the frame is OK but not map it to any Message Objects.

    Regards

    Amit

  • Hi Amit,

    First thanks for the previous answers.

    Here I have other questions.

    Question8:

    I have implemented the example from the: TivaWare Peripheral Driver Library - spmu298.pdf.

    sMsgObjectRx.ulMsgID = (0x400);
    sMsgObjectRx.ulMsgIDMask = 0x7f8;

    I am sending CAN messages from a second board having IDs from 0x400 to 0x407.

    None of these messages is passing trough !!!

    I think the example is wrong.

    Question9:

    Setting only the mask field ulMsgIDMask, but not the ID ulMsgID=0 has any relevance?,

    I have noticed that on this case all the received messages are passing trough.

    Question10:

    The example configures mailboxes 1 2 3 4 to receive data, then uses mailbox 2 to send data.

    Will the mailbox 2 be able to receive messages, once its been configured for transmission?

    Question11:

    I am trying to understand the use of the MSG_OBJ_FIFO flag.

    Is possible to use multiple receive mailboxes having different settings like:

    MSG_OBJ_TYPE_RX,

    MSG_OBJ_TYPE_RX_REMOTE,

    masks and IDs

    ......without the MSG_OBJ_FIFO flag set?

    It is mandatory to use the MSG_OBJ_FIFO flag for multiple mailboxes?

    It is mandatory to use the MSG_OBJ_FIFO flag for multiple mailboxes that try to receive a large amount of data for a specific CAN ID?

    Thank you

  • Hello Liv,

    Can you please send the CCS Project for both sides? I would need to check what is going on!!!

    Regards

    Amit

  • Hi Amit

    Here is the code:

     
    void InitCANA()
    {
        //
        // The CAN0 is used with RX and TX pins on port B4 and B5.
        // GPIO port B needs to be enabled so these pins can be used.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

        //
        // Configure the GPIO pin muxing to select CAN0 functions for these pins.
        // This step selects which alternate function is available for these pins.
        // This is necessary if your part supports GPIO pin function muxing.
        // Consult the data sheet to see which functions are allocated per pin.
        //
        GPIOPinConfigure(GPIO_PB4_CAN0RX);
        GPIOPinConfigure(GPIO_PB5_CAN0TX);

        //
        // Enable the alternate function on the GPIO pins.  The above step selects
        // which alternate function is available.  This step actually enables the
        // alternate function instead of GPIO for these pins.
        //
        GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);

        //
        // The GPIO port and pins have been set up for CAN0.  The CAN peripheral
        // must be enabled.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);

        //
        // Initialize the CAN0 controller
        //
        CANInit(CAN0_BASE);

        //
        // Set up the bit rate for the CAN bus. This function sets up the CAN
        // bus timing for a nominal configuration.
        // The call to SysCtlClockGet() is used to determine the clock rate that
        // is used for clocking the CAN0 peripheral
        //
        CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 1000000);

        //
        // Enable interrupts on the CAN peripheral.  This example uses static
        // allocation of interrupt handlers which means the name of the handler
        // is in the vector table of startup code.  If you want to use dynamic
        // allocation of the vector table, then you must also call CANIntRegister()
        // here.
        //
        // CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors
        //
        CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

        //
        // Enable the CAN interrupt on the processor (NVIC).
        //
        IntEnable(INT_CAN0);

        //
        // Enable the CAN for operation.
        //
        CANEnable(CAN0_BASE);
    }

    void
    CANAIntHandler(void)
    {
        uint32_t ui32Status;
        uint32_t err;

        //
        // Read the CAN interrupt status to find the cause of the interrupt
        //
        ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

        //
        // If the cause is a controller status interrupt, then get the status
        //
        if(ui32Status == CAN_INT_INTID_STATUS)
        {
            ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
            //
            // Set a flag to indicate some errors may have occurred.
            //
            g_bErrFlagA = 1;

            switch(ui32Status) {
            case CAN_STATUS_BUS_OFF: err = 1; break;
            case CAN_STATUS_EWARN: err = 2; break;
            case CAN_STATUS_EPASS: err = 3; break;
            case CAN_STATUS_LEC_MSK: err = 4; break;
            case CAN_STATUS_LEC_NONE: err = 5; break;
            case CAN_STATUS_LEC_STUFF: err = 6; break;
            case CAN_STATUS_LEC_FORM: err = 7; break;
            case CAN_STATUS_LEC_ACK: err = 8; break;
            case CAN_STATUS_LEC_BIT1: err = 9; break;
            case CAN_STATUS_LEC_BIT0: err = 10; break;
            case CAN_STATUS_LEC_CRC: err = 11; break;
            case CAN_STATUS_RXOK: err = INT_STAT_RX; break;
            case CAN_STATUS_TXOK: err = INT_STAT_TX; break;

    // What do I need is:

    1. mailbox number,

    2. message type: ERROR, RX, TX

    to be able to parse/handle it later on.

    It seems that my current implementation doesn't do it right.


        } else if(err == INT_STAT_RX) {
            //
            // Getting to this point means that the RX interrupt occurred on
            // message object ????, and the message reception is complete.  Clear the
            // message object interrupt.
            //
            CANIntClear(CAN0_BASE, ui32Status);

            //
            // Increment a counter to keep track of how many messages have been
            // received.  In a real application this could be used to set flags to
            // indicate when a message is received.
            //
            g_ui32MsgCountA++;

            //
            // Set flag to indicate received message is pending.
            //
            g_bRXFlagA = 1;

            //
            // Since a message was received, clear any error flags.
            //
            g_bErrFlagA = 0;
        }

        //
        else if(err == INT_STAT_RX){
            //
            // Getting to this point means that the RX interrupt occurred on
            // message object ???, and the message reception is complete.  Clear the
            // message object interrupt.
            //
            CANIntClear(CAN0_BASE, ui32Status);

            //
            // Since a message was received, clear any error flags.
            //
            g_bErrFlagA = 0;
        }


        //
        // Otherwise, something unexpected caused the interrupt.  This should
        // never happen.
        //
        else
        {
            //
            // Spurious interrupt handling can go here.
            //
        }
    }

    int IsNewMsg()
    {
        tCANMsgObject sCANMessage;
        uint8_t pui8MsgData[8];
        int r = 0;

        if (g_bRXFlagA)
        {
            sCANMessage.pui8MsgData = pui8MsgData;

            //
            // How can I Get the right mailbox number from the interrupt

           // to be able  to read the message from the CAN ????
            CANMessageGet(CAN0_BASE, 1, &sCANMessage, 0);

            //
            // Clear the pending message flag so that the interrupt handler can
            // set it again when the next message arrives.
            g_bRXFlagA = 0;

            sCANMessage.ui32MsgIDMask = 0;
            sCANMessage.ui32MsgLen = 0;
            sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;

            //Send the CAN message
            CANMessageSet(CAN0_BASE, 2, &sCANMessage, MSG_OBJ_TYPE_TX_REMOTE);

            r= 1;
        }

        return r;
    }

    int
    main(void)
    {
        //
        // Set the clocking to run at 50 MHz from the PLL.
        //
        ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

        InitCANA();

        tCANMsgObject sCANMessageA;

        // Initialize a message object to be used for receiving CAN messages
        sCANMessageA.ui32MsgID = 0x400;
        sCANMessageA.ui32MsgIDMask = 0x7f8;
        sCANMessageA.ui32Flags = MSG_OBJ_RX_INT_ENABLE    |
                                     MSG_OBJ_USE_ID_FILTER    |
                                     MSG_OBJ_EXTENDED_ID;

        // Now load the message object into the CAN peripheral.
        CANMessageSet(CAN0_BASE, 1, &sCANMessageA, MSG_OBJ_TYPE_RX_REMOTE);

        while (1)
        {
            if (IsNewMsg()) {
                printf("!");
            }
        }

        return(0);
    }

  • Hello Liv,

    I thought the issue was with a broken cable?

    Regards

    Amit

  • Hi Amit,

    Thank you again for support.

    I have figure out that the reason for not receiving any message was a broken cable. Was indeed my mistake to blame the documentation.

    Now I try to figure out how to properly deal with a mailbox in an interrupt for a transmitted as well as for a received message.

    How can i get that the triggered interrupt error type, received or transmitted type?, and how do I get the exact mailbox number to clear it?

    Regards

  • Hello Liv

    The forum post has more details. Look at the RX Side of the Code to see how to handle the Interrupt sources.

    http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/363647.aspx

    Regards

    Amit

  • Hi,

    Thanks for pointing the link but doesn't help much...


    What is the best practice to deal with an interup bus error?:

    1

    Should I reset the controller in the interrupt function? using the SysCtlPeripheralReset method,

    2

    or set a flag and reset in in the program main loop?, using same SysCtlPeripheralReset function?

    How long it takes SysCtlPeripheralReset to execute?

    Thanks

    Reset?

  • Hello Liv,

    It depends on the type of error message received in CANSTS register

    As an example: When NACK is received it would mean that there is no CAN node capable of receiving the message. Bit-1 Error would mean some node is holding the line in dominant state and could be not working.

    The controller should be reset "generally" only at start time. The APi generally takes a few clocks to reset the peripheral. So by the time API is completed the peripheral reset is complete.

    Regards

    Amit

  • Hi,

    Thanks again for support.

    I'm doing this test:

    1. Enable CAN A on mailbox number 1 to receive and trigger an interrupt.

    2. I have noticed that the interrupt function triggers 2 times ( is ok? ) for one message (transmitted or received) :

    a - the first time using CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE) returns CAN_INT_INTID_STATUS and check the CANStatusGet(CAN0_BASE, CAN_STS_CONTROL) the results in NO ERROR.

    b - the second time CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE) returns the mailbox number that triggered the interrupt and I clear the interrupt using CANIntClear(CAN0_BASE, CanIntStatus).

    If CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) returns 1 then I set the flag for a received message.

    3. In the main() while loop I check the flag for receiving.

    4. If the flag is set then a message was received.

    5. I read the message using CANMessageGet(CAN0_BASE, g_bRXFlag, &sCANMessage, 1) and send another message as reply using CANMessageSet(CAN0_BASE, mailbox_number, &sCANMessage, MSG_OBJ_TYPE_TX).

    6. After 31 of these request-reply the using mailbox_number = CANStatusGet(pBase, CAN_STS_MSGVAL) returns  0xFFFFFFFF ( si ok? ), like all the mailboxes are busy.

    7. Even so I use zero as parameter (mailbox_number) for CANMessageSet(CAN0_BASE, mailbox_number, &sCANMessage, MSG_OBJ_TYPE_TX).

    8. No problem, with zero as parameter for mailbox number  (is ok? ), my test for request-reply continues successfully.

    Can you give me an answer please.

    Thank You

  • Hello Liv

    Answers to your question in the same order

    1. Yes, it is OK to get two interrupts. One for letting the Application know that the transmission was successful and second one for informing the application that a data has been recieved

    2. Unless the message sent is 0xFFFFFFFF, the message always being 0xFFFFFFFF does not seem correct to me

    3. CAN Message Object is not a valid message object. The valid values are from 0x01-0x20. As you can see in the chapter for CAN, a message object of 0x00 will causes 0x20 to be used

    Regards

    Amit

  • Hi

    Test scenario 1:

    1. The TM4C123GH6PM CAN controller running continuously on normal run-time (CAN message request(PEAK) - reply(TM4C123GH6PM CAN)).

    2. The CAN speed is intentionally changed(PEAK) and the CAN bus gets in error state.

    3. The CAN messages requests(PEAK) continue, but don't get any reply because the bus is in error.

    4. The CAN interrupt is continuously triggered and it checks for the error type:

        bool err= OK;

        if (status & CAN_STATUS_BUS_OFF) {
            err= ERR;
        }

        if (status & CAN_STATUS_EWARN) {
            err= ERR;
        }

        if (status & CAN_STATUS_EPASS) {
            err= ERR;
        }

        if (status & CAN_STATUS_LEC_MSK) {
            err= ERR;
        }

        if (status & CAN_STATUS_LEC_NONE) {
            err= ERR;
        }

        if (status & CAN_STATUS_LEC_STUFF) {
            err= ERR;
        }

        if (status & CAN_STATUS_LEC_FORM) {
            err=ERR;
        }

        if (status & CAN_STATUS_LEC_ACK) {
            err= ERR;
        }

        if (status & CAN_STATUS_LEC_BIT1) {
            err= ERR;
        }

        if (status & CAN_STATUS_LEC_BIT0) {
            err= ERR;
        }

        if (status & CAN_STATUS_LEC_CRC) {
            err= ERR;
        }

        return err;

    4. If err== ERR(CAN_STATUS_EWARN, CAN_STATUS_EPASS, CAN_STATUS_LEC_MSK, CAN_STATUS_LEC_FORM, CAN_STATUS_LEC_ACK, CAN_STATUS_LEC_CRC, ) then the CAN micro is continually-reset/reinitialized (CAN peripheral, controller and mailboxex).

    5.Change the CAN speed to the initial value but the bus does not recover.

    Test scenario 2:

    If the error detection is not used in the interrupt and no run of CAN reinitialization procedure then the bus is recovering by itself.

    QUESTION: what is going on between CAN error interrupts and CAN peripheral/controller initialization that blocks the communication?

    Thanks

    Regards

  • Hello Liv,

    What is on the other side of the CAN Bus?

    Regards
    Amit
  • 1
    On the bus is a PEAK usb can(bursting messages) and a TM4C123GH6PM(reply to messages).

    2
    What I have also noticed during testing is that if I insert a sleep(1ms) before reset/reinitialize the CAN peripheral, then the CAN controller recovers in 1 minute(unacceptable). I have to mention that the CAN interrupt is running under a rtos. CAN messages are sent over a queue to a process task. In the message processing task the CAN pripheral is reset/reinitialized for every error message that comes from the CAN interrupt.
  • 3
    After the first CAN peripheral and mailboxes initialization, In case of an error interrupt is good practice to re-init the mailboxes too?

    4
    It is possible to disable the CAN mailboxes before do the CAN controller initialization?
  • 5
    //I have removed all the other CAN interrupt error verifications and left only the BUSS OFF:

    status = ROM_CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
    if (status & CAN_STATUS_BUS_OFF) {
    err= ERR;//BREAKPOINT in here, but never gets in here, even when i short CANhi with CANlow.
    }

    I only see the buss-off error on the PEAK can usb, the fw breakpoint doesn't trigger, why????
  • Hello Liv,

    I am not familiar with nor used PEAK, but is there a mechanism by which the transmitting equipment is able to self correct (some sort of Baud detection setting).

    You can reset the CAN controller altogether before re-initialization.

    Instead use a while(1) loop in the error condition to see if the problem indeed is the BUS OFF condition not being detected and also monitor the CAN Error Counter.

    Regards
    Amit
  • what while loop?
    what CAN Error Counter?
    can you be more explicit.....
  • Hello Liv

    Set the while loop in the following code

    status = ROM_CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
    if (status & CAN_STATUS_BUS_OFF) {
    err= ERR;//BREAKPOINT in here, but never gets in here, even when i short CANhi with CANlow.
    while(1)
    }

    The CAN Error Counter register is offset 0x008 in the CAN address space (register Name is CANERR)

    Regards
    Amit
  • Hi Amit,

    1
    Is still very unclear to me why do you want to insert a while loop:

    void CANIntHandlerA(void)
    {

    status = ROM_CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
    if (status & CAN_STATUS_BUS_OFF) {
    err= ERR;//BREAKPOINT in here, but never gets in here, even when i short CANhi with CANlow.

    while(1) {} //it doesn't make sense...to add the while loop in the interrupt

    }

    2
    I have added this code:
    err_pasive = ROM_CANErrCntrGet(CAN0_BASE, &RxCount, &TxCount);
    if (err_pasive){
    err_pasive = 1; //BREAKPOINT in here// RxCount = 127 // TxCount=0
    }
    What BUSS OFF error means?:
    a) wire short between CAN-Hi and CAN-Low?
    OR
    b) RxCount = 127 and TxCount=127 in total 255?
    ...because I don't understand why other devices show me BUSSOFF error while short the 2 wires but not my controller.

    Thanks
  • 3
    How can I generate a CAN bus fatal error??? (BUSS OFF or something, that that the micro can not recover by itself) and recover from by reset/reinitialize.
  • Hello Liv

    For the BUSOFF to be detected by a controller it must send a packet on the bus. When the packet is not read back correctly, the error counter increments. When this error counter reaches 127 that is when the controller declares a bus off condition.

    Regards
    Amit.
  • Hi,

    Thanks for previous answers, that was very helpful.

    1

    It is correct(no error can occur during communication and respect the standard) to send a CAN packet over the bus with the DLC = 0 (zero) without setting the RTR field?

    2

    How about sending RTR packets, it is needed to set the DLC field to zero?

    Thanks

  • Hello Liv,

    Please have a look at the section on "Receiving a Remote Frame" as there are different Message Object Configurations/

    Regards
    Amit
  • Hi Amit,

    First thanks for previous answers.

    Considering following code in the CAN initialization:


        // Enable interrupts on the CAN peripheral.  This example uses static
        // allocation of interrupt handlers which means the name of the handler
        // is in the vector table of startup code. 
        ROM_CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

        // Enable the CAN interrupt on the processor (NVIC).
        ROM_IntEnable(INT_CAN0);

    What is the difference between the 2 functions:  ROM_CANIntEnable and ROM_IntEnable ?????, because the spec sheet doesn't make it very clear.

    Thanks

    Regards

  • Hello Liv,

    The CANIntEnable enables the Interrupt Sources in the CAN Module so that the CAN interrupt to the CPU will be asserted when the condition for the interrupt from the CAN controller is true. The IntEnable enables the CAN interrupt line to be recognized by the NVIC Controller and CPU to process the interrupt.

    Regards
    Amit