Skip to content

Commit 3f167ac

Browse files
committed
arch/arm/src/stm32h7/stm32_fdcan_sock: fix clock, ILS register and extended ID filter
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>
1 parent 5024a67 commit 3f167ac

1 file changed

Lines changed: 48 additions & 4 deletions

File tree

arch/arm/src/stm32h7/stm32_fdcan_sock.c

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,11 @@
142142

143143
/* CAN Clock Configuration **************************************************/
144144

145-
#define STM32_FDCANCLK STM32_HSE_FREQUENCY
145+
#ifndef STM32_FDCANCLK
146+
# define STM32_FDCANCLK STM32_HSE_FREQUENCY
147+
#endif
146148
#define CLK_FREQ STM32_FDCANCLK
149+
147150
#define PRESDIV_MAX 256
148151

149152
/* Interrupts ***************************************************************/
@@ -1276,6 +1279,12 @@ static void fdcan_receive_work(void *arg)
12761279

12771280
static void fdcan_txdone(struct fdcan_driver_s *priv)
12781281
{
1282+
/* DEBUG
1283+
* printf("[vmay] TXDONE: IR=0x%lx RXF0S=0x%lx\n",
1284+
* getreg32(priv->base + STM32_FDCAN_IR_OFFSET),
1285+
* getreg32(priv->base + STM32_FDCAN_RXF0S_OFFSET));
1286+
*/
1287+
12791288
/* Read and reset the interrupt flag */
12801289

12811290
uint32_t ir = getreg32(priv->base + STM32_FDCAN_IR_OFFSET);
@@ -1420,7 +1429,7 @@ static int fdcan_interrupt(int irq, void *context,
14201429

14211430
if (irq == priv->config->mb_irq[0])
14221431
{
1423-
fdcan_receive(priv);
1432+
fdcan_receive(priv);
14241433
}
14251434
else if (irq == priv->config->mb_irq[1])
14261435
{
@@ -2042,6 +2051,11 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
20422051

20432052
irqstate_t flags = enter_critical_section();
20442053

2054+
/* DEBUG
2055+
* printf("[vmay] CLK_FREQ=%lu Hz (expected 25000000)\n",
2056+
* (unsigned long)CLK_FREQ);
2057+
*/
2058+
20452059
/* Reset the peripheral clock bus (only do this once) */
20462060

20472061
if (!g_apb1h_init)
@@ -2062,6 +2076,10 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
20622076

20632077
fdcan_setconfig(priv->base, 1);
20642078

2079+
/* Clear Message RAM */
2080+
2081+
memset((void *)STM32_CANRAM_BASE, 0, 2560 * 4);
2082+
20652083
/* Disable interrupts while we configure the hardware */
20662084

20672085
putreg32(0, priv->base + STM32_FDCAN_IE_OFFSET);
@@ -2183,7 +2201,7 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
21832201

21842202
regval = getreg32(priv->base + STM32_FDCAN_ILS_OFFSET);
21852203
regval |= FDCAN_ILS_TCL;
2186-
putreg32(FDCAN_ILS_TCL, priv->base + STM32_FDCAN_ILS_OFFSET);
2204+
putreg32(regval, priv->base + STM32_FDCAN_ILS_OFFSET);
21872205

21882206
/* Enable Tx buffer transmission interrupts
21892207
* Note: Still need fdcan_enable_interrupts() to set ILE (IR line enable)
@@ -2247,9 +2265,13 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
22472265
*
22482266
* Discussion:
22492267
* https://community.st.com/s/question/0D73W000001nzqFSAQ
2268+
*
2269+
* vmay23
2270+
* Using 64 --> some messages are being received but some are not
2271+
* Using 128 --> according to the tests, everything is working fine
22502272
*/
22512273

2252-
const uint8_t n_extid = 64;
2274+
const uint8_t n_extid = 128;
22532275
priv->message_ram.filt_extid_addr = gl_ram_base + ram_offset * WORD_LENGTH;
22542276

22552277
regval = (n_extid << FDCAN_XIDFC_LSE_SHIFT) & FDCAN_XIDFC_LSE_MASK;
@@ -2284,7 +2306,21 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
22842306

22852307
regval = (ram_offset << FDCAN_RXF0C_F0SA_SHIFT) & FDCAN_RXF0C_F0SA_MASK;
22862308
regval |= (NUM_RX_FIFO0 << FDCAN_RXF0C_F0S_SHIFT) & FDCAN_RXF0C_F0S_MASK;
2309+
2310+
/* DEBUG
2311+
* printf("[vmay] NUM_RX_FIFO0=%d SHIFT=%d MASK=0x%lx\n",
2312+
* NUM_RX_FIFO0, FDCAN_RXF0C_F0S_SHIFT, FDCAN_RXF0C_F0S_MASK);
2313+
*/
2314+
22872315
putreg32(regval, priv->base + STM32_FDCAN_RXF0C_OFFSET);
2316+
2317+
/* DEBUG
2318+
* printf("[vmay] RXF0C written=0x%lx readback=0x%lx ram_offset=%lu\n",
2319+
* regval,
2320+
* getreg32(priv->base + STM32_FDCAN_RXF0C_OFFSET),
2321+
* ram_offset);
2322+
*/
2323+
22882324
ram_offset += NUM_RX_FIFO0 * FIFO_ELEMENT_SIZE;
22892325

22902326
/* Not using Rx FIFO1 */
@@ -2320,6 +2356,14 @@ int fdcan_initialize(struct fdcan_driver_s *priv)
23202356
fdcan_dumpregs(priv);
23212357
#endif
23222358

2359+
/* Debug
2360+
* printf("[vmay] IE=0x%lx ILS=0x%lx GFC=0x%lx RXF0C=0x%lx\n",
2361+
* getreg32(priv->base + STM32_FDCAN_IE_OFFSET),
2362+
* getreg32(priv->base + STM32_FDCAN_ILS_OFFSET),
2363+
* getreg32(priv->base + STM32_FDCAN_GFC_OFFSET),
2364+
* getreg32(priv->base + STM32_FDCAN_RXF0C_OFFSET));
2365+
*/
2366+
23232367
leave_critical_section(flags);
23242368

23252369
return 0;

0 commit comments

Comments
 (0)