cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_CAN last two bytes are randomly not what they should be

Framet
Associate III

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].

0690X000008AH5XQAW.png

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

1 ACCEPTED SOLUTION

Accepted Solutions
Framet
Associate III

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

View solution in original post

2 REPLIES 2
Framet
Associate III

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.

Framet
Associate III

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