CAN Message Frame

Papabravo

Joined Feb 24, 2006
22,082
What do you think about post #18 ?

Can we make any progress with pseudo code
It would make more sense to pick an actual CAN controller or alternatively a processor with an embedded CAN controller. The problem with pseudo code is that it can be written but it CANNOT be tested. IMHO it is nearly useless.

If you want, I can take you through your particular application using the CAN controller on the T89C51CC01.
 
Last edited:

nsaspook

Joined Aug 27, 2009
16,322
I was eager to learn about the CAN protocol through experimentation. However, I lack the necessary hardware to conduct the experiment. Although I have a microcontroller with built-in CAN functionality, I've realized that it's not sufficient alone. To properly perform the experiment, I require an additional transceiver IC, which unfortunately I don't have. There are also some constraints preventing me from purchasing new hardware.

This is reason I am asking theoretically question and tring to understand CAN message with basic application like LED control
Check to see if your microcontroller CAN module has loopback mode. Most do for just this sort of testing.

1700333707622.png
 

nsaspook

Joined Aug 27, 2009
16,322
Yes I have seen mode in datasheet PIC18F45K80, Page 470

View attachment 307862
In luck, I have a old (uncompleted project :eek: ) with a K80 on it and a old software project that can be easily patched to test CAN.
1700337233458.png
1700337271709.png
It looks like a mess. Connected the CAN RX/TX pins to some test wires for the scope.
It shouldn't take too long to strip the original code to make something usable as a DEMO here.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
511
In luck, I have a old (uncompleted project :eek: ) with a K80 on it and a old software project that can be easily patched to test CAN.
Nice!

How many CAN controller do you have? Do you have two PIC18F45K80?

What was your first experiment to learn CAN protocol?
 

Papabravo

Joined Feb 24, 2006
22,082
The first experiment should be a lonely node (a node on a network with no other nodes) transmitting a single frame. Once the frame is transmitted the processor should go into a do {forever} loop with interrupts disabled. Since there are other nodes to send a dominant bit in the ACK slot the hardware will try again after the End Delimiter and the Interframe space. You should be able to identify all the bits on your scope trace including the stuff bits which are automatically inserted by the transmitter and removed by the receiver.
 

Papabravo

Joined Feb 24, 2006
22,082
In the file fragment I gave you, "produce.c", the purpose of that module is to respond to requests for data from a device acting as a server to some client device. The incoming message type is called a "Poll Request". A "Poll Request" in this context may or may not contain any data. That means it could consist of a CAN frame with an identifier field, no data field, and a CRC. This is perfectly legitimate for a device that has inputs, but no outputs. The reason for considering this example is to see how to construct a message for transmission. I have reproduced below the code fragment that constructs the "Poll Response" and triggers the transmission of that message.
C:
void produceIO(void)
{
    SET_PROD_IO_SIZE(g_PollProdSize) ;
    /***** Determine XMT_BUF[] availability *****/
    if((CANEN2 & TxPollInt) == 0)
         CANPAGE = TxPoll ;
        CANCONCH = 0 ;
    /***** Produce for the POLLED I/O cnxn *****/
        if(dnetObj.alloc_choice & POLLED)
        {
            /***** Load the IDENTIFIER *****/
            CANIDT1 = ((POLL_RESPONSE << 3) | (dnetObj.macId >> 3));
            CANIDT2 = (dnetObj.macId << 5);
            CANIDT4 = 0 ;
            POLL_PRODUCE_ASSEMBLY ;
        }
        else if    ((dnetObj.alloc_choice & ACK_SUPPRESS) == 0)
        {
            /**** Change of State from Master or zero-length ack - POLL_RSP is also a cos ack msgid ****/
            CANIDT1 = ((POLL_RESPONSE << 3) | (dnetObj.macId >> 3)) ;
            CANIDT2 = (dnetObj.macId << 5) ;
            CANIDT4 = 0 ;
            CANCONCH = TxRequest + NULL_MESSAGE_LEN ;
        }
        g_cnxnProduce.1 = NO_WAITING_PRODUCER ;
    }
    else
    {
        /***** The CAN transmitter must be busy *****/
        if(g_cnxnProduce.1 == NO_WAITING_PRODUCER)
        {
            /***** Point to the I/O connection instance that is to produce *****/
            g_cnxnProduce.1 = WAITING_PRODUCER ;
        }
    }
}
The global variable "g_PollProdSize" is going to be the data length of the "Poll Response" message and it is copied to another global variable called "g_ProdIOSize". Next if the TxPollInt bit in the CANEN2 is equal to 0 then that message object is available for use. The CANEN2 register is described on p. 101, Table 65. If the "Poll Response" object is available we set the CANPAGE register to that object, with index 0, and auto increment enabled. The CANPAGE register is described on p.106, Table 73. Setting register CANCONCH to 0, disables the object and sets the Data Length Code for this message to 0. The next if statement checks to see if we are producing for the polled connection, and for this example, we are. So we set the identifier field to indicate a "Poll Response" and we include our MAC ID (a 6-bit network address). CANIDT4 is always set to 0 because we are not using extended identifiers (extended identifiers are 29-bits long). We then expand the macro "POLL_PRODUCE_ASSEMBLY" this macro does the following:

{
C:
#define    POLL_PRODUCE_ASSEMBLY    \
{    \
    /***** Load the xmt buffer with the POLL Data *****/    \
    CANMSG = pollCnxn_p_data[0] ;            \
    CANMSG = pollCnxn_p_data[1] ;            \
    CANCONCH = TxRequest + g_PollProdSize ;    \
}
This causes two bytes of date from the device input to be transferred to the CAN message under construction using the CANMSG register with the autoincrement feature enable by the way the CANPAGE register was initialized.

Finally the CANCONCH register the transmit request and the Data Length Code which should be 2, and this write to that register will begin the transmission.

Then we set a flag, which is bit 1 of the global variable g_cnxnProduce to NO_WAITING_PRODUCER, which happens to be a 0. Then we exit from the produceIO() function.

That's how you build a frame for transmission.
 
Last edited:

nsaspook

Joined Aug 27, 2009
16,322
MCC app note: https://ww1.microchip.com/downloads...urator-CAN2.0B-Module-For-PIC18-00002714A.pdf
With my quick and dirty APP sending a message via CAN on the K80. No transceiver, so it repeats the original message.
1700354692679.png
Standard
1700354730535.png
Extended

Code fragment.
C:
#include "mcc_generated_files/ecan.h"

    uint8_t leds1 = 0x13, leds2 = 0x37; // some random data that could be LED on/off bits in a byte
    uCAN_MSG txMessage;

    case APP_CONNECT:
        txMessage.frame.idType = dSTANDARD_CAN_MSG_ID_2_0B;
        txMessage.frame.id = 0x120;
        txMessage.frame.dlc = 2;
        txMessage.frame.data0 = leds1++;
        txMessage.frame.data1 = leds2++;
        CAN_transmit(&txMessage);
        appData.state = APP_COMMUNICATE;
        break;
 

Thread Starter

Kittu20

Joined Oct 12, 2022
511
I spent some time on reading CAN protocol documents and discussions read many times, but I'm still struggling to understand with three points with one example. Let's imagine a CAN network with two nodes: one node sending a message to control an LED connected on the other node. For explanation purposes, You can consider your choice of microcontroller and the CAN trans receiver IC for the reference to the explanation. it may be save your time and if you want me to show the specific microcontroller and trans receiver IC. I'll refer to the PIC18F45K80 as the microcontroller and the MCP2515 as the transceiver IC.

Three points In this context:

1. Determining Receiver Node ID:
I've been searching through the MCP2515 datasheet, but I couldn't find information on how to determine the receiver node ID. How can we find or specify this ID for inclusion in the CAN message frame.

2. Data Bytes Required:
To control the LED (turning it on/off), would we need one byte or two?
I'm thinking one byte could turn it on and another could turn it off, but I'm uncertain. Could you clarify this?

3. Configuring CRC Field: Regarding error management in the CRC field, I'm unclear about the specific value needed for error monitoring. Could you provide guidance on what value should be set for effective error management in my application specific?

@Papabravo
 
Last edited:

Ian0

Joined Aug 7, 2020
13,131
I spent some time on reading CAN protocol documents and discussions read many times, but I'm still struggling to understand with three points with one example. Let's imagine a CAN network with two nodes: one node sending a message to control an LED connected on the other node. For explanation purposes, You can consider your choice of microcontroller and the CAN trans receiver IC for the reference to the explanation. it may be save your time and if you want me to show the specific microcontroller and trans receiver IC. I'll refer to the PIC18F45K80 as the microcontroller and the MCP2515 as the transceiver IC.

Three points In this context:

1. Determining Receiver Node ID:
I've been searching through the MCP2515 datasheet, but I couldn't find information on how to determine the receiver node ID. How can we find or specify this ID for inclusion in the CAN message frame.

2. Data Bytes Required:
To control the LED (turning it on/off), would we need one byte or two?
I'm thinking one byte could turn it on and another could turn it off, but I'm uncertain. Could you clarify this?

3. Configuring CRC Field: Regarding error management in the CRC field, I'm unclear about the specific value needed for error monitoring. Could you provide guidance on what value should be set for effective error management in my application specific?

@Papabravo
Receiver node is part of the APPLICATION LAYER, such as J1939 or NMEA2000.
If you are not using the application layer, then there is no node number

CRC, as I said way back in post #4, is calculated automatically by the interface.

If you only need ON/OFF control then won't a single bit do the job? So one byte, with 7 bits unused.
If you are not using an application layer, then there is no receiver node number.

I'm sure that you could control an LED with 1 bit, if all you need is ON and OFF. So that's 1 byte with 7 bits unused

CRC (as I have said before
 

Papabravo

Joined Feb 24, 2006
22,082
I spent some time on reading CAN protocol documents and discussions read many times, but I'm still struggling to understand with three points with one example. Let's imagine a CAN network with two nodes: one node sending a message to control an LED connected on the other node. For explanation purposes, You can consider your choice of microcontroller and the CAN trans receiver IC for the reference to the explanation. it may be save your time and if you want me to show the specific microcontroller and trans receiver IC. I'll refer to the PIC18F45K80 as the microcontroller and the MCP2515 as the transceiver IC.

Three points In this context:

1. Determining Receiver Node ID:
I've been searching through the MCP2515 datasheet, but I couldn't find information on how to determine the receiver node ID. How can we find or specify this ID for inclusion in the CAN message frame.

2. Data Bytes Required:
To control the LED (turning it on/off), would we need one byte or two?
I'm thinking one byte could turn it on and another could turn it off, but I'm uncertain. Could you clarify this?

3. Configuring CRC Field: Regarding error management in the CRC field, I'm unclear about the specific value needed for error monitoring. Could you provide guidance on what value should be set for effective error management in my application specific?

@Papabravo
1. Node Id assignment is completely arbitrary and is not defined by the standards. In practice we used DIP switches, or non-volatile memory. In an 8-pin package we used two switches to determine the bit rate and six switches to determine the node ID (we called it MAC Id, an acronym for Media Access Control). The bit rates were 125 kbps, 250 kbps, and 500 kbps. The total number of MAC addresses was 64. The DIP switch would be read at power up and used to initialize the node. As part of the initialization procedure each node would broadcast its address to see if there were duplicates. A client device could either create a list of nodes on the network or have a list of nodes that are known and/or expected to be on the network. In our case the MAC Id would occupy bits 8 through 3 of the 11 bit identifier.

2. For a single LED, a single byte would be sufficient. A value of 0 would turn the LED off, while a non-zero value would turn it on. The size of the expected message from the client device to the server device of 1 byte would be an attribute of the server (receiving device), known to the client device. Consuming a message of an unexpected size would be considered an error by the server.

3. There is no configuring of the CRC field. It is fixed by the standard in every device. It is all done in hardware and there is literally nothing for you to worry about. In all my work with CAN I have never seen a CRC error, nor have I been able to create one on a CAN network of any description. There is a subtle reason for that fact and it is this:
All nodes on a CAN network receive and check each and every bit of every message including the node that is transmitting the message. Any node that detects an error will throw an ERROR frame. Every node that receives an ERROR frame will throw an ERROR frame as well. As soon as you try to bust a bit on the wire, the transmitting node will see that and throw that ERROR frame because it KNOWS that when it sends a recessive bit it better read a recessive bit.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
511
Node Id assignment is completely arbitrary and is not defined by the standards.
Thanks for confirmation. So the decision of which CAN ID is assigned to which message or node within the network is made by the system designers.

Imagine we've got three nodes in a CAN Network. We've given them CAN IDs: Node 1 is 0x10, Node 2 is 0x20, and Node 3 is 0x03.

Now, if we want to send a message specifically to Node 2, and we put the CAN ID 0x02 in that message, how does Node 2 know it's for him and not for the other nodes? How do the other nodes understand that this message isn't meant for them on the CAN bus?
 

Ian0

Joined Aug 7, 2020
13,131
On a NXP LPC1517, if the data-length code for the receiving mailbox is set wrongly, it is ignored, and the data loaded in according to the DLC in the message.
Thanks for confirmation. So the decision of which CAN ID is assigned to which message or node within the network is made by the system designers.

Imagine we've got three nodes in a CAN Network. We've given them CAN IDs: Node 1 is 0x10, Node 2 is 0x20, and Node 3 is 0x03.

Now, if we want to send a message specifically to Node 2, and we put the CAN ID 0x02 in that message, how does Node 2 know it's for him and not for the other nodes? How do the other nodes understand that this message isn't meant for them on the CAN bus?
You can set that up on the receive mailbox filters. They are specific to the device that you are using.
 

nsaspook

Joined Aug 27, 2009
16,322
I spent some time on reading CAN protocol documents and discussions read many times, but I'm still struggling to understand with three points with one example. Let's imagine a CAN network with two nodes: one node sending a message to control an LED connected on the other node. For explanation purposes, You can consider your choice of microcontroller and the CAN trans receiver IC for the reference to the explanation. it may be save your time and if you want me to show the specific microcontroller and trans receiver IC. I'll refer to the PIC18F45K80 as the microcontroller and the MCP2515 as the transceiver IC.

Three points In this context:

1. Determining Receiver Node ID:
I've been searching through the MCP2515 datasheet, but I couldn't find information on how to determine the receiver node ID. How can we find or specify this ID for inclusion in the CAN message frame.

2. Data Bytes Required:
To control the LED (turning it on/off), would we need one byte or two?
I'm thinking one byte could turn it on and another could turn it off, but I'm uncertain. Could you clarify this?

3. Configuring CRC Field: Regarding error management in the CRC field, I'm unclear about the specific value needed for error monitoring. Could you provide guidance on what value should be set for effective error management in my application specific?

@Papabravo
To the OP only.

Found an old CAN demo system in the junkbox.
https://www.microchip.com/en-us/development-tool/mcp2515dm-bm
https://ww1.microchip.com/downloads/en/DeviceDoc/50001757B.pdf

Reflashed the firmware with the latest version from 2008 so the demo works. The source is old C18 so it's hard to recompile for any changes.
1700424354063.png
1700424385293.png
If you want it, PM me with a valid physical mailing address.
 

Papabravo

Joined Feb 24, 2006
22,082
Thanks for confirmation. So the decision of which CAN ID is assigned to which message or node within the network is made by the system designers.

Imagine we've got three nodes in a CAN Network. We've given them CAN IDs: Node 1 is 0x10, Node 2 is 0x20, and Node 3 is 0x03.

Now, if we want to send a message specifically to Node 2, and we put the CAN ID 0x02 in that message, how does Node 2 know it's for him and not for the other nodes? How do the other nodes understand that this message isn't meant for them on the CAN bus?
Since there is not enough room in the 11-bit identifier, for both the source address and the destination address it should be self-evident that the MAC Id (node address) in the message should be for the destination so that the Mask and Match filters can be used. For networks using multiple client devices the only absolute rule is that no duplicate identifiers are allowed on the network. If this was possible the arbitration scheme would fail - and we just can't abide that situation. This is not really a problem if the clients can divide up the set of servers.
 

nsaspook

Joined Aug 27, 2009
16,322
I fixed the old C18 MCP2515 CAN BUS MONITOR DEMO BOARD software to compile (uses a PIC18F4550 for the controller using SPI for the CAN device) on a modern MPLABX install using a Linux version of the C18 compiler 3.40.
Functional Changes:
Upped the CAN speed to 1mpbs from 125kbps and changed the repeat loading timer to max out (start to see message drops) the two node demo network.
The source project is here:
https://github.com/nsaspook/candemo_c18

1700434861992.png1700434895635.png
 
Top