2019-04-10 08:07 AM
Hello
I'm using an STM32F103T8 who talks over CAN interface with a Raspberry Pi (MCP2515 Controller). The MC also uses USART1 for communication with a sensor module.
For testing purpose I've setup a simple program which sends continuously can frames of length 8 with a fixed payload [0,1,2,3,4,5,6,7]. Only the TxMailbox[0] is used.
The communication is working fine except randomly the last two bytes are not [0x06,0x07] but [0x08, 0xC0].
In the reference manual page 686 Section 24.9.3 it says:
TGT: Transmit global time This bit is active only when the hardware is in the Time Trigger Communication mode, TTCM bit of the CAN_MCR register is set. 0: Time stamp TIME[15:0] is not sent. 1: Time stamp TIME[15:0] value is sent in the last two data bytes of the 8-byte message: TIME[7:0] in data byte 7 and TIME[15:8] in data byte 6, replacing the data written in CAN_TDHxR[31:16] register (DATA6[7:0] and DATA7[7:0]). DLC must be programmed as 8 in order these two bytes to be sent over the CAN bus.
My HAL configuration is therfor:
hcan.Instance = CAN1;
hcan.Init.Prescaler = 2;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_15TQ;
hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
And my TxHeader:
canTxHeader.StdId = 0x47;
canTxHeader.ExtId = 0x00;
canTxHeader.RTR = CAN_RTR_DATA;
canTxHeader.IDE = CAN_ID_STD;
canTxHeader.DLC = 8;
canTxHeader.TransmitGlobalTime = DISABLE;
I'm also checking the registers directly befor I add the frame to the mail box with:
if(hcan.Instance->MCR & CAN_MCR_TTCM){
debugError = 2;
}
if(hcan.Instance->sTxMailBox[0].TDTR & CAN_TDT0R_TGT){
debugError =2;
}
And they are not set. Since breakpoint set inside the if clause is never triggered.
I'm stuck and I don't know how to proceed. Anyone got any ideas? Did I miss something?
Here is my complete function for sending CAN_Message:
bool sendUbloxCanMessage(unsigned char* src, uint32_t id, uint32_t length) {
/* Start the Transmission process */
if (firstCanTxMailBoxAvailable()) {
canTxHeader.StdId = id;
canTxHeader.DLC = length;
canTxHeader.TransmitGlobalTime = DISABLE;
if(hcan.Instance->MCR & CAN_MCR_TTCM){
debugError = 2;
}
if(hcan.Instance->sTxMailBox[0].TDTR & CAN_TDT0R_TGT){
debugError =2;
}
if (HAL_CAN_AddTxMessage(&hcan, &canTxHeader, src , &canTxMailbox) != HAL_OK) {
/* Transmission request Error */
Error_Handler();
return false;
}
setCanTxMailBoxUnavailble(canTxMailbox);
return true;
}
return false;
}
If I send only 6 bytes then this phenomenon does not occure.
Kind regards
Update: when sending 7 bytes instead of 8 bytes the 7th byte is still randomly set to 0x08 instead of 0x07. so it probably has nothing todo with the TTCM since DLC is not 8
Solved! Go to Solution.
2019-04-11 12:38 PM
I've made a little test program to make it easier to analyzer the false can frame on the bus with a scope. The "false" can frame is actually correct on the bus. So all along it was not the MC's fault but the MCP2515 on the raspberry pi.
After more digging I've found out that the linux version used for the raspberry pi had a different spimaxfrequency default value in the device overlay for the MCP2515. After manually setting the spi max frequency to 10mhz the errors did not occure.
So I assume the spi interface for the MCP2515 was just a little bit too slow and didn't catch the complete buffer befor the next frame came into it?
Fix on Raspberry PI:
/boot/config.txt
dtoverlay=mcp2515-can0,spimaxfrequency=10000000
2019-04-10 09:34 AM
Edit: it is still occuring but less frequently (every 4-5 minutes). And instead of 0x08 0xC0 on the 7th and 8th byte it is just 0x00 0x00.
_____________________
based on the code of: https://github.com/HEEV/CanNode/blob/CanNodeLib/can_driver.cpp
I've replaced:
HAL_CAN_AddTxMessage
with:
bool testSendCan(CAN_TxHeaderTypeDef *tx_msg, unsigned char* src, uint32_t* mailbox) {
*mailbox = 0; // find an empty mailbox
if ((hcan.Instance->sTxMailBox[*mailbox].TIR & CAN_TI0R_TXRQ)) {
return false;
}
// add data to register
hcan.Instance->sTxMailBox[*mailbox].TIR = (uint32_t) tx_msg->IDE << 21;
if (tx_msg->RTR == CAN_RTR_REMOTE) {
hcan.Instance->sTxMailBox[*mailbox].TIR |= CAN_TI0R_RTR;
}
// set message length
hcan.Instance->sTxMailBox[*mailbox].TDTR = tx_msg->DLC & 0x0F;
// clear mailbox and add new data
hcan.Instance->sTxMailBox[*mailbox].TDHR = 0;
hcan.Instance->sTxMailBox[*mailbox].TDLR = 0;
for (uint8_t i = 0; i < 4; ++i) {
hcan.Instance->sTxMailBox[*mailbox].TDHR |= src[i + 4] << (8 * i);
hcan.Instance->sTxMailBox[*mailbox].TDLR |= src[i] << (8 * i);
}
// transmit can frame
hcan.Instance->sTxMailBox[*mailbox].TIR |= CAN_TI0R_TXRQ;
return true;
}
Currently working like a charm!
I will let it run over night and check tomorrow if the same error occured again or not.
2019-04-11 12:38 PM
I've made a little test program to make it easier to analyzer the false can frame on the bus with a scope. The "false" can frame is actually correct on the bus. So all along it was not the MC's fault but the MCP2515 on the raspberry pi.
After more digging I've found out that the linux version used for the raspberry pi had a different spimaxfrequency default value in the device overlay for the MCP2515. After manually setting the spi max frequency to 10mhz the errors did not occure.
So I assume the spi interface for the MCP2515 was just a little bit too slow and didn't catch the complete buffer befor the next frame came into it?
Fix on Raspberry PI:
/boot/config.txt
dtoverlay=mcp2515-can0,spimaxfrequency=10000000