cancel
Showing results for 
Search instead for 
Did you mean: 

ID CAN frame field generation with hal_can: fix it at init() or modifiable dinamically

Posted on March 16, 2017 at 10:37

I'm working with HAL_CAN for the stm32L4. I'm developing a fw in a sw layer where I can configure CAN controller, filter banks, reset, send and receive, etc.. One of the things my fw can do in this layer is to generate data and remote frames before transmitting.

In one hand, I'm thinking about fixing the id code and type of standar (ext o st) at init operation (you must sending this frame format statichaly) always, so you can not modify any field of this frame during execution. 

But by the other side, I'm thinking if my node will need to generate, sending or answering data requests, with more than one type of msg with different priorities. So my fw must be able to configure more than one id code, even std selection, during execution. 

I have read, that ID is related to only one node, and ID code must be never modified. But I also read that since app level, there is some stack that allows working with modifying this field during program execution. 

Now I don't know which way to implement, since I have not clear if it's possible to send msgs (frames) from the node msg with different ID (priorities) or only one ID for the node live in the can net. What's the correct way according to the CAN st? Is actually the ID associated with only one node or is it with different type of msg independently of the transmitter node? 

2 REPLIES 2
Richard Lowe
Senior III
Posted on March 21, 2017 at 10:57

Message ID encoding can be changed dynamically. The Node ID you're speaking of is a specific area that can be fixed by masking that area. Here's an example:

0690X00000606VjQAI.png

So the destination is something that I want to be fixed so the node's hardware will filter that out.

For initialization code:

/* USER CODE BEGIN CAN1_MspInit 1 */
canHandle->pRxMsg = &rx_msg;
canHandle->pTxMsg = &tx_msg;
canHandle->pTxMsg->IDE = CAN_ID_EXT;
// Filters
can_filter.FilterNumber = 0; // CAN 1 0..13
can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
/*
 * |- DEST 4bit -|- Origin 4bit -|- Frame Type 8bit -|- Count 5bit -|- EMPTY 8bit -|- IDE -| RTS -|- TXRQ -|
 */
can_filter.FilterIdHigh = 0x01; // ID 1 with IDE enabled
can_filter.FilterIdLow = CAN_F0R1_FB2;// 32bit register is based on 16 bit High << 16 | Low
/*
 * Mask
 */
can_filter.FilterMaskIdHigh = 0xF00F;
can_filter.FilterMaskIdLow = CAN_F0R1_FB2;
can_filter.FilterFIFOAssignment = CAN_FIFO0;
can_filter.FilterActivation = ENABLE;
if(HAL_CAN_ConfigFilter(&hcan1, &can_filter) != HAL_OK)
{
Error_Handler();
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

The node ID is assigned on line ID = 0x01000008

But the mask starting on line 18 is where the magic happens. Mask = 0xF00F0008

Nerd translation is: ''You MUST match the first nibble from the ID, the 4th nibble of the ID, and the 3rd bit of the ID or else they won't pass the filter. Everything else.... I don't care''.

This will allow you to modify those bits that it doesn't care to modify dynamically like this:

// 2. Setup the Message ID encoding
hcan1.pTxMsg->ExtId =
( ( destination & 0x0F ) << ( 28 - EXTID_TX_OFFSET ) ) |
( ( CAN_HOST_ADDRESS & 0x0F ) << ( 24 - EXTID_TX_OFFSET ) ) |
( ( frame_type & 0xFF ) << ( 16 - EXTID_TX_OFFSET ) ) |
( ( frame_count & 0x1F ) << ( 11 - EXTID_TX_OFFSET ) );
�?�?�?�?�?�?

Hope that was clear enough for you. Have fun.

Posted on March 22, 2017 at 10:30

Thanks for the information. I will take it into account.

I will finally follow some tips and suggestions, commonly used at industry as for ex: ID for data rq/answ, ID for command, and ID for mesg sent periodically to the net. If the net of the type of transactions need it I will add more ID msg type to my IDs list .