Skip to content

Commit

Permalink
add support for nucleo l4r5
Browse files Browse the repository at this point in the history
Signed-off-by: Duc Tri Nguyen <[email protected]>
  • Loading branch information
cothan committed Oct 4, 2024
1 parent 2968023 commit c3fe366
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 4 deletions.
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

arm-pkgs = builtins.attrValues {
libopencm3 = pkgs.callPackage ./libopencm3.nix {
targets = [ "stm32/f2" "stm32/f4" "stm32/f7" ];
targets = [ "stm32/f2" "stm32/f4" "stm32/f7" "stm32/l4" ];
};

mbed-os = pkgs.callPackage ./mbed-os.nix {
Expand Down
4 changes: 4 additions & 0 deletions hal/devices.data
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ stm32f407vg stm32f4 ROM=1024K RAM=128K
stm32f4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16
stm32f767zi stm32f7 ROM=2048K RAM=384K
stm32f7 END ROM_OFF=0x08000000 RAM_OFF=0x20010000 CPU=cortex-m7 FPU=hard-fpv5-sp-d16

# Device otherwise missing from OpenCM3
stm32l4r5zi stm32l4 ROM=2048K RAM=256K RAM3=384K
stm32l4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 RAM2_OFF=0x10000000 RAM3_OFF=0x20040000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16
105 changes: 105 additions & 0 deletions hal/hal-opencm3.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,31 @@ const struct rcc_clock_scale benchmarkclock = {
#define SERIAL_PINS (GPIO8 | GPIO9)
#define STM32

#elif defined(STM32L4R5ZI)
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/flash.h>
#include <libopencm3/stm32/rng.h>
#include <libopencm3/stm32/pwr.h>

#define SERIAL_GPIO GPIOG
#define SERIAL_USART LPUART1
#define SERIAL_PINS (GPIO8 | GPIO7)
#define NUCLEO_L4R5_BOARD

/* Patched function for newer PLL not yet supported by opencm3 */
void _rcc_set_main_pll(uint32_t source, uint32_t pllm, uint32_t plln, uint32_t pllp,
uint32_t pllq, uint32_t pllr)
{
RCC_PLLCFGR = (RCC_PLLCFGR_PLLM(pllm) << RCC_PLLCFGR_PLLM_SHIFT) |
(plln << RCC_PLLCFGR_PLLN_SHIFT) |
((pllp & 0x1Fu) << 27u) | /* NEWER PLLP */
(source << RCC_PLLCFGR_PLLSRC_SHIFT) |
(pllq << RCC_PLLCFGR_PLLQ_SHIFT) |
(pllr << RCC_PLLCFGR_PLLR_SHIFT) | RCC_PLLCFGR_PLLREN;
}

#else
#error Unsupported libopencm3 board
#endif
Expand Down Expand Up @@ -156,6 +181,69 @@ static void clock_setup(enum clock_mode clock) {
# else
# error Unsupported STM32F2 Board
# endif
#elif defined(NUCLEO_L4R5_BOARD)
rcc_periph_clock_enable(RCC_PWR);
rcc_periph_clock_enable(RCC_SYSCFG);
pwr_set_vos_scale(PWR_SCALE1);
/* The L4R5ZI chip also needs the R1MODE bit in PWR_CR5 register set, but
OpenCM3 doesn't support this yet. But luckily the default value for the bit
is 1. */
switch (clock) {
case CLOCK_BENCHMARK:
/* Benchmark straight from the HSI16 without prescaling */
rcc_osc_on(RCC_HSI16);
rcc_wait_for_osc_ready(RCC_HSI16);
rcc_ahb_frequency = 20000000;
rcc_apb1_frequency = 20000000;
rcc_apb2_frequency = 20000000;
_clock_freq = 20000000;
rcc_set_hpre(RCC_CFGR_HPRE_NODIV);
rcc_set_ppre1(RCC_CFGR_PPRE_NODIV);
rcc_set_ppre2(RCC_CFGR_PPRE_NODIV);
rcc_osc_off(RCC_PLL);
while(rcc_is_osc_ready(RCC_PLL));
/* Configure the PLL oscillator (use CUBEMX tool -> scale HSI16 to 20MHz). */
_rcc_set_main_pll(RCC_PLLCFGR_PLLSRC_HSI16, 1, 10, 2, RCC_PLLCFGR_PLLQ_DIV2, RCC_PLLCFGR_PLLR_DIV8);
/* Enable PLL oscillator and wait for it to stabilize. */
rcc_osc_on(RCC_PLL);
flash_dcache_enable();
flash_icache_enable();
flash_set_ws(FLASH_ACR_LATENCY_0WS);
flash_prefetch_enable();
rcc_set_sysclk_source(RCC_CFGR_SW_PLL);
rcc_wait_for_sysclk_status(RCC_PLL);
break;
case CLOCK_FAST:
default:
rcc_osc_on(RCC_HSI16);
rcc_wait_for_osc_ready(RCC_HSI16);
rcc_ahb_frequency = 120000000;
rcc_apb1_frequency = 120000000;
rcc_apb2_frequency = 120000000;
_clock_freq = 120000000;
rcc_set_hpre(RCC_CFGR_HPRE_NODIV);
rcc_set_ppre1(RCC_CFGR_PPRE_NODIV);
rcc_set_ppre2(RCC_CFGR_PPRE_NODIV);
rcc_osc_off(RCC_PLL);
while(rcc_is_osc_ready(RCC_PLL));
/* Configure the PLL oscillator (use CUBEMX tool -> scale HSI16 to 120MHz). */
_rcc_set_main_pll(RCC_PLLCFGR_PLLSRC_HSI16, 1, 15, 2, RCC_PLLCFGR_PLLQ_DIV2, RCC_PLLCFGR_PLLR_DIV2);
/* Enable PLL oscillator and wait for it to stabilize. */
rcc_osc_on(RCC_PLL);
rcc_wait_for_osc_ready(RCC_PLL);
flash_dcache_enable();
flash_icache_enable();
flash_set_ws(0x05);
flash_prefetch_enable();
rcc_set_sysclk_source(RCC_CFGR_SW_PLL);
rcc_wait_for_sysclk_status(RCC_PLL);
break;
}
rcc_osc_on(RCC_HSI48); /* HSI48 must always be on for RNG */
rcc_wait_for_osc_ready(RCC_HSI48);
rcc_periph_clock_enable(RCC_RNG);
rcc_set_clock48_source(RCC_CCIPR_CLK48SEL_HSI48);
rng_enable();
#else
#error Unsupported platform
#endif
Expand All @@ -171,6 +259,23 @@ void usart_setup() {
#elif defined(NUCLEO_BOARD)
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_USART2);
#elif defined(NUCLEO_L4R5_BOARD)
rcc_periph_clock_enable(RCC_GPIOG);
rcc_periph_clock_enable(RCC_LPUART1);

PWR_CR2 |= PWR_CR2_IOSV;
gpio_set_output_options(SERIAL_GPIO, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, SERIAL_PINS);
gpio_set_af(SERIAL_GPIO, GPIO_AF8, SERIAL_PINS);
gpio_mode_setup(SERIAL_GPIO, GPIO_MODE_AF, GPIO_PUPD_NONE, SERIAL_PINS);
usart_set_baudrate(SERIAL_USART, SERIAL_BAUD);
usart_set_databits(SERIAL_USART, 8);
usart_set_stopbits(SERIAL_USART, USART_STOPBITS_1);
usart_set_mode(SERIAL_USART, USART_MODE_TX_RX);
usart_set_parity(SERIAL_USART, USART_PARITY_NONE);
usart_set_flow_control(SERIAL_USART, USART_FLOWCONTROL_NONE);
usart_disable_rx_interrupt(SERIAL_USART);
usart_disable_tx_interrupt(SERIAL_USART);
usart_enable(SERIAL_USART);
#else
#error Unsupported platform
#endif
Expand Down
11 changes: 11 additions & 0 deletions hal/nucleo_l4r5.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: Apache-2.0 or CC0-1.0

# This is for STM32L4R5 Nucleo Dev Boards.
source [find interface/stlink-dap.cfg]

transport select dapdirect_swd

source [find target/stm32l4x.cfg]

# use hardware reset (srst seems to be problematic)
reset_config trst_only
13 changes: 10 additions & 3 deletions libopencm3.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

stdenvNoCC.mkDerivation rec {
pname = "libopencm3";
version = "ec5aeba354ec273782e4441440fe9000b1c965e3";
version = "228f28fa66b672535663aa9aa4d12ede8b1a8fc5";
src = fetchFromGitHub {
owner = "libopencm3";
repo = pname;
rev = "ec5aeba354ec273782e4441440fe9000b1c965e3";
sha256 = "sha256-bgoMhOhBJZwPTa9gUH0vPSGZknDrb2mJZuFlCWNivYU=";
rev = "228f28fa66b672535663aa9aa4d12ede8b1a8fc5";
sha256 = "sha256-eqjOtvH+FwRaWqVSxUyK/gXtveEipLsyjd4jLzXbzbw=";
};
setupHook = writeText "setup-hook.sh" ''
export OPENCM3_DIR="$1"
Expand All @@ -25,8 +25,15 @@ stdenvNoCC.mkDerivation rec {
python311
gcc-arm-embedded-13 # arm-gnu-toolchain-13.2.rel1
];
devicesPatch = writeText "devices-patch.txt" ''
# Device otherwise missing from OpenCM3
stm32l4r5zi stm32l4 ROM=2048K RAM=256K RAM3=384K
'';
postPatch = ''
patchShebangs --build scripts/irq2nvic_h
# Apply the patch to devices.data
cat ${devicesPatch} >> ld/devices.data
'';
dontConfigure = true;
buildPhase = ''
Expand Down
6 changes: 6 additions & 0 deletions mk/nucleo-l4r5zi.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: Apache-2.0 or CC0-1.0
DEVICE=stm32l4r5zi
OPENCM3_TARGET=lib/stm32/l4
override DEVICES_DATA := hal/devices.data

include mk/opencm3.mk
5 changes: 5 additions & 0 deletions scripts/tests
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class PLATFORM(Enum):
MPS2_AN500 = 4
NUCLEO_F207ZG = 5
MPS2_AN385 = 6
NUCLEO_L4R5ZI = 7

def __str__(self):
return self.name.lower().replace("_", "-")
Expand Down Expand Up @@ -153,6 +154,10 @@ platform_map = RecursiveNamespace(
f"{PLATFORM.MPS2_AN386}": {},
f"{PLATFORM.MPS2_AN385}": {},
f"{PLATFORM.MPS2_AN500}": {},
f"{PLATFORM.NUCLEO_L4R5ZI}": {
"openocd_cfg": f"{ROOT}/hal/nucleo_l4r5.cfg",
},

}
)

Expand Down

0 comments on commit c3fe366

Please sign in to comment.