2018-04-15 02:27 PM
I am following the example code found here to send and receive CAN messages:
STM32Cube_FW_F4_V1.21.0\Projects\STM324xG_EVAL\Examples\CAN\CAN_Networking\Src
I can happily receive CAN messages but when I call the following code, the CAN message is never sent.
HAL_CAN_AddTxMessage( &hcan1, &TxHeader, TxData, &TxMailbox );
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3) {}TxHeader is configured as:
TxHeader.StdId = 0x123;
TxHeader.ExtId = 0x01; TxHeader.RTR = CAN_RTR_DATA; TxHeader.IDE = CAN_ID_STD; TxHeader.DLC = 7; TxHeader.TransmitGlobalTime = DISABLE;And TxData is filled with seven bytes of data.
HAL_CAN_GetTxMailboxesFreeLevel always returns 2 and I don't see the CAN message on the bus.
Any help or idea would be gratefully appreciated.
Andy
2018-04-15 04:39 PM
Hi,
are you using 2 devices ? on a CanBus ? with a line driver ?
You can receive but not transmit.
Are there only two devices on the bus ?
Did you turn on the ABOM enable ?
When you transmit, make sure no two devices never transmit the same msgID.
2018-04-16 01:04 AM
Thank you for your interest in my problem.
There are two devices on my bus both with line drivers and both ends terminated.
I am using a STM32F429 device with a SN65HVD230D CAN transceiver connected to a Microchip CAN Bus Analyser box which is configured to have bus termination enabled. I have the bit rate set to 20Kbps.
I assume ABOM is Auto Bus Off Management, in the latest HAL it is called AutoBusOff. I have that DISABLED however enabling it makes no difference.
Andy
2018-04-16 01:41 AM
Thanks for the code - you are using LL where I am trying to use the HAL but I gave it a go to see if it helped.
I modified your code to look like this:
if ( ( hcan1.Instance->TSR & CAN_TSR_TME0 ) == CAN_TSR_TME0 ) // (1)
{ hcan1.Instance->sTxMailBox[ 0 ].TDTR = 8; hcan1.Instance->sTxMailBox[ 0 ].TDLR = 0x12345678; hcan1.Instance->sTxMailBox[ 0 ].TDHR = 0xABCDEF12; hcan1.Instance->sTxMailBox[ 0 ].TIR = ( ( uint32_t )0x123 << 21 | CAN_TI0R_TXRQ ); }The first time in, the if statement executes but nothing appears to be launched onto the bus, thereafter, the if statement never becomes true.
Andy
2018-04-16 01:55 AM
I have interrupts enabled though I don't use them.
2018-04-16 02:07 AM
Okay, digging a little deeper (I was able to get a logic analyser on the bus). I do see a message being transmitted after all. However, it seems that it is not being ACK'd because the original message is continually being sent and all the transmit mailboxes are full. So I guess I have to dig a bit deeper into this :(
Andy
2018-04-16 02:11 AM
Even more strange, if I disable automatic re transmission it all works fine. The mailboxes never fill up and I see continually changing data in the messages.
Andy
2018-04-16 03:28 AM
if you want the CanBs to recover from a hardware error, then best to enable ABOM.
I poll this code to transmit:
no interrupts are needed for Tx
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) // (1)
{ CAN->sTxMailBox[0].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length CAN->sTxMailBox[0].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes CAN->sTxMailBox[0].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes CAN->sTxMailBox[0].TIR = ((uint32_t)canTxMsgID[canTxMsgOUT] << 21 | CAN_TI0R_TXRQ); // (4) // send it now if the line is idle// destroy old data to be sure we only transmit fresh data
// not needed canTxMsgLength[canTxMsgOUT] = 0; canTxMsgBottomWord[canTxMsgOUT] = 0; canTxMsgTopWord[canTxMsgOUT] = 0; canTxMsgID[canTxMsgOUT++] = 0; canTxMsgOUT &= 0x3F; // 64 buffer elements canTxMsgTableFULL = false; canTxMsgOverrun = false; //canMsgCounter ++; } if ((CAN->TSR & CAN_TSR_TME1) == CAN_TSR_TME1) // (1)2018-04-16 03:47 AM
I do enable interrupts, but dont use any Tx part of it,
like this : in startup, run only once never enable again
__HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP1); __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);
2018-04-16 04:10 AM
I use the interrupts for the RX side.
only enable it once at startup