Skip to content
12 changes: 10 additions & 2 deletions cmds/bankswitch.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* Switch Flash Banks
*
* Copyright 2022 Phoenix Systems
* Author: Aleksander Kaminski
* Copyright 2026 Apator Metrix
* Author: Aleksander Kaminski, Mateusz Karcz
*
* This file is part of Phoenix-RTOS.
*
Expand Down Expand Up @@ -41,7 +42,14 @@ static int cmd_bankswitch(int argc, char *argv[])
}

if (err == CMD_EXIT_SUCCESS) {
_stm32_switchFlashBank(targetBank);
int switchErr = _stm32_switchFlashBank(targetBank);
if (switchErr < 0) {
log_error("\n%s: Bank switch failed (%d)", argv[0], switchErr);
err = CMD_EXIT_FAILURE;
}
}

if (err == CMD_EXIT_SUCCESS) {
log_info("\n%s: Bank switch successful (%d -> %d)", argv[0],
(targetBank == 0) ? 1 : 0, targetBank);
}
Comment on lines 44 to 55

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for handling the bank switch result can be simplified by using an if-else structure. This avoids checking the err variable twice and makes the code more straightforward and readable.

if (err == CMD_EXIT_SUCCESS) {
		int switchErr = _stm32_switchFlashBank(targetBank);
		if (switchErr < 0) {
			log_error("\n%s: Bank switch failed (%d)", argv[0], switchErr);
			err = CMD_EXIT_FAILURE;
		}
		else {
			log_info("\n%s: Bank switch successful (%d -> %d)", argv[0],
				(targetBank == 0) ? 1 : 0, targetBank);
		}
	}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would break linearity

Expand Down
27 changes: 23 additions & 4 deletions devices/uart-stm32/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
* STM32L4x6 Serial driver
*
* Copyright 2021 Phoenix Systems
* Author: Aleksander Kaminski
* Copyright 2026 Apator Metrix
* Author: Aleksander Kaminski, Mateusz Karcz
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include <board_config.h>
#include <hal/hal.h>
#include <lib/errno.h>
#include <lib/lib.h>
Expand All @@ -37,22 +39,26 @@ enum { cr1 = 0, cr2, cr3, brr, gtpr, rtor, rqr, isr, icr, rdr, tdr, presc };
/* clang-format on */


#if defined(__CPU_STM32N6)
#if defined(__CPU_STM32N6) || defined(__CPU_STM32U3)
/* Values for selecting the peripheral clock for an UART */
enum {
uart_clk_sel_pclk = 0, /* pclk1 or pclk2 depending on peripheral */
#if defined(__CPU_STM32N6)
uart_clk_sel_per_ck,
uart_clk_sel_ic9_ck,
uart_clk_sel_ic14_ck,
uart_clk_sel_lse_ck,
uart_clk_sel_msi_ck,
uart_clk_sel_hsi_div_ck,
#elif defined(__CPU_STM32U3)
uart_clk_sel_hsi_ck,
#endif
};
#endif


static int uartLut[UART_MAX_CNT] = {
#if defined(__CPU_STM32L4X6)
#if defined(__CPU_STM32L4X6) || defined(__CPU_STM32U3)
UART1, UART2, UART3, UART4, UART5
#elif defined(__CPU_STM32N6)
UART1, UART2, UART3, UART4, UART5, UART6, UART7, UART8, UART9, UART10
Expand All @@ -70,7 +76,7 @@ static const struct {
int txport;
unsigned char txpin;
unsigned char txaf;
#if defined(__CPU_STM32N6)
#if defined(__CPU_STM32N6) || defined(__CPU_STM32U3)
u16 ipclk_sel; /* Clock mux (one of ipclk_usart*sel) */
#endif
} uartInfo[UART_MAX_CNT] = {
Expand All @@ -91,6 +97,12 @@ static const struct {
{ UART8_BASE, UART8_CLK, UART8_IRQ, dev_gpioe, 0, 8, dev_gpioe, 1, 8, ipclk_uart8sel },
{ UART9_BASE, UART9_CLK, UART9_IRQ, dev_gpiof, 1, 7, dev_gpiof, 0, 7, ipclk_uart9sel },
{ UART10_BASE, UART10_CLK, UART10_IRQ, dev_gpiod, 3, 6, dev_gpiod, 15, 6, ipclk_usart10sel },
#elif defined(__CPU_STM32U3)
{ UART1_BASE, UART1_CLK, UART1_IRQ, dev_gpioa, 10, 7, dev_gpioa, 9, 7, ipclk_usart1sel },
{ UART2_BASE, UART2_CLK, UART2_IRQ, dev_gpiod, 6, 7, dev_gpioa, 5, 7, ipclk_usart2sel },
{ UART3_BASE, UART3_CLK, UART3_IRQ, dev_gpioc, 11, 7, dev_gpiod, 10, 7, ipclk_usart3sel },
{ UART4_BASE, UART4_CLK, UART4_IRQ, dev_gpioa, 1, 8, dev_gpioa, 0, 8, ipclk_uart4sel },
{ UART5_BASE, UART5_CLK, UART5_IRQ, dev_gpiod, 2, 8, dev_gpioc, 12, 8, ipclk_uart5sel },
#else
#error "Unknown platform"
#endif
Expand Down Expand Up @@ -254,6 +266,13 @@ static u32 uart_configureRefclk(unsigned int minor)
_stm32_rccSetIPClk(uartInfo[minor].ipclk_sel, uart_clk_sel_per_ck);
return _stm32_rccGetPerClock();
}
#elif defined(__CPU_STM32U3)
static u32 uart_configureRefclk(unsigned int minor)
{
/* Switch to PCLK clock */
_stm32_rccSetIPClk(uartInfo[minor].ipclk_sel, uart_clk_sel_pclk);
return _stm32_rccGetPclkClock();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with the suggested renaming of _stm32_rccGetPclkClock to _stm32_rccGetHclkClock for improved clarity, this call should be updated. The original function name is misleading as it returns the HCLK frequency.

return _stm32_rccGetHclkClock();

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

USART doesn't care about HCLK, it cares about PCLKx. The fact that PCLKx is equal to HCLK in this configuration is incidental.

}
#endif


Expand Down
4 changes: 3 additions & 1 deletion hal/armv7m/stm32/l4/stm32l4.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,14 +425,16 @@ int _stm32_getFlashBank(void)
}


void _stm32_switchFlashBank(int bank)
int _stm32_switchFlashBank(int bank)
{
if (bank == 0) {
*(stm32_common.syscfg + syscfg_memrmp) &= ~(1 << 8);
}
else {
*(stm32_common.syscfg + syscfg_memrmp) |= 1 << 8;
}

return 0;
}


Expand Down
2 changes: 1 addition & 1 deletion hal/armv7m/stm32/l4/stm32l4.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ extern int _stm32_gpioGetPort(unsigned int d, u16 *val);
extern int _stm32_getFlashBank(void);


extern void _stm32_switchFlashBank(int bank);
extern int _stm32_switchFlashBank(int bank);


/* Range = 0 - forbidden, 1 - 1.8V, 2 - 1.5V, 3 - 1.2V */
Expand Down
12 changes: 9 additions & 3 deletions hal/armv8m/stm32/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
# %LICENSE%
#

include hal/armv8m/stm32/n6/Makefile
CFLAGS += -I../plo/hal/armv8m/stm32/n6
OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/stm32/, hal.o)
ifneq (, $(findstring stm32n6, $(TARGET_SUBFAMILY)))
include hal/armv8m/stm32/n6/Makefile
CFLAGS += -I../plo/hal/armv8m/stm32/n6
else ifneq (, $(findstring stm32u3, $(TARGET_SUBFAMILY)))
include hal/armv8m/stm32/u3/Makefile
CFLAGS += -I../plo/hal/armv8m/stm32/u3
endif

OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/stm32/, hal.o console.o timer.o)
19 changes: 15 additions & 4 deletions hal/armv8m/stm32/n6/console.c → hal/armv8m/stm32/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
* Console
*
* Copyright 2021, 2025 Phoenix Systems
* Authors: Aleksander Kaminski, Jacek Maksymowicz
* Copyright 2026 Apator Metrix
* Authors: Aleksander Kaminski, Jacek Maksymowicz, Mateusz Karcz
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include <board_config.h>
#include <hal/hal.h>
#include <lib/helpers.h>

#include <board_config.h>

#include "stm32n6.h"
#include "stm32.h"

#if !ISEMPTY(UART_CONSOLE_PLO)

Expand All @@ -39,12 +39,16 @@
/* Values for selecting the peripheral clock for an UART */
enum {
uart_clk_sel_pclk = 0, /* pclk1 or pclk2 depending on peripheral */
#if defined(__CPU_STM32N6)
uart_clk_sel_per_ck,
uart_clk_sel_ic9_ck,
uart_clk_sel_ic14_ck,
uart_clk_sel_lse_ck,
uart_clk_sel_msi_ck,
uart_clk_sel_hsi_div_ck,
#elif defined(__CPU_STM32U3)
uart_clk_sel_hsi_ck,
#endif
};
Comment on lines 40 to 52

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This enum for UART clock selection is also defined in devices/uart-stm32/uart.c. To improve maintainability and avoid potential inconsistencies, consider moving this enum to a shared header file that can be included by both console.c and uart.c.

Copy link
Author

@mkarcz-apator mkarcz-apator Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HAL console and Devices are conceptually distinct subsystems.



Expand Down Expand Up @@ -100,11 +104,13 @@ void console_init(void)
{ UART3_BASE, UART3_CLK, ipclk_usart3sel },
{ UART4_BASE, UART4_CLK, ipclk_uart4sel },
{ UART5_BASE, UART5_CLK, ipclk_uart5sel },
#if defined(__CPU_STM32N6)
{ UART6_BASE, UART6_CLK, ipclk_usart6sel },
{ UART7_BASE, UART7_CLK, ipclk_uart7sel },
{ UART8_BASE, UART8_CLK, ipclk_uart8sel },
{ UART9_BASE, UART9_CLK, ipclk_uart9sel },
{ UART10_BASE, UART10_CLK, ipclk_usart10sel },
#endif
};

const int uart = UART_CONSOLE_PLO - 1, port = UART_IO_PORT_DEV, txpin = UART_PIN_TX, rxpin = UART_PIN_RX, af = UART_IO_AF;
Expand All @@ -119,8 +125,13 @@ void console_init(void)
/* Init rxd pin - input, push-pull, low speed, no pull-up */
_stm32_gpioConfig(port, rxpin, gpio_mode_af, af, gpio_otype_pp, gpio_ospeed_low, gpio_pupd_nopull);

#if defined(__CPU_STM32N6)
_stm32_rccSetIPClk(uarts[uart].ipclk_sel, uart_clk_sel_hsi_div_ck);
halconsole_common.refclkfreq = 64 * 1000 * 1000;
#elif defined(__CPU_STM32U3)
_stm32_rccSetIPClk(uarts[uart].ipclk_sel, uart_clk_sel_pclk);
halconsole_common.refclkfreq = _stm32_rccGetPclkClock();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To align with the suggested renaming of _stm32_rccGetPclkClock to _stm32_rccGetHclkClock for improved clarity, this call should be updated. The original function name is misleading as it returns the HCLK frequency.

Suggested change
halconsole_common.refclkfreq = _stm32_rccGetPclkClock();
halconsole_common.refclkfreq = _stm32_rccGetHclkClock();

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As previously stated.

#endif

/* Enable uart clock */
_stm32_rccSetDevClock(uarts[uart].dev_clk, 1);
Expand Down
9 changes: 8 additions & 1 deletion hal/armv8m/stm32/hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* Hardware Abstraction Layer
*
* Copyright 2020-2025 Phoenix Systems
* Author: Hubert Buczynski, Marcin Baran, Gerard Swiderski, Aleksander Kaminski
* Copyright 2026 Apator Metrix
* Author: Hubert Buczynski, Marcin Baran, Gerard Swiderski, Aleksander Kaminski, Mateusz Karcz
*
* This file is part of Phoenix-RTOS.
*
Expand Down Expand Up @@ -98,7 +99,13 @@ void hal_syspageSet(hal_syspage_t *hs)

const char *hal_cpuInfo(void)
{
#if defined(__CPU_STM32N6)
return "Cortex-M55 STM32N6";
#elif defined(__CPU_STM32U3)
return "Cortex-M33 STM32U3";
#else
#error "Unsupported platform"
#endif
}


Expand Down
3 changes: 2 additions & 1 deletion hal/armv8m/stm32/n6/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Makefile for Phoenix-RTOS loader (ARMv8M HAL stm32n6)
#
# Copyright 2021, 2025 Phoenix Systems
# Copyright 2026 Apator Metrix
#
# %LICENSE%
#
Expand All @@ -17,4 +18,4 @@ PLO_COMMANDS ?= alias app blob call console copy devices dump echo erase go help

PLO_ALLDEVICES := pipe-rtt ram-storage uart-stm32 flash-stm32xspi

OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/stm32/n6/, _init.o stm32n6.o timer.o console.o otp.o)
OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/stm32/n6/, _init.o stm32n6.o otp.o)
22 changes: 22 additions & 0 deletions hal/armv8m/stm32/stm32.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Phoenix-RTOS
*
* Operating system loader
*
* STM32 ARMv8-M MCU specific header dispatch
*
* Copyright 2026 Apator Metrix
* Author: Mateusz Karcz
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#if defined(__CPU_STM32N6)
#include "n6/stm32n6.h"
#elif defined(__CPU_STM32U3)
#include "u3/stm32u3.h"
#else
#error "Unsupported platform"
#endif
2 changes: 1 addition & 1 deletion hal/armv8m/stm32/n6/timer.c → hal/armv8m/stm32/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/

#include <hal/hal.h>
#include "stm32n6.h"
#include "stm32.h"

#define SYSTICK_IRQ 15

Expand Down
28 changes: 28 additions & 0 deletions hal/armv8m/stm32/u3/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# Makefile for Phoenix-RTOS loader (ARMv8M HAL stm32u3)
#
# Copyright 2021, 2025 Phoenix Systems
# Copyright 2026 Apator Metrix
#
# %LICENSE%
#

LDFLAGS := $(filter-out -Tbss% , $(LDFLAGS))
LDFLAGS := $(filter-out -Tdata% , $(LDFLAGS))

CFLAGS := $(filter-out -mfloat-abi% , $(CFLAGS))
CFLAGS += -mfloat-abi=soft

ifneq (,$(FLASH_SIZE))
CFLAGS += -DFLASH_PROGRAM_BANK_SIZE=$(FLASH_SIZE)
endif
ifneq (,$(RAM_SIZE))
CFLAGS += -DRAM_BANK_SIZE=$(RAM_SIZE)
endif

PLO_COMMANDS ?= alias app bankswitch blob call console copy devices dump echo go help kernelimg \
map mem phfs reboot script stop wait

PLO_ALLDEVICES := flash-stm32 uart-stm32 ram-storage

OBJS += $(addprefix $(PREFIX_O)hal/$(TARGET_SUFF)/stm32/u3/, _init.o stm32u3.o)
Loading