cancel
Showing results for 
Search instead for 
Did you mean: 

Problem Sending CAN Message

andy2399
Senior
Posted on April 15, 2018 at 23:27

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

25 REPLIES 25
Posted on April 16, 2018 at 11:57

:

kgedi
Associate II

Hi,

I have same problem about 2 weeks i stuck in here, please can you explain how could you solve this problem?

Thank you, best regards.

T J
Lead
I use this, polled in the foreground: I have a set of buffers for TxMsgs[64]; You would be primarily interested in lines (1)(2)(3)(4) As you may see, there are 3 mail boxes all scanned for an empty mailbox. Thereby the received packets are not likely to be in order, since the mailbox 0 has ‘Tx on the wire’ priority. void checkCanTxMsgs(void) { // this is a non-ordered packet transmitter. if(!canTxMsgTableEMPTY) { if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) // non-ordered packet transmitter { if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) // (1) { if (showRxCanFrames) sendCanTxFrametoConsole(); 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; } if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) if ((CAN->TSR & CAN_TSR_TME1) == CAN_TSR_TME1) // (1) { if (showRxCanFrames) sendCanTxFrametoConsole(); CAN->sTxMailBox[1].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length CAN->sTxMailBox[1].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes CAN->sTxMailBox[1].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes CAN->sTxMailBox[1].TIR = ((uint32_t) canTxMsgID[canTxMsgOUT] << 21 | CAN_TI1R_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 depth canTxMsgOverrun = false; canTxMsgTableFULL = false; } if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) if ((CAN->TSR & CAN_TSR_TME2) == CAN_TSR_TME2) // (1) { if (showRxCanFrames) sendCanTxFrametoConsole(); CAN->sTxMailBox[2].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length CAN->sTxMailBox[2].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes CAN->sTxMailBox[2].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes CAN->sTxMailBox[2].TIR = ((uint32_t) canTxMsgID[canTxMsgOUT] << 21 | CAN_TI2R_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 canTxMsgOverrun = false; canTxMsgTableFULL = false; } if (canTxMsgOUT == canTxMsgIN) canTxMsgTableEMPTY = true; } } }
kgedi
Associate II

Thank you so much TJ i tried ​again in debug mode TxMailbox is always equals to 0x00000001 and the txdatas are not written in TxMailbox even if the selected mailbox(0) is empty why behave like this

Best regards.​

kgedi
Associate II

WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR,

        ((uint32_t)aData[7] << CAN_TDH0R_DATA7_Pos) |

        ((uint32_t)aData[6] << CAN_TDH0R_DATA6_Pos) |

        ((uint32_t)aData[5] << CAN_TDH0R_DATA5_Pos) |

        ((uint32_t)aData[4] << CAN_TDH0R_DATA4_Pos));

   WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR,

        ((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos) |

        ((uint32_t)aData[2] << CAN_TDL0R_DATA2_Pos) |

        ((uint32_t)aData[1] << CAN_TDL0R_DATA1_Pos) |

        ((uint32_t)aData[0] << CAN_TDL0R_DATA0_Pos));

I think there is a problem but i dont know thanks for help.

T J
Lead
Did you try the code snippets ? (1),(2),(3),(4) ?
HAL is not great sometimes… but useful in initialisation.
T J
Lead
That code looks odd,
what values do you have for CAN_TDH0R_DATA(0..7)_Pos ?
kgedi
Associate II

​thank you for your interest...

I have datas like these;

TxData[0]​=0x11;

TxData[1]​=0x12;

TxData[2]​=0x13;

...

T J
Lead
Please tell me the values of:

CAN_TDH0R_DATA7_Pos
CAN_TDH0R_DATA6_Pos
CAN_TDH0R_DATA5_Pos
CAN_TDH0R_DATA4_Pos
CAN_TDL0R_DATA3_Pos
CAN_TDL0R_DATA2_Pos
CAN_TDL0R_DATA1_Pos
CAN_TDL0R_DATA0_Pos



((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos)
kgedi
Associate II

CAN_TDH0R_DATA7_Pos=0x00000018

CAN_TDH0R_DATA6_Pos=0x00000010

CAN_TDH0R_DATA5_Pos=0x00000008

CAN_TDH0R_DATA4_Pos=0x00000000

CAN_TDL0R_DATA3_Pos=0x00000018

CAN_TDL0R_DATA2_Pos=0x00000010

CAN_TDL0R_DATA1_Pos=0x00000008

CAN_TDL0R_DATA0_Pos=0x00000000