How to send multiple(more than 3) sequential messages via CAN bus
HI all,
as the title says, I am investigating how to correctly send more than 3 consecutive messages via CAN Bus to the network. As per now, the network has only two devices connected, which one only sends and the other only receives.
The transmitter is a custom board with STM32F722VET MCU, the receiver a STM32L432KC. Both have a transceiver.
It is all working well, I can connect, send and receive packets between the two nodes, but the problem arises when I want to send more than 3 packets sequentially. I know that the stm32 CAN has 3 mailboxes used to send the messages, and in fact once the mailboxes are full, nothing is sent, and the mailboxes are cleared once the TX gets the ack.
My needs are:
1) transmit 12 packets in a row every 3ms
2) I cannot use a queueing system because I cannot mix packets from a loop with packets from another loop (those packets represents spatial coordinates in time, so different loops represents different "epochs")
Actually I am trying to reimplement the receiver with a STM32F7 Nucleo board, hoping that a 216MHz clocked board would be faster enough to send ack back to the TX.
I'd like to know also you opinion, community. Below my code for initialization, tx and rx handling.
//CAN INIT TX node
CAN_Handle.Instance = CAN1;
CAN_Handle.Init.Prescaler =3;
CAN_Handle.Init.Mode = CAN_MODE_NORMAL;
CAN_Handle.Init.SyncJumpWidth = CAN_SJW_1TQ;
CAN_Handle.Init.TimeSeg1 = CAN_BS1_15TQ
CAN_Handle.Init.TimeSeg2 = CAN_BS2_2TQ;
CAN_Handle.Init.TimeTriggeredMode = DISABLE;
CAN_Handle.Init.AutoBusOff = ENABLE;
CAN_Handle.Init.AutoWakeUp = DISABLE;
CAN_Handle.Init.AutoRetransmission = DISABLE;
CAN_Handle.Init.ReceiveFifoLocked = DISABLE;
CAN_Handle.Init.TransmitFifoPriority = DISABLE;
HAL_CAN_Init(&CAN_Handle);the RX init(STM32L432KC):
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 2;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = ENABLE;// DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}the TX send:
//this snippet is called every 3 ms
{
DGNSTC_SendMsg(G_XY_ID,&p);
DGNSTC_SendMsg(G_ZT_ID,&p);
DGNSTC_SendMsg(R_XY_ID,&p);
DGNSTC_SendMsg(R_ZT_ID,&p);
DGNSTC_SendMsg(S_XY_ID,&p);
DGNSTC_SendMsg(O_XY_ID,&p);
}
//and here the definition of the above method:
void
DGNSTC_SendMsg(DGNSTC_Msg_Id_t id,Pos_2D_t* payload)
{
memset(buffer,0x0U,DGNSTC_MSG_LEN);
SRLZ_Serialize2DPos(payload,buffer);
CAN_SendMsg(id,buffer,DGNSTC_MSG_LEN); //this is the send method, uses HAL_CAN_AddTxMessage
} on RX side, the snippet used to receive packets:
while (1)
{
/* USER CODE END WHILE */
if(HAL_CAN_GetRxFifoFillLevel(&hcan1,CAN_RX_FIFO0))
{
HAL_CAN_GetRxMessage(&hcan1,CAN_RX_FIFO0,&head,data);
SRLZ_Deserialize(data,&pos);
memset(asd,0x0,sizeof(char)*50);
HAL_UART_Transmit(&huart2,(uint8_t*)asd,50,10);
}
}Oh, and I forgot to mention that the receiver forwards to a UART at 921600Baud the received messages.
Thanks for the help!
