cancel
Showing results for 
Search instead for 
Did you mean: 

Correct TX CAN frame form using HAL_CAN libraries

Posted on March 01, 2017 at 10:47

Hi, 

I'm new using stm32 mcu and HAL libraries, too new developing CAN apps. So I have some questions to do in order to understand a few necessary things before testing an app that will transmit two chars in a infinite loop.

I'm working with discovery kit with smt32l4F6 mcu. I configured CAN controller params via HAL_CAN library. I have noticed that using this library, user can only have access from ID frame field to the end of data field (for transmisions). I must guess that CRC, ACK and EOF fields are configured in HAL lowest layers, independently of user code.

Am I wrong? If not, what does it mean if ESR register contains an 010 error field that indicates 'form error' (according datasheet)? 

If I'm wrong, please, could anyone show me where to fill these fields or how to access them through HAL_CAN driver (of course, from my user code)?

Thanks in advance!

#hal_can #can-frame-fields #stm32l4 #can #can_esr
14 REPLIES 14
Posted on March 06, 2017 at 09:52

Well, if someone has had the same question, I know yet that these fields are added by the hardware and not by user. But I still unknowing the possible causes of 010 code error. 

T J
Lead
Posted on March 06, 2017 at 21:43

did you get it working ?

is it BxCan ?

my code works very well, if you are interested.

are you using CubeMX ?

void CAN_Config(){ CAN_FilterConfTypeDef sFilterConfig; static CanTxMsgTypeDef TxMessage; static CanRxMsgTypeDef RxMessage;
 //##-1- Configure the CAN peripheral #######################################// hcan.Instance = CANx; hcan.pTxMsg = &TxMessage; hcan.pRxMsg = &RxMessage;
 hcan.pTxMsg->RTR = CAN_RTR_DATA; // can be CAN_RTR_DATA or CAN_RTR_REMOTE hcan.pTxMsg->DLC = 8; // between Min_Data = 0 and Max_Data = 0x07 hcan.pTxMsg->StdId = 0x101; // between Min_Data = 0 and Max_Data = 0x1FF hcan.pTxMsg->ExtId = 0x102; // between Min_Data = 0 and Max_Data = 0x1FFFFFFF hcan.pRxMsg->DLC = 8; // between Min_Data = 0 and Max_Data = 0x07 hcan.pRxMsg->StdId = 0x101; // between Min_Data = 0 and Max_Data = 0x1FF hcan.pRxMsg->ExtId = 0x102; // between Min_Data = 0 and Max_Data = 0x1FFFFFFF hcan.pRxMsg->RTR = CAN_RTR_DATA; // can be CAN_RTR_DATA or CAN_RTR_REMOTE 
// hcan.Init.TTCM = DISABLE;// hcan.Init.ABOM = DISABLE;// hcan.Init.AWUM = DISABLE;// hcan.Init.NART = DISABLE;// hcan.Init.RFLM = DISABLE;// hcan.Init.TXFP = DISABLE;// hcan.Init.Mode = CAN_MODE_NORMAL;// hcan.Init.SJW = CAN_SJW_1TQ;// hcan.Init.BS1 = CAN_BS1_6TQ;// hcan.Init.BS2 = CAN_BS2_8TQ;// hcan.Init.Prescaler = 2;
 if (HAL_CAN_Init(&hcan) != HAL_OK) { // Initiliazation Error Error_Handler(); } //##-2- Configure the CAN Filter ########################################### sFilterConfig.FilterNumber = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x100 << 5; //11-bit ID in top bits sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x700 << 5; // resolves as 0x01xx sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = 0; sFilterConfig.FilterActivation = ENABLE;// sFilterConfig.BankNumber = 14; sFilterConfig.BankNumber = 0;
 if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) { // Filter configuration Error Error_Handler(); sprintf(string,'Can Filter configuration Error

'); console::puts(string); } 
//##-2- Configure the 2nd CAN Filter ########################################### sFilterConfig.FilterNumber = 1; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x500 << 5; //11-bit ID in top bits // command channel sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x700 << 5; // resolves as 0x01xx sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = 1; sFilterConfig.FilterActivation = ENABLE;// sFilterConfig.BankNumber = 14; sFilterConfig.BankNumber = 0;
 if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) { // Filter configuration Error Error_Handler(); sprintf(string,'Can Filter configuration Error

'); console::puts(string); }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Posted on March 07, 2017 at 15:53

Yes I have used Cube for initialization settings etc. From there I modify a bit the structure and organization of  folders and files according to the policy of my project. 

Now I'm measuring with TX of mcu pinout with the osciloscope in order to see if there is the frame I'm sending, and I can see that. But when I connect these pins to the transceiver and the transceiver to the CAN-USB conector, the CAN controller seems to stop the output frame. It stops of writting frame to these pins. The frame disappears from osc screen. 

Hence, I first will test only looking at the CAN uC pins before connecting. After check this step I will try to understand behavior of controler when it is into network circuit. 

I will get your code for doing some comparition and tests. So thanks a lot. I will comment you the results or doubts if not.

Thank you too much. 

Posted on March 07, 2017 at 18:20

Sorry Marsh, I have just try with your code and neither youts, neither mine works doing this type of test, now. Have you any suggestion? 

The same code works yesterday, today is not the same result. MCU CAN pins stills in high level when program runs.

I have anything connected to the CAN TX and RX mcu pins. Is it enough for only see the frame with oscilloscope? Or there could be unstable results? 

Thanks in advance.

T J
Lead
Posted on March 08, 2017 at 00:18

I use a CanDo unit from the UK.

it is the master and so my code is set to respond, no the initiate canFrames.

maybe you have that problem.

do you have an external master on the bus ?

T J
Lead
Posted on March 08, 2017 at 00:50

This is my Tx code:

void checkCanTxMsgs(void){// this is a non-ordered packet transmitter.
if (!canTxMsgTableEMPTY)
if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL ) // a non - ordered packet transmitter with an 8 byte payload
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 &=0x0F;// 16 buffer elements
canTxMsgTableFULL = false;
canTxMsgOverrun = false;
//canMsgCounter ++;
}
if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) // a non - ordered packet transmitter with an 8 byte payload
if ((CAN->TSR & CAN_TSR_TME1) == CAN_TSR_TME1) // (1) 
{
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 &=0x0F;// 16 buffer elements
canTxMsgOverrun = false;
canTxMsgTableFULL = false;
//canMsgCounter ++;
}
if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) // a non - ordered packet transmitter with an 8 byte payload
if ((CAN->TSR & CAN_TSR_TME2) == CAN_TSR_TME2) // (1) 
{
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 &=0x0F;// 16 buffer elements
canTxMsgOverrun = false;
canTxMsgTableFULL = false;
//canMsgCounter ++;
}
if (canTxMsgOUT == canTxMsgIN)canTxMsgTableEMPTY = true;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Posted on March 08, 2017 at 10:51

thanks marsh,

but I'm using HAL_CAN_transmit to send data.

Here we have a can-usb janztec converter. The idea is to test it with an app able to send and receive msg. But I have divided this tryal in two parts. 

But I first have thought about checking Tx pin when code is running, without being connected to any can transciever, this means: out of a can net, looking directly to the board pinout. I'm looking at the mcu output directly, on GPIOs configured to be Tx CAN pin with an osc. With the same code sometimes I can see my data on osc screen. But sometimes I can't do. Micro seems to stop having data at this pin randomly.

I'm not sure if it's robustness of my code or hardware influences the cause of this randomly output. I would like to ensure if microcontroller TX  output (my choosen GPIO) musts show data signal independently of having connected to transciever (and can-usb connector i. e.) as you can do when uses gpio for sending serie data through uart, etc. You can see the gpio  states when code runs without having connected anything.

Second part was connecting can-usb converter with the transciever to the TX/RX mcu pins when it ran. But, this is not the main thing now. I need to close the first step/question, before this. 

regards

T J
Lead
Posted on March 08, 2017 at 13:45

Have you tried the installed examples ?

________________

Attachments :

Can Examples folders.jpg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hyjb&d=%2Fa%2F0X0000000bD5%2FAJsvgYuC4VC3I_2Rvo8Rd7K8NDohhx9lkmS55wByqDA&asPdf=false
Posted on March 08, 2017 at 13:30

hello again,

I had significant trouble to get it working myself.

I had to initialise HAL driver interrupts first, and receive a frame before I could use my simple Tx system which I have shown you.

Have you initialised the HAL canbus system ?