Skip to content

Commit f43c08f

Browse files
committed
bsp: mcxn947: fix dead console RX on LPUART
LPUART_Init re-ran LP_FLEXCOMM_Init on every configure, resetting the peripheral and wiping CTRL.RIE set by RT_DEVICE_CTRL_SET_INT, so the console never received a byte and host-side VCOM writes wedged. Verified on FRDM-MCXN947 hardware via GDB: NVIC ISER never armed and a hardware breakpoint on uart_isr never fired until these changes. - define LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER=1 so fsl drivers stop re-initialising the FlexComm on every configure - select FlexComm function once in rt_hw_flexcomm_mode_init() - preserve/restore RX interrupt enable across LPUART_Init (PR #11186) - clear OR/FE/NF/PF in uart_isr: an uncleared overrun inhibits all further LPUART reception Reintroduces the drv_uart.c fix from #11186 (reverted in #11191), combined with the one-time FlexComm mode selection that makes it safe. Signed-off-by: Alexander Salas Bastidas <ajsb85@firechip.dev>
1 parent b245c18 commit f43c08f

3 files changed

Lines changed: 62 additions & 2 deletions

File tree

bsp/nxp/mcx/mcxn/Libraries/drivers/drv_uart.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,18 @@ static rt_err_t mcx_configure(struct rt_serial_device *serial, struct serial_con
160160
config.enableTx = true;
161161
config.enableRx = true;
162162

163-
LPUART_Init(uart->uart_base, &config, CLOCK_GetFreq(uart->clock_src));
163+
/* LPUART_Init resets the peripheral, wiping any RX interrupt enable set
164+
* by a prior RT_DEVICE_CTRL_SET_INT (upstream fix, PR #11186). Preserve
165+
* and restore it, or console RX goes permanently dead. */
166+
{
167+
rt_uint32_t irq_regval = LPUART_GetEnabledInterrupts(uart->uart_base);
168+
LPUART_Init(uart->uart_base, &config, CLOCK_GetFreq(uart->clock_src));
169+
if (irq_regval & kLPUART_RxDataRegFullInterruptEnable)
170+
{
171+
LPUART_EnableInterrupts(uart->uart_base, kLPUART_RxDataRegFullInterruptEnable);
172+
EnableIRQ(uart->irqn);
173+
}
174+
}
164175

165176
return RT_EOK;
166177
}
@@ -248,6 +259,12 @@ static void uart_isr(struct rt_serial_device *serial)
248259
/* UART in mode Receiver -------------------------------------------------*/
249260
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
250261

262+
/* Clear error flags: an uncleared overrun (OR) inhibits all further
263+
* reception on LPUART, permanently wedging RX. */
264+
LPUART_ClearStatusFlags(uart->uart_base,
265+
kLPUART_RxOverrunFlag | kLPUART_FramingErrorFlag |
266+
kLPUART_NoiseErrorFlag | kLPUART_ParityErrorFlag);
267+
251268
/* leave interrupt */
252269
rt_interrupt_leave();
253270
}

bsp/nxp/mcx/mcxn/frdm-mcxn947/board/SConscript

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ if GetDepend(['PKG_USING_CJSON']) and GetDepend(['PKG_USING_WEBCLIENT']):
2424

2525

2626
CPPPATH = [cwd, cwd + '/MCUX_Config/board']
27-
CPPDEFINES = ['DEBUG', 'CPU_MCXN947VDF_cm33_core0']
27+
CPPDEFINES = ['DEBUG', 'CPU_MCXN947VDF_cm33_core0', 'LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER=1']
2828

2929
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES)
3030

bsp/nxp/mcx/mcxn/frdm-mcxn947/board/board.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "drv_uart.h"
1919
#include "fsl_port.h"
2020
#include "fsl_cache_lpcac.h"
21+
#include "fsl_lpflexcomm.h"
2122

2223
/**
2324
* This is the timer interrupt service routine.
@@ -34,13 +35,55 @@ void SysTick_Handler(void)
3435
rt_interrupt_leave();
3536
}
3637

38+
/* One-time LP_FLEXCOMM function selection (upstream PR #11186). With
39+
* LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER=1 the fsl drivers no longer re-run
40+
* LP_FLEXCOMM_Init on every configure (which reset the peripheral and
41+
* killed console RX), so the mode must be selected once here. */
42+
static void rt_hw_flexcomm_mode_init(void)
43+
{
44+
/* One entry per FLEXCOMM instance, covering every peripheral the
45+
* drv_uart/drv_i2c/drv_spi drivers can enable on it. Instances that
46+
* support several functions are mutually exclusive per Kconfig,
47+
* except FC2 whose LPI2CAndLPUART mode serves both users at once
48+
* (this board routes FC2 I2C on P0/P1 and UART on P2/P3). */
49+
#ifdef BSP_USING_I2C0
50+
LP_FLEXCOMM_Init(0, LP_FLEXCOMM_PERIPH_LPI2C);
51+
#endif
52+
#if defined(BSP_USING_SPI1)
53+
LP_FLEXCOMM_Init(1, LP_FLEXCOMM_PERIPH_LPSPI);
54+
#elif defined(BSP_USING_I2C1)
55+
LP_FLEXCOMM_Init(1, LP_FLEXCOMM_PERIPH_LPI2C);
56+
#endif
57+
#if defined(BSP_USING_UART2) || defined(BSP_USING_I2C2)
58+
LP_FLEXCOMM_Init(2, LP_FLEXCOMM_PERIPH_LPI2CAndLPUART);
59+
#endif
60+
#ifdef BSP_USING_SPI3
61+
LP_FLEXCOMM_Init(3, LP_FLEXCOMM_PERIPH_LPSPI);
62+
#endif
63+
#ifdef BSP_USING_UART4
64+
LP_FLEXCOMM_Init(4, LP_FLEXCOMM_PERIPH_LPUART);
65+
#endif
66+
#ifdef BSP_USING_UART5
67+
LP_FLEXCOMM_Init(5, LP_FLEXCOMM_PERIPH_LPUART);
68+
#endif
69+
#if defined(BSP_USING_UART6)
70+
LP_FLEXCOMM_Init(6, LP_FLEXCOMM_PERIPH_LPUART);
71+
#elif defined(BSP_USING_SPI6)
72+
LP_FLEXCOMM_Init(6, LP_FLEXCOMM_PERIPH_LPSPI);
73+
#endif
74+
#ifdef BSP_USING_SPI7
75+
LP_FLEXCOMM_Init(7, LP_FLEXCOMM_PERIPH_LPSPI);
76+
#endif
77+
}
78+
3779
/**
3880
* This function will initial board.
3981
*/
4082
void rt_hw_board_init()
4183
{
4284
/* Hardware Initialization */
4385
BOARD_InitBootPins();
86+
rt_hw_flexcomm_mode_init();
4487
L1CACHE_EnableCodeCache();
4588

4689
CLOCK_EnableClock(kCLOCK_Freqme);

0 commit comments

Comments
 (0)