cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F042 Is HAL_CAN_ConfigFilter() required?

Jim Seymour
Senior
Posted on June 18, 2018 at 23:06

I'm trying to get an interrupt-driven CAN receiver working on a STM32F042K6- but I'm not having much luck.

I'veconfigured the CAN module in CubeMX and the code it generates makes sense to me - and seems to match theinstructions listed inthe User Manual.

However,I've seen some posts here that imply that filtering is required. I want to receive ALL messages, so I didn't bother callingHAL_CAN_ConfigFilter(). But I've since addedthat call - but I'm still not receiving anything.

Can someone help me with a simple interrupt-driven receive example?

I'mattaching a subsetof my code. It uses a callback function to set a flag that my main loop inspects. Can anyone see what I might be doing wrong?

Thanks.

Note: this post was migrated and contained many threaded conversations, some content may be missing.
14 REPLIES 14
Posted on June 20, 2018 at 21:14

What does your hardware design look like exactly? For a proper CAN bus you would need at least transceivers and termination  on both ends. For an on-board setup you could also simply tie together all CAN Tx and Rx pins in open drain configuration and connect an additional pull-up resistor of e.g. 1K to VDD.

Posted on June 21, 2018 at 00:37

At this point, we're pretty confident in the hardware.  And now that I have a Kvaser connected, I've proved that I can transmit correctly from the STM.  However, incoming messages are still not being seen - which makes me think I have a filtering issue.

Here's what I'm using:

// This filter should allow all messages

sFilterConfig.FilterNumber = 0;

sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

sFilterConfig.FilterIdHigh = 0x0000;

sFilterConfig.FilterIdLow = 0x0000;

sFilterConfig.FilterMaskIdHigh = 0x0000;

sFilterConfig.FilterMaskIdLow = 0x0000;

sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;

sFilterConfig.FilterActivation = ENABLE;

sFilterConfig.BankNumber = 0;

HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);

As I understand it, this should allow ALL messages through.

I'm also enabling the receive interrupt thusly: __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);

And finally, I'm setting up the receive via HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);

None of the HAL_CAN_* calls generate errors - but the receive callback functions never gets called.

P.S.: When I transmit, I always get a 'Stuff error' on a subsequent Error callback - but the message makes it out and Kvaser sees it, so I'm thinking (hoping) that's harmless.

Posted on June 21, 2018 at 02:00

try bits from my code above, it all works on the F091 and the F767

I never saw a Stuff error.

Did you check on the scope that both CanRx CanTx pins are jumping up and down opposite to each other ?

You must have a terminator on a CanBus.

Posted on June 21, 2018 at 17:14

Stuff error might mean that your slope control isn't good enough, meaning that the 0-1 or 1-0 transitions aren't fast enough.

1. Make sure you are using the CAN pins in Push-pull mode.

2. Your transceiver might have a slow control pin, which has a resistor to the ground, this shouldn't be too high.

3. Adjust your bit segments so the sampling point is relatively at the end of the bit symbol.

4. Make sure you have the bus terminated and that the lines don't have too high capacitance.

Jim Seymour
Senior
Posted on June 22, 2018 at 00:10

Success!

Short version: ST's CAN interrupt handler clears the CAN_IT_FMP0 flag when an error is detected.  In our system, we would often (always?) see at least one glitch on the line when we powered up our transceiver.  This cleared the FMP0 flag, so receives from that point forward were disabled.

For the long story, see a new post that I will compose in a few minutes...