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 0000000000000..9bbb4416de527 Binary files /dev/null and b/Documentation/platforms/arm/stm32n6/boards/nucleo-n657x0-q/nucleo-n657x0-q.jpg differ 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/*/* 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/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; +} 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