From 266465f62adae056023a198ad61cfcfde049087f Mon Sep 17 00:00:00 2001 From: ImBonkers Date: Sat, 16 May 2026 15:40:03 +0200 Subject: [PATCH 1/3] arch/arm/stm32n6: Add STM32N6 chip support. Introduce minimal chip support for the STMicro STM32N6 family (Cortex-M55, ARMv8.1-M with TrustZone and FPU), sufficient to bring up an NSH console over USART1. Scope (deliberately minimal first drop): - Chip selector ARCH_CHIP_STM32N6 wired into arch/arm/Kconfig and chip-name mapping ("stm32n6"). - Sub-Kconfig under arch/arm/src/stm32n6 with the STM32N657X0 chip selector and a single user-selectable USART (USART1). - Boot path: stm32_start with a naked dispatcher that clears the boot-ROM MSPLIM/PSPLIM stack limits before any compiler-emitted prologue, then runs vector relocation and SRAM-only heap init. The chip runs entirely in the Secure state; SAU is left in its reset configuration. - PLL1-based clock tree fed from HSI64 targeting 200 MHz CPU, with USART1 kernel-clock routed to HSI for a predictable BRR that is independent of any later clock change. - Low-level USART driver with full serial framework support. stm32_serial.c is adapted from arch/arm/src/stm32h5/stm32_serial.c (sibling ARMv8-M Mainline port with the same USART IP), stripped of DMA-RX, LPUART, the per-USART2..5 plumbing, RS-485 driver-enable, TIOCSINVERT/SWAP and HALFDUPLEX paths. - SysTick system timer. - GPIO, PWR and RCC helpers. TrustZone, MPU, I/D-cache and Helium (MVE) are left disabled to minimise bring-up surface; these will be added in follow-up patches alongside the drivers that need them. Signed-off-by: ImBonkers --- arch/arm/Kconfig | 17 + arch/arm/include/stm32n6/chip.h | 69 + arch/arm/include/stm32n6/irq.h | 97 + arch/arm/include/stm32n6/stm32n6xx_irq.h | 239 +++ arch/arm/src/stm32n6/CMakeLists.txt | 52 + arch/arm/src/stm32n6/Kconfig | 109 + arch/arm/src/stm32n6/Make.defs | 47 + arch/arm/src/stm32n6/chip.h | 57 + .../src/stm32n6/hardware/stm32n6xxx_gpio.h | 442 ++++ .../stm32n6/hardware/stm32n6xxx_memorymap.h | 173 ++ .../src/stm32n6/hardware/stm32n6xxx_pinmap.h | 54 + .../arm/src/stm32n6/hardware/stm32n6xxx_pwr.h | 112 ++ .../arm/src/stm32n6/hardware/stm32n6xxx_rcc.h | 288 +++ .../src/stm32n6/hardware/stm32n6xxx_syscfg.h | 75 + .../src/stm32n6/hardware/stm32n6xxx_uart.h | 252 +++ arch/arm/src/stm32n6/stm32.h | 46 + arch/arm/src/stm32n6/stm32_gpio.c | 374 ++++ arch/arm/src/stm32n6/stm32_gpio.h | 317 +++ arch/arm/src/stm32n6/stm32_idle.c | 86 + arch/arm/src/stm32n6/stm32_irq.c | 473 +++++ arch/arm/src/stm32n6/stm32_lowputc.c | 257 +++ arch/arm/src/stm32n6/stm32_lowputc.h | 66 + arch/arm/src/stm32n6/stm32_pwr.c | 92 + arch/arm/src/stm32n6/stm32_pwr.h | 92 + arch/arm/src/stm32n6/stm32_rcc.c | 90 + arch/arm/src/stm32n6/stm32_rcc.h | 120 ++ arch/arm/src/stm32n6/stm32_serial.c | 1772 +++++++++++++++++ arch/arm/src/stm32n6/stm32_start.c | 267 +++ arch/arm/src/stm32n6/stm32_start.h | 47 + arch/arm/src/stm32n6/stm32_timerisr.c | 116 ++ arch/arm/src/stm32n6/stm32_uart.h | 96 + arch/arm/src/stm32n6/stm32n6xx_rcc.c | 261 +++ tools/ci/testlist/arm-14.dat | 1 + 33 files changed, 6656 insertions(+) create mode 100644 arch/arm/include/stm32n6/chip.h create mode 100644 arch/arm/include/stm32n6/irq.h create mode 100644 arch/arm/include/stm32n6/stm32n6xx_irq.h create mode 100644 arch/arm/src/stm32n6/CMakeLists.txt create mode 100644 arch/arm/src/stm32n6/Kconfig create mode 100644 arch/arm/src/stm32n6/Make.defs create mode 100644 arch/arm/src/stm32n6/chip.h create mode 100644 arch/arm/src/stm32n6/hardware/stm32n6xxx_gpio.h create mode 100644 arch/arm/src/stm32n6/hardware/stm32n6xxx_memorymap.h create mode 100644 arch/arm/src/stm32n6/hardware/stm32n6xxx_pinmap.h create mode 100644 arch/arm/src/stm32n6/hardware/stm32n6xxx_pwr.h create mode 100644 arch/arm/src/stm32n6/hardware/stm32n6xxx_rcc.h create mode 100644 arch/arm/src/stm32n6/hardware/stm32n6xxx_syscfg.h create mode 100644 arch/arm/src/stm32n6/hardware/stm32n6xxx_uart.h create mode 100644 arch/arm/src/stm32n6/stm32.h create mode 100644 arch/arm/src/stm32n6/stm32_gpio.c create mode 100644 arch/arm/src/stm32n6/stm32_gpio.h create mode 100644 arch/arm/src/stm32n6/stm32_idle.c create mode 100644 arch/arm/src/stm32n6/stm32_irq.c create mode 100644 arch/arm/src/stm32n6/stm32_lowputc.c create mode 100644 arch/arm/src/stm32n6/stm32_lowputc.h create mode 100644 arch/arm/src/stm32n6/stm32_pwr.c create mode 100644 arch/arm/src/stm32n6/stm32_pwr.h create mode 100644 arch/arm/src/stm32n6/stm32_rcc.c create mode 100644 arch/arm/src/stm32n6/stm32_rcc.h create mode 100644 arch/arm/src/stm32n6/stm32_serial.c create mode 100644 arch/arm/src/stm32n6/stm32_start.c create mode 100644 arch/arm/src/stm32n6/stm32_start.h create mode 100644 arch/arm/src/stm32n6/stm32_timerisr.c create mode 100644 arch/arm/src/stm32n6/stm32_uart.h create mode 100644 arch/arm/src/stm32n6/stm32n6xx_rcc.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index de81c0fb81c85..392324a6d3f88 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -587,6 +587,19 @@ config ARCH_CHIP_STM32H5 ---help--- STMicro STM32 H5 architectures (ARM Cortex-M33). +config ARCH_CHIP_STM32N6 + bool "STMicro STM32 N6" + select ARCH_CORTEXM55 + select ARCH_HAVE_FPU + select ARCH_HAVE_MPU + select ARM_HAVE_DSP + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_TRUSTZONE + select ARCH_HAVE_FETCHADD + select ARCH_HAVE_HEAPCHECK + ---help--- + STMicro STM32N6 architectures (ARM Cortex-M55). + config ARCH_CHIP_STM32L5 bool "STMicro STM32 L5" select ARCH_CORTEXM33 @@ -1199,6 +1212,7 @@ config ARCH_CHIP default "stm32h7" if ARCH_CHIP_STM32H7 default "stm32l4" if ARCH_CHIP_STM32L4 default "stm32h5" if ARCH_CHIP_STM32H5 + default "stm32n6" if ARCH_CHIP_STM32N6 default "stm32l5" if ARCH_CHIP_STM32L5 default "stm32u5" if ARCH_CHIP_STM32U5 default "stm32wb" if ARCH_CHIP_STM32WB @@ -1709,6 +1723,9 @@ endif if ARCH_CHIP_STM32H5 source "arch/arm/src/stm32h5/Kconfig" endif +if ARCH_CHIP_STM32N6 +source "arch/arm/src/stm32n6/Kconfig" +endif if ARCH_CHIP_STM32L5 source "arch/arm/src/stm32l5/Kconfig" endif diff --git a/arch/arm/include/stm32n6/chip.h b/arch/arm/include/stm32n6/chip.h new file mode 100644 index 0000000000000..72f643ba3b687 --- /dev/null +++ b/arch/arm/include/stm32n6/chip.h @@ -0,0 +1,69 @@ +/**************************************************************************** + * arch/arm/include/stm32n6/chip.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_STM32N6_CHIP_H +#define __ARCH_ARM_INCLUDE_STM32N6_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* Memory sizes - STM32N6 has no internal flash. Code runs from the + * on-chip AXI SRAM (loaded by the debugger in DEV mode, or by an FSBL + * from external XSPI flash in normal boot). + * + * AXI SRAM layout (from CMSIS stm32n657xx.h): + * AXISRAM1: 0x34000000 1 MB + * AXISRAM2: 0x34100000 1 MB + * AXISRAM3: 0x34200000 448 KB + * AXISRAM4: 0x34270000 448 KB + * AXISRAM5: 0x342E0000 448 KB + * AXISRAM6: 0x34350000 448 KB + * CACHEAXIRAM: 0x343C0000 256 KB + * ------------------------------------------- + * Total: 4 MB (end = 0x34400000) + * + * VENCRAM (128 KB at 0x34400000) is excluded -- reserved for video encoder. + * Each bank requires its RCC MEMENR clock enable bit to be set. + */ + +#define STM32N6_SRAM_SIZE (4 * 1024 * 1024) /* 4194304 bytes (4 MiB) */ + +#define STM32N6_NPORTS (12) /* GPIO ports A-H (8) + N, O, P, Q (4) */ +#define STM32N6_NUSART (1) /* USART1 */ + +/* NVIC priority levels *****************************************************/ + +/* 16 Programmable interrupt levels (4-bit priority) */ + +#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits set in minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Four bits of interrupt priority used */ + +#endif /* __ARCH_ARM_INCLUDE_STM32N6_CHIP_H */ diff --git a/arch/arm/include/stm32n6/irq.h b/arch/arm/include/stm32n6/irq.h new file mode 100644 index 0000000000000..3ae6d859ac6b9 --- /dev/null +++ b/arch/arm/include/stm32n6/irq.h @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/arm/include/stm32n6/irq.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32N6_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32N6_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define STM32_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG_FEATURES) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define STM32_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define STM32_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define STM32_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define STM32_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define STM32_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ + /* Vectors 7-10: Reserved */ +#define STM32_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define STM32_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define STM32_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define STM32_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are + * chip-specific + */ + +#define STM32_IRQ_FIRST (16) /* Vector number of the first external interrupt */ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32N6_IRQ_H */ diff --git a/arch/arm/include/stm32n6/stm32n6xx_irq.h b/arch/arm/include/stm32n6/stm32n6xx_irq.h new file mode 100644 index 0000000000000..ef186921d2791 --- /dev/null +++ b/arch/arm/include/stm32n6/stm32n6xx_irq.h @@ -0,0 +1,239 @@ +/**************************************************************************** + * arch/arm/include/stm32n6/stm32n6xx_irq.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_STM32N6_STM32N6XX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32N6_STM32N6XX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be found + * in arch/arm/include/stm32n6/irq.h. + * + * External interrupts (vectors >= 16) + * + * These interrupt vectors are based on the STM32N657xx CMSIS device header + * (stm32n657xx.h IRQn_Type enumeration). 195 external interrupts total. + */ + +#define STM32_IRQ_PVD_PVM (STM32_IRQ_FIRST + 0) /* 0: PVD/PVM through EXTI Line detection */ +#define STM32_IRQ_DTS (STM32_IRQ_FIRST + 2) /* 2: Thermal sensor interrupt */ +#define STM32_IRQ_RCC (STM32_IRQ_FIRST + 3) /* 3: RCC non-secure global interrupt */ +#define STM32_IRQ_LOCKUP (STM32_IRQ_FIRST + 4) /* 4: LOCKUP interrupt */ +#define STM32_IRQ_CACHE_ECC (STM32_IRQ_FIRST + 5) /* 5: Cache ECC error interrupt */ +#define STM32_IRQ_TCM_ECC (STM32_IRQ_FIRST + 6) /* 6: TCM ECC interrupt */ +#define STM32_IRQ_BKP_ECC (STM32_IRQ_FIRST + 7) /* 7: Backup RAM ECC interrupt */ +#define STM32_IRQ_FPU (STM32_IRQ_FIRST + 8) /* 8: FPU interrupt */ +#define STM32_IRQ_RTC_S (STM32_IRQ_FIRST + 10) /* 10: RTC secure interrupt */ +#define STM32_IRQ_TAMP (STM32_IRQ_FIRST + 11) /* 11: Tamper interrupt */ +#define STM32_IRQ_RIFSC_TAMPER (STM32_IRQ_FIRST + 12) /* 12: RIFSC tamper interrupt */ +#define STM32_IRQ_IAC (STM32_IRQ_FIRST + 13) /* 13: IAC interrupt */ +#define STM32_IRQ_RCC_S (STM32_IRQ_FIRST + 14) /* 14: RCC secure global interrupt */ +#define STM32_IRQ_RTC (STM32_IRQ_FIRST + 16) /* 16: RTC non-secure interrupt */ +#define STM32_IRQ_IWDG (STM32_IRQ_FIRST + 18) /* 18: Independent Watchdog interrupt */ +#define STM32_IRQ_WWDG (STM32_IRQ_FIRST + 19) /* 19: Window Watchdog interrupt */ +#define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST + 20) /* 20: EXTI Line 0 interrupt */ +#define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST + 21) /* 21: EXTI Line 1 interrupt */ +#define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST + 22) /* 22: EXTI Line 2 interrupt */ +#define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST + 23) /* 23: EXTI Line 3 interrupt */ +#define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST + 24) /* 24: EXTI Line 4 interrupt */ +#define STM32_IRQ_EXTI5 (STM32_IRQ_FIRST + 25) /* 25: EXTI Line 5 interrupt */ +#define STM32_IRQ_EXTI6 (STM32_IRQ_FIRST + 26) /* 26: EXTI Line 6 interrupt */ +#define STM32_IRQ_EXTI7 (STM32_IRQ_FIRST + 27) /* 27: EXTI Line 7 interrupt */ +#define STM32_IRQ_EXTI8 (STM32_IRQ_FIRST + 28) /* 28: EXTI Line 8 interrupt */ +#define STM32_IRQ_EXTI9 (STM32_IRQ_FIRST + 29) /* 29: EXTI Line 9 interrupt */ +#define STM32_IRQ_EXTI10 (STM32_IRQ_FIRST + 30) /* 30: EXTI Line 10 interrupt */ +#define STM32_IRQ_EXTI11 (STM32_IRQ_FIRST + 31) /* 31: EXTI Line 11 interrupt */ +#define STM32_IRQ_EXTI12 (STM32_IRQ_FIRST + 32) /* 32: EXTI Line 12 interrupt */ +#define STM32_IRQ_EXTI13 (STM32_IRQ_FIRST + 33) /* 33: EXTI Line 13 interrupt */ +#define STM32_IRQ_EXTI14 (STM32_IRQ_FIRST + 34) /* 34: EXTI Line 14 interrupt */ +#define STM32_IRQ_EXTI15 (STM32_IRQ_FIRST + 35) /* 35: EXTI Line 15 interrupt */ +#define STM32_IRQ_SAES (STM32_IRQ_FIRST + 36) /* 36: SAES interrupt */ +#define STM32_IRQ_CRYP (STM32_IRQ_FIRST + 37) /* 37: CRYP interrupt */ +#define STM32_IRQ_PKA (STM32_IRQ_FIRST + 38) /* 38: PKA interrupt */ +#define STM32_IRQ_HASH (STM32_IRQ_FIRST + 39) /* 39: HASH interrupt */ +#define STM32_IRQ_RNG (STM32_IRQ_FIRST + 40) /* 40: RNG global interrupt */ +#define STM32_IRQ_MCE1 (STM32_IRQ_FIRST + 42) /* 42: MCE1 global interrupt */ +#define STM32_IRQ_MCE2 (STM32_IRQ_FIRST + 43) /* 43: MCE2 global interrupt */ +#define STM32_IRQ_MCE3 (STM32_IRQ_FIRST + 44) /* 44: MCE3 global interrupt */ +#define STM32_IRQ_MCE4 (STM32_IRQ_FIRST + 45) /* 45: MCE4 global interrupt */ +#define STM32_IRQ_ADC1_2 (STM32_IRQ_FIRST + 46) /* 46: ADC1 & ADC2 interrupt */ +#define STM32_IRQ_CSI (STM32_IRQ_FIRST + 47) /* 47: CSI global interrupt */ +#define STM32_IRQ_DCMIPP (STM32_IRQ_FIRST + 48) /* 48: DCMIPP global interrupt */ +#define STM32_IRQ_PAHB_ERR (STM32_IRQ_FIRST + 52) /* 52: PAHB error interrupt */ +#define STM32_IRQ_LTDC_LO (STM32_IRQ_FIRST + 58) /* 58: LTDC low-layer global interrupt */ +#define STM32_IRQ_LTDC_LO_ERR (STM32_IRQ_FIRST + 59) /* 59: LTDC low-layer error interrupt */ +#define STM32_IRQ_DMA2D (STM32_IRQ_FIRST + 60) /* 60: DMA2D global interrupt */ +#define STM32_IRQ_JPEG (STM32_IRQ_FIRST + 61) /* 61: JPEG global interrupt */ +#define STM32_IRQ_VENC (STM32_IRQ_FIRST + 62) /* 62: VENC global interrupt */ +#define STM32_IRQ_GFXMMU (STM32_IRQ_FIRST + 63) /* 63: GFXMMU global interrupt */ +#define STM32_IRQ_GFXTIM (STM32_IRQ_FIRST + 64) /* 64: GFXTIM global interrupt */ +#define STM32_IRQ_GPU2D (STM32_IRQ_FIRST + 65) /* 65: GPU2D interrupt */ +#define STM32_IRQ_GPU2D_ER (STM32_IRQ_FIRST + 66) /* 66: GPU2D error interrupt */ +#define STM32_IRQ_ICACHE (STM32_IRQ_FIRST + 67) /* 67: ICACHE interrupt */ +#define STM32_IRQ_HPDMA1_CH0 (STM32_IRQ_FIRST + 68) /* 68: HPDMA1 Channel 0 interrupt */ +#define STM32_IRQ_HPDMA1_CH1 (STM32_IRQ_FIRST + 69) /* 69: HPDMA1 Channel 1 interrupt */ +#define STM32_IRQ_HPDMA1_CH2 (STM32_IRQ_FIRST + 70) /* 70: HPDMA1 Channel 2 interrupt */ +#define STM32_IRQ_HPDMA1_CH3 (STM32_IRQ_FIRST + 71) /* 71: HPDMA1 Channel 3 interrupt */ +#define STM32_IRQ_HPDMA1_CH4 (STM32_IRQ_FIRST + 72) /* 72: HPDMA1 Channel 4 interrupt */ +#define STM32_IRQ_HPDMA1_CH5 (STM32_IRQ_FIRST + 73) /* 73: HPDMA1 Channel 5 interrupt */ +#define STM32_IRQ_HPDMA1_CH6 (STM32_IRQ_FIRST + 74) /* 74: HPDMA1 Channel 6 interrupt */ +#define STM32_IRQ_HPDMA1_CH7 (STM32_IRQ_FIRST + 75) /* 75: HPDMA1 Channel 7 interrupt */ +#define STM32_IRQ_HPDMA1_CH8 (STM32_IRQ_FIRST + 76) /* 76: HPDMA1 Channel 8 interrupt */ +#define STM32_IRQ_HPDMA1_CH9 (STM32_IRQ_FIRST + 77) /* 77: HPDMA1 Channel 9 interrupt */ +#define STM32_IRQ_HPDMA1_CH10 (STM32_IRQ_FIRST + 78) /* 78: HPDMA1 Channel 10 interrupt */ +#define STM32_IRQ_HPDMA1_CH11 (STM32_IRQ_FIRST + 79) /* 79: HPDMA1 Channel 11 interrupt */ +#define STM32_IRQ_HPDMA1_CH12 (STM32_IRQ_FIRST + 80) /* 80: HPDMA1 Channel 12 interrupt */ +#define STM32_IRQ_HPDMA1_CH13 (STM32_IRQ_FIRST + 81) /* 81: HPDMA1 Channel 13 interrupt */ +#define STM32_IRQ_HPDMA1_CH14 (STM32_IRQ_FIRST + 82) /* 82: HPDMA1 Channel 14 interrupt */ +#define STM32_IRQ_HPDMA1_CH15 (STM32_IRQ_FIRST + 83) /* 83: HPDMA1 Channel 15 interrupt */ +#define STM32_IRQ_GPDMA1_CH0 (STM32_IRQ_FIRST + 84) /* 84: GPDMA1 Channel 0 interrupt */ +#define STM32_IRQ_GPDMA1_CH1 (STM32_IRQ_FIRST + 85) /* 85: GPDMA1 Channel 1 interrupt */ +#define STM32_IRQ_GPDMA1_CH2 (STM32_IRQ_FIRST + 86) /* 86: GPDMA1 Channel 2 interrupt */ +#define STM32_IRQ_GPDMA1_CH3 (STM32_IRQ_FIRST + 87) /* 87: GPDMA1 Channel 3 interrupt */ +#define STM32_IRQ_GPDMA1_CH4 (STM32_IRQ_FIRST + 88) /* 88: GPDMA1 Channel 4 interrupt */ +#define STM32_IRQ_GPDMA1_CH5 (STM32_IRQ_FIRST + 89) /* 89: GPDMA1 Channel 5 interrupt */ +#define STM32_IRQ_GPDMA1_CH6 (STM32_IRQ_FIRST + 90) /* 90: GPDMA1 Channel 6 interrupt */ +#define STM32_IRQ_GPDMA1_CH7 (STM32_IRQ_FIRST + 91) /* 91: GPDMA1 Channel 7 interrupt */ +#define STM32_IRQ_GPDMA1_CH8 (STM32_IRQ_FIRST + 92) /* 92: GPDMA1 Channel 8 interrupt */ +#define STM32_IRQ_GPDMA1_CH9 (STM32_IRQ_FIRST + 93) /* 93: GPDMA1 Channel 9 interrupt */ +#define STM32_IRQ_GPDMA1_CH10 (STM32_IRQ_FIRST + 94) /* 94: GPDMA1 Channel 10 interrupt */ +#define STM32_IRQ_GPDMA1_CH11 (STM32_IRQ_FIRST + 95) /* 95: GPDMA1 Channel 11 interrupt */ +#define STM32_IRQ_GPDMA1_CH12 (STM32_IRQ_FIRST + 96) /* 96: GPDMA1 Channel 12 interrupt */ +#define STM32_IRQ_GPDMA1_CH13 (STM32_IRQ_FIRST + 97) /* 97: GPDMA1 Channel 13 interrupt */ +#define STM32_IRQ_GPDMA1_CH14 (STM32_IRQ_FIRST + 98) /* 98: GPDMA1 Channel 14 interrupt */ +#define STM32_IRQ_GPDMA1_CH15 (STM32_IRQ_FIRST + 99) /* 99: GPDMA1 Channel 15 interrupt */ +#define STM32_IRQ_I2C1_EV (STM32_IRQ_FIRST + 100) /* 100: I2C1 event interrupt */ +#define STM32_IRQ_I2C1_ER (STM32_IRQ_FIRST + 101) /* 101: I2C1 error interrupt */ +#define STM32_IRQ_I2C2_EV (STM32_IRQ_FIRST + 102) /* 102: I2C2 event interrupt */ +#define STM32_IRQ_I2C2_ER (STM32_IRQ_FIRST + 103) /* 103: I2C2 error interrupt */ +#define STM32_IRQ_I2C3_EV (STM32_IRQ_FIRST + 104) /* 104: I2C3 event interrupt */ +#define STM32_IRQ_I2C3_ER (STM32_IRQ_FIRST + 105) /* 105: I2C3 error interrupt */ +#define STM32_IRQ_I2C4_EV (STM32_IRQ_FIRST + 106) /* 106: I2C4 event interrupt */ +#define STM32_IRQ_I2C4_ER (STM32_IRQ_FIRST + 107) /* 107: I2C4 error interrupt */ +#define STM32_IRQ_I3C1_EV (STM32_IRQ_FIRST + 108) /* 108: I3C1 event interrupt */ +#define STM32_IRQ_I3C1_ER (STM32_IRQ_FIRST + 109) /* 109: I3C1 error interrupt */ +#define STM32_IRQ_I3C2_EV (STM32_IRQ_FIRST + 110) /* 110: I3C2 event interrupt */ +#define STM32_IRQ_I3C2_ER (STM32_IRQ_FIRST + 111) /* 111: I3C2 error interrupt */ +#define STM32_IRQ_TIM1_BRK (STM32_IRQ_FIRST + 112) /* 112: TIM1 Break interrupt */ +#define STM32_IRQ_TIM1_UP (STM32_IRQ_FIRST + 113) /* 113: TIM1 Update interrupt */ +#define STM32_IRQ_TIM1_TRG_COM (STM32_IRQ_FIRST + 114) /* 114: TIM1 Trigger and Commutation interrupt */ +#define STM32_IRQ_TIM1_CC (STM32_IRQ_FIRST + 115) /* 115: TIM1 Capture Compare interrupt */ +#define STM32_IRQ_TIM2 (STM32_IRQ_FIRST + 116) /* 116: TIM2 global interrupt */ +#define STM32_IRQ_TIM3 (STM32_IRQ_FIRST + 117) /* 117: TIM3 global interrupt */ +#define STM32_IRQ_TIM4 (STM32_IRQ_FIRST + 118) /* 118: TIM4 global interrupt */ +#define STM32_IRQ_TIM5 (STM32_IRQ_FIRST + 119) /* 119: TIM5 global interrupt */ +#define STM32_IRQ_TIM6 (STM32_IRQ_FIRST + 120) /* 120: TIM6 global interrupt */ +#define STM32_IRQ_TIM7 (STM32_IRQ_FIRST + 121) /* 121: TIM7 global interrupt */ +#define STM32_IRQ_TIM8_BRK (STM32_IRQ_FIRST + 122) /* 122: TIM8 Break interrupt */ +#define STM32_IRQ_TIM8_UP (STM32_IRQ_FIRST + 123) /* 123: TIM8 Update interrupt */ +#define STM32_IRQ_TIM8_TRG_COM (STM32_IRQ_FIRST + 124) /* 124: TIM8 Trigger and Commutation interrupt */ +#define STM32_IRQ_TIM8_CC (STM32_IRQ_FIRST + 125) /* 125: TIM8 Capture Compare interrupt */ +#define STM32_IRQ_TIM9 (STM32_IRQ_FIRST + 126) /* 126: TIM9 global interrupt */ +#define STM32_IRQ_TIM10 (STM32_IRQ_FIRST + 127) /* 127: TIM10 global interrupt */ +#define STM32_IRQ_TIM11 (STM32_IRQ_FIRST + 128) /* 128: TIM11 global interrupt */ +#define STM32_IRQ_TIM12 (STM32_IRQ_FIRST + 129) /* 129: TIM12 global interrupt */ +#define STM32_IRQ_TIM13 (STM32_IRQ_FIRST + 130) /* 130: TIM13 global interrupt */ +#define STM32_IRQ_TIM14 (STM32_IRQ_FIRST + 131) /* 131: TIM14 global interrupt */ +#define STM32_IRQ_TIM15 (STM32_IRQ_FIRST + 132) /* 132: TIM15 global interrupt */ +#define STM32_IRQ_TIM16 (STM32_IRQ_FIRST + 133) /* 133: TIM16 global interrupt */ +#define STM32_IRQ_TIM17 (STM32_IRQ_FIRST + 134) /* 134: TIM17 global interrupt */ +#define STM32_IRQ_TIM18 (STM32_IRQ_FIRST + 135) /* 135: TIM18 global interrupt */ +#define STM32_IRQ_LPTIM1 (STM32_IRQ_FIRST + 136) /* 136: LPTIM1 global interrupt */ +#define STM32_IRQ_LPTIM2 (STM32_IRQ_FIRST + 137) /* 137: LPTIM2 global interrupt */ +#define STM32_IRQ_LPTIM3 (STM32_IRQ_FIRST + 138) /* 138: LPTIM3 global interrupt */ +#define STM32_IRQ_LPTIM4 (STM32_IRQ_FIRST + 139) /* 139: LPTIM4 global interrupt */ +#define STM32_IRQ_LPTIM5 (STM32_IRQ_FIRST + 140) /* 140: LPTIM5 global interrupt */ +#define STM32_IRQ_ADF1_FLT0 (STM32_IRQ_FIRST + 141) /* 141: ADF1 Filter 0 interrupt */ +#define STM32_IRQ_MDF1_FLT0 (STM32_IRQ_FIRST + 142) /* 142: MDF1 Filter 0 interrupt */ +#define STM32_IRQ_MDF1_FLT1 (STM32_IRQ_FIRST + 143) /* 143: MDF1 Filter 1 interrupt */ +#define STM32_IRQ_MDF1_FLT2 (STM32_IRQ_FIRST + 144) /* 144: MDF1 Filter 2 interrupt */ +#define STM32_IRQ_MDF1_FLT3 (STM32_IRQ_FIRST + 145) /* 145: MDF1 Filter 3 interrupt */ +#define STM32_IRQ_MDF1_FLT4 (STM32_IRQ_FIRST + 146) /* 146: MDF1 Filter 4 interrupt */ +#define STM32_IRQ_MDF1_FLT5 (STM32_IRQ_FIRST + 147) /* 147: MDF1 Filter 5 interrupt */ +#define STM32_IRQ_SAI1_A (STM32_IRQ_FIRST + 148) /* 148: SAI1 block A interrupt */ +#define STM32_IRQ_SAI1_B (STM32_IRQ_FIRST + 149) /* 149: SAI1 block B interrupt */ +#define STM32_IRQ_SAI2_A (STM32_IRQ_FIRST + 150) /* 150: SAI2 block A interrupt */ +#define STM32_IRQ_SAI2_B (STM32_IRQ_FIRST + 151) /* 151: SAI2 block B interrupt */ +#define STM32_IRQ_SPDIFRX1 (STM32_IRQ_FIRST + 152) /* 152: SPDIFRX1 interrupt */ +#define STM32_IRQ_SPI1 (STM32_IRQ_FIRST + 153) /* 153: SPI1 global interrupt */ +#define STM32_IRQ_SPI2 (STM32_IRQ_FIRST + 154) /* 154: SPI2 global interrupt */ +#define STM32_IRQ_SPI3 (STM32_IRQ_FIRST + 155) /* 155: SPI3 global interrupt */ +#define STM32_IRQ_SPI4 (STM32_IRQ_FIRST + 156) /* 156: SPI4 global interrupt */ +#define STM32_IRQ_SPI5 (STM32_IRQ_FIRST + 157) /* 157: SPI5 global interrupt */ +#define STM32_IRQ_SPI6 (STM32_IRQ_FIRST + 158) /* 158: SPI6 global interrupt */ +#define STM32_IRQ_USART1 (STM32_IRQ_FIRST + 159) /* 159: USART1 global interrupt */ +#define STM32_IRQ_USART2 (STM32_IRQ_FIRST + 160) /* 160: USART2 global interrupt */ +#define STM32_IRQ_USART3 (STM32_IRQ_FIRST + 161) /* 161: USART3 global interrupt */ +#define STM32_IRQ_UART4 (STM32_IRQ_FIRST + 162) /* 162: UART4 global interrupt */ +#define STM32_IRQ_UART5 (STM32_IRQ_FIRST + 163) /* 163: UART5 global interrupt */ +#define STM32_IRQ_USART6 (STM32_IRQ_FIRST + 164) /* 164: USART6 global interrupt */ +#define STM32_IRQ_UART7 (STM32_IRQ_FIRST + 165) /* 165: UART7 global interrupt */ +#define STM32_IRQ_UART8 (STM32_IRQ_FIRST + 166) /* 166: UART8 global interrupt */ +#define STM32_IRQ_UART9 (STM32_IRQ_FIRST + 167) /* 167: UART9 global interrupt */ +#define STM32_IRQ_USART10 (STM32_IRQ_FIRST + 168) /* 168: USART10 global interrupt */ +#define STM32_IRQ_LPUART1 (STM32_IRQ_FIRST + 169) /* 169: LPUART1 global interrupt */ +#define STM32_IRQ_XSPI1 (STM32_IRQ_FIRST + 170) /* 170: XSPI1 global interrupt */ +#define STM32_IRQ_XSPI2 (STM32_IRQ_FIRST + 171) /* 171: XSPI2 global interrupt */ +#define STM32_IRQ_XSPI3 (STM32_IRQ_FIRST + 172) /* 172: XSPI3 global interrupt */ +#define STM32_IRQ_FMC (STM32_IRQ_FIRST + 173) /* 173: FMC global interrupt */ +#define STM32_IRQ_SDMMC1 (STM32_IRQ_FIRST + 174) /* 174: SDMMC1 global interrupt */ +#define STM32_IRQ_SDMMC2 (STM32_IRQ_FIRST + 175) /* 175: SDMMC2 global interrupt */ +#define STM32_IRQ_UCPD1 (STM32_IRQ_FIRST + 176) /* 176: UCPD1 global interrupt */ +#define STM32_IRQ_USB1_OTG_HS (STM32_IRQ_FIRST + 177) /* 177: USB1 OTG HS interrupt */ +#define STM32_IRQ_USB2_OTG_HS (STM32_IRQ_FIRST + 178) /* 178: USB2 OTG HS interrupt */ +#define STM32_IRQ_ETH1 (STM32_IRQ_FIRST + 179) /* 179: ETH1 global interrupt */ +#define STM32_IRQ_FDCAN1_IT0 (STM32_IRQ_FIRST + 180) /* 180: FDCAN1 interrupt 0 */ +#define STM32_IRQ_FDCAN1_IT1 (STM32_IRQ_FIRST + 181) /* 181: FDCAN1 interrupt 1 */ +#define STM32_IRQ_FDCAN2_IT0 (STM32_IRQ_FIRST + 182) /* 182: FDCAN2 interrupt 0 */ +#define STM32_IRQ_FDCAN2_IT1 (STM32_IRQ_FIRST + 183) /* 183: FDCAN2 interrupt 1 */ +#define STM32_IRQ_FDCAN3_IT0 (STM32_IRQ_FIRST + 184) /* 184: FDCAN3 interrupt 0 */ +#define STM32_IRQ_FDCAN3_IT1 (STM32_IRQ_FIRST + 185) /* 185: FDCAN3 interrupt 1 */ +#define STM32_IRQ_FDCAN_CU (STM32_IRQ_FIRST + 186) /* 186: FDCAN Clock Unit interrupt */ +#define STM32_IRQ_MDIOS (STM32_IRQ_FIRST + 187) /* 187: MDIOS global interrupt */ +#define STM32_IRQ_DCMI_PSSI (STM32_IRQ_FIRST + 188) /* 188: DCMI/PSSI global interrupt */ +#define STM32_IRQ_WAKEUP_PIN (STM32_IRQ_FIRST + 189) /* 189: Wake-up pins interrupt */ +#define STM32_IRQ_CTI_INT0 (STM32_IRQ_FIRST + 190) /* 190: CTI INT0 interrupt */ +#define STM32_IRQ_CTI_INT1 (STM32_IRQ_FIRST + 191) /* 191: CTI INT1 interrupt */ +#define STM32_IRQ_LTDC_UP (STM32_IRQ_FIRST + 193) /* 193: LTDC up-layer global interrupt */ +#define STM32_IRQ_LTDC_UP_ERR (STM32_IRQ_FIRST + 194) /* 194: LTDC up-layer error interrupt */ + +/* Total number of external interrupts (0-194) */ + +#define STM32_IRQ_NEXTINTS 195 + +/* Total number of IRQ numbers */ + +#define NR_IRQS (STM32_IRQ_FIRST + STM32_IRQ_NEXTINTS) + +#endif /* __ARCH_ARM_INCLUDE_STM32N6_STM32N6XX_IRQ_H */ diff --git a/arch/arm/src/stm32n6/CMakeLists.txt b/arch/arm/src/stm32n6/CMakeLists.txt new file mode 100644 index 0000000000000..afb34a68903ba --- /dev/null +++ b/arch/arm/src/stm32n6/CMakeLists.txt @@ -0,0 +1,52 @@ +# ############################################################################## +# arch/arm/src/stm32n6/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +set(SRCS) + +# Required STM32N6 files + +list( + APPEND + SRCS + stm32_gpio.c + stm32_irq.c + stm32_lowputc.c + stm32_rcc.c + stm32_start.c + stm32_pwr.c + stm32_timerisr.c) + +if(NOT CONFIG_ARCH_IDLE_CUSTOM) + list(APPEND SRCS stm32_idle.c) +endif() + +if(CONFIG_STM32N6_USART) + list(APPEND SRCS stm32_serial.c) +endif() + +# Chip-specific RCC + +if(CONFIG_STM32N6_STM32N6XXXX) + list(APPEND SRCS stm32n6xx_rcc.c) +endif() + +target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/arm/src/stm32n6/Kconfig b/arch/arm/src/stm32n6/Kconfig new file mode 100644 index 0000000000000..2e362795f5c79 --- /dev/null +++ b/arch/arm/src/stm32n6/Kconfig @@ -0,0 +1,109 @@ +# arch/arm/src/stm32n6/Kconfig +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +if ARCH_CHIP_STM32N6 + +comment "STM32N6 Configuration Options" + +config STM32N6_STM32N6XXXX + bool + default y + +choice + prompt "STM32 N6 Chip Selection" + default ARCH_CHIP_STM32N657X0 + depends on ARCH_CHIP_STM32N6 + +config ARCH_CHIP_STM32N657X0 + bool "STM32N657X0" + select STM32N6_STM32N6XXXX + +endchoice + +menu "STM32N6 Peripheral Selection" + +config STM32N6_USART1 + bool "USART1" + default n + select STM32N6_USART + select USART1_SERIALDRIVER + select STM32N6_USART1_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS + +config STM32N6_USART1_SERIALDRIVER + bool + default n + +config STM32N6_USART + bool + +if STM32N6_USART + +config STM32N6_SERIAL_DISABLE_REORDERING + bool "Disable reordering of ttySx devices." + depends on STM32N6_USART1 + default n + ---help--- + NuttX per default reorders the serial ports (/dev/ttySx) so that the + console is always on /dev/ttyS0. If more than one UART is in use this + can, however, have the side-effect that all port mappings + (hardware USART1 -> /dev/ttyS0) change if the console is moved to + another UART. This option disables that reordering so port names + stay stable when the console is moved. + +config STM32N6_FLOWCONTROL_BROKEN + bool "Use Software UART RTS flow control" + default n + ---help--- + Enable this option to use software RTS flow control rather than + the hardware RTS line. Useful in cases where the silicon RTS + behaviour does not match the application's needs. + +config STM32N6_SERIALBRK_BSDCOMPAT + bool "Use GPIO to send Break" + default n + ---help--- + Enable this option to send break by reconfiguring TX as a GPIO + held low for the requested duration, matching BSD-compatible + semantics. + +config STM32N6_PM_SERIAL_ACTIVITY + int "PM serial activity" + default 10 + ---help--- + PM activity reported to power management logic on every serial + interrupt. + +endif # STM32N6_USART + +if USART1_SERIALDRIVER + +config USART1_UNCONFIG_RX_ON_CLOSE + bool "Unconfigure USART1 RX pin on close" + default n + +config USART1_UNCONFIG_TX_ON_CLOSE + bool "Unconfigure USART1 TX pin on close" + default n + +endif # USART1_SERIALDRIVER + +endmenu + +endif # ARCH_CHIP_STM32N6 diff --git a/arch/arm/src/stm32n6/Make.defs b/arch/arm/src/stm32n6/Make.defs new file mode 100644 index 0000000000000..cecd24bbf69b7 --- /dev/null +++ b/arch/arm/src/stm32n6/Make.defs @@ -0,0 +1,47 @@ +############################################################################## +# arch/arm/src/stm32n6/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################## + +# The start-up, "head", file. Only common vectors are supported so there +# isn't one. + +HEAD_ASRC = + +# Common ARM and Cortex-M55 files (ARMv8-M base) + +include armv8-m/Make.defs + +# Required STM32N6 files + +CHIP_CSRCS += stm32_gpio.c stm32_irq.c stm32_lowputc.c stm32_rcc.c +CHIP_CSRCS += stm32_start.c stm32_pwr.c stm32_timerisr.c + +ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) +CHIP_CSRCS += stm32_idle.c +endif + +ifeq ($(CONFIG_STM32N6_USART),y) +CHIP_CSRCS += stm32_serial.c +endif + +# Chip-specific RCC + +CHIP_CSRCS += stm32n6xx_rcc.c diff --git a/arch/arm/src/stm32n6/chip.h b/arch/arm/src/stm32n6/chip.h new file mode 100644 index 0000000000000..dfc5d91f4c6e1 --- /dev/null +++ b/arch/arm/src/stm32n6/chip.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/chip.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_CHIP_H +#define __ARCH_ARM_SRC_STM32N6_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Include the memory map and the chip definitions file. Other chip hardware + * files should then include this file for the proper setup. + */ + +#include +#include +#include "hardware/stm32n6xxx_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If the common ARMv8-M vector handling logic is used, then it expects the + * following definition in this file that provides the number of supported + * external interrupts which, for this architecture, is provided in the + * arch/stm32n6/chip.h header file. + */ + +#define ARMV8M_PERIPHERAL_INTERRUPTS STM32_IRQ_NEXTINTS + +/* Cache line sizes for Cortex-M55 (32 bytes). */ + +#define ARMV8M_ICACHE_LINESIZE 32 +#define ARMV8M_DCACHE_LINESIZE 32 + +#endif /* __ARCH_ARM_SRC_STM32N6_CHIP_H */ diff --git a/arch/arm/src/stm32n6/hardware/stm32n6xxx_gpio.h b/arch/arm/src/stm32n6/hardware/stm32n6xxx_gpio.h new file mode 100644 index 0000000000000..8e25b237c96cd --- /dev/null +++ b/arch/arm/src/stm32n6/hardware/stm32n6xxx_gpio.h @@ -0,0 +1,442 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/hardware/stm32n6xxx_gpio.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_GPIO_H +#define __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_GPIO_MODER_OFFSET 0x0000 /* GPIO port mode register */ +#define STM32_GPIO_OTYPER_OFFSET 0x0004 /* GPIO port output type register */ +#define STM32_GPIO_OSPEED_OFFSET 0x0008 /* GPIO port output speed register */ +#define STM32_GPIO_PUPDR_OFFSET 0x000c /* GPIO port pull-up/pull-down register */ +#define STM32_GPIO_IDR_OFFSET 0x0010 /* GPIO port input data register */ +#define STM32_GPIO_ODR_OFFSET 0x0014 /* GPIO port output data register */ +#define STM32_GPIO_BSRR_OFFSET 0x0018 /* GPIO port bit set/reset register */ +#define STM32_GPIO_LCKR_OFFSET 0x001c /* GPIO port configuration lock register */ +#define STM32_GPIO_AFRL_OFFSET 0x0020 /* GPIO alternate function low register */ +#define STM32_GPIO_AFRH_OFFSET 0x0024 /* GPIO alternate function high register */ +#define STM32_GPIO_BRR_OFFSET 0x0028 /* GPIO port bit reset register */ +#define STM32_GPIO_SECCFGR_OFFSET 0x0030 /* GPIO secure configuration register */ +#define STM32_GPIO_PRIVCFGR_OFFSET 0x0034 /* GPIO privilege configuration register */ +#define STM32_GPIO_RCFGLOCKR_OFFSET 0x0038 /* GPIO RIF configuration lock register */ + +/* Register Addresses *******************************************************/ + +/* GPIOA */ + +#define STM32_GPIOA_MODER (STM32_GPIOA_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOA_OTYPER (STM32_GPIOA_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOA_OSPEED (STM32_GPIOA_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOA_PUPDR (STM32_GPIOA_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOA_IDR (STM32_GPIOA_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOA_ODR (STM32_GPIOA_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOA_BSRR (STM32_GPIOA_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOA_LCKR (STM32_GPIOA_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOA_AFRL (STM32_GPIOA_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOA_AFRH (STM32_GPIOA_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOA_BRR (STM32_GPIOA_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOA_SECCFGR (STM32_GPIOA_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOB */ + +#define STM32_GPIOB_MODER (STM32_GPIOB_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOB_OTYPER (STM32_GPIOB_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOB_OSPEED (STM32_GPIOB_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOB_PUPDR (STM32_GPIOB_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOB_IDR (STM32_GPIOB_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOB_ODR (STM32_GPIOB_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOB_BSRR (STM32_GPIOB_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOB_LCKR (STM32_GPIOB_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOB_AFRL (STM32_GPIOB_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOB_AFRH (STM32_GPIOB_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOB_BRR (STM32_GPIOB_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOB_SECCFGR (STM32_GPIOB_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOC */ + +#define STM32_GPIOC_MODER (STM32_GPIOC_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOC_OTYPER (STM32_GPIOC_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOC_OSPEED (STM32_GPIOC_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOC_PUPDR (STM32_GPIOC_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOC_IDR (STM32_GPIOC_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOC_ODR (STM32_GPIOC_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOC_BSRR (STM32_GPIOC_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOC_LCKR (STM32_GPIOC_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOC_AFRL (STM32_GPIOC_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOC_AFRH (STM32_GPIOC_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOC_BRR (STM32_GPIOC_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOC_SECCFGR (STM32_GPIOC_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOD */ + +#define STM32_GPIOD_MODER (STM32_GPIOD_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOD_OTYPER (STM32_GPIOD_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOD_OSPEED (STM32_GPIOD_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOD_PUPDR (STM32_GPIOD_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOD_IDR (STM32_GPIOD_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOD_ODR (STM32_GPIOD_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOD_BSRR (STM32_GPIOD_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOD_LCKR (STM32_GPIOD_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOD_AFRL (STM32_GPIOD_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOD_AFRH (STM32_GPIOD_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOD_BRR (STM32_GPIOD_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOD_SECCFGR (STM32_GPIOD_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOE */ + +#define STM32_GPIOE_MODER (STM32_GPIOE_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOE_OTYPER (STM32_GPIOE_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOE_OSPEED (STM32_GPIOE_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOE_PUPDR (STM32_GPIOE_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOE_IDR (STM32_GPIOE_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOE_ODR (STM32_GPIOE_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOE_BSRR (STM32_GPIOE_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOE_LCKR (STM32_GPIOE_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOE_AFRL (STM32_GPIOE_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOE_AFRH (STM32_GPIOE_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOE_BRR (STM32_GPIOE_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOE_SECCFGR (STM32_GPIOE_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOF */ + +#define STM32_GPIOF_MODER (STM32_GPIOF_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOF_OTYPER (STM32_GPIOF_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOF_OSPEED (STM32_GPIOF_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOF_PUPDR (STM32_GPIOF_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOF_IDR (STM32_GPIOF_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOF_ODR (STM32_GPIOF_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOF_BSRR (STM32_GPIOF_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOF_LCKR (STM32_GPIOF_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOF_AFRL (STM32_GPIOF_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOF_AFRH (STM32_GPIOF_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOF_BRR (STM32_GPIOF_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOF_SECCFGR (STM32_GPIOF_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOG */ + +#define STM32_GPIOG_MODER (STM32_GPIOG_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOG_OTYPER (STM32_GPIOG_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOG_OSPEED (STM32_GPIOG_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOG_PUPDR (STM32_GPIOG_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOG_IDR (STM32_GPIOG_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOG_ODR (STM32_GPIOG_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOG_BSRR (STM32_GPIOG_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOG_LCKR (STM32_GPIOG_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOG_AFRL (STM32_GPIOG_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOG_AFRH (STM32_GPIOG_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOG_BRR (STM32_GPIOG_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOG_SECCFGR (STM32_GPIOG_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOH */ + +#define STM32_GPIOH_MODER (STM32_GPIOH_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOH_OTYPER (STM32_GPIOH_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOH_OSPEED (STM32_GPIOH_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOH_PUPDR (STM32_GPIOH_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOH_IDR (STM32_GPIOH_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOH_ODR (STM32_GPIOH_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOH_BSRR (STM32_GPIOH_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOH_LCKR (STM32_GPIOH_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOH_AFRL (STM32_GPIOH_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOH_AFRH (STM32_GPIOH_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOH_BRR (STM32_GPIOH_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOH_SECCFGR (STM32_GPIOH_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPION */ + +#define STM32_GPION_MODER (STM32_GPION_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPION_OTYPER (STM32_GPION_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPION_OSPEED (STM32_GPION_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPION_PUPDR (STM32_GPION_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPION_IDR (STM32_GPION_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPION_ODR (STM32_GPION_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPION_BSRR (STM32_GPION_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPION_LCKR (STM32_GPION_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPION_AFRL (STM32_GPION_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPION_AFRH (STM32_GPION_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPION_BRR (STM32_GPION_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPION_SECCFGR (STM32_GPION_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOO */ + +#define STM32_GPIOO_MODER (STM32_GPIOO_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOO_OTYPER (STM32_GPIOO_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOO_OSPEED (STM32_GPIOO_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOO_PUPDR (STM32_GPIOO_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOO_IDR (STM32_GPIOO_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOO_ODR (STM32_GPIOO_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOO_BSRR (STM32_GPIOO_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOO_LCKR (STM32_GPIOO_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOO_AFRL (STM32_GPIOO_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOO_AFRH (STM32_GPIOO_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOO_BRR (STM32_GPIOO_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOO_SECCFGR (STM32_GPIOO_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOP */ + +#define STM32_GPIOP_MODER (STM32_GPIOP_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOP_OTYPER (STM32_GPIOP_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOP_OSPEED (STM32_GPIOP_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOP_PUPDR (STM32_GPIOP_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOP_IDR (STM32_GPIOP_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOP_ODR (STM32_GPIOP_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOP_BSRR (STM32_GPIOP_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOP_LCKR (STM32_GPIOP_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOP_AFRL (STM32_GPIOP_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOP_AFRH (STM32_GPIOP_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOP_BRR (STM32_GPIOP_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOP_SECCFGR (STM32_GPIOP_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* GPIOQ */ + +#define STM32_GPIOQ_MODER (STM32_GPIOQ_BASE + STM32_GPIO_MODER_OFFSET) +#define STM32_GPIOQ_OTYPER (STM32_GPIOQ_BASE + STM32_GPIO_OTYPER_OFFSET) +#define STM32_GPIOQ_OSPEED (STM32_GPIOQ_BASE + STM32_GPIO_OSPEED_OFFSET) +#define STM32_GPIOQ_PUPDR (STM32_GPIOQ_BASE + STM32_GPIO_PUPDR_OFFSET) +#define STM32_GPIOQ_IDR (STM32_GPIOQ_BASE + STM32_GPIO_IDR_OFFSET) +#define STM32_GPIOQ_ODR (STM32_GPIOQ_BASE + STM32_GPIO_ODR_OFFSET) +#define STM32_GPIOQ_BSRR (STM32_GPIOQ_BASE + STM32_GPIO_BSRR_OFFSET) +#define STM32_GPIOQ_LCKR (STM32_GPIOQ_BASE + STM32_GPIO_LCKR_OFFSET) +#define STM32_GPIOQ_AFRL (STM32_GPIOQ_BASE + STM32_GPIO_AFRL_OFFSET) +#define STM32_GPIOQ_AFRH (STM32_GPIOQ_BASE + STM32_GPIO_AFRH_OFFSET) +#define STM32_GPIOQ_BRR (STM32_GPIOQ_BASE + STM32_GPIO_BRR_OFFSET) +#define STM32_GPIOQ_SECCFGR (STM32_GPIOQ_BASE + STM32_GPIO_SECCFGR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* GPIO port mode register */ + +#define GPIO_MODER_INPUT (0) /* Input */ +#define GPIO_MODER_OUTPUT (1) /* General purpose output mode */ +#define GPIO_MODER_ALT (2) /* Alternate mode */ +#define GPIO_MODER_ANALOG (3) /* Analog mode */ + +#define GPIO_MODER_SHIFT(n) ((n) << 1) +#define GPIO_MODER_MASK(n) (3 << GPIO_MODER_SHIFT(n)) + +#define GPIO_MODER0_SHIFT (0) +#define GPIO_MODER0_MASK (3 << GPIO_MODER0_SHIFT) +#define GPIO_MODER1_SHIFT (2) +#define GPIO_MODER1_MASK (3 << GPIO_MODER1_SHIFT) +#define GPIO_MODER2_SHIFT (4) +#define GPIO_MODER2_MASK (3 << GPIO_MODER2_SHIFT) +#define GPIO_MODER3_SHIFT (6) +#define GPIO_MODER3_MASK (3 << GPIO_MODER3_SHIFT) +#define GPIO_MODER4_SHIFT (8) +#define GPIO_MODER4_MASK (3 << GPIO_MODER4_SHIFT) +#define GPIO_MODER5_SHIFT (10) +#define GPIO_MODER5_MASK (3 << GPIO_MODER5_SHIFT) +#define GPIO_MODER6_SHIFT (12) +#define GPIO_MODER6_MASK (3 << GPIO_MODER6_SHIFT) +#define GPIO_MODER7_SHIFT (14) +#define GPIO_MODER7_MASK (3 << GPIO_MODER7_SHIFT) +#define GPIO_MODER8_SHIFT (16) +#define GPIO_MODER8_MASK (3 << GPIO_MODER8_SHIFT) +#define GPIO_MODER9_SHIFT (18) +#define GPIO_MODER9_MASK (3 << GPIO_MODER9_SHIFT) +#define GPIO_MODER10_SHIFT (20) +#define GPIO_MODER10_MASK (3 << GPIO_MODER10_SHIFT) +#define GPIO_MODER11_SHIFT (22) +#define GPIO_MODER11_MASK (3 << GPIO_MODER11_SHIFT) +#define GPIO_MODER12_SHIFT (24) +#define GPIO_MODER12_MASK (3 << GPIO_MODER12_SHIFT) +#define GPIO_MODER13_SHIFT (26) +#define GPIO_MODER13_MASK (3 << GPIO_MODER13_SHIFT) +#define GPIO_MODER14_SHIFT (28) +#define GPIO_MODER14_MASK (3 << GPIO_MODER14_SHIFT) +#define GPIO_MODER15_SHIFT (30) +#define GPIO_MODER15_MASK (3 << GPIO_MODER15_SHIFT) + +/* GPIO port output type register */ + +#define GPIO_OTYPER_OD(n) (1 << (n)) /* 1=Output open-drain */ +#define GPIO_OTYPER_PP(n) (0) /* 0=Output push-pull */ + +/* GPIO port output speed register */ + +#define GPIO_OSPEED_2MHZ (0) /* 2 MHz Low speed */ +#define GPIO_OSPEED_25MHZ (1) /* 25 MHz Medium speed */ +#define GPIO_OSPEED_50MHZ (2) /* 50 MHz High speed */ +#define GPIO_OSPEED_100MHZ (3) /* 100 MHz Very High speed on 30 pF (80 MHz Output max speed on 15 pF) */ + +#define GPIO_OSPEED_SHIFT(n) ((n) << 1) +#define GPIO_OSPEED_MASK(n) (3 << GPIO_OSPEED_SHIFT(n)) + +#define GPIO_OSPEED0_SHIFT (0) +#define GPIO_OSPEED0_MASK (3 << GPIO_OSPEED0_SHIFT) +#define GPIO_OSPEED1_SHIFT (2) +#define GPIO_OSPEED1_MASK (3 << GPIO_OSPEED1_SHIFT) +#define GPIO_OSPEED2_SHIFT (4) +#define GPIO_OSPEED2_MASK (3 << GPIO_OSPEED2_SHIFT) +#define GPIO_OSPEED3_SHIFT (6) +#define GPIO_OSPEED3_MASK (3 << GPIO_OSPEED3_SHIFT) +#define GPIO_OSPEED4_SHIFT (8) +#define GPIO_OSPEED4_MASK (3 << GPIO_OSPEED4_SHIFT) +#define GPIO_OSPEED5_SHIFT (10) +#define GPIO_OSPEED5_MASK (3 << GPIO_OSPEED5_SHIFT) +#define GPIO_OSPEED6_SHIFT (12) +#define GPIO_OSPEED6_MASK (3 << GPIO_OSPEED6_SHIFT) +#define GPIO_OSPEED7_SHIFT (14) +#define GPIO_OSPEED7_MASK (3 << GPIO_OSPEED7_SHIFT) +#define GPIO_OSPEED8_SHIFT (16) +#define GPIO_OSPEED8_MASK (3 << GPIO_OSPEED8_SHIFT) +#define GPIO_OSPEED9_SHIFT (18) +#define GPIO_OSPEED9_MASK (3 << GPIO_OSPEED9_SHIFT) +#define GPIO_OSPEED10_SHIFT (20) +#define GPIO_OSPEED10_MASK (3 << GPIO_OSPEED10_SHIFT) +#define GPIO_OSPEED11_SHIFT (22) +#define GPIO_OSPEED11_MASK (3 << GPIO_OSPEED11_SHIFT) +#define GPIO_OSPEED12_SHIFT (24) +#define GPIO_OSPEED12_MASK (3 << GPIO_OSPEED12_SHIFT) +#define GPIO_OSPEED13_SHIFT (26) +#define GPIO_OSPEED13_MASK (3 << GPIO_OSPEED13_SHIFT) +#define GPIO_OSPEED14_SHIFT (28) +#define GPIO_OSPEED14_MASK (3 << GPIO_OSPEED14_SHIFT) +#define GPIO_OSPEED15_SHIFT (30) +#define GPIO_OSPEED15_MASK (3 << GPIO_OSPEED15_SHIFT) + +/* GPIO port pull-up/pull-down register */ + +#define GPIO_PUPDR_NONE (0) /* No pull-up, pull-down */ +#define GPIO_PUPDR_PULLUP (1) /* Pull-up */ +#define GPIO_PUPDR_PULLDOWN (2) /* Pull-down */ + +#define GPIO_PUPDR_SHIFT(n) ((n) << 1) +#define GPIO_PUPDR_MASK(n) (3 << GPIO_PUPDR_SHIFT(n)) + +#define GPIO_PUPDR0_SHIFT (0) +#define GPIO_PUPDR0_MASK (3 << GPIO_PUPDR0_SHIFT) +#define GPIO_PUPDR1_SHIFT (2) +#define GPIO_PUPDR1_MASK (3 << GPIO_PUPDR1_SHIFT) +#define GPIO_PUPDR2_SHIFT (4) +#define GPIO_PUPDR2_MASK (3 << GPIO_PUPDR2_SHIFT) +#define GPIO_PUPDR3_SHIFT (6) +#define GPIO_PUPDR3_MASK (3 << GPIO_PUPDR3_SHIFT) +#define GPIO_PUPDR4_SHIFT (8) +#define GPIO_PUPDR4_MASK (3 << GPIO_PUPDR4_SHIFT) +#define GPIO_PUPDR5_SHIFT (10) +#define GPIO_PUPDR5_MASK (3 << GPIO_PUPDR5_SHIFT) +#define GPIO_PUPDR6_SHIFT (12) +#define GPIO_PUPDR6_MASK (3 << GPIO_PUPDR6_SHIFT) +#define GPIO_PUPDR7_SHIFT (14) +#define GPIO_PUPDR7_MASK (3 << GPIO_PUPDR7_SHIFT) +#define GPIO_PUPDR8_SHIFT (16) +#define GPIO_PUPDR8_MASK (3 << GPIO_PUPDR8_SHIFT) +#define GPIO_PUPDR9_SHIFT (18) +#define GPIO_PUPDR9_MASK (3 << GPIO_PUPDR9_SHIFT) +#define GPIO_PUPDR10_SHIFT (20) +#define GPIO_PUPDR10_MASK (3 << GPIO_PUPDR10_SHIFT) +#define GPIO_PUPDR11_SHIFT (22) +#define GPIO_PUPDR11_MASK (3 << GPIO_PUPDR11_SHIFT) +#define GPIO_PUPDR12_SHIFT (24) +#define GPIO_PUPDR12_MASK (3 << GPIO_PUPDR12_SHIFT) +#define GPIO_PUPDR13_SHIFT (26) +#define GPIO_PUPDR13_MASK (3 << GPIO_PUPDR13_SHIFT) +#define GPIO_PUPDR14_SHIFT (28) +#define GPIO_PUPDR14_MASK (3 << GPIO_PUPDR14_SHIFT) +#define GPIO_PUPDR15_SHIFT (30) +#define GPIO_PUPDR15_MASK (3 << GPIO_PUPDR15_SHIFT) + +/* GPIO port input data register */ + +#define GPIO_IDR(n) (1 << (n)) + +/* GPIO port output data register */ + +#define GPIO_ODR(n) (1 << (n)) + +/* GPIO port bit set/reset register */ + +#define GPIO_BSRR_SET(n) (1 << (n)) +#define GPIO_BSRR_RESET(n) (1 << ((n)+16)) + +/* GPIO port configuration lock register */ + +#define GPIO_LCKR(n) (1 << (n)) +#define GPIO_LCKK (1 << 16) /* Lock key */ + +/* GPIO alternate function low/high register */ + +#define GPIO_AFR_SHIFT(n) ((n) << 2) +#define GPIO_AFR_MASK(n) (15 << GPIO_AFR_SHIFT(n)) + +#define GPIO_AFRL0_SHIFT (0) +#define GPIO_AFRL0_MASK (15 << GPIO_AFRL0_SHIFT) +#define GPIO_AFRL1_SHIFT (4) +#define GPIO_AFRL1_MASK (15 << GPIO_AFRL1_SHIFT) +#define GPIO_AFRL2_SHIFT (8) +#define GPIO_AFRL2_MASK (15 << GPIO_AFRL2_SHIFT) +#define GPIO_AFRL3_SHIFT (12) +#define GPIO_AFRL3_MASK (15 << GPIO_AFRL3_SHIFT) +#define GPIO_AFRL4_SHIFT (16) +#define GPIO_AFRL4_MASK (15 << GPIO_AFRL4_SHIFT) +#define GPIO_AFRL5_SHIFT (20) +#define GPIO_AFRL5_MASK (15 << GPIO_AFRL5_SHIFT) +#define GPIO_AFRL6_SHIFT (24) +#define GPIO_AFRL6_MASK (15 << GPIO_AFRL6_SHIFT) +#define GPIO_AFRL7_SHIFT (28) +#define GPIO_AFRL7_MASK (15 << GPIO_AFRL7_SHIFT) + +#define GPIO_AFRH8_SHIFT (0) +#define GPIO_AFRH8_MASK (15 << GPIO_AFRH8_SHIFT) +#define GPIO_AFRH9_SHIFT (4) +#define GPIO_AFRH9_MASK (15 << GPIO_AFRH9_SHIFT) +#define GPIO_AFRH10_SHIFT (8) +#define GPIO_AFRH10_MASK (15 << GPIO_AFRH10_SHIFT) +#define GPIO_AFRH11_SHIFT (12) +#define GPIO_AFRH11_MASK (15 << GPIO_AFRH11_SHIFT) +#define GPIO_AFRH12_SHIFT (16) +#define GPIO_AFRH12_MASK (15 << GPIO_AFRH12_SHIFT) +#define GPIO_AFRH13_SHIFT (20) +#define GPIO_AFRH13_MASK (15 << GPIO_AFRH13_SHIFT) +#define GPIO_AFRH14_SHIFT (24) +#define GPIO_AFRH14_MASK (15 << GPIO_AFRH14_SHIFT) +#define GPIO_AFRH15_SHIFT (28) +#define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT) + +/* GPIO port bit reset register */ + +#define GPIO_BRR_SET(n) (1 << (n)) + +/* GPIO port secure configuration register + * + * Note: STM32N6 has no per-port HSLVR register (offset 0x2C is reserved). + * High-speed low-voltage selection is controlled via PWR_SVMCRn VRSEL + * bits and the HSLV_VDDIOx OTP option bits. + */ + +#define GPIO_SECCFGR_SET(n) (1 << (n)) +#define GPIO_PRIVCFGR_SET(n) (1 << (n)) +#define GPIO_RCFGLOCKR_SET(n) (1 << (n)) + +#endif /* __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_GPIO_H */ diff --git a/arch/arm/src/stm32n6/hardware/stm32n6xxx_memorymap.h b/arch/arm/src/stm32n6/hardware/stm32n6xxx_memorymap.h new file mode 100644 index 0000000000000..2911e9d02abff --- /dev/null +++ b/arch/arm/src/stm32n6/hardware/stm32n6xxx_memorymap.h @@ -0,0 +1,173 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/hardware/stm32n6xxx_memorymap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_MEMORYMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* STM32N6XXX Address Blocks ************************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_SRAM_BASE 0x34000000 /* 0x34000000: SRAM (no internal flash) */ +#define STM32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ +#define STM32_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M55 block */ + +#define STM32_REGION_MASK 0xf0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == 0x30000000) + +/* SRAM Addresses ***********************************************************/ + +#define STM32_SRAM1_BASE 0x34000000 /* SRAM1 base */ +#define STM32_SRAM2_BASE 0x34100000 /* SRAM2 base */ + +/* External Memory **********************************************************/ + +#define STM32_XSPI1_BANK 0x90000000 /* XSPI1 memory-mapped region */ +#define STM32_XSPI2_BANK 0x70000000 /* XSPI2 memory-mapped region */ + +/* Peripheral Base Addresses ************************************************ + * + * Each peripheral is physically aliased twice: a Non-Secure alias at + * 0x4xxxxxxx and a Secure alias at 0x5xxxxxxx (RM0486 section 3.5.1). + * The same hardware register is reached through either alias. + * + * In DEV boot mode the CPU runs in Secure state with SAU disabled and + * SAU_CTRL.ALLNS=0, so the SAU unilaterally marks every address as + * Secure regardless of which alias is used; both aliases therefore work + * for register access from this port. + * + * We pick the Secure aliases consistently to match the register listings + * in the Reference Manual and to leave the Non-Secure aliases free for a + * future Non-Secure world. + * + * Secure alias = Non-Secure alias + 0x10000000 + */ + +#define STM32_APB1_BASE 0x50000000 /* APB1 (Secure) */ +#define STM32_APB2_BASE 0x52000000 /* APB2 (Secure) */ +#define STM32_APB4_BASE 0x56000000 /* APB4 (Secure) */ +#define STM32_APB5_BASE 0x58000000 /* APB5 (Secure) - LTDC/DCMIPP/CSI2/GFXTIM/VENC */ +#define STM32_AHB4_BASE 0x56020000 /* AHB4 (Secure) */ + +/* APB1 peripherals *********************************************************/ + +#define STM32_TIM2_BASE 0x50000000 +#define STM32_TIM3_BASE 0x50000400 +#define STM32_TIM4_BASE 0x50000800 +#define STM32_TIM5_BASE 0x50000c00 +#define STM32_TIM6_BASE 0x50001000 +#define STM32_TIM7_BASE 0x50001400 +#define STM32_LPTIM1_BASE 0x50002400 +#define STM32_SPI2_BASE 0x50003800 +#define STM32_SPI3_BASE 0x50003c00 +#define STM32_USART2_BASE 0x50004400 +#define STM32_USART3_BASE 0x50004800 +#define STM32_UART4_BASE 0x50004c00 +#define STM32_UART5_BASE 0x50005000 +#define STM32_I2C1_BASE 0x50005400 +#define STM32_I2C2_BASE 0x50005800 +#define STM32_I2C3_BASE 0x50005c00 + +/* APB2 peripherals *********************************************************/ + +#define STM32_TIM1_BASE 0x52000000 +#define STM32_TIM8_BASE 0x52000400 +#define STM32_USART1_BASE 0x52001000 +#define STM32_SPI1_BASE 0x52003000 +#define STM32_SPI4_BASE 0x52003400 +#define STM32_TIM15_BASE 0x52004000 +#define STM32_TIM16_BASE 0x52004400 +#define STM32_TIM17_BASE 0x52004800 +#define STM32_SPI5_BASE 0x52005000 + +/* APB4 peripherals *********************************************************/ + +#define STM32_SPI6_BASE 0x56001400 +#define STM32_I2C4_BASE 0x56001c00 +#define STM32_LPTIM2_BASE 0x56002400 +#define STM32_LPTIM3_BASE 0x56002800 +#define STM32_LPTIM4_BASE 0x56002c00 +#define STM32_LPTIM5_BASE 0x56003000 + +/* APB4 peripherals (RTC on APB4 + 0x4000) **********************************/ + +#define STM32_RTC_BASE 0x56004000 +#define STM32_TAMP_BASE 0x56004400 +#define STM32_IWDG_BASE 0x56004800 +#define STM32_BSEC_BASE 0x56009000 +#define STM32_DTS_BASE 0x5600a000 + +/* AHB4 peripherals *********************************************************/ + +#define STM32_GPIOA_BASE 0x56020000 +#define STM32_GPIOB_BASE 0x56020400 +#define STM32_GPIOC_BASE 0x56020800 +#define STM32_GPIOD_BASE 0x56020c00 +#define STM32_GPIOE_BASE 0x56021000 +#define STM32_GPIOF_BASE 0x56021400 +#define STM32_GPIOG_BASE 0x56021800 +#define STM32_GPIOH_BASE 0x56021c00 +#define STM32_GPION_BASE 0x56023400 +#define STM32_GPIOO_BASE 0x56023800 +#define STM32_GPIOP_BASE 0x56023c00 +#define STM32_GPIOQ_BASE 0x56024000 + +#define STM32_CRC_BASE 0x56024c00 +#define STM32_PWR_BASE 0x56024800 +#define STM32_EXTI_BASE 0x56025000 +#define STM32_RCC_BASE 0x56028000 + +/* AHB1 peripherals *********************************************************/ + +#define STM32_GPDMA1_BASE 0x50021000 /* GPDMA1 (AHB1, Secure) */ +#define STM32_ADC1_BASE 0x50022000 /* ADC1 (AHB1, Secure) */ +#define STM32_ADC2_BASE 0x50022100 /* ADC2 (AHB1, Secure) */ +#define STM32_ADC12_COMMON_BASE 0x50022300 /* ADC1/2 common (AHB1, Secure) */ + +/* AHB3 peripherals *********************************************************/ + +#define STM32_RNG_BASE 0x54020000 /* RNG (AHB3, Secure) */ +#define STM32_RIFSC_BASE 0x54024000 /* RIFSC (AHB3, Secure) */ + +/* AHB2 peripherals *********************************************************/ + +#define STM32_RAMCFG_BASE 0x52023000 /* RAMCFG (AHB2, Secure) */ + +/* AHB5 peripherals *********************************************************/ + +#define STM32_AHB5_BASE 0x58020000 /* AHB5 (Secure) */ +#define STM32_HPDMA1_BASE 0x58020000 /* HPDMA1 (AHB5, Secure) */ +#define STM32_XSPI2_BASE 0x5802A000 /* XSPI2 controller (AHB5, Secure) */ +#define STM32_XSPIM_BASE 0x5802B400 /* XSPIM IO Manager (AHB5, Secure) */ +#define STM32_USB1_HS_PHYC_BASE 0x5803FC00 /* USB1 HS PHY controller (Secure) */ +#define STM32_USB1_OTG_HS_BASE 0x58040000 /* USB1 OTG HS (Secure) */ +#define STM32_USB2_OTG_HS_BASE 0x58080000 /* USB2 OTG HS (Secure) */ +#define STM32_USB2_HS_PHYC_BASE 0x580C0000 /* USB2 HS PHY controller (Secure) */ + +/* SYSCFG *******************************************************************/ + +#define STM32_SYSCFG_BASE 0x56008000 /* SYSCFG (Secure) */ + +#endif /* __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_MEMORYMAP_H */ diff --git a/arch/arm/src/stm32n6/hardware/stm32n6xxx_pinmap.h b/arch/arm/src/stm32n6/hardware/stm32n6xxx_pinmap.h new file mode 100644 index 0000000000000..38ef5adc5a63d --- /dev/null +++ b/arch/arm/src/stm32n6/hardware/stm32n6xxx_pinmap.h @@ -0,0 +1,54 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/hardware/stm32n6xxx_pinmap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_PINMAP_H +#define __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_PINMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, + * etc. Drivers, however, will use the pin selection without the numeric + * suffix. Additional definitions are required in the board.h file. For + * example, if USART1_TX connects via PE5 on some board, then the following + * definition should appear in the board.h header file for that board: + * + * #define GPIO_USART1_TX GPIO_USART1_TX_1 + * + * The driver will then automatically configure PE5 as the USART1 TX pin. + */ + +/* USART1: PE5=TX (AF7), PE6=RX (AF7) - ST-Link Virtual COM Port */ + +#define GPIO_USART1_TX_1 (GPIO_ALT | GPIO_AF7 | GPIO_SPEED_50MHZ | GPIO_PUSHPULL | GPIO_PORTE | GPIO_PIN5) +#define GPIO_USART1_RX_1 (GPIO_ALT | GPIO_AF7 | GPIO_SPEED_50MHZ | GPIO_PORTE | GPIO_PIN6) + +#endif /* __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_PINMAP_H */ diff --git a/arch/arm/src/stm32n6/hardware/stm32n6xxx_pwr.h b/arch/arm/src/stm32n6/hardware/stm32n6xxx_pwr.h new file mode 100644 index 0000000000000..2c6f480a6a820 --- /dev/null +++ b/arch/arm/src/stm32n6/hardware/stm32n6xxx_pwr.h @@ -0,0 +1,112 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/hardware/stm32n6xxx_pwr.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_PWR_H +#define __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_PWR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_PWR_CR1_OFFSET 0x0000 /* Power control register 1 */ +#define STM32_PWR_CR2_OFFSET 0x0004 /* Power control register 2 */ +#define STM32_PWR_CR3_OFFSET 0x0008 /* Power control register 3 */ +#define STM32_PWR_CR4_OFFSET 0x000c /* Power control register 4 */ +#define STM32_PWR_VOSCR_OFFSET 0x0020 /* Voltage scaling control register */ +#define STM32_PWR_BDCR1_OFFSET 0x0024 /* Backup domain control register 1 */ +#define STM32_PWR_BDCR2_OFFSET 0x0028 /* Backup domain control register 2 */ +#define STM32_PWR_DBPCR_OFFSET 0x002c /* Debug backup domain protection control register */ +#define STM32_PWR_CPUCR_OFFSET 0x0030 /* CPU power control register */ +#define STM32_PWR_SVMCR1_OFFSET 0x0034 /* Supply voltage monitoring control register 1 */ +#define STM32_PWR_SVMCR2_OFFSET 0x0038 /* Supply voltage monitoring control register 2 */ +#define STM32_PWR_SVMCR3_OFFSET 0x003c /* Supply voltage monitoring control register 3 */ +#define STM32_PWR_PRIVCFGR_OFFSET 0x0104 /* Privilege configuration register */ +#define STM32_PWR_SECCFGR_OFFSET 0x0100 /* Secure configuration register */ + +/* Register Addresses *******************************************************/ + +#define STM32_PWR_CR1 (STM32_PWR_BASE + STM32_PWR_CR1_OFFSET) +#define STM32_PWR_CR2 (STM32_PWR_BASE + STM32_PWR_CR2_OFFSET) +#define STM32_PWR_CR3 (STM32_PWR_BASE + STM32_PWR_CR3_OFFSET) +#define STM32_PWR_CR4 (STM32_PWR_BASE + STM32_PWR_CR4_OFFSET) +#define STM32_PWR_VOSCR (STM32_PWR_BASE + STM32_PWR_VOSCR_OFFSET) +#define STM32_PWR_BDCR1 (STM32_PWR_BASE + STM32_PWR_BDCR1_OFFSET) +#define STM32_PWR_BDCR2 (STM32_PWR_BASE + STM32_PWR_BDCR2_OFFSET) +#define STM32_PWR_DBPCR (STM32_PWR_BASE + STM32_PWR_DBPCR_OFFSET) +#define STM32_PWR_CPUCR (STM32_PWR_BASE + STM32_PWR_CPUCR_OFFSET) +#define STM32_PWR_SVMCR1 (STM32_PWR_BASE + STM32_PWR_SVMCR1_OFFSET) +#define STM32_PWR_SVMCR2 (STM32_PWR_BASE + STM32_PWR_SVMCR2_OFFSET) +#define STM32_PWR_SVMCR3 (STM32_PWR_BASE + STM32_PWR_SVMCR3_OFFSET) +#define STM32_PWR_PRIVCFGR (STM32_PWR_BASE + STM32_PWR_PRIVCFGR_OFFSET) +#define STM32_PWR_SECCFGR (STM32_PWR_BASE + STM32_PWR_SECCFGR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Debug Backup Domain Protection Control Register (PWR_DBPCR) */ + +#define PWR_DBPCR_DBP (1 << 0) /* Bit 0: Disable backup domain write protection */ + +/* Voltage Scaling Control Register (PWR_VOSCR) + * + * STM32N6 has a single-bit VOS field selecting between low (0) and high (1) + * voltage scaling. VOSRDY/ACTVOS status flags live in the same register. + */ + +#define PWR_VOSCR_VOS (1 << 0) /* Bit 0: Voltage scaling 0=low, 1=high */ +#define PWR_VOSCR_VOSRDY (1 << 1) /* Bit 1: VOS Ready */ +#define PWR_VOSCR_ACTVOS (1 << 16) /* Bit 16: Active VOS (read-back) */ +#define PWR_VOSCR_ACTVOSRDY (1 << 17) /* Bit 17: Active VOS ready */ + +/* CPU Power Control Register (PWR_CPUCR) */ + +#define PWR_CPUCR_PDDS (1 << 0) /* Bit 0: Power down deepsleep for CPU */ +#define PWR_CPUCR_STOPF (1 << 8) /* Bit 8: STOP flag */ +#define PWR_CPUCR_SBF (1 << 9) /* Bit 9: Standby flag */ +#define PWR_CPUCR_SVOS_SHIFT (16) /* Bits 16-17: System voltage scaling in stop */ +#define PWR_CPUCR_SVOS_MASK (3 << PWR_CPUCR_SVOS_SHIFT) + +/* Supply Voltage Monitoring Control Register 1 (PWR_SVMCR1) - VddIO4 */ + +#define PWR_SVMCR1_VDDIO4SV (1 << 8) /* Bit 8: VddIO4 supply valid */ +#define PWR_SVMCR1_VDDIO4VRSEL (1 << 16) /* Bit 16: VddIO4 high-speed low-voltage */ + +/* Supply Voltage Monitoring Control Register 2 (PWR_SVMCR2) - VddIO5 */ + +#define PWR_SVMCR2_VDDIO5SV (1 << 8) /* Bit 8: VddIO5 supply valid */ +#define PWR_SVMCR2_VDDIO5VRSEL (1 << 16) /* Bit 16: VddIO5 high-speed low-voltage */ + +/* Supply Voltage Monitoring Control Register 3 (PWR_SVMCR3) - VddIO2/3 */ + +#define PWR_SVMCR3_VDDIO2SV (1 << 8) /* Bit 8: VddIO2 supply valid */ +#define PWR_SVMCR3_VDDIO3SV (1 << 9) /* Bit 9: VddIO3 supply valid */ +#define PWR_SVMCR3_VDDIO2VRSEL (1 << 16) /* Bit 16: VddIO2 high-speed low-voltage */ +#define PWR_SVMCR3_VDDIO3VRSEL (1 << 17) /* Bit 17: VddIO3 high-speed low-voltage */ + +#endif /* __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_PWR_H */ diff --git a/arch/arm/src/stm32n6/hardware/stm32n6xxx_rcc.h b/arch/arm/src/stm32n6/hardware/stm32n6xxx_rcc.h new file mode 100644 index 0000000000000..824af5f379ddc --- /dev/null +++ b/arch/arm/src/stm32n6/hardware/stm32n6xxx_rcc.h @@ -0,0 +1,288 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/hardware/stm32n6xxx_rcc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_RCC_H +#define __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_RCC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/stm32n6xxx_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32_RCC_SR_OFFSET 0x0004 /* Clock status register */ +#define STM32_RCC_CFGR1_OFFSET 0x0020 /* Clock configuration register 1 */ +#define STM32_RCC_CFGR2_OFFSET 0x0024 /* Clock configuration register 2 */ +#define STM32_RCC_PLL1CFGR1_OFFSET 0x0080 /* PLL1 configuration register 1 */ +#define STM32_RCC_PLL1CFGR3_OFFSET 0x0088 /* PLL1 configuration register 3 */ +#define STM32_RCC_IC1CFGR_OFFSET 0x00c4 /* IC1 configuration register */ +#define STM32_RCC_IC2CFGR_OFFSET 0x00c8 /* IC2 configuration register */ +#define STM32_RCC_IC3CFGR_OFFSET 0x00cc /* IC3 configuration register */ +#define STM32_RCC_IC6CFGR_OFFSET 0x00d8 /* IC6 configuration register */ +#define STM32_RCC_IC11CFGR_OFFSET 0x00ec /* IC11 configuration register */ +#define STM32_RCC_CCIPR13_OFFSET 0x0174 /* Peripheral kernel clock select register 13 */ + +/* Peripheral clock enable / set / clear register offsets. Each enable + * register (xxxENR) has a paired set register (xxxENSR) that performs an + * atomic OR and a clear register (xxxENCR) that performs an atomic AND + * (Reference: RM0486 14.5). The same triplet pattern applies to the LPENR + * (sleep mode) registers. + */ + +#define STM32_RCC_MEMENR_OFFSET 0x024c /* AXI/AHB SRAM clock enable register */ +#define STM32_RCC_AHB4ENR_OFFSET 0x025c /* AHB4 peripheral clock enable register */ +#define STM32_RCC_APB1LENR_OFFSET 0x0264 /* APB1 peripheral clock enable register 1 */ +#define STM32_RCC_APB2ENR_OFFSET 0x026c /* APB2 peripheral clock enable register */ +#define STM32_RCC_APB4HENR_OFFSET 0x0278 /* APB4 peripheral clock enable register 2 */ +#define STM32_RCC_BUSLPENR_OFFSET 0x0284 /* Bus clocks enable in Sleep mode */ +#define STM32_RCC_MEMLPENR_OFFSET 0x028c /* SRAM clocks enable in Sleep mode */ +#define STM32_RCC_APB1LLPENR_OFFSET 0x02a4 /* APB1 LP clock enable register 1 */ +#define STM32_RCC_APB2LPENR_OFFSET 0x02ac /* APB2 LP clock enable register */ + +#define STM32_RCC_DIVENR_OFFSET 0x0240 /* IC divider enable register */ +#define STM32_RCC_DIVENSR_OFFSET 0x0a40 /* IC divider enable set register */ + +#define STM32_RCC_MEMENSR_OFFSET 0x0a4c /* SRAM clock enable set register */ +#define STM32_RCC_AHB4ENSR_OFFSET 0x0a5c /* AHB4 clock enable set register */ +#define STM32_RCC_APB1LENSR_OFFSET 0x0a64 /* APB1 clock enable set register 1 */ +#define STM32_RCC_APB2ENSR_OFFSET 0x0a6c /* APB2 clock enable set register */ +#define STM32_RCC_APB4HENSR_OFFSET 0x0a78 /* APB4 clock enable set register 2 */ +#define STM32_RCC_BUSLPENSR_OFFSET 0x0a84 /* Bus LP clock enable set register */ +#define STM32_RCC_MEMLPENSR_OFFSET 0x0a8c /* SRAM LP clock enable set register */ +#define STM32_RCC_APB1LLPENSR_OFFSET 0x0aa4 /* APB1 LP clock enable set register 1 */ +#define STM32_RCC_APB2LPENSR_OFFSET 0x0aac /* APB2 LP clock enable set register */ + +#define STM32_RCC_CCR_OFFSET 0x1000 /* Clock control clear register */ +#define STM32_RCC_APB2ENCR_OFFSET 0x126c /* APB2 clock enable clear register */ + +#define STM32_RCC_CSR_OFFSET 0x0800 /* Clock status (set) register */ + +/* Register Addresses *******************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE + STM32_RCC_CR_OFFSET) +#define STM32_RCC_SR (STM32_RCC_BASE + STM32_RCC_SR_OFFSET) +#define STM32_RCC_CFGR1 (STM32_RCC_BASE + STM32_RCC_CFGR1_OFFSET) +#define STM32_RCC_CFGR2 (STM32_RCC_BASE + STM32_RCC_CFGR2_OFFSET) +#define STM32_RCC_PLL1CFGR1 (STM32_RCC_BASE + STM32_RCC_PLL1CFGR1_OFFSET) +#define STM32_RCC_PLL1CFGR3 (STM32_RCC_BASE + STM32_RCC_PLL1CFGR3_OFFSET) +#define STM32_RCC_IC1CFGR (STM32_RCC_BASE + STM32_RCC_IC1CFGR_OFFSET) +#define STM32_RCC_IC2CFGR (STM32_RCC_BASE + STM32_RCC_IC2CFGR_OFFSET) +#define STM32_RCC_IC3CFGR (STM32_RCC_BASE + STM32_RCC_IC3CFGR_OFFSET) +#define STM32_RCC_IC6CFGR (STM32_RCC_BASE + STM32_RCC_IC6CFGR_OFFSET) +#define STM32_RCC_IC11CFGR (STM32_RCC_BASE + STM32_RCC_IC11CFGR_OFFSET) +#define STM32_RCC_CCIPR13 (STM32_RCC_BASE + STM32_RCC_CCIPR13_OFFSET) + +#define STM32_RCC_DIVENR (STM32_RCC_BASE + STM32_RCC_DIVENR_OFFSET) +#define STM32_RCC_DIVENSR (STM32_RCC_BASE + STM32_RCC_DIVENSR_OFFSET) + +#define STM32_RCC_MEMENR (STM32_RCC_BASE + STM32_RCC_MEMENR_OFFSET) +#define STM32_RCC_AHB4ENR (STM32_RCC_BASE + STM32_RCC_AHB4ENR_OFFSET) +#define STM32_RCC_APB1LENR (STM32_RCC_BASE + STM32_RCC_APB1LENR_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE + STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_APB4HENR (STM32_RCC_BASE + STM32_RCC_APB4HENR_OFFSET) +#define STM32_RCC_BUSLPENR (STM32_RCC_BASE + STM32_RCC_BUSLPENR_OFFSET) +#define STM32_RCC_MEMLPENR (STM32_RCC_BASE + STM32_RCC_MEMLPENR_OFFSET) +#define STM32_RCC_APB1LLPENR (STM32_RCC_BASE + STM32_RCC_APB1LLPENR_OFFSET) +#define STM32_RCC_APB2LPENR (STM32_RCC_BASE + STM32_RCC_APB2LPENR_OFFSET) + +#define STM32_RCC_MEMENSR (STM32_RCC_BASE + STM32_RCC_MEMENSR_OFFSET) +#define STM32_RCC_AHB4ENSR (STM32_RCC_BASE + STM32_RCC_AHB4ENSR_OFFSET) +#define STM32_RCC_APB1LENSR (STM32_RCC_BASE + STM32_RCC_APB1LENSR_OFFSET) +#define STM32_RCC_APB2ENSR (STM32_RCC_BASE + STM32_RCC_APB2ENSR_OFFSET) +#define STM32_RCC_APB4HENSR (STM32_RCC_BASE + STM32_RCC_APB4HENSR_OFFSET) +#define STM32_RCC_BUSLPENSR (STM32_RCC_BASE + STM32_RCC_BUSLPENSR_OFFSET) +#define STM32_RCC_MEMLPENSR (STM32_RCC_BASE + STM32_RCC_MEMLPENSR_OFFSET) +#define STM32_RCC_APB1LLPENSR (STM32_RCC_BASE + STM32_RCC_APB1LLPENSR_OFFSET) +#define STM32_RCC_APB2LPENSR (STM32_RCC_BASE + STM32_RCC_APB2LPENSR_OFFSET) + +#define STM32_RCC_CCR (STM32_RCC_BASE + STM32_RCC_CCR_OFFSET) +#define STM32_RCC_APB2ENCR (STM32_RCC_BASE + STM32_RCC_APB2ENCR_OFFSET) + +#define STM32_RCC_CSR (STM32_RCC_BASE + STM32_RCC_CSR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Clock control register */ + +#define RCC_CR_PLL1ON (1 << 8) /* Bit 8: PLL1 enable */ +#define RCC_CR_HSION (1 << 3) /* Bit 3: HSI enable */ + +/* Clock status register */ + +#define RCC_SR_PLL1RDY (1 << 8) /* Bit 8: PLL1 clock ready */ +#define RCC_SR_HSIRDY (1 << 3) /* Bit 3: HSI clock ready */ + +/* Clock configuration register 1. SYSSW = 0b11 selects three IC dividers + * (IC2 for SYSCLK, IC6 for AHB, IC11 for APB) -- the SVD names this state + * after the first IC only. + */ + +#define RCC_CFGR1_SYSSWS_SHIFT (28) +#define RCC_CFGR1_SYSSWS_MASK (0x3 << RCC_CFGR1_SYSSWS_SHIFT) +#define RCC_CFGR1_SYSSWS_IC2_IC6_IC11 (3 << RCC_CFGR1_SYSSWS_SHIFT) +#define RCC_CFGR1_SYSSW_SHIFT (24) +#define RCC_CFGR1_SYSSW_MASK (0x3 << RCC_CFGR1_SYSSW_SHIFT) +#define RCC_CFGR1_SYSSW_IC2_IC6_IC11 (3 << RCC_CFGR1_SYSSW_SHIFT) +#define RCC_CFGR1_CPUSWS_SHIFT (20) +#define RCC_CFGR1_CPUSWS_MASK (0x3 << RCC_CFGR1_CPUSWS_SHIFT) +#define RCC_CFGR1_CPUSWS_IC1 (3 << RCC_CFGR1_CPUSWS_SHIFT) +#define RCC_CFGR1_CPUSW_SHIFT (16) +#define RCC_CFGR1_CPUSW_MASK (0x3 << RCC_CFGR1_CPUSW_SHIFT) +#define RCC_CFGR1_CPUSW_IC1 (3 << RCC_CFGR1_CPUSW_SHIFT) + +/* Clock configuration register 2. HPRE divides the SYSCLK fed to AHB + * before it reaches the CPU/peripheral bus matrix. + */ + +#define RCC_CFGR2_HPRE_SHIFT (20) +#define RCC_CFGR2_HPRE_MASK (0x7 << RCC_CFGR2_HPRE_SHIFT) +#define RCC_CFGR2_HPRE_SYSCLK (0 << RCC_CFGR2_HPRE_SHIFT) +#define RCC_CFGR2_HPRE_SYSCLKd2 (1 << RCC_CFGR2_HPRE_SHIFT) +#define RCC_CFGR2_HPRE_SYSCLKd4 (2 << RCC_CFGR2_HPRE_SHIFT) +#define RCC_CFGR2_HPRE_SYSCLKd8 (3 << RCC_CFGR2_HPRE_SHIFT) +#define RCC_CFGR2_HPRE_SYSCLKd16 (4 << RCC_CFGR2_HPRE_SHIFT) + +#define RCC_CFGR2 STM32_RCC_CFGR2 + +/* PLL1 configuration register 1 */ + +#define RCC_PLL1CFGR1_SEL_SHIFT (28) +#define RCC_PLL1CFGR1_SEL_MASK (0x7 << RCC_PLL1CFGR1_SEL_SHIFT) +#define RCC_PLL1CFGR1_SEL_HSI (0 << RCC_PLL1CFGR1_SEL_SHIFT) +#define RCC_PLL1CFGR1_DIVM_SHIFT (20) /* Bits 25-20: Reference divider */ +#define RCC_PLL1CFGR1_DIVM_MASK (0x3f << RCC_PLL1CFGR1_DIVM_SHIFT) +#define RCC_PLL1CFGR1_DIVN_SHIFT (8) /* Bits 19-8: Feedback divider */ +#define RCC_PLL1CFGR1_DIVN_MASK (0xfff << RCC_PLL1CFGR1_DIVN_SHIFT) + +/* PLL1 configuration register 3 */ + +#define RCC_PLL1CFGR3_PDIVEN (1 << 30) /* Bit 30: Post-divider and PLL output enable */ +#define RCC_PLL1CFGR3_PDIV1_SHIFT (27) /* Bits 29-27: Post-divider 1 */ +#define RCC_PLL1CFGR3_PDIV1_MASK (0x7 << RCC_PLL1CFGR3_PDIV1_SHIFT) +#define RCC_PLL1CFGR3_PDIV2_SHIFT (24) /* Bits 26-24: Post-divider 2 */ +#define RCC_PLL1CFGR3_PDIV2_MASK (0x7 << RCC_PLL1CFGR3_PDIV2_SHIFT) +#define RCC_PLL1CFGR3_MODSSDIS (1 << 2) /* Bit 2: Modulation spread spectrum disable */ + +/* IC1..IC20 configuration registers -- all share the same layout. Field + * SEL selects the PLL source (PLL1..PLL4); field INT is an 8-bit integer + * divider where INT[7:0] = N-1 yielding a divide ratio of N. + */ + +#define RCC_ICCFGR_SEL_SHIFT (28) +#define RCC_ICCFGR_SEL_MASK (0x3 << RCC_ICCFGR_SEL_SHIFT) +#define RCC_ICCFGR_SEL_PLL1 (0 << RCC_ICCFGR_SEL_SHIFT) +#define RCC_ICCFGR_INT_SHIFT (16) +#define RCC_ICCFGR_INT_MASK (0xff << RCC_ICCFGR_INT_SHIFT) + +/* IC divider enable register */ + +#define RCC_DIVENR_IC11EN (1 << 10) /* Bit 10: IC11 enable */ +#define RCC_DIVENR_IC6EN (1 << 5) /* Bit 5: IC6 enable */ +#define RCC_DIVENR_IC3EN (1 << 2) /* Bit 2: IC3 enable */ +#define RCC_DIVENR_IC2EN (1 << 1) /* Bit 1: IC2 enable */ +#define RCC_DIVENR_IC1EN (1 << 0) /* Bit 0: IC1 enable */ + +/* SRAM clock enable register */ + +#define RCC_MEMENR_CACHEAXIRAMEN (1 << 10) /* Bit 10: CACHEAXIRAM enable */ +#define RCC_MEMENR_AXISRAM2EN (1 << 8) /* Bit 8: AXISRAM2 enable */ +#define RCC_MEMENR_AXISRAM1EN (1 << 7) /* Bit 7: AXISRAM1 enable */ +#define RCC_MEMENR_AXISRAM6EN (1 << 3) /* Bit 3: AXISRAM6 enable */ +#define RCC_MEMENR_AXISRAM5EN (1 << 2) /* Bit 2: AXISRAM5 enable */ +#define RCC_MEMENR_AXISRAM4EN (1 << 1) /* Bit 1: AXISRAM4 enable */ +#define RCC_MEMENR_AXISRAM3EN (1 << 0) /* Bit 0: AXISRAM3 enable */ + +#define RCC_MEMENR_ALLAXISRAM (RCC_MEMENR_AXISRAM1EN | RCC_MEMENR_AXISRAM2EN | \ + RCC_MEMENR_AXISRAM3EN | RCC_MEMENR_AXISRAM4EN | \ + RCC_MEMENR_AXISRAM5EN | RCC_MEMENR_AXISRAM6EN) + +/* AHB4 peripheral clock enable register */ + +#define RCC_AHB4ENR_PWREN (1 << 18) /* Bit 18: PWR enable */ +#define RCC_AHB4ENR_GPIOQEN (1 << 16) /* Bit 16: GPIOQ enable */ +#define RCC_AHB4ENR_GPIOPEN (1 << 15) /* Bit 15: GPIOP enable */ +#define RCC_AHB4ENR_GPIOOEN (1 << 14) /* Bit 14: GPIOO enable */ +#define RCC_AHB4ENR_GPIONEN (1 << 13) /* Bit 13: GPION enable */ +#define RCC_AHB4ENR_GPIOHEN (1 << 7) /* Bit 7: GPIOH enable */ +#define RCC_AHB4ENR_GPIOGEN (1 << 6) /* Bit 6: GPIOG enable */ +#define RCC_AHB4ENR_GPIOFEN (1 << 5) /* Bit 5: GPIOF enable */ +#define RCC_AHB4ENR_GPIOEEN (1 << 4) /* Bit 4: GPIOE enable */ +#define RCC_AHB4ENR_GPIODEN (1 << 3) /* Bit 3: GPIOD enable */ +#define RCC_AHB4ENR_GPIOCEN (1 << 2) /* Bit 2: GPIOC enable */ +#define RCC_AHB4ENR_GPIOBEN (1 << 1) /* Bit 1: GPIOB enable */ +#define RCC_AHB4ENR_GPIOAEN (1 << 0) /* Bit 0: GPIOA enable */ + +/* APB1 peripheral clock enable register 1 */ + +#define RCC_APB1LENR_TIM2EN (1 << 0) /* Bit 0: TIM2 enable */ + +/* APB2 peripheral clock enable register */ + +#define RCC_APB2ENR_USART1EN (1 << 4) /* Bit 4: USART1 enable */ + +/* APB4 peripheral clock enable register 2 */ + +#define RCC_APB4HENR_BSECEN (1 << 1) /* Bit 1: BSEC enable */ +#define RCC_APB4HENR_SYSCFGEN (1 << 0) /* Bit 0: SYSCFG enable */ + +/* Bus clock enable in Sleep mode */ + +#define RCC_BUSLPENR_ACLKNCLPEN (1 << 1) /* Bit 1: ACLKNC clock enable in CSLEEP */ +#define RCC_BUSLPENR_ACLKNLPEN (1 << 0) /* Bit 0: ACLKN clock enable in CSLEEP */ + +/* SRAM clock enable in Sleep mode */ + +#define RCC_MEMLPENR_CACHEAXIRAMLPEN (1 << 10) /* Bit 10: CACHEAXIRAM enable in CSLEEP */ +#define RCC_MEMLPENR_AXISRAM2LPEN (1 << 8) +#define RCC_MEMLPENR_AXISRAM1LPEN (1 << 7) +#define RCC_MEMLPENR_AXISRAM6LPEN (1 << 3) +#define RCC_MEMLPENR_AXISRAM5LPEN (1 << 2) +#define RCC_MEMLPENR_AXISRAM4LPEN (1 << 1) +#define RCC_MEMLPENR_AXISRAM3LPEN (1 << 0) + +#define RCC_MEMLPENR_ALLAXISRAM (RCC_MEMLPENR_AXISRAM1LPEN | RCC_MEMLPENR_AXISRAM2LPEN | \ + RCC_MEMLPENR_AXISRAM3LPEN | RCC_MEMLPENR_AXISRAM4LPEN | \ + RCC_MEMLPENR_AXISRAM5LPEN | RCC_MEMLPENR_AXISRAM6LPEN) + +/* APB1 peripheral clock enable in Sleep mode (register 1) */ + +#define RCC_APB1LLPENR_TIM2LPEN (1 << 0) /* Bit 0: TIM2 enable in CSLEEP */ + +/* APB2 peripheral clock enable in Sleep mode */ + +#define RCC_APB2LPENR_USART1LPEN (1 << 4) /* Bit 4: USART1 enable in CSLEEP */ + +/* Peripheral kernel clock select register 13 */ + +#define RCC_CCIPR13_USART1SEL_SHIFT (0) +#define RCC_CCIPR13_USART1SEL_MASK (0x7 << RCC_CCIPR13_USART1SEL_SHIFT) +#define RCC_CCIPR13_USART1SEL_HSI (6 << RCC_CCIPR13_USART1SEL_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_RCC_H */ diff --git a/arch/arm/src/stm32n6/hardware/stm32n6xxx_syscfg.h b/arch/arm/src/stm32n6/hardware/stm32n6xxx_syscfg.h new file mode 100644 index 0000000000000..69fae56af1c2e --- /dev/null +++ b/arch/arm/src/stm32n6/hardware/stm32n6xxx_syscfg.h @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/hardware/stm32n6xxx_syscfg.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_SYSCFG_H +#define __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_SYSCFG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/stm32n6xxx_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_SYSCFG_INITSVTORCR_OFFSET 0x010 /* Secure vector table base address register */ +#define STM32_SYSCFG_VDDIO2CCCR_OFFSET 0x054 /* VDDIO2 compensation cell control register */ +#define STM32_SYSCFG_VDDIO3CCCR_OFFSET 0x05c /* VDDIO3 compensation cell control register */ +#define STM32_SYSCFG_VDDCCCR_OFFSET 0x064 /* VDD compensation cell control register */ + +/* Register Addresses *******************************************************/ + +#define STM32_SYSCFG_INITSVTORCR (STM32_SYSCFG_BASE + STM32_SYSCFG_INITSVTORCR_OFFSET) +#define STM32_SYSCFG_VDDIO2CCCR (STM32_SYSCFG_BASE + STM32_SYSCFG_VDDIO2CCCR_OFFSET) +#define STM32_SYSCFG_VDDIO3CCCR (STM32_SYSCFG_BASE + STM32_SYSCFG_VDDIO3CCCR_OFFSET) +#define STM32_SYSCFG_VDDCCCR (STM32_SYSCFG_BASE + STM32_SYSCFG_VDDCCCR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Compensation cell control register (VDDxCCCR / VDDIOxCCCR). The four + * banks (VDD, VDDIO2, VDDIO3, VDDIO4, VDDIO5) share an identical layout, so + * the port refers to them with a single set of CCCR_* macros. + */ + +#define SYSCFG_CCCR_CS (1 << 9) /* Bit 9: Compensation code source select */ +#define SYSCFG_CCCR_EN (1 << 8) /* Bit 8: Enable compensation cell */ +#define SYSCFG_CCCR_RAPSRC_SHIFT (4) /* Bits 7-4: Manual PMOS compensation code */ +#define SYSCFG_CCCR_RAPSRC_MASK (0xf << SYSCFG_CCCR_RAPSRC_SHIFT) +#define SYSCFG_CCCR_RANSRC_SHIFT (0) /* Bits 3-0: Manual NMOS compensation code */ +#define SYSCFG_CCCR_RANSRC_MASK (0xf << SYSCFG_CCCR_RANSRC_SHIFT) + +/* ES0620 I/O compensation mitigation: write 0x00000287 (EN=0, CS=1, + * RAPSRC=0x8, RANSRC=0x7) to VDDCCCR and every VDDIOxCCCR before + * enabling high-speed pads. This disables the cell and overrides the + * broken defaults (RAPSRC=0x7, RANSRC=0x8) that deform output edges. + */ + +#define SYSCFG_CCCR_ES0620_MANUAL (SYSCFG_CCCR_CS | \ + (8 << SYSCFG_CCCR_RAPSRC_SHIFT) | \ + (7 << SYSCFG_CCCR_RANSRC_SHIFT)) + +#endif /* __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_SYSCFG_H */ diff --git a/arch/arm/src/stm32n6/hardware/stm32n6xxx_uart.h b/arch/arm/src/stm32n6/hardware/stm32n6xxx_uart.h new file mode 100644 index 0000000000000..138f8c4ab7e13 --- /dev/null +++ b/arch/arm/src/stm32n6/hardware/stm32n6xxx_uart.h @@ -0,0 +1,252 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/hardware/stm32n6xxx_uart.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_UART_H +#define __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_USART_CR1_OFFSET 0x0000 /* Control register 1 */ +#define STM32_USART_CR2_OFFSET 0x0004 /* Control register 2 */ +#define STM32_USART_CR3_OFFSET 0x0008 /* Control register 3 */ +#define STM32_USART_BRR_OFFSET 0x000c /* Baud Rate register */ +#define STM32_USART_GTPR_OFFSET 0x0010 /* Guard time and prescaler register */ +#define STM32_USART_RTOR_OFFSET 0x0014 /* Receiver timeout register */ +#define STM32_USART_RQR_OFFSET 0x0018 /* Request register */ +#define STM32_USART_ISR_OFFSET 0x001c /* Interrupt and status register */ +#define STM32_USART_ICR_OFFSET 0x0020 /* Interrupt flag clear register */ +#define STM32_USART_RDR_OFFSET 0x0024 /* Receive Data register */ +#define STM32_USART_TDR_OFFSET 0x0028 /* Transmit Data register */ +#define STM32_USART_PRESC_OFFSET 0x002c /* Prescaler register */ + +/* Register Addresses *******************************************************/ + +/* USART1 */ + +#define STM32_USART1_CR1 (STM32_USART1_BASE + STM32_USART_CR1_OFFSET) +#define STM32_USART1_CR2 (STM32_USART1_BASE + STM32_USART_CR2_OFFSET) +#define STM32_USART1_CR3 (STM32_USART1_BASE + STM32_USART_CR3_OFFSET) +#define STM32_USART1_BRR (STM32_USART1_BASE + STM32_USART_BRR_OFFSET) +#define STM32_USART1_GTPR (STM32_USART1_BASE + STM32_USART_GTPR_OFFSET) +#define STM32_USART1_RTOR (STM32_USART1_BASE + STM32_USART_RTOR_OFFSET) +#define STM32_USART1_RQR (STM32_USART1_BASE + STM32_USART_RQR_OFFSET) +#define STM32_USART1_ISR (STM32_USART1_BASE + STM32_USART_ISR_OFFSET) +#define STM32_USART1_ICR (STM32_USART1_BASE + STM32_USART_ICR_OFFSET) +#define STM32_USART1_RDR (STM32_USART1_BASE + STM32_USART_RDR_OFFSET) +#define STM32_USART1_TDR (STM32_USART1_BASE + STM32_USART_TDR_OFFSET) +#define STM32_USART1_PRESC (STM32_USART1_BASE + STM32_USART_PRESC_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Control register 1 */ + +#define USART_CR1_UE (1 << 0) /* Bit 0: USART Enable */ +#define USART_CR1_UESM (1 << 1) /* Bit 1: USART Enable in Stop mode */ +#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ +#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ +#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ +#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ +#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ +#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */ +#define USART_CR1_M0 (1 << 12) /* Bit 12: Word length */ +#define USART_CR1_MME (1 << 13) /* Bit 13: Mute mode enable */ +#define USART_CR1_CMIE (1 << 14) /* Bit 14: Character match interrupt enable */ +#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ + +#define USART_CR1_DEDT_SHIFT (16) /* Bits 16..20 DE deactivation delay */ +#define USART_CR1_DEDT_MASK (0x1f << USART_CR1_DEDT_SHIFT) + +#define USART_CR1_DEAT_SHIFT (21) /* Bits 21..25 DE activation delay */ +#define USART_CR1_DEAT_MASK (0x1f << USART_CR1_DEAT_SHIFT) + +#define USART_CR1_RTOIE (1 << 26) /* Bit 26: Receiver timeout interrupt enable */ +#define USART_CR1_EOBIE (1 << 27) /* Bit 27: End of block interrupt enable */ +#define USART_CR1_M1 (1 << 28) /* Bit 28: Word length */ +#define USART_CR1_FIFOEN (1 << 29) /* Bit 29: FIFO mode enable */ +#define USART_CR1_TXFEIE (1 << 30) /* Bit 30: TXFIFO empty interrupt enable */ +#define USART_CR1_RXFFIE (1 << 31) /* Bit 31: RXFIFO full interrupt enable */ + +#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE| \ + USART_CR1_TCIE|USART_CR1_TXEIE| \ + USART_CR1_PEIE|USART_CR1_CMIE| \ + USART_CR1_RTOIE|USART_CR1_EOBIE) + +/* Control register 2 */ + +#define USART_CR2_ADDM7 (1 << 4) /* Bit 4: 7-bit/4-bit Address Detection */ +#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ +#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ +#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ +#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ +#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ + +#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ +#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) +# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ +# define USART_CR2_STOP0p5 (1 << USART_CR2_STOP_SHIFT) /* 01: 0.5 Stop bit */ +# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ +# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ + +#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ +#define USART_CR2_SWAP (1 << 15) /* Bit 15: Swap TX/RX pins */ +#define USART_CR2_RXINV (1 << 16) /* Bit 16: RX pin active level inversion */ +#define USART_CR2_TXINV (1 << 17) /* Bit 17: TX pin active level inversion */ +#define USART_CR2_DATAINV (1 << 18) /* Bit 18: Binary data inversion */ +#define USART_CR2_MSBFIRST (1 << 19) /* Bit 19: Most significant bit first */ +#define USART_CR2_ABREN (1 << 20) /* Bit 20: Auto Baud rate enable */ + +#define USART_CR2_ABRMOD_SHIFT (21) /* Bits 21-22: Autobaud rate mode*/ +#define USART_CR2_ABRMOD_MASK (3 << USART_CR2_ABRMOD_SHIFT) +#define USART_CR2_ABRMOD_START (0 << USART_CR2_ABRMOD_SHIFT) /* 00: Start bit */ +#define USART_CR2_ABRMOD_EDGES (1 << USART_CR2_ABRMOD_SHIFT) /* 01: Falling-to-falling edge */ +#define USART_CR2_ABRMOD_7F (2 << USART_CR2_ABRMOD_SHIFT) /* 10: 0x7F */ +#define USART_CR2_ABRMOD_55 (3 << USART_CR2_ABRMOD_SHIFT) /* 11: 0x55 */ + +#define USART_CR2_RTOEN (1 << 23) /* Bit 23: Receiver timeout enable */ + +#define USART_CR2_ADD_SHIFT (24) /* Bits 24-31: Address of the USART node */ +#define USART_CR2_ADD_MASK (0xff << USART_CR2_ADD_SHIFT) + +/* Control register 3 */ + +#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ +#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ +#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ +#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ +#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ +#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ +#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ +#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ +#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ +#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ +#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ +#define USART_CR3_ONEBIT (1 << 11) /* Bit 11: One sample bit method Enable */ +#define USART_CR3_OVRDIS (1 << 12) /* Bit 12: Overrun Disable */ +#define USART_CR3_DDRE (1 << 13) /* Bit 13: DMA disable on Reception error */ +#define USART_CR3_DEM (1 << 14) /* Bit 14: Driver Enable mode */ +#define USART_CR3_DEP (1 << 15) /* Bit 15: Driver Enable polarity selection */ +#define USART_CR3_SCARCNT2_SHIFT (17) /* Bits 17-19: Smart card auto retry count */ +#define USART_CR3_SCARCNT2_MASK (7 << USART_CR3_SCARCNT2_SHIFT) +#define USART_CR3_WUS_SHIFT (20) /* Bits 20-21: Wakeup from Stop mode interrupt flag selection */ +#define USART_CR3_WUS_MASK (3 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUS_ADDRESS (0 << USART_CR3_WUS_SHIFT) /* 00: WUF active on address match */ +#define USART_CR3_WUS_START (2 << USART_CR3_WUS_SHIFT) /* 10: WUF active on Start bit detection */ +#define USART_CR3_WUS_RXNE (3 << USART_CR3_WUS_SHIFT) /* 11: WUF active on RXNE */ +#define USART_CR3_WUFIE (1 << 22) /* Bit 22: Wakeup from Stop mode interrupt enable */ + +/* Baud Rate Register */ + +#define USART_BRR_FRAC_SHIFT (0) /* Bits 3-0: fraction of USARTDIV */ +#define USART_BRR_FRAC_MASK (0x0f << USART_BRR_FRAC_SHIFT) +#define USART_BRR_MANT_SHIFT (4) /* Bits 15-4: mantissa of USARTDIV */ +#define USART_BRR_MANT_MASK (0x0fff << USART_BRR_MANT_SHIFT) + +/* Guard time and prescaler register */ + +#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) + +/* Request Register */ + +#define USART_RQR_ABRRQ (1 << 0) /* Bit 0: Auto baud rate request */ +#define USART_RQR_SBKRQ (1 << 1) /* Bit 1: Send break request */ +#define USART_RQR_MMRQ (1 << 2) /* Bit 2: Mute mode request */ +#define USART_RQR_RXFRQ (1 << 3) /* Bit 3: Receive data flush request */ +#define USART_RQR_TXFRQ (1 << 4) /* Bit 4: Transmit data flush request */ + +/* Interrupt and Status register */ + +#define USART_ISR_PE (1 << 0) /* Bit 0: Parity Error */ +#define USART_ISR_FE (1 << 1) /* Bit 1: Framing Error */ +#define USART_ISR_NF (1 << 2) /* Bit 2: Noise Error Flag */ +#define USART_ISR_ORE (1 << 3) /* Bit 3: OverRun Error */ +#define USART_ISR_IDLE (1 << 4) /* Bit 4: IDLE line detected */ +#define USART_ISR_RXNE (1 << 5) /* Bit 5: Read Data Register Not Empty */ +#define USART_ISR_TC (1 << 6) /* Bit 6: Transmission Complete */ +#define USART_ISR_TXE (1 << 7) /* Bit 7: Transmit Data Register Empty */ +#define USART_ISR_LBDF (1 << 8) /* Bit 8: LIN Break Detection Flag */ +#define USART_ISR_CTSIF (1 << 9) /* Bit 9: CTS Interrupt Flag */ +#define USART_ISR_CTS (1 << 10) /* Bit 10: CTS Flag */ +#define USART_ISR_RTOF (1 << 11) /* Bit 11: Receiver timeout Flag */ +#define USART_ISR_EOBF (1 << 12) /* Bit 12: End of block Flag */ +#define USART_ISR_UDR (1 << 13) /* Bit 13: SPI slave underrun error flag */ +#define USART_ISR_ABRE (1 << 14) /* Bit 14: Auto baud rate Error */ +#define USART_ISR_ABRF (1 << 15) /* Bit 15: Auto baud rate Flag */ +#define USART_ISR_BUSY (1 << 16) /* Bit 16: Busy Flag */ +#define USART_ISR_CMF (1 << 17) /* Bit 17: Character match Flag */ +#define USART_ISR_SBKF (1 << 18) /* Bit 18: Send break Flag */ +#define USART_ISR_RWU (1 << 19) /* Bit 19: Receiver wakeup from Mute mode */ +#define USART_ISR_WUF (1 << 20) /* Bit 20: Wakeup from Stop mode Flag */ +#define USART_ISR_TEACK (1 << 21) /* Bit 21: Transmit enable acknowledge Flag */ +#define USART_ISR_REACK (1 << 22) /* Bit 22: Receive enable acknowledge Flag */ + +/* ICR */ + +#define USART_ICR_PECF (1 << 0) /* Bit 0: Parity error clear flag */ +#define USART_ICR_FECF (1 << 1) /* Bit 1: Framing error clear flag */ +#define USART_ICR_NCF (1 << 2) /* Bit 2: Noise detected clear flag */ +#define USART_ICR_ORECF (1 << 3) /* Bit 3: Overrun error clear flag */ +#define USART_ICR_IDLECF (1 << 4) /* Bit 4: Idle line detected clear flag */ +#define USART_ICR_TCCF (1 << 6) /* Bit 6: Transmission complete clear flag */ +#define USART_ICR_LBDCF (1 << 8) /* Bit 8: LIN break detection clear flag */ +#define USART_ICR_CTSCF (1 << 9) /* Bit 9: CTS clear flag */ +#define USART_ICR_RTOCF (1 << 11) /* Bit 11: Receiver timeout clear flag */ +#define USART_ICR_EOBCF (1 << 12) /* Bit 12: End of block clear flag */ +#define USART_ICR_CMCF (1 << 17) /* Bit 17: Character match clear flag */ +#define USART_ICR_WUCF (1 << 20) /* Bit 20: Wakeup from Stop mode clear flag */ + +/* Receive Data register */ + +#define USART_RDR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_RDR_MASK (0xff << USART_RDR_SHIFT) + +/* Transmit Data register */ + +#define USART_TDR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_TDR_MASK (0xff << USART_TDR_SHIFT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32N6_HARDWARE_STM32N6XXX_UART_H */ diff --git a/arch/arm/src/stm32n6/stm32.h b/arch/arm/src/stm32n6/stm32.h new file mode 100644 index 0000000000000..468ea2b34e407 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_STM32_H +#define __ARCH_ARM_SRC_STM32N6_STM32_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "arm_internal.h" + +/* Peripherals **************************************************************/ + +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_lowputc.h" +#include "stm32_pwr.h" +#include "stm32_rcc.h" +#include "stm32_uart.h" + +#endif /* __ARCH_ARM_SRC_STM32N6_STM32_H */ diff --git a/arch/arm/src/stm32n6/stm32_gpio.c b/arch/arm/src/stm32n6/stm32_gpio.c new file mode 100644 index 0000000000000..4127545303266 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_gpio.c @@ -0,0 +1,374 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_gpio.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "arm_internal.h" +#include "chip.h" +#include "stm32_gpio.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static spinlock_t g_configgpio_lock = SP_UNLOCKED; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Base addresses for each GPIO block. + * STM32N6 has 12 GPIO ports: A-H (indices 0-7) and N, O, P, Q (indices + * 8-11). Note that there is no GPIOI-M on this chip. + */ + +const uint32_t g_gpiobase[STM32N6_NPORTS] = +{ + STM32_GPIOA_BASE, /* Port A - index 0 */ + STM32_GPIOB_BASE, /* Port B - index 1 */ + STM32_GPIOC_BASE, /* Port C - index 2 */ + STM32_GPIOD_BASE, /* Port D - index 3 */ + STM32_GPIOE_BASE, /* Port E - index 4 */ + STM32_GPIOF_BASE, /* Port F - index 5 */ + STM32_GPIOG_BASE, /* Port G - index 6 */ + STM32_GPIOH_BASE, /* Port H - index 7 */ + STM32_GPION_BASE, /* Port N - index 8 */ + STM32_GPIOO_BASE, /* Port O - index 9 */ + STM32_GPIOP_BASE, /* Port P - index 10 */ + STM32_GPIOQ_BASE, /* Port Q - index 11 */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with stm32_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returned Value: + * OK on success + * A negated errno value on invalid port, or when pin is locked as ALT + * function. + * + ****************************************************************************/ + +int stm32_configgpio(uint32_t cfgset) +{ + uintptr_t base; + uint32_t regval; + uint32_t setting; + unsigned int regoffset; + unsigned int port; + unsigned int pin; + unsigned int pos; + unsigned int pinmode; + irqstate_t flags; + + /* Verify that this hardware supports the select GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= STM32N6_NPORTS) + { + return -EINVAL; + } + + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and select the port configuration register for that + * pin + */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set up the mode register (and remember whether the pin mode) */ + + switch (cfgset & GPIO_MODE_MASK) + { + default: + case GPIO_INPUT: /* Input mode */ + pinmode = GPIO_MODER_INPUT; + break; + + case GPIO_OUTPUT: /* General purpose output mode */ + + /* Set the initial output value */ + + stm32_gpiowrite(cfgset, (cfgset & GPIO_OUTPUT_SET) != 0); + pinmode = GPIO_MODER_OUTPUT; + break; + + case GPIO_ALT: /* Alternate function mode */ + pinmode = GPIO_MODER_ALT; + break; + + case GPIO_ANALOG: /* Analog mode */ + pinmode = GPIO_MODER_ANALOG; + break; + } + + /* Interrupts must be disabled from here on out so that we have mutually + * exclusive access to all of the GPIO configuration registers. + */ + + flags = spin_lock_irqsave(&g_configgpio_lock); + + /* Now apply the configuration to the mode register */ + + regval = getreg32(base + STM32_GPIO_MODER_OFFSET); + regval &= ~GPIO_MODER_MASK(pin); + regval |= ((uint32_t)pinmode << GPIO_MODER_SHIFT(pin)); + putreg32(regval, base + STM32_GPIO_MODER_OFFSET); + + /* Set up the pull-up/pull-down configuration (all but analog pins) */ + + setting = GPIO_PUPDR_NONE; + if (pinmode != GPIO_MODER_ANALOG) + { + switch (cfgset & GPIO_PUPD_MASK) + { + default: + case GPIO_FLOAT: /* No pull-up, pull-down */ + break; + + case GPIO_PULLUP: /* Pull-up */ + setting = GPIO_PUPDR_PULLUP; + break; + + case GPIO_PULLDOWN: /* Pull-down */ + setting = GPIO_PUPDR_PULLDOWN; + break; + } + } + + regval = getreg32(base + STM32_GPIO_PUPDR_OFFSET); + regval &= ~GPIO_PUPDR_MASK(pin); + regval |= (setting << GPIO_PUPDR_SHIFT(pin)); + putreg32(regval, base + STM32_GPIO_PUPDR_OFFSET); + + /* Set the alternate function (Only alternate function pins) */ + + if (pinmode == GPIO_MODER_ALT) + { + setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; + } + else + { + setting = 0; + } + + if (pin < 8) + { + regoffset = STM32_GPIO_AFRL_OFFSET; + pos = pin; + } + else + { + regoffset = STM32_GPIO_AFRH_OFFSET; + pos = pin - 8; + } + + regval = getreg32(base + regoffset); + regval &= ~GPIO_AFR_MASK(pos); + regval |= (setting << GPIO_AFR_SHIFT(pos)); + putreg32(regval, base + regoffset); + + /* Set speed (Only outputs and alternate function pins) */ + + if (pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) + { + switch (cfgset & GPIO_SPEED_MASK) + { + default: + case GPIO_SPEED_2MHZ: /* 2 MHz Low speed output */ + setting = GPIO_OSPEED_2MHZ; + break; + + case GPIO_SPEED_25MHZ: /* 25 MHz Medium speed output */ + setting = GPIO_OSPEED_25MHZ; + break; + + case GPIO_SPEED_50MHZ: /* 50 MHz High speed output */ + setting = GPIO_OSPEED_50MHZ; + break; + + case GPIO_SPEED_100MHZ: /* 100 MHz Very High speed output */ + setting = GPIO_OSPEED_100MHZ; + break; + } + } + else + { + setting = 0; + } + + regval = getreg32(base + STM32_GPIO_OSPEED_OFFSET); + regval &= ~GPIO_OSPEED_MASK(pin); + regval |= (setting << GPIO_OSPEED_SHIFT(pin)); + putreg32(regval, base + STM32_GPIO_OSPEED_OFFSET); + + /* Set push-pull/open-drain (Only outputs and alternate function pins) */ + + regval = getreg32(base + STM32_GPIO_OTYPER_OFFSET); + setting = GPIO_OTYPER_OD(pin); + + if ((pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) && + (cfgset & GPIO_OPENDRAIN) != 0) + { + regval |= setting; + } + else + { + regval &= ~setting; + } + + putreg32(regval, base + STM32_GPIO_OTYPER_OFFSET); + + spin_unlock_irqrestore(&g_configgpio_lock, flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_unconfiggpio + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin, set + * it into default HiZ state (and possibly mark it's unused) and unlock it + * whether it was previously selected as alternative function + * (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from shocks, as + * unexpected write to the Timer Channel Output GPIO to fixed '1' or '0' + * while it should operate in PWM mode could produce excessive on-board + * currents and trigger over-current/alarm function. + * + * Returned Value: + * OK on success + * A negated errno value on invalid port + * + ****************************************************************************/ + +int stm32_unconfiggpio(uint32_t cfgset) +{ + /* Reuse port and pin number and set it to default HiZ INPUT */ + + cfgset &= GPIO_PORT_MASK | GPIO_PIN_MASK; + cfgset |= GPIO_INPUT | GPIO_FLOAT; + + return stm32_configgpio(cfgset); +} + +/**************************************************************************** + * Name: stm32_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void stm32_gpiowrite(uint32_t pinset, bool value) +{ + uint32_t base; + uint32_t bit; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < STM32N6_NPORTS) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + + if (value) + { + bit = GPIO_BSRR_SET(pin); + } + else + { + bit = GPIO_BSRR_RESET(pin); + } + + putreg32(bit, base + STM32_GPIO_BSRR_OFFSET); + } +} + +/**************************************************************************** + * Name: stm32_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool stm32_gpioread(uint32_t pinset) +{ + uint32_t base; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < STM32N6_NPORTS) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(base + STM32_GPIO_IDR_OFFSET) & (1 << pin)) != 0); + } + + return 0; +} diff --git a/arch/arm/src/stm32n6/stm32_gpio.h b/arch/arm/src/stm32n6/stm32_gpio.h new file mode 100644 index 0000000000000..4c32f43d43c2d --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_gpio.h @@ -0,0 +1,317 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_gpio.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_STM32_GPIO_H +#define __ARCH_ARM_SRC_STM32N6_STM32_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include +#include + +#include "chip.h" +#include "hardware/stm32n6xxx_pinmap.h" +#include "hardware/stm32n6xxx_gpio.h" + +/**************************************************************************** + * Pre-Processor Declarations + ****************************************************************************/ + +/* Bit-encoded input to stm32_configgpio() */ + +/* Each port bit of the general-purpose I/O (GPIO) ports can be individually + * configured by software in several modes: + * + * - Input floating + * - Input pull-up + * - Input-pull-down + * - Output open-drain with pull-up or pull-down capability + * - Output push-pull with pull-up or pull-down capability + * - Alternate function push-pull with pull-up or pull-down capability + * - Alternate function open-drain with pull-up or pull-down capability + * - Analog + * + * 20-bit Encoding: 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * Inputs: MMUU .... ...X PPPP BBBB + * Outputs: MMUU .... FFOV PPPP BBBB + * Alternate Functions: MMUU AAAA FFO. PPPP BBBB + * Analog: MM.. .... .... PPPP BBBB + */ + +/* Mode: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * MM.. .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (18) /* Bits 18-19: GPIO port mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input mode */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* General purpose output mode */ +# define GPIO_ALT (2 << GPIO_MODE_SHIFT) /* Alternate function mode */ +# define GPIO_ANALOG (3 << GPIO_MODE_SHIFT) /* Analog mode */ + +/* Input/output pull-ups/downs (not used with analog): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * ..UU .... .... .... .... + */ + +#define GPIO_PUPD_SHIFT (16) /* Bits 16-17: Pull-up/pull down */ +#define GPIO_PUPD_MASK (3 << GPIO_PUPD_SHIFT) +# define GPIO_FLOAT (0 << GPIO_PUPD_SHIFT) /* No pull-up, pull-down */ +# define GPIO_PULLUP (1 << GPIO_PUPD_SHIFT) /* Pull-up */ +# define GPIO_PULLDOWN (2 << GPIO_PUPD_SHIFT) /* Pull-down */ + +/* Alternate Functions: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... AAAA .... .... .... + */ + +#define GPIO_AF_SHIFT (12) /* Bits 12-15: Alternate function */ +#define GPIO_AF_MASK (15 << GPIO_AF_SHIFT) +# define GPIO_AF(n) ((n) << GPIO_AF_SHIFT) +# define GPIO_AF0 (0 << GPIO_AF_SHIFT) +# define GPIO_AF1 (1 << GPIO_AF_SHIFT) +# define GPIO_AF2 (2 << GPIO_AF_SHIFT) +# define GPIO_AF3 (3 << GPIO_AF_SHIFT) +# define GPIO_AF4 (4 << GPIO_AF_SHIFT) +# define GPIO_AF5 (5 << GPIO_AF_SHIFT) +# define GPIO_AF6 (6 << GPIO_AF_SHIFT) +# define GPIO_AF7 (7 << GPIO_AF_SHIFT) +# define GPIO_AF8 (8 << GPIO_AF_SHIFT) +# define GPIO_AF9 (9 << GPIO_AF_SHIFT) +# define GPIO_AF10 (10 << GPIO_AF_SHIFT) +# define GPIO_AF11 (11 << GPIO_AF_SHIFT) +# define GPIO_AF12 (12 << GPIO_AF_SHIFT) +# define GPIO_AF13 (13 << GPIO_AF_SHIFT) +# define GPIO_AF14 (14 << GPIO_AF_SHIFT) +# define GPIO_AF15 (15 << GPIO_AF_SHIFT) + +/* Output/Alt function frequency selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... FF.. .... .... + */ + +#define GPIO_SPEED_SHIFT (10) /* Bits 10-11: GPIO frequency selection */ +#define GPIO_SPEED_MASK (3 << GPIO_SPEED_SHIFT) +# define GPIO_SPEED_2MHZ (0 << GPIO_SPEED_SHIFT) /* 2 MHz Low speed output */ +# define GPIO_SPEED_25MHZ (1 << GPIO_SPEED_SHIFT) /* 25 MHz Medium speed output */ +# define GPIO_SPEED_50MHZ (2 << GPIO_SPEED_SHIFT) /* 50 MHz High speed output */ +# define GPIO_SPEED_100MHZ (3 << GPIO_SPEED_SHIFT) /* 100 MHz Very High speed output */ + +/* Output/Alt function type selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ..O. .... .... + */ + +#define GPIO_OPENDRAIN (1 << 9) /* Bit9: 1=Open-drain output */ +#define GPIO_PUSHPULL (0) /* Bit9: 0=Push-pull output */ + +/* If the pin is a GPIO digital output, then this identifies the initial + * output value. If the pin is an input, this bit is overloaded to provide + * the qualifier to distinguish input pull-up and -down: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...V .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 8) /* Bit 8: If output, initial value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* External interrupt selection (GPIO inputs only): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...X .... .... + */ + +#define GPIO_EXTI (1 << 8) /* Bit 8: Configure as EXTI interrupt */ + +/* This identifies the GPIO port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... PPPP .... + * + * STM32N6 has ports A-H (0-7) and N, O, P, Q (8-11). + */ + +#define GPIO_PORT_SHIFT (4) /* Bit 4-7: Port number */ +#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) /* GPIOA */ +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) /* GPIOB */ +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) /* GPIOC */ +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) /* GPIOF */ +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) /* GPIOG */ +# define GPIO_PORTH (7 << GPIO_PORT_SHIFT) /* GPIOH */ +# define GPIO_PORTN (8 << GPIO_PORT_SHIFT) /* GPION */ +# define GPIO_PORTO (9 << GPIO_PORT_SHIFT) /* GPIOO */ +# define GPIO_PORTP (10 << GPIO_PORT_SHIFT) /* GPIOP */ +# define GPIO_PORTQ (11 << GPIO_PORT_SHIFT) /* GPIOQ */ + +/* This identifies the bit in the port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... .... BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Base addresses for each GPIO block */ + +EXTERN const uint32_t g_gpiobase[STM32N6_NPORTS]; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with stm32_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returned Value: + * OK on success + * ERROR on invalid port, or when pin is locked as ALT function. + * + ****************************************************************************/ + +int stm32_configgpio(uint32_t cfgset); + +/**************************************************************************** + * Name: stm32_unconfiggpio + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin, set + * it into default HiZ state (and possibly mark it's unused) and unlock it + * whether it was previously selected as alternative function + * (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from shocks, as + * unexpected write to the Timer Channel Output GPIO to fixed '1' or '0' + * while it should operate in PWM mode could produce excessive on-board + * currents and trigger over-current/alarm function. + * + * Returned Value: + * OK on success + * ERROR on invalid port + * + ****************************************************************************/ + +int stm32_unconfiggpio(uint32_t cfgset); + +/**************************************************************************** + * Name: stm32_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void stm32_gpiowrite(uint32_t pinset, bool value); + +/**************************************************************************** + * Name: stm32_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool stm32_gpioread(uint32_t pinset); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32N6_STM32_GPIO_H */ diff --git a/arch/arm/src/stm32n6/stm32_idle.c b/arch/arm/src/stm32n6/stm32_idle.c new file mode 100644 index 0000000000000..9cfee2870a5e2 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_idle.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_idle.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "nvic.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when there is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + nxsched_process_timer(); +#else + /* SLEEPDEEP is cleared once at boot in __start_c() so that WFI here + * enters plain SLEEP mode -- the system clock keeps running and SysTick + * continues to fire, waking the CPU on the next tick. + */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +} diff --git a/arch/arm/src/stm32n6/stm32_irq.c b/arch/arm/src/stm32n6/stm32_irq.c new file mode 100644 index 0000000000000..5f9f3118b1f66 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_irq.c @@ -0,0 +1,473 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_irq.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "arm_internal.h" +#include "stm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ_INFO) +static void stm32_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + irqinfo("NVIC (%s, irq=%d):\n", msg, irq); + irqinfo(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); + irqinfo(" IRQ ENABLE: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE), getreg32(NVIC_IRQ96_127_ENABLE)); + irqinfo(" %08x %08x %08x\n", + getreg32(NVIC_IRQ128_159_ENABLE), getreg32(NVIC_IRQ160_191_ENABLE), + getreg32(NVIC_IRQ192_223_ENABLE)); + irqinfo(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + irqinfo(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), + getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); + + leave_critical_section(flags); +} +#else +# define stm32_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: stm32_nmi, stm32_pendsv, stm32_reserved + * + * Description: + * Handlers for various exceptions. None are handled and all are fatal + * error conditions. The only advantage these provide over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +static int stm32_nmi(int irq, void *context, void *arg) +{ + up_irq_save(); + _err("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int stm32_pendsv(int irq, void *context, void *arg) +{ + up_irq_save(); + _err("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int stm32_reserved(int irq, void *context, void *arg) +{ + up_irq_save(); + _err("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +static inline void stm32_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} + +/**************************************************************************** + * Name: stm32_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int stm32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + int n; + + DEBUGASSERT(irq >= STM32_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= STM32_IRQ_FIRST) + { + n = irq - STM32_IRQ_FIRST; + *regaddr = NVIC_IRQ_ENABLE(n) + offset; + *bit = (uint32_t)1 << (n & 0x1f); + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == STM32_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == STM32_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == STM32_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == STM32_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int num_priority_registers; + int i; + + /* Disable all interrupts */ + + for (i = 0; i < NR_IRQS - STM32_IRQ_FIRST; i += 32) + { + putreg32(0xffffffff, NVIC_IRQ_CLEAR(i)); + } + + /* The standard location for the vector table is at the beginning of FLASH + * at address 0x0800:0000. STM32N6 has no internal flash, so the vector + * table will be in SRAM or external memory, and we need to set the NVIC + * vector location accordingly. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports: + * + * 0 -> 32 interrupt lines, 8 priority registers + * 1 -> 64 " " " ", 16 priority registers + * 2 -> 96 " " " ", 32 priority registers + * ... + */ + + num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8; + + /* Now set all of the interrupt lines to the default priority */ + + regaddr = NVIC_IRQ0_3_PRIORITY; + while (num_priority_registers--) + { + putreg32(DEFPRIORITY32, regaddr); + regaddr += 4; + } + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(STM32_IRQ_SVCALL, arm_svcall, NULL); + irq_attach(STM32_IRQ_HARDFAULT, arm_hardfault, NULL); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + + /* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ + +#endif + + stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(STM32_IRQ_MEMFAULT, arm_memfault, NULL); + + /* NOTE: Do NOT call up_enable_irq(STM32_IRQ_MEMFAULT) here. + * On Cortex-M55 in Secure state, setting MEMFAULTENA in SHCSR causes + * D-cache set/way operations (DCCISW) to silently fail, breaking DMA + * cache coherency. MemFault escalates to HardFault when disabled, + * which is acceptable -- the arm_hardfault handler is always attached. + * + * Diagnostics are not lost: escalated faults still populate CFSR MMFSR + * bits and MMFAR, and arm_hardfault checks HFSR.FORCED to decode them. + * The only trade-off is losing independent MemManage priority/preemption, + * which is irrelevant since all faults are fatal in this configuration. + */ +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG_FEATURES + irq_attach(STM32_IRQ_NMI, stm32_nmi, NULL); +#ifndef CONFIG_ARM_MPU + irq_attach(STM32_IRQ_MEMFAULT, arm_memfault, NULL); +#endif + irq_attach(STM32_IRQ_BUSFAULT, arm_busfault, NULL); + irq_attach(STM32_IRQ_USAGEFAULT, arm_usagefault, NULL); + irq_attach(STM32_IRQ_PENDSV, stm32_pendsv, NULL); + arm_enable_dbgmonitor(); + irq_attach(STM32_IRQ_DBGMONITOR, arm_dbgmonitor, NULL); + irq_attach(STM32_IRQ_RESERVED, stm32_reserved, NULL); +#endif + + stm32_dumpnvic("initial", NR_IRQS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + arm_color_intstack(); + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (stm32_irqinfo(irq, ®addr, &bit, NVIC_CLRENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= STM32_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (stm32_irqinfo(irq, ®addr, &bit, NVIC_ENA_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= STM32_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } +} + +/**************************************************************************** + * Name: arm_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void arm_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < STM32_IRQ_FIRST) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= 4; + } + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= STM32_IRQ_FIRST; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + stm32_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/stm32n6/stm32_lowputc.c b/arch/arm/src/stm32n6/stm32_lowputc.c new file mode 100644 index 0000000000000..68f297161943c --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_lowputc.c @@ -0,0 +1,257 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_lowputc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "arm_internal.h" +#include "chip.h" + +#include "stm32.h" +#include "stm32_rcc.h" +#include "stm32_gpio.h" +#include "stm32_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select USART parameters for the selected console. Only USART1 is + * supported in this initial port. + */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_USART1_SERIAL_CONSOLE) +# define STM32N6_CONSOLE_BASE STM32_USART1_BASE +# define STM32N6_APBCLOCK STM32_HSI_FREQUENCY /* USART1SEL=HSI via CCIPR13 */ +# define STM32N6_CONSOLE_APBREG STM32_RCC_APB2ENSR +# define STM32N6_CONSOLE_APBEN RCC_APB2ENR_USART1EN +# define STM32N6_CONSOLE_BAUD CONFIG_USART1_BAUD +# define STM32N6_CONSOLE_BITS CONFIG_USART1_BITS +# define STM32N6_CONSOLE_PARITY CONFIG_USART1_PARITY +# define STM32N6_CONSOLE_2STOP CONFIG_USART1_2STOP +# define STM32N6_CONSOLE_TX GPIO_USART1_TX +# define STM32N6_CONSOLE_RX GPIO_USART1_RX +# endif + + /* CR1 settings */ + +# if STM32N6_CONSOLE_BITS == 9 +# define USART_CR1_M0_VALUE USART_CR1_M0 +# define USART_CR1_M1_VALUE 0 +# elif STM32N6_CONSOLE_BITS == 7 +# define USART_CR1_M0_VALUE 0 +# define USART_CR1_M1_VALUE USART_CR1_M1 +# else /* 8 bits */ +# define USART_CR1_M0_VALUE 0 +# define USART_CR1_M1_VALUE 0 +# endif + +# if STM32N6_CONSOLE_PARITY == 1 /* odd parity */ +# define USART_CR1_PARITY_VALUE (USART_CR1_PCE|USART_CR1_PS) +# elif STM32N6_CONSOLE_PARITY == 2 /* even parity */ +# define USART_CR1_PARITY_VALUE USART_CR1_PCE +# else /* no parity */ +# define USART_CR1_PARITY_VALUE 0 +# endif + +# define USART_CR1_CLRBITS \ + (USART_CR1_UE | USART_CR1_UESM | USART_CR1_RE | USART_CR1_TE | USART_CR1_PS | \ + USART_CR1_PCE | USART_CR1_WAKE | USART_CR1_M0 | USART_CR1_M1 | \ + USART_CR1_MME | USART_CR1_OVER8 | USART_CR1_DEDT_MASK | \ + USART_CR1_DEAT_MASK | USART_CR1_ALLINTS) + +# define USART_CR1_SETBITS (USART_CR1_M0_VALUE|USART_CR1_M1_VALUE|USART_CR1_PARITY_VALUE) + + /* CR2 settings */ + +# if STM32N6_CONSOLE_2STOP != 0 +# define USART_CR2_STOP2_VALUE USART_CR2_STOP2 +# else +# define USART_CR2_STOP2_VALUE 0 +# endif + +# define USART_CR2_CLRBITS \ + (USART_CR2_ADDM7 | USART_CR2_LBDL | USART_CR2_LBDIE | USART_CR2_LBCL | \ + USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_STOP_MASK | \ + USART_CR2_LINEN | USART_CR2_SWAP | USART_CR2_RXINV | USART_CR2_TXINV | \ + USART_CR2_DATAINV | USART_CR2_MSBFIRST | USART_CR2_ABREN | \ + USART_CR2_ABRMOD_MASK | USART_CR2_RTOEN | USART_CR2_ADD_MASK) + +# define USART_CR2_SETBITS USART_CR2_STOP2_VALUE + + /* CR3 settings */ + +# define USART_CR3_CLRBITS \ + (USART_CR3_EIE | USART_CR3_IREN | USART_CR3_IRLP | USART_CR3_HDSEL | \ + USART_CR3_NACK | USART_CR3_SCEN | USART_CR3_DMAR | USART_CR3_DMAT | \ + USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_CTSIE | USART_CR3_ONEBIT | \ + USART_CR3_OVRDIS | USART_CR3_DDRE | USART_CR3_DEM | USART_CR3_DEP | \ + USART_CR3_SCARCNT2_MASK | USART_CR3_WUS_MASK | USART_CR3_WUFIE) + +# define USART_CR3_SETBITS 0 + +# undef USE_OVER8 + + /* Calculate USART BAUD rate divider. + * + * Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / UARTDIV + * UARTDIV = fCK / baud + * + * In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / UARTDIV + * UARTDIV = 2 * fCK / baud + */ + +# define STM32N6_USARTDIV8 \ + (((STM32N6_APBCLOCK << 1) + (STM32N6_CONSOLE_BAUD >> 1)) / STM32N6_CONSOLE_BAUD) +# define STM32N6_USARTDIV16 \ + ((STM32N6_APBCLOCK + (STM32N6_CONSOLE_BAUD >> 1)) / STM32N6_CONSOLE_BAUD) + + /* Pick OVER8 only when the divisor is small enough that the loss of + * the low BRR bit (DIV_FRACTION[0]) does not exceed half a step. + */ + +# if STM32N6_USARTDIV8 > 2000 +# define STM32N6_BRR_VALUE STM32N6_USARTDIV16 +# else +# define USE_OVER8 1 +# define STM32N6_BRR_VALUE \ + ((STM32N6_USARTDIV8 & 0xfff0) | ((STM32N6_USARTDIV8 & 0x000f) >> 1)) +# endif +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void arm_lowputc(char ch) +{ +#ifdef HAVE_CONSOLE + while ((getreg32(STM32N6_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & + USART_ISR_TXE) == 0); + + putreg32((uint32_t)ch, STM32N6_CONSOLE_BASE + STM32_USART_TDR_OFFSET); +#endif +} + +/**************************************************************************** + * Name: stm32_lowsetup + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output available as soon + * as possible. + * + ****************************************************************************/ + +void stm32_lowsetup(void) +{ +#if defined(HAVE_UART) +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint32_t cr; +#endif + +#if defined(HAVE_CONSOLE) + /* Use the write-1-to-set ENSR alias rather than RMW on ENR so we do + * not race other producers of the clock-enable bitmap. + */ + + putreg32(STM32N6_CONSOLE_APBEN, STM32N6_CONSOLE_APBREG); +#endif + +#ifdef STM32N6_CONSOLE_TX + stm32_configgpio(STM32N6_CONSOLE_TX); +#endif +#ifdef STM32N6_CONSOLE_RX + stm32_configgpio(STM32N6_CONSOLE_RX); +#endif + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + cr = getreg32(STM32N6_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + cr &= ~USART_CR2_CLRBITS; + cr |= USART_CR2_SETBITS; + putreg32(cr, STM32N6_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + + cr = getreg32(STM32N6_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + cr &= ~USART_CR1_CLRBITS; + cr |= USART_CR1_SETBITS; + putreg32(cr, STM32N6_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + + cr = getreg32(STM32N6_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + cr &= ~USART_CR3_CLRBITS; + cr |= USART_CR3_SETBITS; + putreg32(cr, STM32N6_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + + putreg32(STM32N6_BRR_VALUE, + STM32N6_CONSOLE_BASE + STM32_USART_BRR_OFFSET); + + cr = getreg32(STM32N6_CONSOLE_BASE + STM32_USART_CR1_OFFSET); +#ifdef USE_OVER8 + cr |= USART_CR1_OVER8; + putreg32(cr, STM32N6_CONSOLE_BASE + STM32_USART_CR1_OFFSET); +#endif + + cr |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + putreg32(cr, STM32N6_CONSOLE_BASE + STM32_USART_CR1_OFFSET); +#endif +#endif +} diff --git a/arch/arm/src/stm32n6/stm32_lowputc.h b/arch/arm/src/stm32n6/stm32_lowputc.h new file mode 100644 index 0000000000000..3aece326180e2 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_lowputc.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_lowputc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_STM32_LOWPUTC_H +#define __ARCH_ARM_SRC_STM32N6_STM32_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: stm32_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization of serial console. + * + ****************************************************************************/ + +void stm32_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32N6_STM32_LOWPUTC_H */ diff --git a/arch/arm/src/stm32n6/stm32_pwr.c b/arch/arm/src/stm32n6/stm32_pwr.c new file mode 100644 index 0000000000000..1ae3f54cd286d --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_pwr.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_pwr.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "arm_internal.h" +#include "stm32_pwr.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pwr_enablebkp + * + * Description: + * Enables write access to the backup domain (RTC registers, RTC backup + * data registers and backup SRAM). + * + * Input Parameters: + * writable - True: enable ability to write to backup domain registers + * + * Returned Value: + * True: The backup domain was previously writable. + * + ****************************************************************************/ + +bool stm32_pwr_enablebkp(bool writable) +{ + uint32_t regval; + bool waswritable; + + regval = getreg32(STM32_PWR_DBPCR); + waswritable = ((regval & PWR_DBPCR_DBP) != 0); + + if (writable) + { + regval |= PWR_DBPCR_DBP; + } + else + { + regval &= ~PWR_DBPCR_DBP; + } + + putreg32(regval, STM32_PWR_DBPCR); + + return waswritable; +} + +/**************************************************************************** + * Name: stm32_pwr_enablevddio + * + * Description: + * Mark a set of I/O voltage domains as supply-valid in PWR SVMCR3 and + * optionally select their VRSEL (1.8 V) range. The board passes the + * bitmask of PWR_SVMCR3_* bits matching the GPIO ports it uses. + * + * Input Parameters: + * mask - OR of PWR_SVMCR3_VDDIOxSV and PWR_SVMCR3_VDDIOxVRSEL bits. + * + ****************************************************************************/ + +void stm32_pwr_enablevddio(uint32_t mask) +{ + modifyreg32(STM32_PWR_SVMCR3, 0, mask); +} diff --git a/arch/arm/src/stm32n6/stm32_pwr.h b/arch/arm/src/stm32n6/stm32_pwr.h new file mode 100644 index 0000000000000..6b85c8ab3c192 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_pwr.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_pwr.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_STM32_PWR_H +#define __ARCH_ARM_SRC_STM32N6_STM32_PWR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "hardware/stm32n6xxx_pwr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pwr_enablebkp + * + * Description: + * Enables write access to the backup domain (RTC registers, RTC backup + * data registers and backup SRAM). + * + * Input Parameters: + * writable - True: enable ability to write to backup domain registers + * + * Returned Value: + * True: The backup domain was previously writable. + * + ****************************************************************************/ + +bool stm32_pwr_enablebkp(bool writable); + +/**************************************************************************** + * Name: stm32_pwr_enablevddio + * + * Description: + * Mark a set of I/O voltage domains as supply-valid in PWR SVMCR3. + * The board passes an OR of PWR_SVMCR3_VDDIOxSV (and optionally + * PWR_SVMCR3_VDDIOxVRSEL for the 1.8 V range) bits matching the GPIO + * ports it uses. + * + ****************************************************************************/ + +void stm32_pwr_enablevddio(uint32_t mask); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32N6_STM32_PWR_H */ diff --git a/arch/arm/src/stm32n6/stm32_rcc.c b/arch/arm/src/stm32n6/stm32_rcc.c new file mode 100644 index 0000000000000..11054f26f7081 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_rcc.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_rcc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "arm_internal.h" +#include "chip.h" +#include "stm32_rcc.h" +#include "stm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_clockconfig + * + * Description: + * Establish the clock tree from the values in board.h, then enable the + * peripheral clocks needed by the chip. + * + ****************************************************************************/ + +void stm32_clockconfig(void) +{ + stm32_stdclockconfig(); + stm32_rcc_enableperipherals(); +} + +/**************************************************************************** + * Name: stm32_clockenable + * + * Description: + * Re-enable the clock and restore the clock settings based on settings in + * board.h. This function is only available to support low-power modes of + * operation: When re-awakening from deep-sleep modes, it is necessary to + * re-enable/re-start the PLL. + * + * This function performs a subset of the operations performed by + * stm32_clockconfig(): It does not reset any devices, and it does not + * reset the currently enabled peripheral clocks. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_PM +void stm32_clockenable(void) +{ + stm32_stdclockconfig(); +} +#endif diff --git a/arch/arm/src/stm32n6/stm32_rcc.h b/arch/arm/src/stm32n6/stm32_rcc.h new file mode 100644 index 0000000000000..0ad0049087171 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_rcc.h @@ -0,0 +1,120 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_rcc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_STM32_RCC_H +#define __ARCH_ARM_SRC_STM32N6_STM32_RCC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm_internal.h" +#include "chip.h" + +#include "hardware/stm32n6xxx_rcc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void stm32_clockconfig(void); + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * The standard logic to configure the clocks based on settings in board.h. + * This function is chip type specific and implemented in stm32n6xx_rcc.c. + * + ****************************************************************************/ + +void stm32_stdclockconfig(void); + +/**************************************************************************** + * Name: stm32_clockenable + * + * Description: + * Re-enable the clock and restore the clock settings based on settings in + * board.h. This function is only available to support low-power modes of + * operation: When re-awakening from deep-sleep modes, it is necessary to + * re-enable/re-start the PLL + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_PM +void stm32_clockenable(void); +#endif + +/**************************************************************************** + * Name: stm32_rcc_enableperipherals + * + * Description: + * Enable all the chip peripherals according to configuration. This is + * chip type specific and thus implemented in stm32n6xx_rcc.c. + * + ****************************************************************************/ + +void stm32_rcc_enableperipherals(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32N6_STM32_RCC_H */ diff --git a/arch/arm/src/stm32n6/stm32_serial.c b/arch/arm/src/stm32n6/stm32_serial.c new file mode 100644 index 0000000000000..d6972700da69c --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_serial.c @@ -0,0 +1,1772 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_serial.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_uart.h" + +#include "stm32_rcc.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Power management definitions */ + +#if defined(CONFIG_PM) && !defined(CONFIG_STM32N6_PM_SERIAL_ACTIVITY) +# define CONFIG_STM32N6_PM_SERIAL_ACTIVITY 10 +#endif + +/* USART Unconfigure bits */ + +#define USART_UNCONFIGURE_RX (1 << 0) +#define USART_UNCONFIGURE_TX (1 << 1) + +/* Keep track if a Break was set + * + * Note: + * + * 1) This value is set in the priv->ie but never written to the control + * register. It must not collide with USART_CR1_USED_INTS or USART_CR3_EIE + * 2) USART_CR3_EIE is also carried in the up_dev_s ie member. + * + * See stm32serial_restoreusartint where the masking is done. + */ + +#ifdef CONFIG_STM32N6_SERIALBRK_BSDCOMPAT +# define USART_CR1_IE_BREAK_INPROGRESS_SHFTS 15 +# define USART_CR1_IE_BREAK_INPROGRESS (1 << USART_CR1_IE_BREAK_INPROGRESS_SHFTS) +#endif + +#ifdef USE_SERIALDRIVER +#ifdef HAVE_UART + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct stm32_serial_s +{ + struct uart_dev_s dev; /* Generic UART device */ + uint16_t ie; /* Saved interrupt mask bits value */ + uint16_t sr; /* Saved status bits */ + + /* Has been initialized and HW is setup. */ + + bool initialized; + +#ifdef CONFIG_PM + bool suspended; /* UART device has been suspended. */ + + /* Interrupt mask value stored before suspending for stop mode. */ + + uint16_t suspended_ie; +#endif + + /* If termios are supported, then the following fields may vary at + * runtime. + */ + +#ifdef CONFIG_SERIAL_TERMIOS + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_OFLOWCONTROL + bool oflow; /* output flow control (CTS) enabled */ +#endif + uint32_t baud; /* Configured baud */ +#else + const uint8_t parity; /* 0=none, 1=odd, 2=even */ + const uint8_t bits; /* Number of bits (7 or 8) */ + const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const bool oflow; /* output flow control (CTS) enabled */ +#endif + const uint32_t baud; /* Configured baud */ +#endif + const uint8_t irq; /* IRQ associated with this USART */ + const uint32_t apbclock; /* PCLK 1 or 2 frequency */ + const uint32_t usartbase; /* Base address of USART registers */ + const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ + const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */ +#endif + const bool iflow; /* input flow control (RTS) enabled */ + + const uint8_t unconfigure; /* Unconfigure pins on close */ + spinlock_t lock; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_UART_CONFIG +static void stm32serial_setformat(struct uart_dev_s *dev); +#endif +static int stm32serial_setup(struct uart_dev_s *dev); +static void stm32serial_shutdown(struct uart_dev_s *dev); +static int stm32serial_attach(struct uart_dev_s *dev); +static void stm32serial_detach(struct uart_dev_s *dev); +static int stm32serial_interrupt(int irq, void *context, void *arg); +static int stm32serial_ioctl(struct file *filep, + int cmd, unsigned long arg); +static int stm32serial_receive(struct uart_dev_s *dev, + unsigned int *status); +static void stm32serial_rxint(struct uart_dev_s *dev, bool enable); +static bool stm32serial_rxavailable(struct uart_dev_s *dev); +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool stm32serial_rxflowcontrol(struct uart_dev_s *dev, + unsigned int nbuffered, bool upper); +#endif +static void stm32serial_send(struct uart_dev_s *dev, int ch); +static void stm32serial_txint(struct uart_dev_s *dev, bool enable); +static bool stm32serial_txready(struct uart_dev_s *dev); + +#ifdef CONFIG_PM +static void stm32serial_setsuspend(struct uart_dev_s *dev, bool suspend); +static void stm32serial_pm_setsuspend(bool suspend); +static void stm32serial_pmnotify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +static int stm32serial_pmprepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = stm32serial_setup, + .shutdown = stm32serial_shutdown, + .attach = stm32serial_attach, + .detach = stm32serial_detach, + .ioctl = stm32serial_ioctl, + .receive = stm32serial_receive, + .rxint = stm32serial_rxint, + .rxavailable = stm32serial_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = stm32serial_rxflowcontrol, +#endif + .send = stm32serial_send, + .txint = stm32serial_txint, + .txready = stm32serial_txready, + .txempty = stm32serial_txready, +}; + +/* I/O buffers */ + +#ifdef CONFIG_STM32N6_USART1_SERIALDRIVER +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +#endif + +/* This describes the state of the STM32N6 USART1 port. */ + +#ifdef CONFIG_STM32N6_USART1_SERIALDRIVER +static struct stm32_serial_s g_usart1priv = +{ + .dev = + { +# if CONSOLE_UART == 1 + .isconsole = true, +# endif + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_usart1priv, + }, + + .irq = STM32_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, + .baud = CONFIG_USART1_BAUD, + .apbclock = STM32_HSI_FREQUENCY, /* USART1SEL=HSI via CCIPR13 */ + .usartbase = STM32_USART1_BASE, + .tx_gpio = GPIO_USART1_TX, + .rx_gpio = GPIO_USART1_RX, +# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART1_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART1_CTS, +# endif +# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART1_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART1_RTS, +# endif + + .lock = SP_UNLOCKED, + .unconfigure = 0 +#if defined(CONFIG_USART1_UNCONFIG_RX_ON_CLOSE) + | + USART_UNCONFIGURE_RX +#endif +#if defined(CONFIG_USART1_UNCONFIG_TX_ON_CLOSE) + | + USART_UNCONFIGURE_TX +#endif + , +}; +#endif + +/* This table lets us iterate over the configured USARTs */ + +static struct stm32_serial_s * const + g_uart_devs[STM32N6_NUSART] = +{ +#ifdef CONFIG_STM32N6_USART1_SERIALDRIVER + [0] = &g_usart1priv, +#endif +}; + +#ifdef CONFIG_PM +struct serialpm_s +{ + struct pm_callback_s pm_cb; + bool serial_suspended; +}; + +static struct serialpm_s g_serialpm = +{ + .pm_cb.notify = stm32serial_pmnotify, + .pm_cb.prepare = stm32serial_pmprepare, + .serial_suspended = false +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32serial_getreg + ****************************************************************************/ + +static inline +uint32_t stm32serial_getreg(struct stm32_serial_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: stm32serial_putreg + ****************************************************************************/ + +static inline +void stm32serial_putreg(struct stm32_serial_s *priv, + int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: stm32serial_setusartint + ****************************************************************************/ + +static inline +void stm32serial_setusartint(struct stm32_serial_s *priv, + uint16_t ie) +{ + uint32_t cr; + + /* Save the interrupt mask */ + + priv->ie = ie; + + /* And restore the interrupt state (see the interrupt enable/usage table + * above) + */ + + cr = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + cr &= ~(USART_CR1_USED_INTS); + cr |= (ie & (USART_CR1_USED_INTS)); + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr); + + cr = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); + cr &= ~USART_CR3_EIE; + cr |= (ie & USART_CR3_EIE); + stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, cr); +} + +/**************************************************************************** + * Name: stm32serial_restoreusartint + ****************************************************************************/ + +static void stm32serial_restoreusartint(struct stm32_serial_s *priv, + uint16_t ie) +{ + irqstate_t flags; + + flags = spin_lock_irqsave(&priv->lock); + + stm32serial_setusartint(priv, ie); + + spin_unlock_irqrestore(&priv->lock, flags); +} + +/**************************************************************************** + * Name: stm32serial_disableusartint + ****************************************************************************/ + +static void stm32serial_disableusartint(struct stm32_serial_s *priv, + uint16_t *ie) +{ + irqstate_t flags; + + flags = spin_lock_irqsave(&priv->lock); + + if (ie) + { + uint32_t cr1; + uint32_t cr3; + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ---------------- -------------- ---------------------- ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready + * to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register + * Empty + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NF Noise Flag + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + */ + + cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + cr3 = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); + + /* Return the current interrupt mask value for the used interrupts. + * Notice that this depends on the fact that none of the used interrupt + * enable bits overlap. This logic would fail if we needed the break + * interrupt! + */ + + *ie = (cr1 & (USART_CR1_USED_INTS)) | (cr3 & USART_CR3_EIE); + } + + /* Disable all interrupts */ + + stm32serial_setusartint(priv, 0); + + spin_unlock_irqrestore(&priv->lock, flags); +} + +/**************************************************************************** + * Name: stm32serial_setformat + * + * Description: + * Set the serial line format and speed. + * + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_UART_CONFIG +static void stm32serial_setformat(struct uart_dev_s *dev) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + uint32_t regval; + uint32_t brr; + uint32_t cr1; + uint32_t usartdiv8; + + /* In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / usartdiv8 + * usartdiv8 = 2 * fCK / baud + */ + + usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; + + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / usartdiv16 + * usartdiv16 = fCK / baud + * = 2 * usartdiv8 + */ + + /* Use oversampling by 8 only if divisor is small. But what is small? */ + + cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + if (usartdiv8 > 2000) + { + /* Use usartdiv16 */ + + brr = (usartdiv8 + 1) >> 1; + + /* Clear oversampling by 8 to enable oversampling by 16 */ + + cr1 &= ~USART_CR1_OVER8; + } + else + { + DEBUGASSERT(usartdiv8 >= 8); + + /* Perform mysterious operations on bits 0-3 */ + + brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); + + /* Set oversampling by 8 */ + + cr1 |= USART_CR1_OVER8; + } + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); + stm32serial_putreg(priv, STM32_USART_BRR_OFFSET, brr); + + /* Configure parity mode */ + + regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0 | USART_CR1_M1); + + if (priv->parity == 1) /* Odd parity */ + { + regval |= (USART_CR1_PCE | USART_CR1_PS); + } + else if (priv->parity == 2) /* Even parity */ + { + regval |= USART_CR1_PCE; + } + + /* Configure word length (parity uses one of configured bits) + * + * Default: 1 start, 8 data (no parity), n stop, OR + * 1 start, 7 data + parity, n stop + */ + + if (priv->bits == 9 || (priv->bits == 8 && priv->parity != 0)) + { + /* Select: 1 start, 8 data + parity, n stop, OR + * 1 start, 9 data (no parity), n stop. + */ + + regval |= USART_CR1_M0; + } + else if (priv->bits == 7 && priv->parity == 0) + { + /* Select: 1 start, 7 data (no parity), n stop */ + + regval |= USART_CR1_M1; + } + + /* Else Select: 1 start, 7 data + parity, n stop, OR + * 1 start, 8 data (no parity), n stop. + */ + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); + + /* Configure STOP bits */ + + regval = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK); + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + stm32serial_putreg(priv, STM32_USART_CR2_OFFSET, regval); + + /* Configure hardware flow control */ + + regval = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSE | USART_CR3_RTSE); + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && !defined(CONFIG_STM32N6_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + regval |= USART_CR3_RTSE; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow && (priv->cts_gpio != 0)) + { + regval |= USART_CR3_CTSE; + } +#endif + + stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); +} +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + +/**************************************************************************** + * Name: stm32serial_setsuspend + * + * Description: + * Suspend or resume serial peripheral. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void stm32serial_setsuspend(struct uart_dev_s *dev, bool suspend) +{ + struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; + + if (priv->suspended == suspend) + { + return; + } + + priv->suspended = suspend; + + if (suspend) + { +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Force RTS high to prevent further Rx. */ + + stm32_configgpio((priv->rts_gpio & ~GPIO_MODE_MASK) + | (GPIO_OUTPUT | GPIO_OUTPUT_SET)); + } +#endif + + /* Disable interrupts to prevent Tx. */ + + stm32serial_disableusartint(priv, &priv->suspended_ie); + + /* Wait last Tx to complete. */ + + while ((stm32serial_getreg(priv, STM32_USART_ISR_OFFSET) & + USART_ISR_TC) == 0); + } + else + { + /* Re-enable interrupts to resume Tx. */ + + stm32serial_restoreusartint(priv, priv->suspended_ie); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Restore peripheral RTS control. */ + + stm32_configgpio(priv->rts_gpio); + } +#endif + } +} +#endif + +/**************************************************************************** + * Name: stm32serial_pm_setsuspend + * + * Description: + * Suspend or resume serial peripherals for/from deep-sleep/stop modes. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void stm32serial_pm_setsuspend(bool suspend) +{ + int n; + + /* Already in desired state? */ + + if (suspend == g_serialpm.serial_suspended) + return; + + g_serialpm.serial_suspended = suspend; + + for (n = 0; n < STM32N6_NUSART; n++) + { + struct stm32_serial_s *priv = g_uart_devs[n]; + + if (!priv || !priv->initialized) + { + continue; + } + + stm32serial_setsuspend(&priv->dev, suspend); + } +} +#endif + +/**************************************************************************** + * Name: stm32serial_setapbclock + * + * Description: + * Enable or disable APB clock for the USART peripheral + * + * Input Parameters: + * dev - A reference to the UART driver state structure + * on - Enable clock if 'on' is 'true' and disable if 'false' + * + ****************************************************************************/ + +static void stm32serial_setapbclock(struct uart_dev_s *dev, bool on) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + uint32_t rcc_en; + uint32_t regaddr_set; + uint32_t regaddr_clr; + + /* Determine which USART to configure */ + + switch (priv->usartbase) + { + default: + return; +#ifdef CONFIG_STM32N6_USART1_SERIALDRIVER + case STM32_USART1_BASE: + rcc_en = RCC_APB2ENR_USART1EN; + regaddr_set = STM32_RCC_APB2ENSR; + regaddr_clr = STM32_RCC_APB2ENCR; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for USART. + * Use atomic SET/CLEAR registers (ENSR/ENCR) instead of read-modify-write + * on ENR because the RCC's internal RIF security may block ENR access. + */ + + if (on) + { + putreg32(rcc_en, regaddr_set); + } + else + { + putreg32(rcc_en, regaddr_clr); + } +} + +/**************************************************************************** + * Name: stm32serial_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int stm32serial_setup(struct uart_dev_s *dev) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t regval; + + /* Note: The logic here depends on the fact that that the USART module + * was enabled in stm32_lowsetup(). + */ + + /* Enable USART APB1/2 clock */ + + stm32serial_setapbclock(dev, true); + + /* Configure pins for USART use */ + + stm32_configgpio(priv->tx_gpio); + stm32_configgpio(priv->rx_gpio); + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32_configgpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + uint32_t config = priv->rts_gpio; + +#ifdef CONFIG_STM32N6_FLOWCONTROL_BROKEN + /* Instead of letting hw manage this pin, we will bitbang */ + + config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; +#endif + stm32_configgpio(config); + } +#endif + + /* Configure CR2 */ + + /* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */ + + regval = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | + USART_CR2_CPHA | USART_CR2_LBCL | USART_CR2_LBDIE); + + /* Configure STOP bits */ + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + stm32serial_putreg(priv, STM32_USART_CR2_OFFSET, regval); + + /* Configure CR1 */ + + /* Clear UE, TE, RE, and all interrupt enable bits. + * UE must be cleared so FIFOEN can be set when re-enabling. + */ + + regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | + USART_CR1_ALLINTS); + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); + + /* Configure CR3 */ + + /* Clear CTSE, RTSE, and all interrupt enable bits */ + + regval = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | + USART_CR3_EIE); + + stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); + + /* Configure the USART line format and speed. */ + + stm32serial_setformat(dev); + + /* Enable Rx, Tx, and the USART */ + + regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | + USART_CR1_FIFOEN); + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); + +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + + /* Set up the cached interrupt enables value */ + + priv->ie = 0; + + /* Mark device as initialized. */ + + priv->initialized = true; + + return OK; +} + +/**************************************************************************** + * Name: stm32serial_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void stm32serial_shutdown(struct uart_dev_s *dev) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + uint32_t regval; + + /* Mark device as uninitialized. */ + + priv->initialized = false; + + /* Disable all interrupts */ + + stm32serial_disableusartint(priv, NULL); + + /* Disable USART APB1/2 clock */ + + stm32serial_setapbclock(dev, false); + + /* Disable Rx, Tx, and the UART */ + + regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); + + /* Release pins. "If the serial-attached device is powered down, the TX + * pin causes back-powering, potentially confusing the device to the point + * of complete lock-up." + * + * REVISIT: Is unconfiguring the pins appropriate for all devices? If + * not, then this may need to be a configuration option. + */ + + if (priv->unconfigure & USART_UNCONFIGURE_TX) + { + stm32_unconfiggpio(priv->tx_gpio); + } + + if (priv->unconfigure & USART_UNCONFIGURE_RX) + { + stm32_unconfiggpio(priv->rx_gpio); + } + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32_unconfiggpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + stm32_unconfiggpio(priv->rts_gpio); + } +#endif +} + +/**************************************************************************** + * Name: stm32serial_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method + * is called when the serial port is opened. Normally, this is just after + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless + * the hardware supports multiple levels of interrupt enabling). The RX + * and TX interrupts are not enabled until the txint() and rxint() methods + * are called. + * + ****************************************************************************/ + +static int stm32serial_attach(struct uart_dev_s *dev) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, stm32serial_interrupt, priv); + + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32serial_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The + * exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void stm32serial_detach(struct uart_dev_s *dev) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: stm32serial_interrupt + * + * Description: + * This is the USART interrupt handler. It will be invoked when an + * interrupt is received on the 'irq'. It should call uart_xmitchars or + * uart_recvchars to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'arg' to the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int stm32serial_interrupt(int irq, void *context, void *arg) +{ + struct stm32_serial_s *priv = (struct stm32_serial_s *)arg; + int passes; + bool handled; + DEBUGASSERT(priv != NULL); + + /* Report serial activity to the power management logic */ + +#if defined(CONFIG_PM) && CONFIG_STM32N6_PM_SERIAL_ACTIVITY > 0 + pm_activity(PM_IDLE_DOMAIN, CONFIG_STM32N6_PM_SERIAL_ACTIVITY); +#endif + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the masked USART status word. */ + + priv->sr = stm32serial_getreg(priv, STM32_USART_ISR_OFFSET); + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ---------------- -------------- ---------------------- ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to + * be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register + * Empty + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NE Noise Error + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + * + * NOTE: Some of these status bits must be cleared by explicitly + * writing one to the ICR register: USART_ICR_CTSCF, USART_ICR_LBDCF. + * None of those are currently being used. + */ + + /* Handle incoming, receive bytes. */ + + if ((priv->sr & USART_ISR_RXNE) != 0 && + (priv->ie & USART_CR1_RXNEIE) != 0) + { + /* Received data ready... process incoming bytes. NOTE the check + * for RXNEIE: We cannot call uart_recvchars if RX interrupts are + * disabled. + */ + + uart_recvchars(&priv->dev); + handled = true; + } + + /* We may still have to read from the DR register to clear any pending + * error conditions. + */ + + else if ((priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) + != 0) + { + /* These errors are cleared by writing the corresponding bit to the + * interrupt clear register (ICR). + */ + + stm32serial_putreg(priv, STM32_USART_ICR_OFFSET, + (USART_ICR_NCF | USART_ICR_ORECF | + USART_ICR_FECF)); + } + + /* Handle outgoing, transmit bytes */ + + if ((priv->sr & USART_ISR_TXE) != 0 && + (priv->ie & USART_CR1_TXEIE) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(&priv->dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: stm32serial_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int stm32serial_ioctl(struct file *filep, int cmd, + unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; +#endif +#if defined(CONFIG_SERIAL_TERMIOS) + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct stm32_serial_s *user; + + user = (struct stm32_serial_s *)arg; + + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct stm32_serial_s)); + } + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + cfsetispeed(termiosp, priv->baud); + + /* Note that since we only support 8/9 bit modes and + * there is no way to report 9-bit mode, we always claim 8. + */ + + termiosp->c_cflag = + ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0) | + ((priv->stopbits2) ? CSTOPB : 0) | +#ifdef CONFIG_SERIAL_OFLOWCONTROL + ((priv->oflow) ? CCTS_OFLOW : 0) | +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + ((priv->iflow) ? CRTS_IFLOW : 0) | +#endif + CS8; + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Perform some sanity checks before accepting any changes */ + + if (((termiosp->c_cflag & CSIZE) != CS8) +#ifdef CONFIG_SERIAL_OFLOWCONTROL + || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)) +#endif + ) + { + ret = -EINVAL; + break; + } + + if (termiosp->c_cflag & PARENB) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + priv->parity = 0; + } + + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#ifdef CONFIG_SERIAL_OFLOWCONTROL + priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; +#endif + + /* Note that since there is no way to request 9-bit mode + * and no way to support 5/6/7-bit modes, we ignore them + * all here. + */ + + /* Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + priv->baud = cfgetispeed(termiosp); + + /* Effect the changes immediately - note that we do not implement + * TCSADRAIN / TCSAFLUSH + */ + + stm32serial_setformat(dev); + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32serial_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int stm32serial_receive(struct uart_dev_s *dev, + unsigned int *status) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + uint32_t rdr; + + /* Get the Rx byte */ + + rdr = stm32serial_getreg(priv, STM32_USART_RDR_OFFSET); + + /* Get the Rx byte plus error information. Return those in status */ + + *status = priv->sr << 16 | rdr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return rdr & 0xff; +} + +/**************************************************************************** + * Name: stm32serial_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void stm32serial_rxint(struct uart_dev_s *dev, bool enable) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + irqstate_t flags; + uint16_t ie; + + /* USART receive interrupts: + * + * Enable Status Meaning Usage + * ---------------- -------------- ---------------------- ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready + * to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NF Noise Flag + * " " USART_ISR_ORE Overrun Error Detected + */ + + flags = enter_critical_section(); + ie = priv->ie; + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data + * register (or an Rx timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS +#ifdef CONFIG_USART_ERRINTS + ie |= (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); +#else + ie |= USART_CR1_RXNEIE; +#endif +#endif + } + else + { + ie &= ~(USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); + } + + /* Then set the new interrupt state */ + + stm32serial_restoreusartint(priv, ie); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32serial_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool stm32serial_rxavailable(struct uart_dev_s *dev) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + + return ((stm32serial_getreg(priv, STM32_USART_ISR_OFFSET) & + USART_ISR_RXNE) != 0); +} + +/**************************************************************************** + * Name: stm32serial_rxflowcontrol + * + * Description: + * Called when Rx buffer is full (or exceeds configured watermark levels + * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined). + * Return true if UART activated RX flow control to block more incoming + * data + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool stm32serial_rxflowcontrol(struct uart_dev_s *dev, + unsigned int nbuffered, bool upper) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + +#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && \ + defined(CONFIG_STM32N6_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + /* Assert/de-assert nRTS set it high resume/stop sending */ + + stm32_gpiowrite(priv->rts_gpio, upper); + + if (upper) + { + /* With heavy Rx traffic, RXNE might be set and data pending. + * Returning 'true' in such case would cause RXNE left unhandled + * and causing interrupt storm. Sending end might be also be slow + * to react on nRTS, and returning 'true' here would prevent + * processing that data. + * + * Therefore, return 'false' so input data is still being processed + * until sending end reacts on nRTS signal and stops sending more. + */ + + return false; + } + + return upper; + } + +#else + if (priv->iflow) + { + /* Is the RX buffer full? */ + + if (upper) + { + /* Disable Rx interrupt to prevent more data being from + * peripheral. When hardware RTS is enabled, this will + * prevent more data from coming in. + * + * This function is only called when UART recv buffer is full, + * that is: "dev->recv.head + 1 == dev->recv.tail". + * + * Logic in "uart_read" will automatically toggle Rx interrupts + * when buffer is read empty and thus we do not have to re- + * enable Rx interrupts. + */ + + uart_disablerxint(dev); + return true; + } + + /* No.. The RX buffer is empty */ + + else + { + /* We might leave Rx interrupt disabled if full recv buffer was + * read empty. Enable Rx interrupt to make sure that more input is + * received. + */ + + uart_enablerxint(dev); + } + } +#endif + + return false; +} +#endif + +/**************************************************************************** + * Name: stm32serial_send + * + * Description: + * This method will send one byte on the USART + * + ****************************************************************************/ + +static void stm32serial_send(struct uart_dev_s *dev, int ch) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + + stm32serial_putreg(priv, STM32_USART_TDR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: stm32serial_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void stm32serial_txint(struct uart_dev_s *dev, bool enable) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + irqstate_t flags; + + /* USART transmit interrupts: + * + * Enable Status Meaning Usage + * --------------- ------------- ---------------------------- ---------- + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + */ + + flags = enter_critical_section(); + if (enable) + { + /* Set to receive an interrupt when the TX data register is empty */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + uint16_t ie = priv->ie | USART_CR1_TXEIE; + +# ifdef CONFIG_STM32N6_SERIALBRK_BSDCOMPAT + if (priv->ie & USART_CR1_IE_BREAK_INPROGRESS) + { + leave_critical_section(flags); + return; + } +# endif + + stm32serial_restoreusartint(priv, ie); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + stm32serial_restoreusartint(priv, priv->ie & ~USART_CR1_TXEIE); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32serial_txready + * + * Description: + * Return true if the transmit data register is empty + * + ****************************************************************************/ + +static bool stm32serial_txready(struct uart_dev_s *dev) +{ + struct stm32_serial_s *priv = + (struct stm32_serial_s *)dev->priv; + + return ((stm32serial_getreg(priv, STM32_USART_ISR_OFFSET) & + USART_ISR_TXE) != 0); +} + +/**************************************************************************** + * Name: stm32serial_pmnotify + * + * Description: + * Notify the driver of new power state. This callback is called after + * all drivers have had the opportunity to prepare for the new power state. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void stm32serial_pmnotify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + switch (pmstate) + { + case PM_NORMAL: + { + stm32serial_pm_setsuspend(false); + } + break; + + case PM_IDLE: + { + stm32serial_pm_setsuspend(false); + } + break; + + case PM_STANDBY: + { + stm32serial_pm_setsuspend(true); + } + break; + + case PM_SLEEP: + { + stm32serial_pm_setsuspend(true); + } + break; + + default: + + /* Should not get here */ + + break; + } +} +#endif + +/**************************************************************************** + * Name: stm32serial_pmprepare + * + * Description: + * Request the driver to prepare for a new power state. This is a warning + * that the system is about to enter into a new power state. The driver + * should begin whatever operations that may be required to enter power + * state. The driver may abort the state change mode by returning a + * non-zero value from the callback function. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static int stm32serial_pmprepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + int n; + + /* Logic to prepare for a reduced power state goes here. */ + + switch (pmstate) + { + case PM_NORMAL: + case PM_IDLE: + break; + + case PM_STANDBY: + case PM_SLEEP: + + /* Check if any of the active ports have data pending on Tx/Rx + * buffers. + */ + + for (n = 0; n < STM32N6_NUSART; n++) + { + struct stm32_serial_s *priv = g_uart_devs[n]; + + if (!priv || !priv->initialized) + { + /* Not active, skip. */ + + continue; + } + + if (priv->suspended) + { + /* Port already suspended, skip. */ + + continue; + } + + /* Check if port has data pending (Rx & Tx). */ + + if (priv->dev.xmit.head != priv->dev.xmit.tail) + { + return ERROR; + } + + if (priv->dev.recv.head != priv->dev.recv.tail) + { + return ERROR; + } + } + break; + + default: + + /* Should not get here */ + + break; + } + + return OK; +} +#endif + +#endif /* HAVE_UART */ +#endif /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Name: arm_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during boot up. This must be called + * before arm_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void arm_earlyserialinit(void) +{ +#ifdef HAVE_UART + unsigned i; + + /* Disable all USART interrupts */ + + for (i = 0; i < STM32N6_NUSART; i++) + { + if (g_uart_devs[i]) + { + stm32serial_disableusartint(g_uart_devs[i], NULL); + } + } + + /* Configure whichever one is the console */ + +#if CONSOLE_UART > 0 + stm32serial_setup(&g_uart_devs[CONSOLE_UART - 1]->dev); +#endif + +#endif /* HAVE UART */ +} +#endif /* USE_EARLYSERIALINIT */ + +/**************************************************************************** + * Name: arm_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that arm_earlyserialinit was called previously. + * + ****************************************************************************/ + +void arm_serialinit(void) +{ +#ifdef HAVE_UART + char devname[16]; + unsigned i; + unsigned minor = 0; +#ifdef CONFIG_PM + int ret; +#endif + + /* Register to receive power management callbacks */ + +#ifdef CONFIG_PM + ret = pm_register(&g_serialpm.pm_cb); + DEBUGASSERT(ret == OK); + UNUSED(ret); +#endif + + /* Register the console */ + +#if CONSOLE_UART > 0 + uart_register("/dev/console", &g_uart_devs[CONSOLE_UART - 1]->dev); + +#ifndef CONFIG_STM32N6_SERIAL_DISABLE_REORDERING + /* If not disabled, register the console UART to ttyS0 and exclude + * it from initializing it further down + */ + + uart_register("/dev/ttyS0", &g_uart_devs[CONSOLE_UART - 1]->dev); + minor = 1; +#endif + +#endif /* CONSOLE_UART > 0 */ + + /* Register all remaining USARTs */ + + strlcpy(devname, "/dev/ttySx", sizeof(devname)); + + for (i = 0; i < STM32N6_NUSART; i++) + { + /* Don't create a device for non-configured ports. */ + + if (g_uart_devs[i] == 0) + { + continue; + } + +#ifndef CONFIG_STM32N6_SERIAL_DISABLE_REORDERING + /* Don't create a device for the console - we did that above */ + + if (g_uart_devs[i]->dev.isconsole) + { + continue; + } +#endif + + /* Register USARTs as devices in increasing order */ + + devname[9] = '0' + minor++; + uart_register(devname, &g_uart_devs[i]->dev); + } +#endif /* HAVE UART */ +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +void up_putc(int ch) +{ +#if CONSOLE_UART > 0 + struct stm32_serial_s *priv = g_uart_devs[CONSOLE_UART - 1]; + uint16_t ie; + + stm32serial_disableusartint(priv, &ie); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + arm_lowputc('\r'); + } + + arm_lowputc(ch); + stm32serial_restoreusartint(priv, ie); +#endif +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +void up_putc(int ch) +{ +#if CONSOLE_UART > 0 + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + arm_lowputc('\r'); + } + + arm_lowputc(ch); +#endif +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/stm32n6/stm32_start.c b/arch/arm/src/stm32n6/stm32_start.c new file mode 100644 index 0000000000000..3c7664921bb21 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_start.c @@ -0,0 +1,267 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_start.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "arm_internal.h" +#include "nvic.h" + +#include "stm32.h" +#include "stm32_gpio.h" +#include "stm32_pwr.h" +#include "stm32_start.h" +#include "hardware/stm32n6xxx_syscfg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Cortex-M55 CCR.LOB (Low-Overhead Branch) enable bit. Not yet exposed by + * the generic armv8-m nvic.h. + */ + +#define NVIC_CFGCON_LOB (1 << 19) + +#define HEAP_BASE ((uintptr_t)_ebss + CONFIG_IDLETHREAD_STACKSIZE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Top of the idle thread stack; the heap begins immediately above it. */ + +const uintptr_t g_idle_topstack = HEAP_BASE; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) arm_lowputc(c) +#else +# define showprogress(c) +#endif + +/* Cortex-M55 ARMv8.1-M Low-Overhead Branch: enables WLS/DLS/LE. + * CCR.LOB resets to 0; enable before any loop the compiler may lower + * with LE (and before MVE code, which is gated on the same bit). + */ + +static inline void stm32_enable_lob(void) +{ + uint32_t regval; + + regval = getreg32(NVIC_CFGCON); + regval |= NVIC_CFGCON_LOB; + putreg32(regval, NVIC_CFGCON); + UP_ISB(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* __start_c() carries the real boot logic; __start() below is a naked + * dispatcher that clears the boot-ROM stack limits before any prologue. + * __start_c is reached via "b __start_c" from __start's inline asm and + * therefore must have external linkage. + */ + +void __start_c(void) noinstrument_function; + +/**************************************************************************** + * Name: __start + * + * Description: + * Reset entry point. The STM32N6 boot ROM (DEV mode) leaves MSPLIM and + * PSPLIM set such that the first stack push from C code can fault. + * This function is naked so the limits can be cleared before any + * compiler-generated prologue runs. It then tail-calls __start_c. + * + ****************************************************************************/ + +void __attribute__((naked)) noinstrument_function __start(void) +{ + __asm__ volatile ("mov r0, #0\n\t" + "msr msplim, r0\n\t" + "msr psplim, r0\n\t" + "b __start_c\n\t"); +} + +/**************************************************************************** + * Name: __start_c + * + * Description: + * The C-level boot path, reached from the naked __start dispatcher. + * + ****************************************************************************/ + +void __start_c(void) +{ + const uint32_t *src; + uint32_t *dest; + + /* The DEV-mode boot ROM leaves VTOR pointing at its own ROM region. Set + * VTOR to our SRAM vector table before enabling any exception path. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + + /* When chain-loaded by an FSBL that called HAL_Init(), SysTick may be + * left running. Disable it and clear any pending interrupt so it does + * not fire before NuttX has attached its handler. + */ + + putreg32(0, NVIC_SYSTICK_CTRL); + putreg32(NVIC_INTCTRL_PENDSTCLR, NVIC_INTCTRL); + + /* Force plain SLEEP (not DEEPSLEEP) on WFI so the system clock keeps + * running and SysTick continues to wake us. Cleared once here so + * up_idle() does not need to touch it on every idle entry. + */ + + modifyreg32(NVIC_SYSCON, NVIC_SYSCON_SLEEPDEEP, 0); + + /* Enable the FPU before stm32_clockconfig and the rest of init. With + * hard-float ABI the compiler may emit FPU instructions later, and any + * exception entry will try to push FP context -- both require CP10/CP11. + */ + + arm_fpuconfig(); + + /* Clear .bss inline rather than calling memset, so global state is sane + * even if anything depends on it during the rest of __start. + */ + + for (dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; ) + { + *dest++ = 0; + } + + /* Copy .data from its load address to SRAM. For SRAM-only DEV-mode + * builds the linker arranges _eronly == _sdata so the copy is skipped; + * the explicit check avoids corrupting .data when alignment padding + * would otherwise leave a gap between _eronly and _sdata. + */ + + if (&_eronly[0] != &_sdata[0]) + { + for (src = (const uint32_t *)_eronly, + dest = (uint32_t *)_sdata; dest < (uint32_t *)_edata; + ) + { + *dest++ = *src++; + } + } + + stm32_enable_lob(); + + stm32_clockconfig(); + + /* Per ES0620, BSECEN must remain set or WFI/sleep fails. Set it via + * the atomic SET register, together with SYSCFGEN which we need below. + */ + + putreg32(RCC_APB4HENR_SYSCFGEN | RCC_APB4HENR_BSECEN, + STM32_RCC_APB4HENSR); + + /* Enable the LPEN bits that keep clocks running through WFI (CSLEEP). + * Without these, WFI halts the clocks for the AXISRAM banks and any + * enabled peripherals, and the system never wakes up. + */ + + putreg32(RCC_BUSLPENR_ACLKNLPEN | RCC_BUSLPENR_ACLKNCLPEN, + STM32_RCC_BUSLPENSR); + putreg32(RCC_MEMLPENR_ALLAXISRAM | RCC_MEMLPENR_CACHEAXIRAMLPEN, + STM32_RCC_MEMLPENSR); +#ifdef CONFIG_STM32N6_USART1 + putreg32(RCC_APB2LPENR_USART1LPEN, STM32_RCC_APB2LPENSR); +#endif + + /* Mark the board's I/O voltage domains as supply-valid before any GPIO + * pad is driven. The mask of PWR_SVMCR3_* bits is board-specific and + * provided by board.h via BOARD_PWR_VDDIO. + */ + + stm32_pwr_enablevddio(BOARD_PWR_VDDIO); + + /* Apply the ES0620 I/O-compensation mitigation (write 0x287) to the + * domains we use. Only VDDIO2 and VDDIO3 are touched: the other + * VDDIOxCCCR registers cannot be accessed without their VDDIOxSV bit + * set first (separate ES0620 erratum), and only VDDIO2/3 are declared + * supply-valid in BOARD_PWR_VDDIO above. + */ + + putreg32(SYSCFG_CCCR_ES0620_MANUAL, STM32_SYSCFG_VDDIO2CCCR); + putreg32(SYSCFG_CCCR_ES0620_MANUAL, STM32_SYSCFG_VDDIO3CCCR); + putreg32(SYSCFG_CCCR_ES0620_MANUAL, STM32_SYSCFG_VDDCCCR); + + putreg32((uint32_t)_vectors, STM32_SYSCFG_INITSVTORCR); + + /* Read-back to ensure prior SYSCFG writes complete */ + + (void)getreg32(STM32_SYSCFG_VDDCCCR); + +#ifdef CONFIG_STM32N6_USART1 + /* Route USART1's kernel clock to HSI so the BRR computation is + * independent of any later SYSCLK changes. + */ + + putreg32(RCC_CCIPR13_USART1SEL_HSI, STM32_RCC_CCIPR13); +#endif + + stm32_lowsetup(); + +#ifdef USE_EARLYSERIALINIT + arm_earlyserialinit(); +#endif + + stm32_board_initialize(); + + /* Final DSB+ISB after SCB writes (VTOR, SYSTICK_CTRL, SYSCFG INITSVTORCR) + * before handing off to NuttX. + */ + + UP_DSB(); + UP_ISB(); + + showprogress('\r'); + showprogress('\n'); + + nx_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/stm32n6/stm32_start.h b/arch/arm/src/stm32n6/stm32_start.h new file mode 100644 index 0000000000000..af474bc03a3c5 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_start.h @@ -0,0 +1,47 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_start.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_STM32_START_H +#define __ARCH_ARM_SRC_STM32N6_STM32_START_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_board_initialize + * + * Description: + * All STM32N6 architectures must provide the following entry point. This + * entry point is called early in the initialization -- after all memory + * has been configured and mapped but before any devices have been + * initialized. + * + ****************************************************************************/ + +void stm32_board_initialize(void); + +#endif /* __ARCH_ARM_SRC_STM32N6_STM32_START_H */ diff --git a/arch/arm/src/stm32n6/stm32_timerisr.c b/arch/arm/src/stm32n6/stm32_timerisr.c new file mode 100644 index 0000000000000..5ee494573d6bf --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_timerisr.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_timerisr.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "arm_internal.h" +#include "chip.h" +#include "stm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 ms interval). + * + * SysTick is clocked from the processor clock when CLKSOURCE=1 (the + * configuration used here). The reload value must fit in 24 bits. + */ + +#define SYSTICK_RELOAD ((STM32_CPUCLK_FREQUENCY / CLK_TCK) - 1) + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_timerisr + * + * Description: + * SysTick interrupt handler. Processes the system timer tick. + * + ****************************************************************************/ + +static int stm32_timerisr(int irq, uint32_t *regs, void *arg) +{ + nxsched_process_timer(); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the system + * timer interrupt using SysTick clocked from the processor clock. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + irq_attach(STM32_IRQ_SYSTICK, (xcpt_t)stm32_timerisr, NULL); + + /* Enable SysTick clocked from the processor clock with interrupts on */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + up_enable_irq(STM32_IRQ_SYSTICK); +} diff --git a/arch/arm/src/stm32n6/stm32_uart.h b/arch/arm/src/stm32n6/stm32_uart.h new file mode 100644 index 0000000000000..2726f7fffaf25 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32_uart.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32_uart.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32N6_STM32_UART_H +#define __ARCH_ARM_SRC_STM32N6_STM32_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" + +#include "hardware/stm32n6xxx_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Sanity checks */ + +#if !defined(CONFIG_STM32N6_USART1) +# undef CONFIG_STM32N6_USART1_SERIALDRIVER +# undef CONFIG_STM32N6_USART1_1WIREDRIVER +#endif + +/* Is there a USART enabled? */ + +#if defined(CONFIG_STM32N6_USART1) +# define HAVE_UART 1 +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32N6_USART1_SERIALDRIVER) +# define CONSOLE_UART 1 +# define HAVE_CONSOLE 1 +#else +# undef CONFIG_USART1_SERIAL_CONSOLE +# define CONSOLE_UART 0 +# undef HAVE_CONSOLE +#endif + +#define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32N6_STM32_UART_H */ diff --git a/arch/arm/src/stm32n6/stm32n6xx_rcc.c b/arch/arm/src/stm32n6/stm32n6xx_rcc.c new file mode 100644 index 0000000000000..e1615178a7652 --- /dev/null +++ b/arch/arm/src/stm32n6/stm32n6xx_rcc.c @@ -0,0 +1,261 @@ +/**************************************************************************** + * arch/arm/src/stm32n6/stm32n6xx_rcc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include + +#include "stm32_rcc.h" +#include "stm32_pwr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. + */ + +#define HSIRDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) +#define PLL1RDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_enableahb4 + * + * Description: + * Enable selected AHB4 peripherals - primarily GPIO clocks and PWR. + * On STM32N6, GPIO ports A-H and N-Q are on AHB4. + * + ****************************************************************************/ + +static inline void rcc_enableahb4(void) +{ + /* Use the write-1-to-set ENSR alias rather than a read-modify-write on + * ENR so concurrent producers (e.g. RCC IRQ later) cannot lose bits. + * Matches the ST LL pattern in stm32n6xx_ll_bus.h. + */ + + putreg32(RCC_AHB4ENR_GPIOAEN + | RCC_AHB4ENR_GPIOBEN + | RCC_AHB4ENR_GPIOCEN + | RCC_AHB4ENR_GPIODEN + | RCC_AHB4ENR_GPIOEEN + | RCC_AHB4ENR_GPIOFEN + | RCC_AHB4ENR_GPIOGEN + | RCC_AHB4ENR_GPIOHEN + | RCC_AHB4ENR_GPIONEN + | RCC_AHB4ENR_GPIOOEN + | RCC_AHB4ENR_GPIOPEN + | RCC_AHB4ENR_GPIOQEN + | RCC_AHB4ENR_PWREN, + STM32_RCC_AHB4ENSR); +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals. + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval = 0; + +#ifdef CONFIG_STM32N6_USART1 + regval |= RCC_APB2ENR_USART1EN; +#endif + + if (regval != 0) + { + putreg32(regval, STM32_RCC_APB2ENSR); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rcc_enableperipherals + ****************************************************************************/ + +void stm32_rcc_enableperipherals(void) +{ + /* Enable all AXISRAM bank clocks. The boot ROM only enables AXISRAM1/2 + * which is sufficient for code execution, but the NuttX heap extends + * across all SRAM banks (up to AXISRAM5 at 0x34400000+). Without these + * clocks, mm_initialize writing the tail node at the heap end will cause + * an IMPRECISERR bus fault. + */ + + putreg32(RCC_MEMENR_ALLAXISRAM | RCC_MEMENR_CACHEAXIRAMEN, + STM32_RCC_MEMENSR); + + rcc_enableahb4(); + rcc_enableapb2(); +} + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Configure PLL1 from values supplied by board.h (M, N, IC1_DIV). The + * clock tree is laid out in the board header; see board.h for the full + * diagram. + * + * IMPORTANT: CFGR1 locks after the first write -- CPUSW and SYSSW must + * be written together in a single putreg32(). CFGR2 (bus prescalers) + * also locks after CFGR1 is written, so it must be set first. + * + ****************************************************************************/ + +void stm32_stdclockconfig(void) +{ + volatile int32_t timeout; + uint32_t regval; + + /* If clocks are already configured (e.g. FSBL set up PLL1 and switched + * CPUSW to IC1), skip PLL1/CFGR1 reconfiguration. CFGR1 locks after + * the first write - a second write crashes the system (SRAM goes + * offline). + */ + + regval = getreg32(STM32_RCC_CFGR1); + if ((regval & RCC_CFGR1_CPUSWS_MASK) == RCC_CFGR1_CPUSWS_IC1 && + (regval & RCC_CFGR1_SYSSWS_MASK) == RCC_CFGR1_SYSSWS_IC2_IC6_IC11) + { + return; + } + + for (timeout = HSIRDY_TIMEOUT; timeout > 0; timeout--) + { + if ((getreg32(STM32_RCC_SR) & RCC_SR_HSIRDY) != 0) + { + break; + } + } + + putreg32(RCC_CR_PLL1ON, STM32_RCC_CCR); + + for (timeout = PLL1RDY_TIMEOUT; timeout > 0; timeout--) + { + if ((getreg32(STM32_RCC_SR) & RCC_SR_PLL1RDY) == 0) + { + break; + } + } + + regval = (RCC_PLL1CFGR1_SEL_HSI) + | (STM32_PLL1_M << RCC_PLL1CFGR1_DIVM_SHIFT) + | (STM32_PLL1_N << RCC_PLL1CFGR1_DIVN_SHIFT); + putreg32(regval, STM32_RCC_PLL1CFGR1); + + regval = RCC_PLL1CFGR3_MODSSDIS + | RCC_PLL1CFGR3_PDIVEN + | (1 << RCC_PLL1CFGR3_PDIV1_SHIFT) + | (1 << RCC_PLL1CFGR3_PDIV2_SHIFT); + putreg32(regval, STM32_RCC_PLL1CFGR3); + + putreg32(RCC_CR_PLL1ON, STM32_RCC_CSR); + + for (timeout = PLL1RDY_TIMEOUT; timeout > 0; timeout--) + { + if ((getreg32(STM32_RCC_SR) & RCC_SR_PLL1RDY) != 0) + { + break; + } + } + + /* IC dividers: register field is (divider - 1). IC1_DIV from board.h + * picks the CPU rate; the other ICs are fixed multiples that feed + * SYSCLK and the XSPI2 kernel clock. + * + * IC1 = VCO / IC1_DIV -> CPU + * IC2 = VCO / (IC1_DIV * 2) -> SYSCLK + * IC3 = VCO / (IC1_DIV * 4) -> XSPI2 kernel clock (reserved) + * IC6 = VCO / (IC1_DIV * 3) -> SYSCLK + * IC11 = VCO / (IC1_DIV * 2) -> SYSCLK + */ + + putreg32(RCC_ICCFGR_SEL_PLL1 + | ((STM32_PLL1_IC1_DIV - 1) << RCC_ICCFGR_INT_SHIFT), + STM32_RCC_IC1CFGR); + putreg32(RCC_ICCFGR_SEL_PLL1 + | ((STM32_PLL1_IC1_DIV * 2 - 1) << RCC_ICCFGR_INT_SHIFT), + STM32_RCC_IC2CFGR); + putreg32(RCC_ICCFGR_SEL_PLL1 + | ((STM32_PLL1_IC1_DIV * 4 - 1) << RCC_ICCFGR_INT_SHIFT), + STM32_RCC_IC3CFGR); + putreg32(RCC_ICCFGR_SEL_PLL1 + | ((STM32_PLL1_IC1_DIV * 3 - 1) << RCC_ICCFGR_INT_SHIFT), + STM32_RCC_IC6CFGR); + putreg32(RCC_ICCFGR_SEL_PLL1 + | ((STM32_PLL1_IC1_DIV * 2 - 1) << RCC_ICCFGR_INT_SHIFT), + STM32_RCC_IC11CFGR); + + putreg32(RCC_DIVENR_IC1EN | RCC_DIVENR_IC2EN | RCC_DIVENR_IC3EN + | RCC_DIVENR_IC6EN | RCC_DIVENR_IC11EN, + STM32_RCC_DIVENSR); + + /* CFGR2 (bus prescalers) and CFGR1 (clock-source switch) both lock + * after CFGR1 is written, so CFGR2 must be set first and CFGR1 must + * be written exactly once with both CPUSW and SYSSW in place. + */ + + putreg32(RCC_CFGR2_HPRE_SYSCLKd2, STM32_RCC_CFGR2); + + regval = getreg32(STM32_RCC_CFGR1); + regval &= ~(RCC_CFGR1_CPUSW_MASK | RCC_CFGR1_SYSSW_MASK); + regval |= RCC_CFGR1_CPUSW_IC1 | RCC_CFGR1_SYSSW_IC2_IC6_IC11; + putreg32(regval, STM32_RCC_CFGR1); + + /* Some SRAM bank clocks drop out across the clock-domain switch on + * STM32N6; re-arm them so the heap stays alive. + */ + + putreg32(RCC_MEMENR_ALLAXISRAM | RCC_MEMENR_CACHEAXIRAMEN, + STM32_RCC_MEMENSR); + + for (timeout = PLL1RDY_TIMEOUT; timeout > 0; timeout--) + { + if (((getreg32(STM32_RCC_CFGR1) & RCC_CFGR1_CPUSWS_MASK) + == RCC_CFGR1_CPUSWS_IC1) && + ((getreg32(STM32_RCC_CFGR1) & RCC_CFGR1_SYSSWS_MASK) + == RCC_CFGR1_SYSSWS_IC2_IC6_IC11)) + { + break; + } + } +} diff --git a/tools/ci/testlist/arm-14.dat b/tools/ci/testlist/arm-14.dat index 08a3bcf246977..b1b37bcb0ac5b 100644 --- a/tools/ci/testlist/arm-14.dat +++ b/tools/ci/testlist/arm-14.dat @@ -1,4 +1,5 @@ /arm/stm32l*,CONFIG_ARM_TOOLCHAIN_GNU_EABI +/arm/stm32n*,CONFIG_ARM_TOOLCHAIN_GNU_EABI /arm/stm32u*,CONFIG_ARM_TOOLCHAIN_GNU_EABI /arm/stm32w*,CONFIG_ARM_TOOLCHAIN_GNU_EABI From 3f159db26ad74dd2666e0b3089a1448c8f0f8172 Mon Sep 17 00:00:00 2001 From: ImBonkers Date: Sat, 16 May 2026 15:40:03 +0200 Subject: [PATCH 2/3] boards/arm/stm32n6/nucleo-n657x0-q: Add Nucleo-N657X0-Q board support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add board support for the STMicro Nucleo-N657X0-Q, sufficient to boot NSH over the on-board ST-LINK virtual COM port (USART1, 115200 8N1) in DEV (serial) boot mode. Two defconfigs are shipped: - nsh: minimal NuttShell prompt. - ostest: nsh + apps/testing/ostest for RTOS smoke testing. Production signed XSPI flash boot is deferred to a follow-up; in DEV mode the image is loaded directly into AXISRAM at 0x34000400 by the host (e.g. STM32CubeProgrammer over ST-LINK), keeping the linker script trivial — .text/.rodata/.data/.bss/.heap all in AXISRAM. Signed-off-by: ImBonkers --- boards/Kconfig | 13 ++ .../stm32n6/nucleo-n657x0-q/CMakeLists.txt | 23 +++ boards/arm/stm32n6/nucleo-n657x0-q/Kconfig | 8 ++ .../nucleo-n657x0-q/configs/nsh/defconfig | 32 +++++ .../nucleo-n657x0-q/configs/ostest/defconfig | 36 +++++ .../stm32n6/nucleo-n657x0-q/include/board.h | 133 ++++++++++++++++++ .../stm32n6/nucleo-n657x0-q/scripts/Make.defs | 40 ++++++ .../stm32n6/nucleo-n657x0-q/scripts/flash.ld | 103 ++++++++++++++ .../nucleo-n657x0-q/src/CMakeLists.txt | 27 ++++ .../arm/stm32n6/nucleo-n657x0-q/src/Makefile | 28 ++++ .../nucleo-n657x0-q/src/nucleo-n657x0-q.h | 65 +++++++++ .../stm32n6/nucleo-n657x0-q/src/stm32_boot.c | 78 ++++++++++ .../nucleo-n657x0-q/src/stm32_bringup.c | 58 ++++++++ 13 files changed, 644 insertions(+) create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/CMakeLists.txt create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/Kconfig create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/configs/nsh/defconfig create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/configs/ostest/defconfig create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/include/board.h create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/scripts/Make.defs create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/scripts/flash.ld create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/src/CMakeLists.txt create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/src/Makefile create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/src/nucleo-n657x0-q.h create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_boot.c create mode 100644 boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_bringup.c diff --git a/boards/Kconfig b/boards/Kconfig index 50ee48cd9916f..c2c04276a9ee6 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -3153,6 +3153,15 @@ config ARCH_BOARD_NUCLEO_H563ZI ---help--- STMicro Nucleo-H563ZI board based on the STMicro STM32H563ZI MCU. +config ARCH_BOARD_NUCLEO_N657X0_Q + bool "NUCLEO_N657X0_Q" + depends on ARCH_CHIP_STM32N657X0 + ---help--- + STMicro Nucleo-N657X0-Q development board based on the STMicro + STM32N657X0 MCU (Cortex-M55). Boots in DEV mode by loading + code directly into SRAM via the on-board ST-Link V3EC, with + the NSH console on USART1 (ST-Link Virtual COM Port). + config ARCH_BOARD_STM32L562E_DK bool "STM32L562E-DK" depends on ARCH_CHIP_STM32L562QE @@ -3926,6 +3935,7 @@ config ARCH_BOARD default "b-l475e-iot01a" if ARCH_BOARD_B_L475E_IOT01A default "b-u585i-iot02a" if ARCH_BOARD_B_U585I_IOT02A default "nucleo-h563zi" if ARCH_BOARD_NUCLEO_H563ZI + default "nucleo-n657x0-q" if ARCH_BOARD_NUCLEO_N657X0_Q default "nucleo-u5a5zj-q" if ARCH_BOARD_NUCLEO_U5A5ZJ_Q default "stm32l476vg-disco" if ARCH_BOARD_STM32L476VG_DISCO default "stm32l476-mdk" if ARCH_BOARD_STM32L476_MDK @@ -4578,6 +4588,9 @@ endif if ARCH_BOARD_NUCLEO_H563ZI source "boards/arm/stm32h5/nucleo-h563zi/Kconfig" endif +if ARCH_BOARD_NUCLEO_N657X0_Q +source "boards/arm/stm32n6/nucleo-n657x0-q/Kconfig" +endif if ARCH_BOARD_STM32L562E_DK source "boards/arm/stm32l5/stm32l562e-dk/Kconfig" endif diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/CMakeLists.txt b/boards/arm/stm32n6/nucleo-n657x0-q/CMakeLists.txt new file mode 100644 index 0000000000000..ee687620d81c7 --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/CMakeLists.txt @@ -0,0 +1,23 @@ +# ############################################################################## +# boards/arm/stm32n6/nucleo-n657x0-q/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +add_subdirectory(src) diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/Kconfig b/boards/arm/stm32n6/nucleo-n657x0-q/Kconfig new file mode 100644 index 0000000000000..4a4f23f616ec5 --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_BOARD_NUCLEO_N657X0_Q + +endif diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/configs/nsh/defconfig b/boards/arm/stm32n6/nucleo-n657x0-q/configs/nsh/defconfig new file mode 100644 index 0000000000000..f18c05e1d6240 --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/configs/nsh/defconfig @@ -0,0 +1,32 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="nucleo-n657x0-q" +CONFIG_ARCH_BOARD_NUCLEO_N657X0_Q=y +CONFIG_ARCH_CHIP="stm32n6" +CONFIG_ARCH_CHIP_STM32N657X0=y +CONFIG_ARCH_CHIP_STM32N6=y +CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=21000 +CONFIG_BUILTIN=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=4096 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_RAM_SIZE=4193280 +CONFIG_RAM_START=0x34000400 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_STM32N6_USART1=y +CONFIG_SYSTEM_NSH=y +CONFIG_USART1_SERIAL_CONSOLE=y diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/configs/ostest/defconfig b/boards/arm/stm32n6/nucleo-n657x0-q/configs/ostest/defconfig new file mode 100644 index 0000000000000..9e14513b6c7a4 --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/configs/ostest/defconfig @@ -0,0 +1,36 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="nucleo-n657x0-q" +CONFIG_ARCH_BOARD_NUCLEO_N657X0_Q=y +CONFIG_ARCH_CHIP="stm32n6" +CONFIG_ARCH_CHIP_STM32N657X0=y +CONFIG_ARCH_CHIP_STM32N6=y +CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=21000 +CONFIG_BUILTIN=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=4096 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_CHILDSTATUS=2 +CONFIG_RAM_SIZE=4193280 +CONFIG_RAM_START=0x34000400 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_CHILD_STATUS=y +CONFIG_SCHED_HAVE_PARENT=y +CONFIG_SCHED_WAITPID=y +CONFIG_STM32N6_USART1=y +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_OSTEST=y +CONFIG_USART1_SERIAL_CONSOLE=y diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/include/board.h b/boards/arm/stm32n6/nucleo-n657x0-q/include/board.h new file mode 100644 index 0000000000000..0dfe61e2af150 --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/include/board.h @@ -0,0 +1,133 @@ +/**************************************************************************** + * boards/arm/stm32n6/nucleo-n657x0-q/include/board.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_STM32N6_NUCLEO_N657X0_Q_INCLUDE_BOARD_H +#define __BOARDS_ARM_STM32N6_NUCLEO_N657X0_Q_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Clocking *****************************************************************/ + +/* Clock tree (single PLL1 fed from the internal HSI): + * + * HSI 64 MHz / M=4 * N=50 = 800 MHz VCO + * IC1 /4 = 200 MHz -> CPU clock (CPUSW) + * IC2 /8 = 100 MHz \ + * IC6 /12 = 66.7 MHz > SYSCLK components (SYSSW IC2_IC6_IC11) + * IC11 /8 = 100 MHz / + * HPRE /2 = 50 MHz -> HCLK + * PPRE1 /1 = 50 MHz -> PCLK1 + * PPRE2 /1 = 50 MHz -> PCLK2 + * + * Works with the default VOS SCALE1, no SMPS overdrive required. Higher + * CPU frequencies (600/800 MHz) are deferred to a follow-up. + */ + +#define STM32_HSI_FREQUENCY 64000000ul + +#define STM32_PLL1_M 4 +#define STM32_PLL1_N 50 +#define STM32_PLL1_IC1_DIV 4 + +#define STM32_CPUCLK_FREQUENCY 200000000ul +#define STM32_SYSCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) +#define STM32_HCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 4) +#define STM32_PCLK1_FREQUENCY STM32_HCLK_FREQUENCY +#define STM32_PCLK2_FREQUENCY STM32_HCLK_FREQUENCY + +/* Timer input clock = SYSCLK (TIMPRE=0 default) */ + +#define STM32_APB1_TIM_FREQUENCY STM32_SYSCLK_FREQUENCY +#define STM32_APB2_TIM_FREQUENCY STM32_SYSCLK_FREQUENCY + +/* I/O voltage domains ******************************************************/ + +/* GPIO port E (USART1 TX/RX on PE5/PE6) is on the VddIO2 and VddIO3 + * domains; both are wired to the board's 1.8 V rail. This mask is + * applied to PWR_SVMCR3 early in boot to mark the supplies valid and + * select their 1.8 V range. + */ + +#define BOARD_PWR_VDDIO (PWR_SVMCR3_VDDIO2SV | PWR_SVMCR3_VDDIO3SV | \ + PWR_SVMCR3_VDDIO2VRSEL | PWR_SVMCR3_VDDIO3VRSEL) + +/* Alternate function pin selections ****************************************/ + +/* USART1 GPIOs *************************************************************/ + +/* USART1 (Nucleo Virtual Console): PE5=TX (AF7), PE6=RX (AF7) + * Connected to the on-board ST-Link to provide a Virtual COM Port. + */ + +#define GPIO_USART1_TX GPIO_USART1_TX_1 +#define GPIO_USART1_RX GPIO_USART1_RX_1 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_board_initialize + * + * Description: + * All STM32N6 architectures must provide the following entry point. + * This entry point is called early in the initialization -- after all + * memory has been configured and mapped but before any devices + * have been initialized. + * + ****************************************************************************/ + +void stm32_board_initialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_ARM_STM32N6_NUCLEO_N657X0_Q_INCLUDE_BOARD_H */ diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/scripts/Make.defs b/boards/arm/stm32n6/nucleo-n657x0-q/scripts/Make.defs new file mode 100644 index 0000000000000..1fc8862769117 --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/scripts/Make.defs @@ -0,0 +1,40 @@ +############################################################################## +# boards/arm/stm32n6/nucleo-n657x0-q/scripts/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################## + +include ${TOPDIR}/.config +include ${TOPDIR}/tools/Config.mk +include ${TOPDIR}/arch/arm/src/armv8-m/Toolchain.defs + +ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)flash.ld + +ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS := $(CFLAGS) -D__ASSEMBLY__ + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)$(DELIM)binfmt$(DELIM)libnxflat$(DELIM)gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/scripts/flash.ld b/boards/arm/stm32n6/nucleo-n657x0-q/scripts/flash.ld new file mode 100644 index 0000000000000..97e9d927e7e2f --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/scripts/flash.ld @@ -0,0 +1,103 @@ +/**************************************************************************** + * boards/arm/stm32n6/nucleo-n657x0-q/scripts/flash.ld + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* The STM32N657X0 has no internal flash. In DEV boot mode, code is loaded + * directly into SRAM by the ST-Link debugger at 0x34000400. The first + * 1 KiB of SRAM is reserved for the boot ROM header. + */ + +MEMORY +{ + sram (rwx) : ORIGIN = 0x34000400, LENGTH = 4193280 +} + +OUTPUT_ARCH(arm) +ENTRY(_stext) +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > sram + + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o) .ctors)) + _einit = ABSOLUTE(.); + } > sram + + .ARM.extab : { + *(.ARM.extab*) + } > sram + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > sram + __exidx_end = ABSOLUTE(.); + + .data : { + _eronly = ABSOLUTE(.); + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/src/CMakeLists.txt b/boards/arm/stm32n6/nucleo-n657x0-q/src/CMakeLists.txt new file mode 100644 index 0000000000000..0146628e33d1a --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/src/CMakeLists.txt @@ -0,0 +1,27 @@ +# ############################################################################## +# boards/arm/stm32n6/nucleo-n657x0-q/src/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +set(SRCS stm32_boot.c stm32_bringup.c) + +target_sources(board PRIVATE ${SRCS}) + +set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/flash.ld") diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/src/Makefile b/boards/arm/stm32n6/nucleo-n657x0-q/src/Makefile new file mode 100644 index 0000000000000..6bcfb95b605df --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/src/Makefile @@ -0,0 +1,28 @@ +############################################################################## +# boards/arm/stm32n6/nucleo-n657x0-q/src/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################## + +-include $(TOPDIR)/Make.defs + +ASRCS = +CSRCS = stm32_boot.c stm32_bringup.c + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/src/nucleo-n657x0-q.h b/boards/arm/stm32n6/nucleo-n657x0-q/src/nucleo-n657x0-q.h new file mode 100644 index 0000000000000..99c6e3e54766b --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/src/nucleo-n657x0-q.h @@ -0,0 +1,65 @@ +/**************************************************************************** + * boards/arm/stm32n6/nucleo-n657x0-q/src/nucleo-n657x0-q.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_STM32N6_NUCLEO_N657X0_Q_SRC_NUCLEO_N657X0_Q_H +#define __BOARDS_ARM_STM32N6_NUCLEO_N657X0_Q_SRC_NUCLEO_N657X0_Q_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_bringup + * + * Description: + * Perform architecture-specific initialization + * + * CONFIG_BOARD_LATE_INITIALIZE=y : + * Called from board_late_initialize(). + * + * CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_BOARDCTL=y : + * Called from the NSH library + * + ****************************************************************************/ + +int stm32_bringup(void); + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_ARM_STM32N6_NUCLEO_N657X0_Q_SRC_NUCLEO_N657X0_Q_H */ diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_boot.c b/boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_boot.c new file mode 100644 index 0000000000000..6bb40b35dc527 --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_boot.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_boot.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "arm_internal.h" +#include "nucleo-n657x0-q.h" + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_board_initialize + * + * Description: + * All STM32 architectures must provide the following entry point. This + * entry point is called early in the initialization -- after all memory + * has been configured and mapped but before any devices have been + * initialized. + * + ****************************************************************************/ + +void stm32_board_initialize(void) +{ +} + +/**************************************************************************** + * Name: board_late_initialize + * + * Description: + * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional + * initialization call will be performed in the boot-up sequence to a + * function called board_late_initialize(). board_late_initialize() will + * be called immediately after up_initialize() is called and just before + * the initial application is started. This additional initialization + * phase may be used, for example, to initialize board-specific device + * drivers. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ + /* Perform board-specific initialization here if so configured */ + + stm32_bringup(); +} +#endif diff --git a/boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_bringup.c b/boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_bringup.c new file mode 100644 index 0000000000000..fb6f999995723 --- /dev/null +++ b/boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_bringup.c @@ -0,0 +1,58 @@ +/**************************************************************************** + * boards/arm/stm32n6/nucleo-n657x0-q/src/stm32_bringup.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "nucleo-n657x0-q.h" + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_bringup + * + * Description: + * Perform architecture-specific initialization + * + * CONFIG_BOARD_LATE_INITIALIZE=y : + * Called from board_late_initialize(). + * + * CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_BOARDCTL=y : + * Called from the NSH library + * + ****************************************************************************/ + +int stm32_bringup(void) +{ + return OK; +} From 4cd7fa7d46ec25b96a7f40087140535a023f21a3 Mon Sep 17 00:00:00 2001 From: ImBonkers Date: Mon, 18 May 2026 10:43:57 +0200 Subject: [PATCH 3/3] Documentation/arm: Add STM32N6 and Nucleo-N657X0-Q Add documentation for the STMicro STM32N6 chip family and the Nucleo-N657X0-Q development board introduced in the previous two commits. - platforms/arm/stm32n6/index.rst Chip overview: core, peripherals supported in the initial port, and a pointer to the board page. - platforms/arm/stm32n6/boards/nucleo-n657x0-q/index.rst Board page, structured per Documentation/contributing/ doc_templates/board.rst: hardware summary, user LED and button pin map, the two shipped configs (nsh, ostest), and the DEV-mode flash recipe used to load NuttX into AXISRAM via ST-LINK. - platforms/arm/stm32n6/boards/nucleo-n657x0-q/nucleo-n657x0-q.jpg Photograph of the board, referenced from the board page. The pages are picked up by the existing glob-based toctree in Documentation/platforms/arm/index.rst, no parent index changes are required. Signed-off-by: ImBonkers --- .../stm32n6/boards/nucleo-n657x0-q/index.rst | 172 ++++++++++++++++++ .../nucleo-n657x0-q/nucleo-n657x0-q.jpg | Bin 0 -> 235978 bytes Documentation/platforms/arm/stm32n6/index.rst | 71 ++++++++ 3 files changed, 243 insertions(+) create mode 100644 Documentation/platforms/arm/stm32n6/boards/nucleo-n657x0-q/index.rst create mode 100644 Documentation/platforms/arm/stm32n6/boards/nucleo-n657x0-q/nucleo-n657x0-q.jpg create mode 100644 Documentation/platforms/arm/stm32n6/index.rst diff --git a/Documentation/platforms/arm/stm32n6/boards/nucleo-n657x0-q/index.rst b/Documentation/platforms/arm/stm32n6/boards/nucleo-n657x0-q/index.rst new file mode 100644 index 0000000000000..a9eddcf134e69 --- /dev/null +++ b/Documentation/platforms/arm/stm32n6/boards/nucleo-n657x0-q/index.rst @@ -0,0 +1,172 @@ +================== +ST Nucleo-N657X0-Q +================== + +.. tags:: chip:stm32, chip:stm32n6, chip:stm32n657 + +.. figure:: nucleo-n657x0-q.jpg + :width: 50 % + :align: center + :alt: STMicro Nucleo-N657X0-Q development board + + Nucleo-N657X0-Q + +The STM Nucleo-N657X0-Q is a development +board for the STM32N657X0H3Q, an Arm Cortex-M55 with 4 MiB of on-chip +AXISRAM, an on-chip Neural-ART NPU, and no internal flash. In +production, code is fetched from external XSPI NOR flash and in +development, the image is loaded directly into AXISRAM by the on-board +ST-LINK-V3EC. Refer to the +https://www.st.com/en/evaluation-tools/nucleo-n657x0-q.html website +for the full product page. + +Features +======== + +* STM32N657X0H3Q MCU (Arm Cortex-M55, up to 800 MHz) +* On-chip Neural-ART NPU accelerator +* 4 MiB on-chip AXISRAM (no internal flash) +* External XSPI NOR flash interface +* On-board ST-LINK-V3EC +* 3 user LEDs (LD5 red, LD6 green, LD7 blue), plus status LEDs + (LD1 5V_PWR, LD4 PWR, LD9 COM) +* User pushbutton (B1) and reset pushbutton +* 32.768 kHz crystal oscillator +* USB Type-C connectors (ST-LINK and user) +* ST Zio connector +* ST morpho headers + +.. warning:: + + This is the initial NuttX port for the STM32N6 family. The supported + peripheral set is intentionally minimal: USART1 (the ST-LINK VCOM + console), GPIO, RCC, PWR, and the SysTick-based timer. Other on-chip + peripherals and on-board features (XSPI flash boot, networking, + user LEDs/buttons, USB, MIPI, NPU, etc) are not yet wired up. The CPU is + currently clocked at 200 MHz from PLL1. Raising it to the standard + 600 / 800 MHz operating points is deferred to a follow-up change. + +Buttons and LEDs +================ + +The board exposes three user LEDs and a user pushbutton, but the +initial NuttX port does not yet ship ``userleds`` or ``buttons`` +drivers. The hardware wiring is summarised here so a follow-up +driver can be written against an authoritative pin map: + +===== ======= ======== ====================================== +ID Color GPIO Notes +===== ======= ======== ====================================== +LD5 Red PG10 Active low +LD6 Green PG0 Active low +LD7 Blue PG8 Active low +B1 Blue PC13 Active high, external pull-down +===== ======= ======== ====================================== + +Pin Mapping +=========== + +The shipped configurations map only the pins required for the serial +console. All other GPIOs retain their reset state and are free for +application use. + +===== ============= ======= ================================= +Pin Signal AF Notes +===== ============= ======= ================================= +PE5 USART1_TX AF7 Routed to ST-LINK VCOM (host RX) +PE6 USART1_RX AF7 Routed to ST-LINK VCOM (host TX) +===== ============= ======= ================================= + +Power Supply +============ + +The board is powered over either USB Type-C connector (ST-LINK or +user) at 5 V. On-board regulators derive the MCU and I/O rails. See +the ST user manual for the full power tree and jumper selection. + +Installation +============ + +Two host tools are required: + +* A bare-metal Arm toolchain, e.g. the GNU Arm Embedded toolchain + (``arm-none-eabi-gcc``) packaged by most Linux distributions or + available from Arm. +* `STM32CubeProgrammer + `_ for + loading images into AXISRAM over the on-board ST-LINK. + +Building NuttX +============== + +From the top of the NuttX source tree: + +.. code:: console + + $ ./tools/configure.sh nucleo-n657x0-q: + $ make + +At the end of the build, ``nuttx.bin`` is the raw image that the +flashing step below loads into AXISRAM. + +The toolchain selection can be changed via ``make menuconfig``. + +Flashing +======== + +The board boots in development mode: the on-board ST-LINK loads the +image directly into AXISRAM at ``0x34000400`` (the first 1 KiB is +reserved for the boot ROM header) and starts execution there. Signed +XSPI flash boot via a first-stage bootloader is not yet supported. + +Use STM32CubeProgrammer's CLI to load and run ``nuttx.bin``: + +.. code:: console + + $ STM32_Programmer_CLI -c port=SWD mode=UR -halt \ + -d nuttx.bin 0x34000400 \ + -w32 0xE000ED08 0x34000400 \ + -g 0x34000400 + +The ``-w32`` write retargets VTOR to the SRAM image before the ``-g`` +jump, so the Cortex-M55 starts from the NuttX vector table rather +than the boot ROM's. + +Configurations +============== + +Each configuration is selected with:: + + $ ./tools/configure.sh nucleo-n657x0-q: + +Unless otherwise noted, console output is accessed via ST-LINK +(USART1) at 115200 8N1. + +nsh +--- + +Minimal NuttShell configuration. Boots into the NSH prompt via +ST-LINK and exposes the built-in commands plus +:doc:`getprime `-style apps +selectable via ``make menuconfig``. + +ostest +------ + +Builds the NSH configuration with :doc:`apps/testing/ostest +` added. Run ``ostest`` from the +NSH prompt to exercise the core RTOS primitives (tasks, mutexes, +semaphores, signals, message queues, POSIX timers, condition +variables, scheduling). Used as the smoke test. + +License Exceptions +================== + +None. + +References +========== + +* [RM0486] STM32N647/657xx Arm\ :sup:`Ā®`-based 32-bit MCUs reference manual +* [UM3417] STM32N6 Nucleo-144 board (MB1940) user manual +* [ES0620] STM32N657 errata sheet diff --git a/Documentation/platforms/arm/stm32n6/boards/nucleo-n657x0-q/nucleo-n657x0-q.jpg b/Documentation/platforms/arm/stm32n6/boards/nucleo-n657x0-q/nucleo-n657x0-q.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9bbb4416de527aefc3a32f28d9c6b4e24f7ae1c2 GIT binary patch literal 235978 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

8@_)qOUaVdgko{X@!iPj?Casm)YBKw|g`G zNcMv<=wWh&2L7s>&a7mwLvfT3`cqNW)5PRGR{E9%dB8S|*SWoEByE!is_CXJTTb#_ zUyJ-Ym44s^Zve39jyJRtXP<+05*okdSD|JnOh)NQ(?6tcnaNOxnc((sBRLtd9UUV4 z1~ora2JcniHUF$4q^o;Z9i2Sb+AUePX4vpuO2~c}+`${4l-sOdT~aAX645HekGHA9 zj%z~_ZF{XkC;5#(hjm7O=4{3cUcdX7vR(${0iFvWOl6>Q7kC|95RH;-VvWkm&9RJ) zfAQ;s7+2B@13H{+5-4VMVSZ)%q^?ma;$JM@ZwCvWNNWAGiG#!*#Sky#=PTo^%gH$0 zr>eeysgn&n^X=ISk-2DeklnJxwEsB6sXq=7$Ev;3_vbrp74_LkUHu6U{b~xj`hICu zbfqgzMF1cH3M6n6d71wvj!R1Ddav={sjWshrP8hRp~c!~KVXoKTMPSd+>)|b5JEK* zNcs6)_Vf$#h}8^+!@GN7q@ziWKu-QXK`PPIR(VlDO<9_{)`|YesexA%`%=<5MtJu? zHNC2eOdz6#$N6t9iXBRQ$zDD?Z1jm)Cn-@9ZLs;h?s>NUy{dium|N>t2T**eY1GH? zaWuFD)!V_tSE2uKbocE*iL}`xErOUmas1^FNwWQH|9B1OnK9mfO)DV{%>iCc|A%g6}4X*%gEV*K3WdFxRQ5?&t%;k+n zxF^+G&~U-1fpmBs43?hm>MvBeL4|J(EDy)y^&A#Ru^I7PcIG!^IZin`$~FG@s4F{o zNm9)}%yg5ycB8oF-D)(aW&pD8#4SL;EMdcB$&D3!BTPXsq5Y0vy`RVA#p6!4Eg91S zp>I;s?qUuv29V~?GQ=tee>xF~qrv11*bYe<#6Jge&P(jor-s2799l*e>K}qd%i8dD zm^(eoAYJmTyPuo>)R&r?Igh_sPYBBV;ItXpyGfCqFgmXj)6%EQB(9(#sHmLe6rGc_ zaMEaVTuI*OeWpU*lviMvwAfNwLpj2Hp&0cCPDA$ys63;fW7-ctpKD2;a#Z44Y2x5x6^0R25o@2q6VZE;jcdWjHyxZKJ?46umC6daEFH2#3qHxzb+xvsXFORo$=9u zRYgbvwPoz(dK*xX6L}b+n+jRe8Z`#RhYbu&=9T@sbKRjpRj?tWoXa;u{p&nXif~f* zr(C4L3_QeBa_IbziOb*iEvO9UambVLsXGcNu&Z(Rn&lL`4qa}`IPQQ82YEFJ{6p-& z@_6#8ww0Hr{Ala89A%+B-VySf6a$H5xqXWJnj*>Jo8=81rRqJ%RU`3aGqAa4Wb}Md@qwzPCMxgODy=vsY2GElVzb_HBzib#p|I04#}mZkY(h zWhxL!0f+WOaqY^%e0v9^Tfw`iG%>(yy1QSH3iB}KrLpBHv0}DOV4WB!0g9A*7C&8? zUqKe()#mQeB3V}<-WRyzfT+33s_)IsNmGd>>W}lIle~3mKqMgCbj;Qnc|l~lQt~ma zj3v>$sS^yB!1{KMl0B#AHFathq4-;Fsln&EWI0f2>*(XEy1pR3>~e=ZrP;audUH3p zjFEctoQ?s*{F?XiR$Qu z8>y@%)YTU!Lm8S~QF-;olmStj#S*_m(A}WK?YiT=K^oHeo-sJpyI~U5UqQv)+c#>- zXG=&-5J(u0-Q)zpc1~;j;ksQZeicO^!=S&`2m@8W<4z27Tj>jE#VIqf~_6I+-X)pZ?(5GF9Odq#ODb zFz)l2r%~v2XFfCO0VqrC^H6c9FevVx#0Hr$ud{Tl+30-=^;I6>;x)pX>@T?@9SOC# zTNe=uxhb^kGB459Ji})!661X7e-@N+@Y0vgy;1sI~t(#&YhW zQpusN&PA%Nr;mb9L_88h!hn-GlR{j|gqESE28V9l3DL1?S=BmYZjGqSk2kh>{zAXR zn2nGxjKE5Iq8htY|J&P{87?VqG6Ak<{D6A~jj)DoJ$WMnqWrpMa_#}if6NJS6bTcwH)hd)? z?o03OST+*ey}=eWNlyHXdSE3c{HTfYBjNPorXo$P1CANP!4`VSUf_sAmC3rsY_hB3 zB0Wd0rq{%ihiZ8hRF)FS7-?|Tva2fNhLrsol*%e^kH6QFNSyF^i}<(>=VV<_KK&U^ zl=M%T#p`0yX{lJ4dZcQ4j7Wa=mB6P0)^%1{5v4kF`!%t7U0DBiyIs!A%sI_N4jh>Z zuiG`x_~6F)CaH~B?5R&*bu)0N;9jS_R0)O5%;;|7cg0paTEh8oM)FVHL;MGDstXt? z0t1z~Yze6ixj;-tX*5p1G^L7g!2GX`Rm6v|WRsExJjJ~#If$~p@1%{HY01n}QBhqk zH7PU~=2AKGPS>ke7SU~VxiIX;d3TjLx#_C9k?Lkr>fYHTv%<{Sp1SdChX|OTuIBks zjrKFWf1$y?U_Y%e`_aap7NYL$&Y%rFTK1Q6uCrJ-*1K4_GmYu(;DsU2lY#O-cEPd%d0jj<0;qI!4-aPDrM zkl*G?M*MB_WEY{|F;Bf?%E`8N*k0r zKeP1}I&hYShnXWz-pc@L*&un4Atw)Vtk{y@@1Dz@MKeA02L?|fJr3RRcHvi$h zRYJjxeUUeN?S}D5R&a%(xF7x8K^Xhxu?`@y6Wip;A9y|gS_Kns7t6^E#5-O*02{xm zpJ_#V;2GF_`OSHSaQW!w6}gXW2W`LwLfe0zK?J+{?r<7C1UYTrviS9&{^{U6R{?;n zh`%!=N{yB2DC4h_3jY~8l1uqSa}7;c()wK{EA> zomW&IvN_*4X{ffFw^8Hd3Z;}s3K$IeoZS@PU|%D!G1=QPlP?R9i3HGz;((;~2N zV%%n;$AQqQq4v*_?JieV&>kMwp4dRv@C#6~h;XA0FU_%xNZ`{XQ0DV@?=HUR8-2bf z1p8jF_kIv-nje|~-pH^HJ3K_rgh(xZ{R$S_A$av5*g)_DeT2x`T#jX9HtM(ff`&SN8V4F$E{ko|bVS+I+fMykmA+k6m?GdgiC}GfZYp+oqEb)Q zI&8r3%ro40$e79w!bx{r#iqkv_UwMQ;sbS%8GX+D29m2dz`~*GjHi14-;bCG{g?V^ z?*Rj_lD&mw1>B0W;4LL`EHZ_0054hf;CTR~G4PNE%-R z0DfdFhDB8(E7*I@6q+ZcDEm}76LJ{FfRS|c;h$-J*4ORla~IwCkNUIIB6a6_xfhdv zVEZHl#Mvfx9`3ZAPlSM@hth1V{NajRo{$z)MTP2pDp-_atU=(GXW z^z$T<7jKRk?B#B%f9W{wj^?u3eO}4)kVY@1^238M~Po3L&bLV*hi5!nm`wG*_x%S4osu~W>YaY>QIT*1(}WxK8ww0PTl7=(qlgHR8CP<< zDOlgN$cMLsgkpj5wds!yhwsOzDe*1x3~GS5YN(Jv&W9Z^23Ln-sVp(U z=Lg?XPNcn2^!28qy0RLHqBAUO6e+pgh~N+0byQufck167+TlwbWAx2EY;n~_YCv7e zzcQeP~G9G{zve7m$KrXL}T4^&azdTvXdB|Ol_ z3dm)Oafgd$atI$!=b_#k^<(ui*KW79AClk%DnVsA!*lPUJ{#L=DLf~tw_N!=jGZym^xF!Yfb9jE`Oy_)jt#NBoW?( znYdOo(jI>{@8xf3hjQpdY znF#~t?}OWoI~Gbu^4?38R1z55d&eIL+2CV1V0h$q)Pbo{iTM;ae%-X3mgpsz84#1V z-?!zgxT8xW(c0;J$dX$5_qhFQ7y$#G2sy)X_BgJH4+tO`Pmn7QS{_)$F~|U z{HCtaQ|pyEATa zmTkask;b&^3oX+B09ujT>nUgj6ngtZp;BJbj&8jQul$2pW{Ex1n2$9nOoCJbc=Kc!46rEvIoOZNNDr zjy$){rIzU@rLw5I$qB3vA$^Uxd3GQvJ;n&edB&>$02wZAM6k*xNg67JeVf1_ZD4Rc z{%tt+F40)YQ~E~tQBf1E24pf1gGNP}a(U$7gZ9(tD%bRlQQeKqhw6CLP}W6HDzKh# zP;F33oDAn0A#bbR(@xt$y9^D(I=O5kq3uO%MJK0gT+b6ZW?iFcIqo_4=Z!P!I{9Lb zFNZ~J0flAH=b`m)<;uSiyfI>2q`BO_n)Ov>C1i+Fu*6r5+fI{6sIp6As*u{_k%(Ce zX9Iu_wmmcg-(6PyLLe?oA;}*v=bY$;G@>eWj#`r`MG7BxI32VlYapboGbO@6n~%z? z!5*Vi#CAxoRggnGa=J<8Z7YC;tD!j{>6+XqW6exyQ|1{PlBed#uC_ww2Dk{Qq zRLJ!^k`p6i8?px+ggCJmH|VT^*R+td4-n@UKd_=%$qj>?Wgq@dwekonq_>P z0GKE5sG@>2@;oJ6WMjTPwP*B1(a91rwlXrn9F0;d)KN5#95j`4Y~v{&f0nGD2``j2 z#6$539N7{15-?c<4snCujOkDlFBSI=gg-Lm*2B&|r&Ux=J8x2bv8!9fQ5W?YQc!%q zjfZ#sEmf4!+Jh3&NO9PLN!OX?waoNwn znaby!k~Hl8g+M}3NKd~f8uO&l+K{X}Jj1%JHfKta3d$SelV_;N&XcD2L_3y%NIi)3 z(FCfX3A6MfG4bLq{II3*R-gflOO#hU-vcbO^hQYEjCUlX@d?=$)>W> zjIk7yze3Bd>Hq0%!%z|SO(g#6eU$Jbg#3E6abeBb>7T8jWS#K8M-?VQ|w$F7KYbqrNLAKMjkudByzg2X(J$z zaIM@9IL^J;HlV2TB$JyXRsJbQMzt_ntyOgHEm^d&T$~zAq4u6te-EoGtRm4@j(q0 zU1CvHrNWjcC}xahLGO(Ef$p|5kuqTcjFjg4!)wOT%%cY{Csh*PPwel=GqoY`SW2}uZw@+c>C<-WpT`7=CRmC_ zj2L7R8w7n0H9b-1$WRtc(@koxq^7&vYHuk#f})-4BzU_VBA{KPZ`A&J=Xh2# zP6={cafNPq9sb%e%Is|yH-HwJo%Hv6Vp183%M_-sd}s+E02mw|Ip?;z0^RXdR1nKn zi%Th7lvmCV`D>oM2CRBXZOd6!)YkB7Bmtp!S+_3UHiOEM>#l~T2~$rT)PkN^*kxEp zjE~Q@hV~&~QOt!%&k9e|TSluGF1^U)p8COq54s?T>OTnKTkrmQ$`K@F45`it#~|ne zs`0kl*0)8f{R0JL)YNfA>m58`hjQHR^*zQ0hj>G0>w8^9S4+(m#uuKj)6~N@)7nx}7+k`)btR5lh&dJ)@?LUpuq$l&4M7~0^RWc^3e>#3pGKdG(nbm`lT zy*KZvr+9u+Glm#A&l$lwjrdQ|Z_zMTP*TY>*7}{52=xU+`Iy>92c`m@O=3c^l~*B$ zsrCEo9$Ut$3vLCnexCmT$4AJBZ&SvVA?2s2yw+T)W!*^=+r*Iv+&)~G#uw|mj``HO z;Qs&%M^jL-d4?$2_J+oA3BWqm<#LAIZHiACM*ol|(c8r`)!>Wax6XdJ2neo#K%`mwAx z8mas^s#}dRNidMnNGf-Ea%F<&9mvV#XVB_NP1M#oD@82~b5=CT9H-&w3nm*OcOQNa z9+*1YuJ0C`S5DPWdQ~(9LNsfD%t_!TG0u4ecGhu(p#81}6?aQDJ*RTp=BGCp zsbzShXtqS)s49aX5PrDEgIv1M!PatHyx2uFHMI0>hMkCz$hk6k`PhYjxOq7G>OV== z-3fM%l8SnZ#16HIQybJ&Hd7;BY6w{wVQE0Z$jA=X zVd&V_sl?8t5v-|-C4#0}l!*+$A!C5q&wVhV>U$5vstdgVatHv<2RS@y75ySElG!>P zB&7XpvsT9#X%FB8F(hO6etPF`>ji3{P?4MuVl@diXsGL`FFi9!38{|bXs47n&9ZdE z4D-f)Kf_B;e(8}Yce&Zi1_VEu9^sBb&wX*)-|Iw-%N#uVVCzwRt^j}{3+OT1OM?qX zU4EPCDJvwBD$6vomEK&+yNhQTKf_A@09hyom`1uo>^8g9}GqN7P+E6jPzQ+X5&-gDL@x4&&F4UtK6VlcyY#nR0)2xcJ{|aLNQ{aR)s5YhlziyRu`5WT2+w_W_vZI6ajXYHKD3Qd#gvbPLKQDgV>PtyX^BAkG_mLa< zD-4evG;WdvB&iG8NXg)Ft~D3>=-9}jAj6Zv*Hw5ubgR2`TD@d&r0~pPV-`SQ6-YQa z!NU*Tr^-m4F$hz1oL1VCak5-xrMNoD@os67MXKKW+vPY4LG6R|(W^BA(9=sTJo44c zQ!`Xlvw#e)*aWJM6pR74*YBm_+~WX{7lJ;zRfm*Bs&WY)VE*y#pTG0exi*HPkm?Lc z7<6T2Bip{52tytRI2vb9kv%~lwT4sM=Epj5MrPQpDI1%*pG`?ZpA2$II@ifVIuZsz zBpo>4!5P-Ag2M+G9B2WpL?~U?>W4p`w+N!HLI!Y(27Np063915#{lLm{W;ciis?N+ zR-|Xwk~9cHwghAtja+)E?taHe$4XHUK&=k|70%!Wh;Q6T9f2-WZ# z006{ssApVBQ9&$qRPff!B#+99mYU{i%&(GuR0AcyhB2v(#as=;gUCFBH4y4y(@)fe zujy}!NNLmIC7szMZQHjMY=OowarDl#$5*mv(8@XBv2@)qy0g(2C-qg8LRVK}PSWQa zk3IFy9x2rdj=8#{L9nesA+y+b)xFgf{#}lNW48ITRYg5Cb9oX?6cIBOc{#};fCWMK z#(Qds>ey-G>KWprmPskl1&!s-=1?)nJcGw=S09jz*j~j`X@jNWS*t1`xO`N^taN^2 z7|O2JcF5pz02w{_)KWP%^2m-`@dg>^PvS|1F+m_iBRh9@_Bv%EoB|XA2=A=oskUm} zqepO6l@Ko&I6cm!-BEO+t+YcOHAI3%WLat2lqxXC;zk_c5!tYL<59|WSAIxW-}s5+ z8eURYaPCj9xYKdAn3JR;lQdBUXpz&tdmrDYmU$zkyhAXSNTX19JZK%pLEsMA_C2)9 zKo~nW7~{7ZT7^PPgr0qVnr~h356C6Me$Fx5o;4l?mS$s#H$GdB#gobUX?Z-QixH14Na1_q^V3-uJc38f z-04OsHpbnmH=R}LW)a}Rj#Wq)<2+=0=#qZTgEK0U z!w0Y){+dQWwR6g2iD8JdKGNCPnc!#F8uIy*I~L52e`xYfomiHFT|;t)qrJg5Qt?ASD+VKziRWyl2vXje2 zwEV5_f}oFVpM5~-;g8JXG$8ipURRi|N1@_=A-ZUg2F$Sc%KXDlq4L9L%!9XL!#WpF zO8_|u{Bwh+aneQ(L~DcFUUZ^%rWL2Cf+pJ1KotFRr53J@GEvlza5Oz>p$F$h&%QLU zr>9;pqtiInP9<6hE#8Z7;zRey*Rcg&e;Jc)Afz0Utd>sZAV(u^yPxKXl0h1Nfc1Vqj@{BNj>{^ z)U%)@Z~Yt4pbX5*GJrdiy|fpr`pSyIRTVu|n!2Wp0O$^e5Q2|By%9Def zXCGsO#;vQLi#Mu8yzI7Ddi9>YQrbyzym$9KKh%7XOm(uMbFH@ z_V)wpsMkw%4JG-i;G&_Hg{frn=kpafY?1QqCnq5DsU)6Qia26I@&I-WejoLZ(^^BL zDRwo!QPEb?HM(jQs7H=MB3-GS-S<8-$-v3ZsrWn^wn(tZZFfl12h2fNOx*tfbR3R8 zzr$A)jU_B^yoX{lA@}-fmXpML{i6D~zzo&?RM& z&>cTd((qGT=q*)L@gaBkxoYEbNjclKbDlusw;GkbD0x9bB01dKPBMSz(@+luu6L`A zp)NOyxoYF8R+1?W(2It_MFX)Op#3#shR+~me;o)_T0Gw=+{`wQU1iX}>tZ9!1M*?) zf57Vq%Eto)5uIXbL=^H$SrH>$%vj(6IVV7j$09d;2F?n%aCNkbjNV|AW8(yX4oBBQ z2T)obf?J(ZO-~d>5Spr1jj-nkKqDj)csg9v)0?5Th~X7$51z@eoF?tLCm8SPr$K0Z zRfj(mG5)~+06ike;$VI=hT|Ss$KSrZ$lDurJux7EcY~_4ulzt>nXh^(ceQ**{j8@F zG<ac%H)DaVm(H( zRc4Q(sQ#3P{{Wz>T%F(g!3iU<;jylD+;;*74!R@yOhnQ2GN>w{tKlA5IoLpM-|C;? zu6&7ka@o8ry3e42AmVT99`De};h=$;LI|tej_9$Jl#l10-RFIrTZ?UT@v>*Rth7=jH5m zsPE2zJbwdZp5B`3&*=P1bZt_Q{{SsgU&d@Wiu<#x+P0_PL8JRva zaNK(X6lVkJq5dpSvck%!=YoB-ok%SUkucf_Bw%sRzJO3u(JkVsYUrjnX)2}>P2|4g z5eH%4+h)^@XBqnH8F;r;Cr?jDW>%?9l11M@~bGDp9*vz&OgjbQmJAJBM#)3tT!Lj_ERcRN&h zX9WHAB^78g-0(0*W6r2ZXzi|LG){{q#x%;v5uU*u5!)Yp~p&t~> z6fG#66>Z!T#~}SRl9uSUi&9Fc7tAJT@_fGRGx)Wds>GI|76Nx6%FDMallv#=b;jS< zJDD5A5QXkn%{Vy!03CE6hgFpqYAZF$dyMfxap=97^y8(_s&u;p2j{!mQCdOCu$`x&=vCzJ$X}?3r z@HG2UL}|VrK$7`D{QC(w&-`>dt$LPA6$Ld_H3QelQJB&+eZHB_aobI(YJaU=Ck0$| zkikEkuJqNJF|kG=k+I!Rz7HUAq78DOlF-r#s%}YCEpuMsx0Q`2dYX_Vjr_rr8ObYz z$vHUf_0d~(WYWym`nQg>!ZNk6>}aN6LckN{$?m<5GC1G~sIpYm8nf{BDhVD0MW>}C z$5FOG*_#1);I9DVarNW6=AC(i|x<^EOSamNR~x0_8FM$;eH z6B@XWE1to4&+gYK_^lXU6E8ks%9+k{?|^mHcWI!uTPiBrDdkw#b1X5L9r4%zJDqYT zTU=W4)pgf_43NcFF=a<>#drXWkG8Un(XYtHDjKSlf$8a4)>kmcvl(|>WC8EU(lvC` zQq;*$Qv{Jq6q_WDP71K@57$zTm%sjuviWwfZn1!)Q@6l3mq&X%6tUksBaOeG8~5?l~=Gj<0Z zv#lsj$qbUl@~X-zt0+z-@1uvx^- zlT3=s50KKV(PV_ePkwj$~*zF6y2Z5a9+gP9V@~~5vJmWpIOQek?SCJ)j z5zQPx9k2LF&l`uR`f8h{VvgMmDxi2u$22B6HipjdLj&7L$kDnWh&p_qFk_x`qa9&c zO<8<1Qd_C1Bl4A5Ajn2xpO_EX;~Wk&7^9$%3gK8DaqFTk*1`9oN?4|yKUP(MJ3uGb zSy-43N)=$PGI--WAFia`4Rg0xXl1LZw@_TCs5n%sQoMqsE; z)EkKaXPjf-og~|AZ6t&l7X+qAIV=wzzWQ29W<>MU0T2TjZ<`0)4J3$Ih35tESPn){ zwxsvltvYnzu+rNonL?&2O)e@vQ=FI1ewgjfhT3X@B}7#`t+EzCFchyRj(Hzk>31+S z6*O@y$yf`Co#hOSx%oDLGCsOOL~|ikAB(nqbn?)P4Z=A@hzwt>Ld%d?ase8r(2&}q zj!JZmq>)Q8I0|!&X%8{gcJb?zjTq{S&1LH1Dr(Fdlodsa6^&45unIIG$;t^iTzY$G zjn=`{=w6mDJ&O6M8Vqva{{0u|>LdREq&rO!Wd$xMg@I+TFrYY&@D}z*gTylusCyn-PZ<`DTMtw%16vjqQDr3j{ zLtbB)s%L+P_zvM`T#~=@@1iuavX7lcG%H+6VtaR*#MXG#yjGp?h!3xW~4UEXB{vbN1HCBna2kBf5p( zx4w4w_Qsq1ViCf*KA9R?X#kM^u<^z;$=ni1IQ+G=R){Zu3MN+Y?%vyThnu+n0NNc4 z>l-bmruk2Nxm8j@Bq0@Go!85eK_rG!MnTS=_&QYhb3%Ot(~taTQNI#8O>g~cK_yr# zZ;=uirdap1Dj1e*cRls%$M8p$FU^duo+5aA=TA>hY@~sPW5g7Jqf?&Xk&-{>I-+l_ zZ0ZZO;_pKRJ(h|VEgd(Ry`(2`2b^-mb_0y+=DGM~ZlJhSQ&CG*aivEBDzuU)LykME z4Ds7PO;LSMYKoHiSx;}BZZO3o7kE^#i<9!P0~r|S9B9Q>{tA~%A2Wc4KjE+8|T^~J|{1zvMmoA#O(TVQURJC3LN99JK#5419d-44BaCFCB zbVRk{kXk7ks-hzdH5Ji@NXLD{amI27eNx^ZbgUPObgrIh;7G^~847&v=PCTT)veQh zA9VeF+L%;URnbu(4N$WMsom-T3OM9rA6;QD&!a{7?UKHWv|H@e6~ChDO;ojH0A0Zx zWRvpt89J21AcvgM|mO2 zg(hhb4f)_P$<~qR$@W6J^QqvXwN^tz4aR!F3P zZ6xTmjZrlXK$9_3(RrC=<3BGWpK;q)!;0!ap-apYb zQPWo*8R`+jZrnCum4F`n`)j2wBIdL)y=uaf?r1(Nasv~X z@wBgVq^`7vve#EeBvkl_9xd!L6tKV~YkEM*N}+*f8SVGh@X2s&hdF7#LX zpG;jXl1FWZqC`mHQBcgJ0;QRb-ZQs>kG`KsD&^{$dX$EoQyK@4%=1q0#lv7OFjtQM z09^{N>N?7MZ9QyMQO`Y99YpC9Nw9vYH-Vq1)0(TT(VE>&Yp0+!H8$g1@>Meg+5-HG zx15s0lfW9fWav3ixrpJmao=3))pi=^xLoV2)$62=sK)gs9H~9P&)AJ$rtw62VmsAb zf}WY_(q|+W^1}hg1D;47wMlrL)U*=7-=lA~&n8Ju8Db%e0fV@P!61DztY;ZMjiAya zHoFs4EkwqQm8Xcv%pu0y0zuEFufGl}J}08>lT9#|e=iappl-n+91c5cm}#z2#Un{2 z{w7x7uIIxKVgqtMn!5ZP>PW7E=_9YEs;b;y%7He89A_)&KDtqaquU&seG-op;Yhj_DpjB5nSl%E&F$@vh^OKxowwc=P)(fXZQ{65U z_S-CVbt182rI-}n*uZ8y2Ou5*K-={_k^CR|O5;_K=;I#4B5+!zEWLjvB6^}k( zUU92cV}eLwnvswJ81h|D%2UyQ*~f2fRUIwiM@QT4#-^L8UP_ASWKjroIafJWPji9m z-uChs{Xxe3E{U|1hx*8DCy38vh!C}~Q zk)3mfMlt;T_0oURiaA%HM)Xpmx*f6sllxiEvDY;&PPB(YH&4QIv!8zY*8unLjcfqg zTX^r=)azbPB=M>duc6>;W!vkF{WY)WuV?L`4CgI?2kzEJGwF=_>mBid+kuT`oy%fE zTO4!T0qLL&;DXEYoO^Su1v^W64_$eCZBxnDhYDA=PdWf`S1bbA9V`G7w|uTgCC~W| zHPs#kH=WUS0RF74Uf%tPial~{pV>Y?x^>n51-hP%s#vfa;{N~sqzmb%MZPg`@jyVSHsX;qP3)ep-V0e0=lB#d+Gr57KN zY5W4}I-=_>o*SLIl7-%K5h&^=e>SDV5&DylnHUYhh#Ys-YyBl|^-atRK@9=){fK7m^7=7{U$i5(gkn>jx`j!!oraB4YvgKHa<%kk;GkVxoq4 zBWdHFH!jJM0FVFMBWPN~oyc;w5E`We(Ypupr>$IQ7mo zVN3BFX83FeclmSJr@8kWYk!7WqmGuUII0y}bfM5PoDMi6zilY$Ryiw;5K4M$Nua(D z&=x2b7h7zv1wj$a%_5NJ9I6bd&wS)$=$A~;P^VB;ihEU}mV0viIjW(UpEx*H#>3cS z86=*29Z9R`;*NrUgtpSjCc;DlB|$bh+uI*(`sy!Z>YHuK{Hl z1N9o~RK_qn4M%UiKKBZ0>KUtxQPxb;sx>0BMD2|2a(M0S>+7uI%~{9^Ay}CM1teoR z)ThJVfV_3ROT|ZudN@?G&clNKh&{>G*;CM=*t zNd=zs7sJHtva?Vo<&YnlTn6Be<$^fpRj$Qs<$j^FS9JZ>Y6|$BCPv|iz-)1!zqs_! z`i7Ch=LbK8DCFy{Z`}_UQe5M!xm@P+gj;vh(jxEn&nF~%`)DUlbSF;K&GB~2#YIn% zHdH(jl_Vbc$0Is47Wyifd?o5N=!L(^L~^+E1uno@7aSHn#(!|*KKg=D!Xc?;s8<_F zR$jyr@9nP5NG@+72Iv_%1x*tC!1ox>ZC4jwk?7icx^U6iWCK_dq%smF$17u~wLmU{i|M?#8xrpVt>AmeK1f%*Ntb#kwS zwt@r4f4LL{h9M(7k4%A$8m6+>+UVf7+j@?8p@mPDrh+cs#j%1k{i~)cZ{X#Aps`%6 zmnNjCibiE5EA1eV4lqZd9f&=&(c+q-WJu}ecW;$fX$(p12f5cu_=(c?`Kj9Rb-O&Z zg;FCaf+S3nfbwnqk=VD`Y3EGzWs(S?tfaV9rCcf*eA;-)Mk9l?_RcasntWAQl%GXK za`1ZZZs?S|R#h_G8<{D=%0M&1x3+Wmy92@Z)qe#f(MuvrOE7VfgBix{b;ZSJr$tGw z*9xgB5rC(Hh8JgCe8+A(4E}k?I*gu#>8h#(sHCZ#qnUTaQ4j_nVmS7}?b}L*n>oVE zVz^!|FK>dF0PG$~oiJii-=A-$vDB6awA>z-=6$2(Z1BU;htuikb!v57G4#Daq_);p z5j*C6wDGGi83U2{v6GD8;NzV^FXY$Cs`YZzuMVY^M}KZO(A5n}$gUNV&twTvZEw?6 zbHhnIQlup#3AsZ64$u!7<4Vx>3GsHwDf()LzFUoLeN;6oPYcdh<&Bh*I0O5mRjg4> zlk(*I>g4f=Zs_VuW<}SN=1Qb`o*&>ej+SQmwjBDL>C_aGp7HMI z``RH086T})KAL||8jxGg1MBOrI#W9m1}!~6JjcQM>13y=Qc9^z@O`veD5E1E5IOqk zXwz$9s+VaU$?dG1%LhjdVL|gJ=dWnMjX>t1e}28GdS4Dr({K*sX&cP z3ftVV92U{<2W1K2uH zezbVA{fw(Gei-$9HO71TR6|uX%m9+EG~JH)BhVGZc1JcbkB~&$3vbLRU8^b*?B5ijRI8+G9y#^Lp&o}*nVo6nNhS9avr|*LCxCl2Y1f?@`;LK&tdo zx~t`|S;{HF@4@UfDeBeg4xZ`jeLa?@O1kN)J{EZk{8(@iiDV@~Je-#Q090#8MOBe0 zJEA$z9S3Ex+3DKxcDL15#_};rDwZrG$YYj|lZ6NEom#dUSPilnsHBl;+vbQCa!M1C zo!p*1_0JSB_=LV9n?auS0>?axwM!cf+f#ObyZ0KtYhQ}S+Ibf`uPAXzC?JQL? z2_Bw@Qj)!PJJBFwqk?~ql9s9{zGjg@2RP2XQi|L103?i)=rvw=nR~QbD2z3Al+aYV zk|HvI-;uG4U#qo=01)EOvX z_(-ZLYZOZ9fC@7Kj2sU^+gz(hb+xK(nkc-$vKi!1LmZQkPp_t|-voM!(t@^cjH05N zQlIGO5u{3>fPSoV$sWU2`6MKwTpdM4eulwKYw1%@O(J1XO&YqG(Q~&g>%ix~8s#q# zME?LEAH}e0hLPGtKmsW~zzk>nHP)R&2T|5rX(_sLrV&+BAloCxjJraUk-Lx2T(jcL zmuY%|KTcJ(MPkV4*a{Q@*nj{W>nOi@s$S9)uz=088n*l*x8I&ibze_NVR8ydD{R8# zfI%!fbN>K1)l>4h*wO?9_alM#)$jctZWB!f9hlAyA*ZQlh@X^^BH;1s$^H7)dqgc4 zWhD(y!Q<&0l(1zDfUAra zB>L)5p(T&XBM1gK^wSQb>C1ioik^z9St5oh)??+UVo1*b9z9N_HyxsC%7)A06|HJ4 zG*xX2TPVnB4p~}Soz01x1CYD27tpcx)t}NfS}vNVuNK2AQd}y9b=GDo(#oFDQ! zBhf~~u^i`K8Q6YPf$NUi-j$S0tl?O0m|eeGlJU%`QBbBb=$%P z)==MIrH)BRs0i610d5I9Pt<+&&`>R;8|A_E`(s&-_ivter>D3LKDW{Ti z3PRNps01l(+w-)H4&C#{irrvJ+B)bakixT~CzupA(hfnv?}7%K$wPRli_Lq*168F! zmK@u|LZcY`CAVj}-Mjc}NT~df@8BO>)b%voKTms((@|MXG-~I`seq7J;41$Be4kCa zJ@Ha46V*s07=*}DL{LBgv0tI%_vmedr=Ycb8qZW~8jv`M7{Ve~ z%Px0d4Ch|B_=9M*TPy1>)a^>t69^=xStFI1*>@;Hrwj=79ldp%A4$>JVyF<@B~A1( z(t}s}^+2bcq0b23soS;)(}_A-)NNJt)ztJ73ifA|r7EOxlA8fQbF|I*G1Ta@*m!$jbE96A#ud!H}!ZZ2th}I>t#F z#=$;6++m>UdP?e;>ZYPvuO>vNaT}e=cK6_ngQuMo_3z;wElmvamYN@kk9^@I5g7q0 zT=1u6Kt7r$*ECj}l|35VmX=CLoV%rJmW!~#I3V%pe)`w+UAl|I`EBvmMHL)pd@P7$ zL>^#dk7(tWKQ0GwbVu_Eejs$Hx~00Jv!^Q_rmxDLNg!(BSjvq50I6M@kItiU$l&%l z()~MZjt;P=ucfTG*U48DpQR8(((CA&USu^TGOQjK+qTM{|zx`YPjWH8Ru% zw2)zvVlb|Re`nij`kqFMSZ;MU8`TUI7t4gTajVH$Zm6~S3>2rz#~+1rf~5ED-(6Bv zogDGoB~1iEPmnM}$s$AFO)r(!`#rW=`rzvXV~`z*W9&K7*LS72+v;vrBWx7$Z<7nV z0DV2bmZDWxOT}f{!%=CjwoL^@lfxx6(6b1DKwB;k&Z8I&k6d%kx#F*8&Co~04xY4L z`gA>IK%z)WxRJ?ZImQ7W-p&eAgWT>k;-9DZhC1b@s3}wjoW*nHfCwYFA+z{^&m8EtN_54h z&k~a%s;xO=E2)f@#tRe&0zx=qJNL$$*sb>FyVX>wx4lZ0Xx@+wkYRR(UfJwVZZo4D zOD)ct&eb;0hZP_KC7E|dhyMU*JMBHUe$GKWXAQOZp(XOn(pKARFEuvEqGy(#Fz(D) z2FWTw&*B5IBaU&Pv>h?iF!cq)5yxC(+VVvtLO~c~kgUXV>x_e)+fExe2Sqw=-&-6W zb;3xbMVro}K@%jDg@z=EQ31dbI8ZP2RfTcOlFQq*cgL? zyN7THBO~fG5`x7#)~G{92C79me5+U~g9FkB6Xzo|TsNg8pk*gNS0ygjre1Xi1D zG!ZotM#~6j#bf6pcZl;Fft4fNo=C=x-Hj~`9J2_OrQV?w&9mlq3Z%E9FFo{P{EQo+YU(WhGX1z89lhvCX#~VbGu)awzJCV z1Ep;#Mp#J7JbC;wMslPBgYvM!@2@2;`b2T#(X=$ztIg>ycFWBzRCK8vg{au5WRZXB znC<|O0BGBe6^7HI*BPj(Ass($siOTSurzelvy^8HcQ#LaoRh{*dDiz@^tRh-DC|^{ zMIua#J3$Cl4&-i9--TshcqC&iGDdVUZFDyapXqCaGgec^zYRw%#-H_tP7lqT5Xjq< zF&V+frb?|_=o8%{y6eh%I(YZgRm@r9FiA&Qu*(xG%n7XkC0P+D->4HAKy6Q_cb0rO|f#x)^Ksju3Q#sG&tgSU@xhixc<2+lsGMYS* zn)t>?f5P1Ar>COl{*x&DwQKm$@BK`qU>p9PnFGJzZB-G=I^Y;(?d`8G&Aw-);eG@7 z=*a^!%um>9%rroN8fmlnX{-{;dGck)u^M+2l7oR1gnARNIoaHp;V2M{iK+nmjVhM- z!NHPa$G(z}&SS)FpH6Y5yvgHWtpjJba7MCrP@theFeI1#?R!`cDC1*|drFx0Hkd@* zig11YT{n>|b2(nl&V zBUT{ul^p45CW~ebM(?oGX=bKi0hNY5LhEFSE`JAKJqHoS2&|t29lL4IP}(e2x9ffK z>m@$=G}>wBlq^%ONg=rh-?p3hEYUwf?gWwXvvNm2v!Na)bWK-KU#RAdVfa0pXOnJT zA-|Fr*MsS=Zy)MMi$B>SJ%8$t59#Wv>5*w*e~f2COGK`yr}hw$jiCDa>XW#`Z@u2G zwUjZX4J{z^95xHj^Bk}o1Klb66MS;RBN;>rU&{Ho4o4aP039q#ZnQa7C)hgK1XUG@9F;LrESxJ!2^r4|$Eo`9 zr#IRcw%r;Uhl0w;n+hFG2~4Z%v|zio8x`!UrM z-wkW}a)uPCys?s{IFJ1pH~$F38=15O2^^Sx|LQwextGb=Tz5+ z9U|B7Dz`H%NN`hX{rrRpv*ireLFEf7pfvr(%v=Ld`fgT@K^{dI)v zpGJ%Ddn6qjY_i*GYisCk5!TIG+vX_h<0XkW12`EczNJXe%OD<6Mhm+jZTz)d^k+y{ z*l#yVid~fSl~bP}A}GR{ILi6}xYdCoN|G5CMwt*{ffys}$9-uYjHTEf{{U^HxZkZ5 zbq`k1&G8E&M^`Lhg;2vG2nUjT>KHn@8zm1+ML}kgNUCd$Gu4wUkkcoc@cgGIbFlRO zdSm02?pPYtMzxJdlFrQ4akGbkcHxLA&ImXoRp{z^gs?$F9Q!FLwoMEna1oI1Q|@`> z{(9L-B}|SDyDz#fqqx*pQ&vqaBU>silG|Z{BRkQQvWW}ll1dzmb|aoOB&tZBcq-ik zPYK$R9!L#^Vfl?yJ`X(&#&LG53oUP$)8!q)MJ#~itY_s9jO2mqtA+f=qj-w~>$408 z;so$@GOM&Teqd~I_ER%k0N6k$zi9Vt z6!8<14p3u0`g>%7?ROe!V3gCet+OFPQ_co*2p}GG-s5wlqnY56I1GTCkyfN<@2L%< z3SOde^s&WjSRgoAYSKeAxyZrbC_i0c1(9}dHww{o-=V(L+7c@*Ocd2@cKMPbd1@6& zBMrx=811fX@t()l6qg!Go~22po>qO2!9jor%d`MJ4!V_<>L{TwNd^k1&7HvU>7kuL zY=*v`DC#ODK?@cDM;wZBF@haP{o3hE-Df@0ql;Rer0`>N>@lm8!LFFSOKzmRTcECk zBg=+z$dT?cVnTD=4{u+~Q!46PO`fJog5^*Q0w}3KKmJcgI)AB_V5n;9C53^BB9b`7 zKpsKbiay_-u2m&Mi)feF#cEPATtV}aW=-2d?*N=O2OqmpE}`qV?3c+ccWfNVy%v!U zQXHM7n>Zza>@kf?t&G!%kz?9UI3Aq#8m%e1OQ)}AiKmkQktiS?u>N|JQ2%>`BdbB0h-*JL!jq%e-E!C<+NF&Q5 zuc06lxC~@^YjqoqnewMZEBa0Ozxq6p42sL~a1(?h_K&&OHKc4tKo~uV*GK;VNs5pD zf+hah{YHmS(~=#NDS7~5$%9sM+!;~IG)#HB<|WGsGQ%eQam zrm}uE3CIV&ngdVws9H=0=N)=}k6 zP|>50G)8t3ax#5C%T+bA!tS==i68{*=XnsDpj?z zDm#pk&2WhoDnL2;hC#_39^amu+^qLwQZ95?8GlspqEaXU88>|7{{Y?2oOG2-Tp z)e#7$o|ZO{DwP=of^qq1x;nf#MmXdQpKUs^SORNZZBJHDayN$fT4|9Xp(H6~E6b1X zV3H50`)WZi%)codFw}3Y??0d|G1Uqv}cN))#T}dxa+UcaHqZLh6Qk3KuE3$6JG6iCdw4C~Zs=LG}X`jR@Mw+6vY7oQlsHzNnoHkB!J$(+Xh~ZX^W64q6 z^W5k)e@oNVT%NW_ZPPOpD=e`wnk|PTV`tYNmUK-zq!DZ6iuk8NN^CUJOloPNieVg$ z5(x>6f-!QMLCW&peC|eMoOMcy92{cnah{ZXOUW#3tP!@R;emse z;E&HyD_@9xOLLiGjM7t5H94t*v|FWhYK@r`j2Q59k+>ZN@s96!uA%BHUE!(R+wGL^ z9FW3d4$m?cQVBe#;p1I$#W<(QobbsBHAu3$JH#t5Q&mAvO$3Uy1>#0`je#H>t0*Ll zjQ1Ei5lPfGI~~5g?0r8~B0~VFt1nWjVTijbBzv=!%CP`rAAMDS(U96B@dBoz;~Zh2 zqYnXY!0y8z-J_EA7fnUb*E*_xo2_cfh-ZdMwvcRd<}(Jy{OtsS1~tzOCT%73Z+w>F zQGS-~Lu#rtalTZX5LfoTT=x5DjnbZ$%ZMy-)k*P?ERa(N0Z=$4xjn$g8SDuIQFN`V z6u+sjs94IAg_MADJqCEronCr@>o1W}!@eU)M^0mv8w3EP93M|jaYs9Rj+cpOmvmLr z^aZx%QFo%2AxR&c;7W{2XXeHaBzMQL<5nF9R9b38K*eyURthswM#!MJJ2HC!{+|7~ z)gv{1OZ1OcPgOHjKfuNhns;s+@q_sjt52Y+DXO}9n%Q}RN?NKaXzD&5S@((IQJCFd z{;@zHd#M9IUXLBAt7bWFFGQ%`XawmHT7wxV4Bk=lkhmLFo6ww(-ZWGXoAB^IJwduK z(AGd`YeigDQ-~_o8mYsq@Sq-B#=s5W0HKHC1PuBeO-{iov`zpYh-dK)YmzE1k(?Wn zwkS%T0Lb(@XK}5!+hF*r`k3irXA!K74g)d3&H=_xAALGzj6QtTEKZtT=xDA`2_f)yXX?5bf(%d<};P!B;?~*s-~8DcJif-B?K}FOL=(**Bpe|gsB3Ctkz}cRl)GR>2L-&?X_(d&z} zzGJc6OnXPz3;;FOogoPQ3qj_wk))-iP!DnPXI!^y_(&@Y-6CNF!p0Y2!nQakAM!QU zeKQ)p6)7Yz*$x>`2j$?6XDy+FylxoisxqXH{a~E`0Nj04keNdT^JOFNtAob{3DNX9 zBxd5inf-^=OBjTv14s$=+pjCk)Xz)9`~~4x+6y#@&(N~9p3K_l<2gwQwPS+k8P9I%i;Nz3}@jb~*VZBJOv ze){&Di780t34h<$wKfAStT|Z5J$0<~+Y}Nq4{_%cdLD(#afiJ)jnx6x3jaV~qKMKsoh3 znzQ;>q&n$t^zzw7OwR9&QBJZI9=m}%Pal?bU35=T)mm04>1nC_?fb*vhks$;R)5(;no4wp zz8h%ae?01I`pBu8Nq-W9fV^kxpdB65_WP|>T@59wTWs`$6C{d*2RJL0Cy;b@s-w({ z%8ZF5Vadk|Jmr-&e^;OiI{4!Rp$%s5+4iRH8^Ail&{^?PZWi2LyT%!5Zl9slLN!tEQ!T zD$1IQ`4$>@X`>9x%a%RJ7{JwS(R~0qSEjnMdPYIWDt z?AI$@%`Vou2`$xPbv4dbIYCxkpo5(Aol>TeF4JKK<%l)mZFLvhzYNXhH zMyQf^4&GKy3WJOe`fcK0N?NWxDRxL`Qabq}nqyM0^UB*!6#42&sk3-W6z8$JXq&MwbEf?f z)7?>XjF=o=)6zo} zUlTe9!j@w(Uz^_<^wng7lH$zcCw7L>M;&B#*)CDVEg+?>j;OwTzF9{V>EP+O zI+D~Zk3~Iv^)8Y)sFGPBi^_7$yO{0l27bDfz{`QY}t4vqOS0^B>P%0D=A*$&NwY9DZ8aVtoGqWh)GNDb-U8HDZ`MS8lan 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

G`LuMt`K8Dm_}0caLHTzT z`YAefB^_f8-x5I`u%lWn6<}|gu0x+;ph6^3M*Bg1$G9kSt@hI3f#$Y5e5Y9b6;|1A zi(-G)9F2J`b)%n+etT(#jan*lcH&H)z>RDmfks4bPPZ0%oDyp!EOvD9=1~O8RKh)gkZCyWG~{zj zmD1~Mri^FcQ2lYD#i2B*pcy|G2qXP*uRV3RHa;pW`|i?`P{0%Zh=@J$r9KjyYLA9O zK<|wf8W=TQ0bs_mFb8lBbExg=AaAnP(X>+2$fGHe2;dKIrlrQ3oe5^9kGB}cy&M$a zZ&;&WOk`@YIeXsRU3`HGZ+AFlZN~4?WYezI#<0_E%wZdD{f^bLIV$D zw>Z*GEjp5=BFG-BF|ATqSP;zu{$rhV{{VRYj6b%Byh*lpX1!X3fNck4xcvTJ+H?_S zpY?b81XWO22;}*WeK`LBEdzS0bdw%*Bio%QE2;2Dn-KdAHRem`f7+nTvcRa+@?L3( zJ)7ZQkGDEXghdwZm)KW~5-A^_T;n*-go}ka8+_#_{gb5LvJv=a$Nkf#{p9|G`&fmg zmN+Wajm%ZV+g4RH?7t^G=RD(39=qv^i=D{56>>{YlFH2<)?E4ydDM^egb1fIH$AYY zP14~^M>Dr4`=?X==1+p7<3wxIl$F+-O+B?@^Hw3l9x`*CKQr8NcF}|X0DDOq>U5Vs z65|JtlS_-GAD5p!nEH@2u2*t)&WfW@_XZrn8h|+j`s*>J(eiN`gWDRwxYE8rnaKA8 zNHx|7azwKau*QUd^s!#@Q+!z`gU+?`uJAAGCP0In?$cV1r3H$>lRJ+2IMyOHb)?Bz zB+nWD0ILK5KaQ<0v0FD<>W8hTMUc#|DhArTV|ew|s}y)ZsHCpkl0Uugs?G)p$3VfQmGkJ679x#Z8b4$MFbp?+dQwn ziq@i&zvjSv@!td2OcmWF9%6>pG^h;MBxc!JDranz&UR=0Q_tUA*KO(B&CY@fx*K!L z1nIpUW>r&zk6y=)+UYvg*=?)giSk`f+hc02@bJi;8%CaD1zq?jBleD`CV60wBwjpA zEUA#;(bx7s4W3fi;}sF-wvas;)DIw$Y<`{1On>LAN?E5><6-)Mbc)R~58;4T9gJI`S`ZcDXt>8+Gw%QkLFCX=b{#vYlbn?rKB7P)s$C50%h|~?KkfXNI z>#gCBVJJye&g2KsdmU;SQbpYEH#Rouz|K|IZq_{KU1uXl~e|m&%eqw zf|Ug1O2B%2gI*n;r3wltah;k_(Np6dTIso3t+`p{+x8m3Y4_ves<@JNw7B;;<4(e#*hAo867Aea(_1wiGK0=e zhb>KWxoo!K!6XfB=2o^yXXk_4MUI8!qon*>K_|GzlKmS-No~A;4I!G4PGped(@IAr zMm}emN7!jt>-jw`zJPMk5>FW#SW!{=Lu`0GhLD1cKGor<_ zNa-mVet5?J0I1fYhMCJDLGDjFUlL?yS0^62L0&|5A>=vZMU2nrdP#nm^cmL2r>G<$ zjBCfJCtIx21^jK#eQqZqm=~Djb`7SR0gY{fh$eQE$P0paC*MvM!)<8BLlf_~>wh)a z5KQ16z`y)8v6f!@<>UQrCfHjOipg%y+#G#QwwlR7w19-*d!2cuZ!7ybc2bMg1_%1uOx-DoJ7iq{0JXu;H@jNn zY=g=~(VG zrz|LmJ-G)(Fr*O|s$-D61MUv8F7W}$Q}&GMidQVZG;}?^)bpiG)eOa!jRKE#Kj)%@ zLh;`z!!cw$cKuo8YtaGm3=Z?&{zqkiw>%Y#wwuK*L#r{SPCYgdb>x=4hw7kI`^Te* z^g3JE*u!MNj{g9w9rc5GlV=c2!~IY+mz8iR#G-T03#1C%l=C4`>4h3p2_Z+izCrRT z!5*38N&cCa1S~U#C!TevhU-6Rh{5$ytO_fDW4*}Ft~+SZXv175BXNdOPi!_cnYh*D z27+w*7JVuyDue$3XvF&cbg#ixxH)2*M{?X9G|*^jZdU|S{{RZ-JZE|5Uij;jpN5qi z+b(qJXlG#dT4aJfgx&wV=!K zv!ejf*1qBCk*_74_K_u9f=?K29Tu1Y$>%=A>r-xkHVABe^jLBPM`ev%lUBzbo3W(l zw!&C1o_IOsyXe89qz42ueYKNoqQ>JJ9P`eVhae!eQtsU=sptFM^{d*gyyif@-#(2s zx}2UPVUEKc^qoZ|1w31%gy-2~%V{RZ$O>(?rBBvQpHH8iG@3g^AcT@Wd-8eFAA_3U zSs%$4to(&kW>~r?ix|@H1Ch zCO+PSQpkFKjThyl!1MrVSgjGG98(jX*cwiMK$#wiEfJ5^l;izFrxDd#z#&~mJA9gw z3x3ofQ)BYhiEngm!WBOHmcqa^@={b*Q`7H2WS%uFR{&+lB>E4otq)5V8GKR+Sw!WH%is5RgS&~O2U~mg( zAJ0>evdPJ*e0mQwyA%B~1+j?2gy9 zBQh%d-fmceaol6~Y1~odb5|Jr^u7YR5my)^vjfQ1m~yOgvNA=^G)?~iLG>zxZ_x7s zJCiJVA8(sl$7SkqCR)!UASAA3kJr=jef17%mL!(01b?)3y3_)3@q=zZymj0C{63CP z?PvB&+RN1PBDd(54}-X@vEcg*=Ua<6QJDV#`d9kF{{Xj-2ix|w3^K+C{WAmT$6Ap9 z?^<(?eq*Ei_FFAEhJPtX~s#mM~rtRU-}Y#{LOh}xosh6 zRAax-qmeu%PU^4^+e!ZbqbVfTXa4TI{z&ZDEe*ttzXpTY7uF0{Je*R(LGSZushR=* z0M#I4>8vG1KmPz;bLqy8NP7hna6yAl9tVGz<4LUb>va%w ziNHSi@1npA7QJ)22=Y&%))-dp$CA8z9Tz4tf9WT0(RH{n6$8)z0K=tdHV2H=4t$_- ztiQyza~JQ?l#VQaZ{O*!EO2hYoc`?=g21t@Mn3}n?QBI)my;5nc+s&sE%~0VxuFiPVTw#89uqV~=fNY1DJ(f-&u&c12_tvfm{< zJpFWo&D03oQAXn(!5Wu}c>DQ-_iHOp06*ICrlcH*RJA=wzyU;q9-xhFPbX1v=2PGg zY-(a@qV4AckEXW}D*g$$KTRBikrk2eXy6Fdm)wmZS1tJ%d2uUb@qwwBgLZ$?v+eTh zKMqu6&ZOtnbnFy}IG3ppKMsTG$N6j8nwmyqpNUR?)Yr6f{sWK{*>VFK*|I%#x9EuQ zL)FxuvC<9IFrHS9LcaX#!>ZsaaYrX^cskmVpSWCDDVSu-PDz@oQ{nMh5y~CBU(&H?QNcUoOqgd&4xkE45_tSILHDI6pStc>) zgzF#HE0d=9?T$hJ08r?m`-dxIqHYR4KBVbL>~`*R2_x!s)ZQ;lyO!RcVh**2uc?C* z@R4Ag^QA)f4oIiw1~6&k`{PMRCsZ-r@U-|N+e)bFY-FV`+aK}KL9unQ z(kClT0sjEHGo^*L5%R4(1ODjKc;o680JBpkui+X|X|D{&by5$=ai^hdTl8vU9!y+) zHQ_`E$CVyF+DYgxxyZQ%&Xf2Hx{^OiuNqnnj{Xp+%8rV{^E5DOtMHgeNQr`fJZhr@VlS zX)o0FX_-!OfHk3l0&>$&-`^UWL#8a$)Uo5topOJ8){c~t0={t|j(FCMO+Z|*^IZFG z(u%Z&vE;rxcN#4L=xOL>4ng_rl_3Y%_aw+T`wH9K>`PJ#~9H-Zr`RIhT4}^^&5H8u+h{Z-RH4m z-zqeaHEruAb&{2t&c-9|bW{2shhZuNXERC9wlu6wKkZL1A6#f}l~%+Jjz8~dNa-q= z@T7f9X;bl=r#5| z!*G5f$oJo^7#_xAe($F1ZK?0MaC?0M-^^BOoXv}b)A9vy!r)}`s98@DU_ z{F=j4QlFKpqQ~5Eti?@C2?<>p8PUOop;&6^Ks!`tzxH}wI>=8XDEIj^np07fVAUu| z`u5kFf{}h@ae43TjK|HQjczX>&824FUeG( z<0p+ASXv(og*$%1IP7-o&2pw0%x(VfeKesc$JC_^Lv0K2C30){mtOin#<>!y-VP7%I#9B^^T(Z!EL)vbv@;eq=NXw`9L zh(;v)4K$&82?<#wAfI4)`{~9lu@V=10&|>b;=AbJ`b+8 z{Uu02IFmnZGgxSdAsmnoZ0li9OdBEFJ+yHR4wmIiLCQ!yIU34V(6HuWKAUvfq8J=0 zXK$3`VCl4!^zDztPBEQ2{zE}eilql4U`N|t6_7SU%y(!i(9vxzi8ll9>#WCbqe+B; zTpVYE>!n}F^cfX&Y7d=M5x>?r)?TiJ4c``@zd>NOQ5?LR*!tx0r5=ijyKWqDf;3n1 z6oQReMi2cc{lL~1<3zb16zz{dx)3PN%q;KQ>7*KxrB2~i%lQoy{=$(VHS~Y>lN0HL z)`G4X4%KOfea18eVyzvk8}r7LDR9W!R(|*zHXKlA%p-uzN8Ib$4h6#>^vC`h_KJUD H#UKCK1Q7u% literal 0 HcmV?d00001 diff --git a/Documentation/platforms/arm/stm32n6/index.rst b/Documentation/platforms/arm/stm32n6/index.rst new file mode 100644 index 0000000000000..241cca916c360 --- /dev/null +++ b/Documentation/platforms/arm/stm32n6/index.rst @@ -0,0 +1,71 @@ +========== +ST STM32N6 +========== + +This is a port of NuttX to the STM32N6 family. +The STM32N6 is a chip based on the Arm Cortex-M55. + +Development is performed on the Nucleo-N657X0-Q. At this time only the +STM32N657X0 is supported. Kconfig will need updates to support other +MCUs in the family. + +Supported MCUs +============== + +=========== ======= ================ +MCU Support Note +=========== ======= ================ +STM32N645 No +STM32N647 No +STM32N655 No +STM32N657 Yes STM32N657X0 only +=========== ======= ================ + +Peripheral Support +================== + +The following list indicates peripherals supported in NuttX: + +========== ======= =============================================== +Peripheral Support Notes +========== ======= =============================================== +GPIO Yes +PWR Yes Partial. +RCC Yes PLL1 clock tree. +USART Yes USART1 only. + +ADC No +DCACHE No +DCMIPP No +DMA No +ETH No +I2C No +ICACHE No +IWDG No +LPTIM No +LTDC No +MPU No +NPU No +RNG No +RTC No +SAI No +SDMMC No +SPI No +TIM No +USB No +XSPI No +========== ======= =============================================== + +References +========== + +[RM0486] STMicroelectronics, STM32N647/657xx ArmĀ®-based 32-bit MCUs + +Supported Boards +================ + +.. toctree:: + :glob: + :maxdepth: 1 + + boards/*/*