Hi,
back working on the CAN driver. I'm now on the filtering part, I would like to have some canAddFilter() and canDelFilter() functions to dynamically register and unregister filters, like
which returns the number of the filter that has been added (or -1 if there are no more filters available), so it is easy to set up an array of callbacks to handle the filtered messages.
Trying to be not STM32-ish as usual, I've looked into NXP and Atmel CAN peripheral reference manuals discovering that, like for the I2C, the STM32 implementation is pretty different from others.
Basically, NXP and Atmel have "Message Objects" (up to 32 MOBs) and each can be configured as TX or RX mailbox. If a MOB is configured as RX, a id/mask can be specified and that will be the filter, so each matching CAN frame is stored in that MOB. You can also configure them as FIFO, there is a lot of flexibility while the filtering scheme remains absolutely simple.
On the STM32, you have 3 TX mailboxes and 2 RX FIFO, and a set of "filter banks" (14 in normal line, 28 in connectivity line). Each "bank" can be configured as single 32-bit id/mask pair, or two 32-bit id list, or 2 16-bit id/mask pair, or 4 16-bit id list. Then, each filter is identified by a number that depends also on the previous filters configuration (reference manual RM0008 Fig. 201 pag 555 has an example of filter numbering). Each filter can be assigned to FIFO0 or FIFO1, and this again changes the numbering scheme. One more annoying point is that seems to me that there is no way to understand if a filter is free or not: you can activate a whole filter bank, so up to 4 16-bit id-list filters, but then you cannot guess which of the 4 filters are used and which are free.
As a consequence i think we have to trace which filters are used and which not. But if the filter bank configuration is modified, the filtering numbering scheme changes and to handle this a lot of complexity (and overhead) is needed.
So, the first proposal is to define at compile time if the driver uses id/mask pairs or id-list, and 32-bit or 16-bit long filters. This defines the maximum number of filters available and a constant numbering scheme that reflects what we have in other platforms. We loose some flexibility on STM32 platform but everything becomes much easier.
Then we have to keep trace of used and unused filters. On NXP/Atmel CAN peripherals you can determine the status of a filter looking into some register bits, so the "tracing" part should stay in the STM32 low level driver.
Finally, we can also avoid the storage of the filters in an array (each filters is at least 9 bytes long, and we can have up to 54 filters) to save RAM, as we can register/unregister/get the filter status and configuration from the registers. I was thinking about a canFilterInit() function that accepts an array of filters (like the one we have now) for static CAN filter configuration, and the "new" functions for dynamic use..
Any comment/suggestion?
Sorry for being that verbose, it is useful aslo to clarify everything to myself
