arch/stm32h7: fix FDCAN clock, ILS register and extended ID

Fix three issues in the STM32H7 FDCAN SocketCAN driver:

1. Clock configuration: Allow board.h to override STM32_FDCANCLK.
   Previously the driver hardcoded STM32_HSE_FREQUENCY, ignoring
   any board-specific clock configuration.

2. ILS register bug: Fix putreg32 call that was writing FDCAN_ILS_TCL
   constant instead of the computed regval, causing interrupt routing
   issues.

3. Extended ID filter size: Increase n_extid from 64 to 128. Despite
   the reference manual (RM0433) suggesting 64 max, testing shows
   that 128 is required for reliable extended ID frame reception.
   With 64, some extended ID frames were silently dropped.

Signed-off-by: Vinicius May <vmay.sweden@gmail.com>
This commit is contained in:
vrmay23
2026-02-10 08:34:25 -03:00
committed by Alan C. Assis
parent ef71625ede
commit 6da5100bc0
+24 -4
View File
@@ -73,6 +73,10 @@
#define CAN_ERROR_WARNING_THRESHOLD 96
#define WORD_LENGTH 4U
#define CANRAM_WORDS 2560U /* Total words in Message RAM (RM0433) */
/* General Configuration ****************************************************/
#if !defined(CONFIG_SCHED_WORKQUEUE)
@@ -142,8 +146,11 @@
/* CAN Clock Configuration **************************************************/
#define STM32_FDCANCLK STM32_HSE_FREQUENCY
#ifndef STM32_FDCANCLK
# define STM32_FDCANCLK STM32_HSE_FREQUENCY
#endif
#define CLK_FREQ STM32_FDCANCLK
#define PRESDIV_MAX 256
/* Interrupts ***************************************************************/
@@ -2050,6 +2057,11 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
if (!g_apb1h_init)
{
/* Clear Message RAM (shared between FDCAN1/2/3) */
memset((void *)STM32_CANRAM_BASE, 0,
CANRAM_WORDS * WORD_LENGTH);
fdcan_apb1hreset();
g_apb1h_init = true;
}
@@ -2187,7 +2199,7 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
regval = getreg32(priv->base + STM32_FDCAN_ILS_OFFSET);
regval |= FDCAN_ILS_TCL;
putreg32(FDCAN_ILS_TCL, priv->base + STM32_FDCAN_ILS_OFFSET);
putreg32(regval, priv->base + STM32_FDCAN_ILS_OFFSET);
/* Enable Tx buffer transmission interrupts
* Note: Still need fdcan_enable_interrupts() to set ILE (IR line enable)
@@ -2224,7 +2236,9 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
* and relative address (in words) used for configuration
*/
const uint32_t iface_ram_base = (2560 / 2) * priv->iface_idx;
const uint32_t iface_ram_base =
(CANRAM_WORDS / 2) * priv->iface_idx;
const uint32_t gl_ram_base = STM32_CANRAM_BASE;
uint32_t ram_offset = iface_ram_base;
@@ -2251,9 +2265,13 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
*
* Discussion:
* https://community.st.com/s/question/0D73W000001nzqFSAQ
*
* vmay23
* Using 64 --> some messages are being received but some are not
* Using 128 --> according to the tests, everything is working fine
*/
const uint8_t n_extid = 64;
const uint8_t n_extid = 128;
priv->message_ram.filt_extid_addr = gl_ram_base + ram_offset * WORD_LENGTH;
regval = (n_extid << FDCAN_XIDFC_LSE_SHIFT) & FDCAN_XIDFC_LSE_MASK;
@@ -2288,7 +2306,9 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
regval = (ram_offset << FDCAN_RXF0C_F0SA_SHIFT) & FDCAN_RXF0C_F0SA_MASK;
regval |= (NUM_RX_FIFO0 << FDCAN_RXF0C_F0S_SHIFT) & FDCAN_RXF0C_F0S_MASK;
putreg32(regval, priv->base + STM32_FDCAN_RXF0C_OFFSET);
ram_offset += NUM_RX_FIFO0 * FIFO_ELEMENT_SIZE;
/* Not using Rx FIFO1 */