diff --git a/bsp/nxp/mcx/mcxn/Libraries/drivers/drv_uart.c b/bsp/nxp/mcx/mcxn/Libraries/drivers/drv_uart.c index 31b457d9fe35..14c95f665379 100644 --- a/bsp/nxp/mcx/mcxn/Libraries/drivers/drv_uart.c +++ b/bsp/nxp/mcx/mcxn/Libraries/drivers/drv_uart.c @@ -160,7 +160,18 @@ static rt_err_t mcx_configure(struct rt_serial_device *serial, struct serial_con config.enableTx = true; config.enableRx = true; - LPUART_Init(uart->uart_base, &config, CLOCK_GetFreq(uart->clock_src)); + /* LPUART_Init resets the peripheral, wiping any RX interrupt enable set + * by a prior RT_DEVICE_CTRL_SET_INT (upstream fix, PR #11186). Preserve + * and restore it, or console RX goes permanently dead. */ + { + rt_uint32_t irq_regval = LPUART_GetEnabledInterrupts(uart->uart_base); + LPUART_Init(uart->uart_base, &config, CLOCK_GetFreq(uart->clock_src)); + if (irq_regval & kLPUART_RxDataRegFullInterruptEnable) + { + LPUART_EnableInterrupts(uart->uart_base, kLPUART_RxDataRegFullInterruptEnable); + EnableIRQ(uart->irqn); + } + } return RT_EOK; } @@ -248,6 +259,12 @@ static void uart_isr(struct rt_serial_device *serial) /* UART in mode Receiver -------------------------------------------------*/ rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + /* Clear error flags: an uncleared overrun (OR) inhibits all further + * reception on LPUART, permanently wedging RX. */ + LPUART_ClearStatusFlags(uart->uart_base, + kLPUART_RxOverrunFlag | kLPUART_FramingErrorFlag | + kLPUART_NoiseErrorFlag | kLPUART_ParityErrorFlag); + /* leave interrupt */ rt_interrupt_leave(); } diff --git a/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/SConscript b/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/SConscript index 277739d361f2..70958fbab06f 100644 --- a/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/SConscript +++ b/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/SConscript @@ -24,7 +24,7 @@ if GetDepend(['PKG_USING_CJSON']) and GetDepend(['PKG_USING_WEBCLIENT']): CPPPATH = [cwd, cwd + '/MCUX_Config/board'] -CPPDEFINES = ['DEBUG', 'CPU_MCXN947VDF_cm33_core0'] +CPPDEFINES = ['DEBUG', 'CPU_MCXN947VDF_cm33_core0', 'LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER=1'] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES) diff --git a/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/board.c b/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/board.c index c7fd47bac4e3..f85e607760a3 100644 --- a/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/board.c +++ b/bsp/nxp/mcx/mcxn/frdm-mcxn947/board/board.c @@ -18,6 +18,7 @@ #include "drv_uart.h" #include "fsl_port.h" #include "fsl_cache_lpcac.h" +#include "fsl_lpflexcomm.h" /** * This is the timer interrupt service routine. @@ -34,6 +35,47 @@ void SysTick_Handler(void) rt_interrupt_leave(); } +/* One-time LP_FLEXCOMM function selection (upstream PR #11186). With + * LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER=1 the fsl drivers no longer re-run + * LP_FLEXCOMM_Init on every configure (which reset the peripheral and + * killed console RX), so the mode must be selected once here. */ +static void rt_hw_flexcomm_mode_init(void) +{ + /* One entry per FLEXCOMM instance, covering every peripheral the + * drv_uart/drv_i2c/drv_spi drivers can enable on it. Instances that + * support several functions are mutually exclusive per Kconfig, + * except FC2 whose LPI2CAndLPUART mode serves both users at once + * (this board routes FC2 I2C on P0/P1 and UART on P2/P3). */ +#ifdef BSP_USING_I2C0 + LP_FLEXCOMM_Init(0, LP_FLEXCOMM_PERIPH_LPI2C); +#endif +#if defined(BSP_USING_SPI1) + LP_FLEXCOMM_Init(1, LP_FLEXCOMM_PERIPH_LPSPI); +#elif defined(BSP_USING_I2C1) + LP_FLEXCOMM_Init(1, LP_FLEXCOMM_PERIPH_LPI2C); +#endif +#if defined(BSP_USING_UART2) || defined(BSP_USING_I2C2) + LP_FLEXCOMM_Init(2, LP_FLEXCOMM_PERIPH_LPI2CAndLPUART); +#endif +#ifdef BSP_USING_SPI3 + LP_FLEXCOMM_Init(3, LP_FLEXCOMM_PERIPH_LPSPI); +#endif +#ifdef BSP_USING_UART4 + LP_FLEXCOMM_Init(4, LP_FLEXCOMM_PERIPH_LPUART); +#endif +#ifdef BSP_USING_UART5 + LP_FLEXCOMM_Init(5, LP_FLEXCOMM_PERIPH_LPUART); +#endif +#if defined(BSP_USING_UART6) + LP_FLEXCOMM_Init(6, LP_FLEXCOMM_PERIPH_LPUART); +#elif defined(BSP_USING_SPI6) + LP_FLEXCOMM_Init(6, LP_FLEXCOMM_PERIPH_LPSPI); +#endif +#ifdef BSP_USING_SPI7 + LP_FLEXCOMM_Init(7, LP_FLEXCOMM_PERIPH_LPSPI); +#endif +} + /** * This function will initial board. */ @@ -41,6 +83,7 @@ void rt_hw_board_init() { /* Hardware Initialization */ BOARD_InitBootPins(); + rt_hw_flexcomm_mode_init(); L1CACHE_EnableCodeCache(); CLOCK_EnableClock(kCLOCK_Freqme);