From 5c1c939cdc9323b6d58284a186a7af74278ff913 Mon Sep 17 00:00:00 2001 From: Michael Jung Date: Sat, 12 Feb 2022 08:20:38 +0100 Subject: [PATCH] stm32u5: Architecture Support for STM32U5 Architecture support for STMicroelectronics STMU585xx MCUs. This is based on corresponding code for STM32L5, but has been considerably adjusted. Tested with a B-U585I-IOT02A board and a simple NSH configuration, but only running NuttX in the non-secure world with TrustedFirmware-M. Signed-off-by: Michael Jung --- arch/arm/Kconfig | 21 +- arch/arm/include/stm32u5/chip.h | 82 + arch/arm/include/stm32u5/irq.h | 40 + arch/arm/include/stm32u5/stm32_irq.h | 95 + arch/arm/include/stm32u5/stm32u585xx_irq.h | 194 + arch/arm/src/stm32u5/Kconfig | 3533 +++++++++++++++++ arch/arm/src/stm32u5/Make.defs | 106 + arch/arm/src/stm32u5/README.txt | 22 + arch/arm/src/stm32u5/chip.h | 51 + arch/arm/src/stm32u5/hardware/stm32_exti.h | 119 + arch/arm/src/stm32u5/hardware/stm32_flash.h | 305 ++ arch/arm/src/stm32u5/hardware/stm32_gpio.h | 387 ++ .../src/stm32u5/hardware/stm32_memorymap.h | 185 + arch/arm/src/stm32u5/hardware/stm32_pinmap.h | 37 + arch/arm/src/stm32u5/hardware/stm32_pwr.h | 203 + arch/arm/src/stm32u5/hardware/stm32_spi.h | 37 + arch/arm/src/stm32u5/hardware/stm32_syscfg.h | 37 + arch/arm/src/stm32u5/hardware/stm32_tim.h | 1060 +++++ arch/arm/src/stm32u5/hardware/stm32_uart.h | 308 ++ .../src/stm32u5/hardware/stm32u585xx_dbgmcu.h | 96 + .../src/stm32u5/hardware/stm32u585xx_pinmap.h | 1180 ++++++ .../src/stm32u5/hardware/stm32u585xx_rcc.h | 1203 ++++++ .../src/stm32u5/hardware/stm32u585xx_spi.h | 407 ++ .../src/stm32u5/hardware/stm32u585xx_syscfg.h | 135 + arch/arm/src/stm32u5/stm32.h | 48 + arch/arm/src/stm32u5/stm32_allocateheap.c | 372 ++ arch/arm/src/stm32u5/stm32_dbgmcu.h | 38 + arch/arm/src/stm32u5/stm32_dumpgpio.c | 140 + arch/arm/src/stm32u5/stm32_exti.h | 153 + arch/arm/src/stm32u5/stm32_exti_gpio.c | 173 + arch/arm/src/stm32u5/stm32_flash.c | 507 +++ arch/arm/src/stm32u5/stm32_flash.h | 57 + arch/arm/src/stm32u5/stm32_gpio.c | 403 ++ arch/arm/src/stm32u5/stm32_gpio.h | 363 ++ arch/arm/src/stm32u5/stm32_idle.c | 100 + arch/arm/src/stm32u5/stm32_irq.c | 521 +++ arch/arm/src/stm32u5/stm32_lowputc.c | 400 ++ arch/arm/src/stm32u5/stm32_lowputc.h | 64 + arch/arm/src/stm32u5/stm32_lse.c | 187 + arch/arm/src/stm32u5/stm32_lsi.c | 71 + arch/arm/src/stm32u5/stm32_mpuinit.c | 100 + arch/arm/src/stm32u5/stm32_mpuinit.h | 63 + arch/arm/src/stm32u5/stm32_pwr.c | 296 ++ arch/arm/src/stm32u5/stm32_pwr.h | 127 + arch/arm/src/stm32u5/stm32_rcc.c | 236 ++ arch/arm/src/stm32u5/stm32_rcc.h | 236 ++ arch/arm/src/stm32u5/stm32_serial.c | 3249 +++++++++++++++ arch/arm/src/stm32u5/stm32_spi.c | 2432 ++++++++++++ arch/arm/src/stm32u5/stm32_spi.h | 179 + arch/arm/src/stm32u5/stm32_start.c | 315 ++ arch/arm/src/stm32u5/stm32_start.h | 45 + arch/arm/src/stm32u5/stm32_tim.c | 1693 ++++++++ arch/arm/src/stm32u5/stm32_tim.h | 210 + arch/arm/src/stm32u5/stm32_tim_lowerhalf.c | 605 +++ arch/arm/src/stm32u5/stm32_timerisr.c | 149 + arch/arm/src/stm32u5/stm32_uart.h | 298 ++ arch/arm/src/stm32u5/stm32_uid.c | 46 + arch/arm/src/stm32u5/stm32_uid.h | 36 + arch/arm/src/stm32u5/stm32_userspace.c | 91 + arch/arm/src/stm32u5/stm32_userspace.h | 49 + arch/arm/src/stm32u5/stm32_waste.c | 42 + arch/arm/src/stm32u5/stm32_waste.h | 64 + arch/arm/src/stm32u5/stm32u585xx_rcc.c | 935 +++++ 63 files changed, 24935 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/stm32u5/chip.h create mode 100644 arch/arm/include/stm32u5/irq.h create mode 100644 arch/arm/include/stm32u5/stm32_irq.h create mode 100644 arch/arm/include/stm32u5/stm32u585xx_irq.h create mode 100644 arch/arm/src/stm32u5/Kconfig create mode 100644 arch/arm/src/stm32u5/Make.defs create mode 100644 arch/arm/src/stm32u5/README.txt create mode 100644 arch/arm/src/stm32u5/chip.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_exti.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_flash.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_gpio.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_memorymap.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_pinmap.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_pwr.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_spi.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_syscfg.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_tim.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32_uart.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32u585xx_dbgmcu.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32u585xx_pinmap.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32u585xx_rcc.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32u585xx_spi.h create mode 100644 arch/arm/src/stm32u5/hardware/stm32u585xx_syscfg.h create mode 100644 arch/arm/src/stm32u5/stm32.h create mode 100644 arch/arm/src/stm32u5/stm32_allocateheap.c create mode 100644 arch/arm/src/stm32u5/stm32_dbgmcu.h create mode 100644 arch/arm/src/stm32u5/stm32_dumpgpio.c create mode 100644 arch/arm/src/stm32u5/stm32_exti.h create mode 100644 arch/arm/src/stm32u5/stm32_exti_gpio.c create mode 100644 arch/arm/src/stm32u5/stm32_flash.c create mode 100644 arch/arm/src/stm32u5/stm32_flash.h create mode 100644 arch/arm/src/stm32u5/stm32_gpio.c create mode 100644 arch/arm/src/stm32u5/stm32_gpio.h create mode 100644 arch/arm/src/stm32u5/stm32_idle.c create mode 100644 arch/arm/src/stm32u5/stm32_irq.c create mode 100644 arch/arm/src/stm32u5/stm32_lowputc.c create mode 100644 arch/arm/src/stm32u5/stm32_lowputc.h create mode 100644 arch/arm/src/stm32u5/stm32_lse.c create mode 100644 arch/arm/src/stm32u5/stm32_lsi.c create mode 100644 arch/arm/src/stm32u5/stm32_mpuinit.c create mode 100644 arch/arm/src/stm32u5/stm32_mpuinit.h create mode 100644 arch/arm/src/stm32u5/stm32_pwr.c create mode 100644 arch/arm/src/stm32u5/stm32_pwr.h create mode 100644 arch/arm/src/stm32u5/stm32_rcc.c create mode 100644 arch/arm/src/stm32u5/stm32_rcc.h create mode 100644 arch/arm/src/stm32u5/stm32_serial.c create mode 100644 arch/arm/src/stm32u5/stm32_spi.c create mode 100644 arch/arm/src/stm32u5/stm32_spi.h create mode 100644 arch/arm/src/stm32u5/stm32_start.c create mode 100644 arch/arm/src/stm32u5/stm32_start.h create mode 100644 arch/arm/src/stm32u5/stm32_tim.c create mode 100644 arch/arm/src/stm32u5/stm32_tim.h create mode 100644 arch/arm/src/stm32u5/stm32_tim_lowerhalf.c create mode 100644 arch/arm/src/stm32u5/stm32_timerisr.c create mode 100644 arch/arm/src/stm32u5/stm32_uart.h create mode 100644 arch/arm/src/stm32u5/stm32_uid.c create mode 100644 arch/arm/src/stm32u5/stm32_uid.h create mode 100644 arch/arm/src/stm32u5/stm32_userspace.c create mode 100644 arch/arm/src/stm32u5/stm32_userspace.h create mode 100644 arch/arm/src/stm32u5/stm32_waste.c create mode 100644 arch/arm/src/stm32u5/stm32_waste.h create mode 100644 arch/arm/src/stm32u5/stm32u585xx_rcc.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8f839c304c..82883a6633 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -411,7 +411,22 @@ config ARCH_CHIP_STM32L5 select ARM_HAVE_MPU_UNIFIED select ARMV8M_HAVE_STACKCHECK ---help--- - STMicro STM32 architectures (ARM Cortex-M33). + STMicro STM32 L5 architectures (ARM Cortex-M33). + +config ARCH_CHIP_STM32U5 + bool "STMicro STM32 U5" + select ARCH_CORTEXM33 + select ARCH_HAVE_MPU + select ARCH_HAVE_FETCHADD + select ARCH_HAVE_HEAPCHECK + select ARCH_HAVE_PROGMEM + select ARCH_HAVE_SPI_BITORDER + select ARCH_HAVE_TICKLESS + select ARM_HAVE_MPU_UNIFIED + select ARMV8M_HAVE_STACKCHECK + select ARCH_HAVE_TRUSTZONE + ---help--- + STMicro STM32 U5 architectures (ARM Cortex-M33). config ARCH_CHIP_STR71X bool "STMicro STR71x" @@ -830,6 +845,7 @@ config ARCH_CHIP default "stm32h7" if ARCH_CHIP_STM32H7 default "stm32l4" if ARCH_CHIP_STM32L4 default "stm32l5" if ARCH_CHIP_STM32L5 + default "stm32u5" if ARCH_CHIP_STM32U5 default "str71x" if ARCH_CHIP_STR71X default "tms570" if ARCH_CHIP_TMS570 default "xmc4" if ARCH_CHIP_XMC4 @@ -1180,6 +1196,9 @@ endif if ARCH_CHIP_STM32L5 source "arch/arm/src/stm32l5/Kconfig" endif +if ARCH_CHIP_STM32U5 +source "arch/arm/src/stm32u5/Kconfig" +endif if ARCH_CHIP_STR71X source "arch/arm/src/str71x/Kconfig" endif diff --git a/arch/arm/include/stm32u5/chip.h b/arch/arm/include/stm32u5/chip.h new file mode 100644 index 0000000000..9b2708cf47 --- /dev/null +++ b/arch/arm/include/stm32u5/chip.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/arm/include/stm32u5/chip.h + * + * 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_STM32U5_CHIP_H +#define __ARCH_ARM_INCLUDE_STM32U5_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +#if defined(CONFIG_STM32U5_STM32U585XX) +# define STM32_SRAM1_SIZE (192*1024) /* 192Kb SRAM1 on AHB bus Matrix */ +# define STM32_SRAM2_SIZE (64*1024) /* 64kB SRAM2 on AHB bus Matrix */ +# define STM32_SRAM3_SIZE (512*1024) /* 512kB SRAM3 on AHB bus Matrix */ +#else +# error "Unsupported STM32U5 chip" +#endif + +#if defined(CONFIG_STM32U5_STM32U585XX) +# define STM32_NFSMC 1 /* Have FSMC memory controller */ +# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32_NGTIM32 2 /* 32-bit general timers TIM2 and 5 with DMA */ +# define STM32_NGTIM16 2 /* 16-bit general timers TIM3 and 4 with DMA */ +# define STM32_NGTIMNDMA 3 /* 16-bit general timers TIM15-17 without DMA */ +# define STM32_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32_NLPTIM 2 /* Two low-power timers, LPTIM1-2 */ +# define STM32_NRNG 1 /* Random number generator (RNG) */ +# define STM32_NUART 2 /* UART 4-5 */ +# define STM32_NUSART 3 /* USART 1-3 */ +# define STM32_NLPUART 1 /* LPUART 1 */ +# define STM32_QSPI 0 /* No QuadSPI1 */ +# define STM32_OCTOSPI 2 /* OCTOSPI1-2 */ +# define STM32_NSPI 3 /* SPI1-3 */ +# define STM32_NI2C 4 /* I2C1-4 */ +# define STM32_NSWPMI 0 /* No SWPMI1 */ +# define STM32_NUSBOTGFS 1 /* USB OTG FS */ +# define STM32_NUSBFS 0 /* No USB FS */ +# define STM32_NCAN 1 /* CAN1 */ +# define STM32_NSAI 2 /* SAI1-2 */ +# define STM32_NSDMMC 1 /* SDMMC interface */ +# define STM32_NDMA 2 /* DMA1-2 */ +# define STM32_NPORTS 9 /* 9 GPIO ports, GPIOA-I */ +# define STM32_NADC 1 /* 12-bit ADC1, up to 20 channels */ +# define STM32_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32_NCRC 1 /* CRC */ +# define STM32_NCOMP 2 /* Comparators */ +# define STM32_NOPAMP 2 /* Operational Amplifiers */ +#endif /* CONFIG_STM32U5_STM32U585XX */ + +/* NVIC priority levels *****************************************************/ + +/* 16 Programmable interrupt levels */ + +#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_STM32U5_CHIP_H */ diff --git a/arch/arm/include/stm32u5/irq.h b/arch/arm/include/stm32u5/irq.h new file mode 100644 index 0000000000..6bd2ef79b0 --- /dev/null +++ b/arch/arm/include/stm32u5/irq.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * arch/arm/include/stm32u5/irq.h + * + * 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_STM32U5_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32U5_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_STM32U5_STM32U585XX) +# include +#else +# error "Unsupported STM32U5 chip" +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32U5_IRQ_H */ diff --git a/arch/arm/include/stm32u5/stm32_irq.h b/arch/arm/include/stm32u5/stm32_irq.h new file mode 100644 index 0000000000..1cff3ca946 --- /dev/null +++ b/arch/arm/include/stm32u5/stm32_irq.h @@ -0,0 +1,95 @@ +/**************************************************************************** + * arch/arm/include/stm32u5/stm32_irq.h + * + * 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 by the chip type specific header files + * (e.g. stm32u585xx_irq.h) + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32U5_STM32_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32U5_STM32_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 */ + +/**************************************************************************** + * 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_STM32U5_STM32_IRQ_H */ diff --git a/arch/arm/include/stm32u5/stm32u585xx_irq.h b/arch/arm/include/stm32u5/stm32u585xx_irq.h new file mode 100644 index 0000000000..48c74ac085 --- /dev/null +++ b/arch/arm/include/stm32u5/stm32u585xx_irq.h @@ -0,0 +1,194 @@ +/**************************************************************************** + * arch/arm/include/stm32u5/stm32u585xx_irq.h + * + * 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_STM32U5_STM32U585XX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32U5_STM32U585XX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#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 the file nuttx/arch/arm/include/stm32u5/stm32_irq.h, which is + * included above. + * + * External interrupts (vectors >= 16) + * + * These interrupt vectors were implemented based on RM0456 Table 153 + * (STM32U575/585 vector table) and should work for STM32U575xx and + * STL32U585xx. + */ + +#define STM32_IRQ_WWDG (STM32_IRQ_FIRST + 0) /* 0: Window Watchdog interrupt */ +#define STM32_IRQ_PVD_PVM (STM32_IRQ_FIRST + 1) /* 1: PVD/PVM1/PVM2/PVM3/PVM4 */ +#define STM32_IRQ_RTC (STM32_IRQ_FIRST + 2) /* 2: RTC global interrupts */ +#define STM32_IRQ_RTC_S (STM32_IRQ_FIRST + 3) /* 3: RTC secure global interrupts */ +#define STM32_IRQ_TAMP (STM32_IRQ_FIRST + 4) /* 4: Tamper global interrupt */ +#define STM32_IRQ_RAMCFG (STM32_IRQ_FIRST + 5) /* 5: RAM configuration global interrupt */ +#define STM32_IRQ_FLASH (STM32_IRQ_FIRST + 6) /* 6: Flash memory global interrupt */ +#define STM32_IRQ_FLASH_S (STM32_IRQ_FIRST + 7) /* 7: Flash memory secure global interrupt */ +#define STM32_IRQ_GTZC (STM32_IRQ_FIRST + 8) /* 8: TZIC secure global interrupt */ +#define STM32_IRQ_RCC (STM32_IRQ_FIRST + 9) /* 9: RCC global interrupt */ +#define STM32_IRQ_RCC_S (STM32_IRQ_FIRST + 10) /* 10: RCC secure global interrupt */ +#define STM32_IRQ_EXTI0 (STM32_IRQ_FIRST + 11) /* 11: EXTI Line 0 interrupt */ +#define STM32_IRQ_EXTI1 (STM32_IRQ_FIRST + 12) /* 12: EXTI Line 1 interrupt */ +#define STM32_IRQ_EXTI2 (STM32_IRQ_FIRST + 13) /* 13: EXTI Line 2 interrupt */ +#define STM32_IRQ_EXTI3 (STM32_IRQ_FIRST + 14) /* 14: EXTI Line 3 interrupt */ +#define STM32_IRQ_EXTI4 (STM32_IRQ_FIRST + 15) /* 15: EXTI Line 4 interrupt */ +#define STM32_IRQ_EXTI5 (STM32_IRQ_FIRST + 16) /* 16: EXTI Line 5 interrupt */ +#define STM32_IRQ_EXTI6 (STM32_IRQ_FIRST + 17) /* 17: EXTI Line 6 interrupt */ +#define STM32_IRQ_EXTI7 (STM32_IRQ_FIRST + 18) /* 18: EXTI Line 7 interrupt */ +#define STM32_IRQ_EXTI8 (STM32_IRQ_FIRST + 19) /* 19: EXTI Line 8 interrupt */ +#define STM32_IRQ_EXTI9 (STM32_IRQ_FIRST + 20) /* 20: EXTI Line 9 interrupt */ +#define STM32_IRQ_EXTI10 (STM32_IRQ_FIRST + 21) /* 21: EXTI Line 10 interrupt */ +#define STM32_IRQ_EXTI11 (STM32_IRQ_FIRST + 22) /* 22: EXTI Line 11 interrupt */ +#define STM32_IRQ_EXTI12 (STM32_IRQ_FIRST + 23) /* 23: EXTI Line 12 interrupt */ +#define STM32_IRQ_EXTI13 (STM32_IRQ_FIRST + 24) /* 24: EXTI Line 13 interrupt */ +#define STM32_IRQ_EXTI14 (STM32_IRQ_FIRST + 25) /* 25: EXTI Line 14 interrupt */ +#define STM32_IRQ_EXTI15 (STM32_IRQ_FIRST + 26) /* 26: EXTI Line 15 interrupt */ +#define STM32_IRQ_IWDG (STM32_IRQ_FIRST + 27) /* 27: Independent watchdog interrupt */ +#define STM32_IRQ_SAES (STM32_IRQ_FIRST + 28) /* 28: Secure AES */ +#define STM32_IRQ_GPDMA1_CH0 (STM32_IRQ_FIRST + 29) /* 29: GPDMA1 Channel 0 global interrupt */ +#define STM32_IRQ_GPDMA1_CH1 (STM32_IRQ_FIRST + 30) /* 30: GPDMA1 Channel 1 global interrupt */ +#define STM32_IRQ_GPDMA1_CH2 (STM32_IRQ_FIRST + 31) /* 31: GPDMA1 Channel 2 global interrupt */ +#define STM32_IRQ_GPDMA1_CH3 (STM32_IRQ_FIRST + 32) /* 32: GPDMA1 Channel 3 global interrupt */ +#define STM32_IRQ_GPDMA1_CH4 (STM32_IRQ_FIRST + 33) /* 33: GPDMA1 Channel 4 global interrupt */ +#define STM32_IRQ_GPDMA1_CH5 (STM32_IRQ_FIRST + 34) /* 34: GPDMA1 Channel 5 global interrupt */ +#define STM32_IRQ_GPDMA1_CH6 (STM32_IRQ_FIRST + 35) /* 35: GPDMA1 Channel 6 global interrupt */ +#define STM32_IRQ_GPDMA1_CH7 (STM32_IRQ_FIRST + 36) /* 36: GPDMA1 Channel 7 global interrupt */ +#define STM32_IRQ_ADC1 (STM32_IRQ_FIRST + 37) /* 37: ADC1 (14 bits) global interrupt */ +#define STM32_IRQ_DAC1 (STM32_IRQ_FIRST + 38) /* 38: DAC1 global interrupt */ +#define STM32_IRQ_FDCAN1_IT0 (STM32_IRQ_FIRST + 39) /* 39: FDCAN1 Interrupt 0 */ +#define STM32_IRQ_FDCAN1_IT1 (STM32_IRQ_FIRST + 40) /* 40: FDCAN1 Interrupt 1 */ +#define STM32_IRQ_TIM1_BRK (STM32_IRQ_FIRST + 41) /* 41: TIM1 break */ +#define STM32_IRQ_TIM1_TERR (STM32_IRQ_FIRST + 41) /* 41: TIM1 transition error */ +#define STM32_IRQ_TIM1_IERR (STM32_IRQ_FIRST + 41) /* 41: TIM1 index error */ +#define STM32_IRQ_TIM1_UP (STM32_IRQ_FIRST + 42) /* 42: TIM1 update */ +#define STM32_IRQ_TIM1_TRG_COM (STM32_IRQ_FIRST + 43) /* 43: TIM1 trigger and communication */ +#define STM32_IRQ_TIM1_DIR (STM32_IRQ_FIRST + 43) /* 43: TIM1 direction change interrupt */ +#define STM32_IRQ_TIM1_IDX (STM32_IRQ_FIRST + 43) /* 43: TIM1 index */ +#define STM32_IRQ_TIM1_CC (STM32_IRQ_FIRST + 44) /* 44: TIM1 capture compare interrupt */ +#define STM32_IRQ_TIM2 (STM32_IRQ_FIRST + 45) /* 45: TIM2 global interrupt */ +#define STM32_IRQ_TIM3 (STM32_IRQ_FIRST + 46) /* 46: TIM3 global interrupt */ +#define STM32_IRQ_TIM4 (STM32_IRQ_FIRST + 47) /* 47: TIM4 global interrupt */ +#define STM32_IRQ_TIM5 (STM32_IRQ_FIRST + 48) /* 48: TIM5 global interrupt */ +#define STM32_IRQ_TIM6 (STM32_IRQ_FIRST + 49) /* 49: TIM6 global interrupt */ +#define STM32_IRQ_TIM7 (STM32_IRQ_FIRST + 50) /* 50: TIM7 global interrupt */ +#define STM32_IRQ_TIM8_BRK (STM32_IRQ_FIRST + 51) /* 51: TIM8 break */ +#define STM32_IRQ_TIM8_TERR (STM32_IRQ_FIRST + 51) /* 51: TIM8 transition error */ +#define STM32_IRQ_TIM8_IERR (STM32_IRQ_FIRST + 51) /* 51: TIM8 index error */ +#define STM32_IRQ_TIM8_UP (STM32_IRQ_FIRST + 52) /* 52: TIM8 update */ +#define STM32_IRQ_TIM8_TRG_COM (STM32_IRQ_FIRST + 53) /* 53: TIM8 trigger and communication */ +#define STM32_IRQ_TIM8_DIR (STM32_IRQ_FIRST + 53) /* 53: TIM8 direction change interrupt */ +#define STM32_IRQ_TIM8_IDX (STM32_IRQ_FIRST + 53) /* 53: TIM8 index */ +#define STM32_IRQ_TIM8_CC (STM32_IRQ_FIRST + 54) /* 54: TIM8 capture compare interrupt */ +#define STM32_IRQ_I2C1_EV (STM32_IRQ_FIRST + 55) /* 55: I2C1 event interrupt */ +#define STM32_IRQ_I2C1_ER (STM32_IRQ_FIRST + 56) /* 56: I2C1 error interrupt */ +#define STM32_IRQ_I2C2_EV (STM32_IRQ_FIRST + 57) /* 57: I2C2 event interrupt */ +#define STM32_IRQ_I2C2_ER (STM32_IRQ_FIRST + 58) /* 58: I2C2 error interrupt */ +#define STM32_IRQ_SPI1 (STM32_IRQ_FIRST + 59) /* 59: SPI1 global interrupt */ +#define STM32_IRQ_SPI2 (STM32_IRQ_FIRST + 60) /* 60: SPI2 global interrupt */ +#define STM32_IRQ_USART1 (STM32_IRQ_FIRST + 61) /* 61: USART1 global interrupt */ +#define STM32_IRQ_USART2 (STM32_IRQ_FIRST + 62) /* 62: USART2 global interrupt */ +#define STM32_IRQ_USART3 (STM32_IRQ_FIRST + 63) /* 63: USART3 global interrupt */ +#define STM32_IRQ_UART4 (STM32_IRQ_FIRST + 64) /* 64: UART4 global interrupt */ +#define STM32_IRQ_UART5 (STM32_IRQ_FIRST + 65) /* 65: UART5 global interrupt */ +#define STM32_IRQ_LPUART1 (STM32_IRQ_FIRST + 66) /* 66: LPUART 1 global interrupt */ +#define STM32_IRQ_LPTIM1 (STM32_IRQ_FIRST + 67) /* 67: LPTIM1 global interrupt */ +#define STM32_IRQ_LPTIM2 (STM32_IRQ_FIRST + 68) /* 68: LPTIM2 global interrupt */ +#define STM32_IRQ_TIM15 (STM32_IRQ_FIRST + 69) /* 69: TIM15 global interrupt */ +#define STM32_IRQ_TIM16 (STM32_IRQ_FIRST + 70) /* 70: TIM16 global interrupt */ +#define STM32_IRQ_TIM17 (STM32_IRQ_FIRST + 71) /* 71: TIM17 global interrupt */ +#define STM32_IRQ_COMP (STM32_IRQ_FIRST + 72) /* 72: COMP1/COMP2 interrupts */ +#define STM32_IRQ_OTG_FS (STM32_IRQ_FIRST + 73) /* 73: USB OTG FS global interrupt */ +#define STM32_IRQ_CRS (STM32_IRQ_FIRST + 74) /* 74: CRS global interrupt */ +#define STM32_IRQ_FMC (STM32_IRQ_FIRST + 75) /* 75: FMC global interrupt */ +#define STM32_IRQ_OCTOSPI1 (STM32_IRQ_FIRST + 76) /* 76: OCTOSPI1 global interrupt */ +#define STM32_PWER_S3WU (STM32_IRQ_FIRST + 77) /* 77: PWR wakeup from Stop 3 interrupt */ +#define STM32_IRQ_SDMMC1 (STM32_IRQ_FIRST + 78) /* 78: SDMMC1 global interrupt */ +#define STM32_IRQ_SDMMC2 (STM32_IRQ_FIRST + 79) /* 79: SDMMC2 global interrupt */ +#define STM32_IRQ_GPDMA1_CH8 (STM32_IRQ_FIRST + 80) /* 80: GPDMA1 Channel 8 interrupt */ +#define STM32_IRQ_GPDMA1_CH9 (STM32_IRQ_FIRST + 81) /* 81: GPDMA1 Channel 9 interrupt */ +#define STM32_IRQ_GPDMA1_CH10 (STM32_IRQ_FIRST + 82) /* 82: GPDMA1 Channel 10 interrupt */ +#define STM32_IRQ_GPDMA1_CH11 (STM32_IRQ_FIRST + 83) /* 83: GPDMA1 Channel 11 interrupt */ +#define STM32_IRQ_GPDMA1_CH12 (STM32_IRQ_FIRST + 84) /* 84: GPDMA1 Channel 12 interrupt */ +#define STM32_IRQ_GPDMA1_CH13 (STM32_IRQ_FIRST + 85) /* 85: GPDMA1 Channel 13 interrupt */ +#define STM32_IRQ_GPDMA1_CH14 (STM32_IRQ_FIRST + 86) /* 86: GPDMA1 Channel 14 interrupt */ +#define STM32_IRQ_GPDMA1_CH15 (STM32_IRQ_FIRST + 87) /* 87: GPDMA1 Channel 15 interrupt */ +#define STM32_IRQ_I2C3_EV (STM32_IRQ_FIRST + 88) /* 88: I2C3 event interrupt */ +#define STM32_IRQ_I2C3_ER (STM32_IRQ_FIRST + 89) /* 89: I2C3 error interrupt */ +#define STM32_IRQ_SAI1 (STM32_IRQ_FIRST + 90) /* 90: SAI1 global interrupt */ +#define STM32_IRQ_SAI2 (STM32_IRQ_FIRST + 91) /* 91: SAI2 global interrupt */ +#define STM32_IRQ_TSC (STM32_IRQ_FIRST + 92) /* 92: TSC global interrupt */ +#define STM32_IRQ_AES (STM32_IRQ_FIRST + 93) /* 93: AES global interrupt */ +#define STM32_IRQ_RNG (STM32_IRQ_FIRST + 94) /* 94: RNG global interrupt */ +#define STM32_IRQ_FPU (STM32_IRQ_FIRST + 95) /* 95: FPU global interrupt */ +#define STM32_IRQ_HASH (STM32_IRQ_FIRST + 96) /* 96: HASH global interrupt */ +#define STM32_IRQ_PKA (STM32_IRQ_FIRST + 97) /* 97: PKA global interrupt */ +#define STM32_IRQ_LPTIM3 (STM32_IRQ_FIRST + 98) /* 98: LPTIM3 global interrupt */ +#define STM32_IRQ_SPI3 (STM32_IRQ_FIRST + 99) /* 99: SPI3 global interrupt */ +#define STM32_IRQ_I2C4_EV (STM32_IRQ_FIRST + 100) /* 100: I2C4 event interrupt */ +#define STM32_IRQ_I2C4_ER (STM32_IRQ_FIRST + 101) /* 101: I2C4 error interrupt */ +#define STM32_IRQ_MDF1_FLT0 (STM32_IRQ_FIRST + 102) /* 102: MDF1 filter 0 global interrupt */ +#define STM32_IRQ_MDF1_FLT1 (STM32_IRQ_FIRST + 103) /* 103: MDF1 filter 1 global interrupt */ +#define STM32_IRQ_MDF1_FLT2 (STM32_IRQ_FIRST + 104) /* 104: MDF1 filter 2 global interrupt */ +#define STM32_IRQ_MDF1_FLT3 (STM32_IRQ_FIRST + 105) /* 105: MDF1 filter 3 global interrupt */ +#define STM32_IRQ_UCPD1 (STM32_IRQ_FIRST + 106) /* 106: UCPD1 global interrupt */ +#define STM32_IRQ_ICACHE (STM32_IRQ_FIRST + 107) /* 107: Instruction cache global interrupt */ +#define STM32_IRQ_OTFDEC1 (STM32_IRQ_FIRST + 108) /* 108: OTFDEC1 secure global interrupt */ +#define STM32_IRQ_OTFDEC2 (STM32_IRQ_FIRST + 109) /* 109: OTFDEC2 secure global interrupt */ +#define STM32_IRQ_LPTIM4 (STM32_IRQ_FIRST + 110) /* 110: LPTIM4 global interrupt */ +#define STM32_IRQ_DCACHE1 (STM32_IRQ_FIRST + 111) /* 111: Data cache global interrupt */ +#define STM32_IRQ_ADF1_FLT0 (STM32_IRQ_FIRST + 112) /* 112: ADF1 filter 0 global interrupt */ +#define STM32_IRQ_ADC4 (STM32_IRQ_FIRST + 113) /* 113: ADC4 (12 bits) global interrupt */ +#define STM32_IRQ_LPDMA1_CH0 (STM32_IRQ_FIRST + 114) /* 114: LPDMA1 SmartRun channel 0 global interrupt */ +#define STM32_IRQ_LPDMA1_CH1 (STM32_IRQ_FIRST + 115) /* 115: LPDMA1 SmartRun channel 1 global interrupt */ +#define STM32_IRQ_LPDMA1_CH2 (STM32_IRQ_FIRST + 116) /* 116: LPDMA1 SmartRun channel 2 global interrupt */ +#define STM32_IRQ_LPDMA1_CH3 (STM32_IRQ_FIRST + 117) /* 117: LPDMA1 SmartRun channel 3 global interrupt */ +#define STM32_IRQ_DMA2D (STM32_IRQ_FIRST + 118) /* 118: DMA2D global interrupt */ +#define STM32_IRQ_DCMI_PSSI (STM32_IRQ_FIRST + 119) /* 119: DCMI/PSSI global interrupt */ +#define STM32_IRQ_OCTOSPI2 (STM32_IRQ_FIRST + 120) /* 120: OCTOSPI2 global interrupt */ +#define STM32_IRQ_MDF1_FLT4 (STM32_IRQ_FIRST + 121) /* 121: MDF1 filter 4 global interrupt */ +#define STM32_IRQ_MDF1_FLT5 (STM32_IRQ_FIRST + 122) /* 122: MDF1 filter 5 global interrupt */ +#define STM32_IRQ_CORDIC (STM32_IRQ_FIRST + 123) /* 123: CORDIC interrupt */ +#define STM32_IRQ_FMAC (STM32_IRQ_FIRST + 124) /* 124: FMAC interrupt */ + +#if defined(CONFIG_STM32U5_STM32U585XX) +# define STM32_IRQ_NEXTINTS 125 +#else +# error "Unsupported STM32U5 chip" +#endif + +/* (EXTI interrupts do not use IRQ numbers) */ + +#define NR_IRQS (STM32_IRQ_FIRST + STM32_IRQ_NEXTINTS) + +#endif /* __ARCH_ARM_INCLUDE_STM32U5_STM32U585XX_IRQ_H */ diff --git a/arch/arm/src/stm32u5/Kconfig b/arch/arm/src/stm32u5/Kconfig new file mode 100644 index 0000000000..708d06fc22 --- /dev/null +++ b/arch/arm/src/stm32u5/Kconfig @@ -0,0 +1,3533 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_STM32U5 + +comment "STM32U5 Configuration Options" + +choice + prompt "STM32 U5 Chip Selection" + default ARCH_CHIP_STM32U585AI + depends on ARCH_CHIP_STM32U5 + +config ARCH_CHIP_STM32U585AI + bool "STM32U585AI" + select STM32U5_STM32U585XX + select STM32U5_FLASH_CONFIG_I + select STM32U5_IO_CONFIG_A + ---help--- + STM32 U5 Cortex M33, 2048 Kb FLASH, 768 Kb SRAM + +endchoice # STM32 L5 Chip Selection + +# Chip families: + +config STM32U5_STM32U585XX + # STM32U575 and STM32U585 devices documented in RM0456 + bool + default n + select ARCH_HAVE_FPU + select STM32U5_HAVE_LPUART1 + select STM32U5_HAVE_USART1 + select STM32U5_HAVE_USART2 + select STM32U5_HAVE_USART3 + select STM32U5_HAVE_UART4 + select STM32U5_HAVE_UART5 + +choice + prompt "Override Flash Size Designator" + depends on ARCH_CHIP_STM32U5 + default STM32U5_FLASH_OVERRIDE_DEFAULT + ---help--- + STM32U5 series parts numbering (sans the package type) ends with a letter + that designates the FLASH size. + + Designator Size in KiB + 8 64 + B 128 + C 256 + E 512 + G 1024 + I 2048 + + This configuration option defaults to using the configuration based on that designator + or the default smaller size if there is no last character designator is present in the + STM32 Chip Selection. + + Examples: + If the STM32U585AI is chosen, the Flash configuration would be 'I', if a variant of + the part with a 1024 KiB Flash is released in the future one could simply select + the 'G' designator here. + + If an STM32U5xxx Series parts is chosen the default Flash configuration will be set + herein and can be changed. + +config STM32U5_FLASH_OVERRIDE_DEFAULT + bool "Default" + +config STM32U5_FLASH_OVERRIDE_8 + bool "8 64 KB" + +config STM32U5_FLASH_OVERRIDE_B + bool "B 128 KB" + +config STM32U5_FLASH_OVERRIDE_C + bool "C 256 KB" + +config STM32U5_FLASH_OVERRIDE_E + bool "E 512 KB" + +config STM32U5_FLASH_OVERRIDE_G + bool "G 1024 KB" + +config STM32U5_FLASH_OVERRIDE_I + bool "I 2048 KB" + +endchoice # "Override Flash Size Designator" + +# Flash configurations + +config STM32U5_FLASH_CONFIG_8 + bool + default n + +config STM32U5_FLASH_CONFIG_B + bool + default n + +config STM32U5_FLASH_CONFIG_C + bool + default n + +config STM32U5_FLASH_CONFIG_E + bool + default n + +config STM32U5_FLASH_CONFIG_G + bool + default n + +config STM32U5_FLASH_CONFIG_I + bool + default n + +# Pin/package configurations + +config STM32U5_IO_CONFIG_K + bool + default n + +config STM32U5_IO_CONFIG_T + bool + default n + +config STM32U5_IO_CONFIG_C + bool + default n + +config STM32U5_IO_CONFIG_R + bool + default n + +config STM32U5_IO_CONFIG_J + bool + default n + +config STM32U5_IO_CONFIG_M + bool + default n + +config STM32U5_IO_CONFIG_V + bool + default n + +config STM32U5_IO_CONFIG_Q + bool + default n + +config STM32U5_IO_CONFIG_Z + bool + default n + +config STM32U5_IO_CONFIG_A + bool + default n + +comment "STM32U5 SRAM2 Options" + +config STM32U5_SRAM2_HEAP + bool "SRAM2 is used for heap" + default n + select STM32U5_SRAM2_INIT + ---help--- + The STM32U5 SRAM2 region has special properties (power, protection, parity) + which may be used by the application for special purposes. But if these + special properties are not needed, it may be instead added to the heap for + use by malloc(). + NOTE: you must also select an appropriate number of memory regions in the + 'Memory Management' section. + +config STM32U5_SRAM2_INIT + bool "SRAM2 is initialized to zero" + default n + ---help--- + The STM32U5 SRAM2 region has parity checking. However, when the system + powers on, the memory is in an unknown state, and reads from uninitialized + memory can trigger parity faults from the random data. This can be + avoided by first writing to all locations to force the parity into a valid + state. + However, if the SRAM2 is being used for it's battery-backed capability, + this may be undesirable (because it will destroy the contents). In that + case, the board should handle the initialization itself at the appropriate + time. + +comment "STM32U5 Peripherals" + +menu "STM32U5 Peripheral Support" + +# These "hidden" settings determine is a peripheral option is available for the +# selection MCU + +config STM32U5_HAVE_LPUART1 + bool + default n + +config STM32U5_HAVE_USART1 + bool + default n + +config STM32U5_HAVE_USART2 + bool + default n + +config STM32U5_HAVE_USART3 + bool + default n + +config STM32U5_HAVE_UART4 + bool + default n + +config STM32U5_HAVE_UART5 + bool + default n + +# These "hidden" settings are the OR of individual peripheral selections +# indicating that the general capability is required. + +config STM32U5_SPI + bool + default n + +config STM32U5_USART + bool + default n + +# These are the peripheral selections proper + +comment "AHB1 Peripherals" + +config STM32U5_GPADMA1 + bool "GPADMA1" + default n + +config STM32U5_CORDIC + bool "CORDIC" + default n + +config STM32U5_FMAC + bool "FMAC" + default n + +config STM32U5_MDF1 + bool "MDF1" + default n + +config STM32U5_FLASH + bool "FLASH" + default n + +config STM32U5_CRC + bool "CRC" + default n + +config STM32U5_TSC + bool "TSC" + default n + +config STM32U5_RAMCFG + bool "RAMCFG" + default n + +config STM32U5_DMA2D + bool "DMA2D" + default n + +config STM32U5_GTZC1 + bool "GTZC1" + default n + +config STM32U5_BKPSRAM + bool "BKPSRAM" + default n + +config STM32U5_DCACHE1 + bool "DCACHE1" + default n + +config STM32U5_SRAM1 + bool "SRAM1" + default n + +comment "AHB2 Peripherals" + +config STM32U5_ADC1 + bool "ADC1" + default n + +config STM32U5_DCMI_PSSI + bool "DCMI_PSSI" + default n + +config STM32U5_OTG + bool "OTG" + default n + +config STM32U5_AES + bool "AES" + default n + +config STM32U5_HASH + bool "HASH" + default n + +config STM32U5_RNG + bool "RNG" + default n + +config STM32U5_PKA + bool "PKA" + default n + +config STM32U5_SAES + bool "SAES" + default n + +config STM32U5_OCTOSPIM + bool "OCTOSPIM" + default n + +config STM32U5_OTFDEC1 + bool "OTFDEC1" + default n + +config STM32U5_OTFDEC2 + bool "OTFDEC2" + default n + +config STM32U5_SDMMC1 + bool "SDMMC1" + default n + +config STM32U5_SDMMC2 + bool "SDMMC2" + default n + +config STM32U5_SRAM2 + bool "SRAM2" + default n + +config STM32U5_SRAM3 + bool "SRAM3" + default n + +config STM32U5_FSMC + bool "FSMC" + default n + +config STM32U5_OCTOSPI1 + bool "OCTOSPI1" + default n + +config STM32U5_OCTOSPI2 + bool "OCTOSPI2" + default n + +comment "AHB3 Peripherals" + +config STM32U5_LPGPIO1 + bool "LPGPIO1" + default n + +config STM32U5_PWR + bool "PWR" + default n + +config STM32U5_ADC4 + bool "ADC4" + default n + +config STM32U5_DAC1 + bool "DAC1" + default n + +config STM32U5_LPDMA1 + bool "LPDMA1" + default n + +config STM32U5_ADF1 + bool "ADF1" + default n + +config STM32U5_GTZC2 + bool "GTZC2" + default n + +config STM32U5_SRAM4 + bool "SRAM4" + default n + +comment "APB1 Peripherals" + +config STM32U5_TIM2 + bool "TIM2" + default n + +config STM32U5_TIM3 + bool "TIM3" + default n + +config STM32U5_TIM4 + bool "TIM4" + default n + +config STM32U5_TIM5 + bool "TIM5" + default n + +config STM32U5_TIM6 + bool "TIM6" + default n + +config STM32U5_TIM7 + bool "TIM7" + default n + +config STM32U5_WWDG + bool "WWDG" + default n + +config STM32U5_SPI2 + bool "SPI2" + default n + select SPI + select STM32U5_SPI + +config STM32U5_USART2 + bool "USART2" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select STM32U5_USART + +config STM32U5_USART3 + bool "USART3" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select STM32U5_USART + +config STM32U5_UART4 + bool "UART4" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select STM32U5_USART + +config STM32U5_UART5 + bool "UART5" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select STM32U5_USART + +config STM32U5_I2C1 + bool "I2C1" + default n + +config STM32U5_I2C2 + bool "I2C2" + default n + +config STM32U5_CRS + bool "CRS" + default n + +config STM32U5_I2C4 + bool "I2C4" + default n + +config STM32U5_LPTIM2 + bool "LPTIM2" + default n + +config STM32U5_FDCAN1 + bool "FDCAN1" + default n + +config STM32U5_UCPD1 + bool "UCPD1" + default n + +comment "APB2 Peripherals" + +config STM32U5_TIM1 + bool "TIM1" + default n + +config STM32U5_SPI1 + bool "SPI1" + default n + select SPI + select STM32U5_SPI + +config STM32U5_TIM8 + bool "TIM8" + default n + +config STM32U5_USART1 + bool "USART1" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select STM32U5_USART + +config STM32U5_TIM15 + bool "TIM15" + default n + +config STM32U5_TIM16 + bool "TIM16" + default n + +config STM32U5_TIM17 + bool "TIM17" + default n + +config STM32U5_SAI1 + bool "SAI1" + default n + +config STM32U5_SAI2 + bool "SAI2" + default n + +comment "APB3 Peripherals" + +config STM32U5_SYSCFG + bool "SYSCFG" + default y + +config STM32U5_SPI3 + bool "SPI3" + default n + select SPI + select STM32U5_SPI + +config STM32U5_LPUART1 + bool "LPUART1" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select STM32U5_USART + +config STM32U5_I2C3 + bool "I2C3" + default n + +config STM32U5_LPTIM1 + bool "LPTIM1" + default n + +config STM32U5_LPTIM3 + bool "LPTIM3" + default n + +config STM32U5_LPTIM4 + bool "LPTIM4" + default n + +config STM32U5_OPAMP + bool "OPAMP" + default n + +config STM32U5_COMP + bool "COMP" + default n + +config STM32U5_VREF + bool "VREF" + default n + +config STM32U5_RTCAPB + bool "RTCAPB" + default n + +endmenu + +config STM32U5_SAI1PLL + bool "SAI1PLL" + default n + ---help--- + The STM32U5 has a separate PLL for the SAI1 block. + Set this true and provide configuration parameters in + board.h to use this PLL. + +config STM32U5_SAI2PLL + bool "SAI2PLL" + default n + depends on STM32U5_HAVE_SAI2 + ---help--- + The STM32U5 has a separate PLL for the SAI2 block. + Set this true and provide configuration parameters in + board.h to use this PLL. + +config STM32U5_FLASH_PREFETCH + bool "Enable FLASH Pre-fetch" + default y + ---help--- + Enable FLASH prefetch + +config STM32U5_DISABLE_IDLE_SLEEP_DURING_DEBUG + bool "Disable IDLE Sleep (WFI) in debug mode" + default n + ---help--- + In debug configuration, disables the WFI instruction in the IDLE loop + to prevent the JTAG from disconnecting. With some JTAG debuggers, such + as the ST-LINK2 with OpenOCD, if the ARM is put to sleep via the WFI + instruction, the debugger will disconnect, terminating the debug session. + +config ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG + bool "Custom clock configuration" + default n + ---help--- + Enables special, board-specific STM32 clock configuration. + +config STM32U5_HAVE_RTC_SUBSECONDS + bool + select ARCH_HAVE_RTC_SUBSECONDS + default y + +menu "RTC Configuration" + depends on STM32U5_RTC + +config STM32U5_RTC_MAGIC_REG + int "BKP register" + default 0 + range 0 31 + ---help--- + The BKP register used to store/check the Magic value to determine if + RTC is already setup + +config STM32U5_RTC_MAGIC + hex "RTC Magic 1" + default 0xfacefeed + ---help--- + Value used as Magic to determine if the RTC is already setup + +config STM32U5_RTC_MAGIC_TIME_SET + hex "RTC Magic 2" + default 0xf00dface + ---help--- + Value used as Magic to determine if the RTC has been setup and has + time set + +choice + prompt "RTC clock source" + default STM32U5_RTC_LSECLOCK + depends on STM32U5_RTC + +config STM32U5_RTC_LSECLOCK + bool "LSE clock" + ---help--- + Drive the RTC with the LSE clock + +config STM32U5_RTC_LSICLOCK + bool "LSI clock" + ---help--- + Drive the RTC with the LSI clock + +config STM32U5_RTC_HSECLOCK + bool "HSE clock" + ---help--- + Drive the RTC with the HSE clock, divided down to 1MHz. + +endchoice + +if STM32U5_RTC_LSECLOCK + +config STM32U5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + bool "Automatically boost the LSE oscillator drive capability level until it starts-up" + default n + ---help--- + This will cycle through the values from low to high. To avoid + damaging the the crystal. We want to use the lowest setting that gets + the OSC running. See app note AN2867 + + 0 = Low drive capability (default) + 1 = Medium low drive capability + 2 = Medium high drive capability + 3 = High drive capability + +config STM32U5_RTC_LSECLOCK_START_DRV_CAPABILITY + int "LSE oscillator drive capability level at LSE start-up" + default 0 + range 0 3 + depends on !STM32U5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + ---help--- + 0 = Low drive capability (default) + 1 = Medium low drive capability + 2 = Medium high drive capability + 3 = High drive capability + +config STM32U5_RTC_LSECLOCK_LOWER_RUN_DRV_CAPABILITY + bool "Decrease LSE oscillator drive capability after LSE start-up" + default n + depends on !STM32U5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + ---help--- + The LSE oscillator drive capability can remain at the level used + during LSE start-up at run-time, or it can be reduced to the + 'Low drive capability' once the LSE started up successfully. + +endif # STM32U5_RTC_LSECLOCK + +endmenu # RTC Configuration + +menu "Timer Configuration" + +if SCHED_TICKLESS + +config STM32U5_ONESHOT + bool + default y + +config STM32U5_FREERUN + bool + default y + +config STM32U5_TICKLESS_ONESHOT + int "Tickless one-shot timer channel" + default 2 + range 1 8 + depends on STM32U5_ONESHOT + ---help--- + If the Tickless OS feature is enabled, then one clock must be + assigned to provide the one-shot timer needed by the OS. + +config STM32U5_TICKLESS_FREERUN + int "Tickless free-running timer channel" + default 5 + range 1 8 + depends on STM32U5_FREERUN + ---help--- + If the Tickless OS feature is enabled, then one clock must be + assigned to provide the free-running timer needed by the OS. + +endif # SCHED_TICKLESS + +if !SCHED_TICKLESS + +config STM32U5_ONESHOT + bool "TIM one-shot wrapper" + default n + ---help--- + Enable a wrapper around the low level timer/counter functions to + support one-shot timer. + +config STM32U5_FREERUN + bool "TIM free-running wrapper" + default n + ---help--- + Enable a wrapper around the low level timer/counter functions to + support a free-running timer. + +endif # !SCHED_TICKLESS + +config STM32U5_ONESHOT_MAXTIMERS + int "Maximum number of oneshot timers" + default 1 + range 1 8 + depends on STM32U5_ONESHOT + ---help--- + Determines the maximum number of oneshot timers that can be + supported. This setting pre-allocates some minimal support for each + of the timers and places an upper limit on the number of oneshot + timers that you can use. + +config STM32U5_LPTIM1_PWM + bool "LPTIM1 PWM" + default n + depends on STM32U5_LPTIM1 + select PWM + ---help--- + Reserve low-power timer 1 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_LPTIM1 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_LPTIM1_PWM + +choice + prompt "LPTIM1 clock source" + default STM32U5_LPTIM1_CLK_APB1 + +config STM32U5_LPTIM1_CLK_APB1 + bool "Clock LPTIM1 from APB1" + +config STM32U5_LPTIM1_CLK_LSE + bool "Clock LPTIM1 from LSE" + +config STM32U5_LPTIM1_CLK_LSI + bool "Clock LPTIM1 from LSI" + +config STM32U5_LPTIM1_CLK_HSI + bool "Clock LPTIM1 from HSI" +endchoice + +endif # STM32U5_LPTIM1_PWM + +config STM32U5_LPTIM2_PWM + bool "LPTIM2 PWM" + default n + depends on STM32U5_LPTIM2 + select PWM + ---help--- + Reserve low-power timer 2 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_LPTIM2 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_LPTIM2_PWM + +choice + prompt "LPTIM2 clock source" + default STM32U5_LPTIM2_CLK_APB1 + +config STM32U5_LPTIM2_CLK_APB1 + bool "Clock LPTIM2 from APB1" + +config STM32U5_LPTIM2_CLK_LSE + bool "Clock LPTIM2 from LSE" + +config STM32U5_LPTIM2_CLK_LSI + bool "Clock LPTIM2 from LSI" + +config STM32U5_LPTIM2_CLK_HSI + bool "Clock LPTIM2 from HSI" +endchoice + +endif # STM32U5_LPTIM2_PWM + +config STM32U5_TIM1_PWM + bool "TIM1 PWM" + default n + depends on STM32U5_TIM1 + select PWM + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 1 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_TIM1 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_TIM1_PWM + +config STM32U5_TIM1_MODE + int "TIM1 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32U5_PWM_MULTICHAN + +config STM32U5_TIM1_CHANNEL1 + bool "TIM1 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32U5_TIM1_CHANNEL1 + +config STM32U5_TIM1_CH1MODE + int "TIM1 Channel 1 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM1_CH1OUT + bool "TIM1 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32U5_TIM1_CH1NOUT + bool "TIM1 Channel 1 Complementary Output" + default n + depends on STM32U5_TIM1_CH1OUT + ---help--- + Enables channel 1 complementary output. + +endif # STM32U5_TIM1_CHANNEL1 + +config STM32U5_TIM1_CHANNEL2 + bool "TIM1 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32U5_TIM1_CHANNEL2 + +config STM32U5_TIM1_CH2MODE + int "TIM1 Channel 2 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM1_CH2OUT + bool "TIM1 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32U5_TIM1_CH2NOUT + bool "TIM1 Channel 2 Complemenrary Output" + default n + depends on STM32U5_TIM1_CH2OUT + ---help--- + Enables channel 2 complementary output. + +endif # STM32U5_TIM1_CHANNEL2 + +config STM32U5_TIM1_CHANNEL3 + bool "TIM1 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32U5_TIM1_CHANNEL3 + +config STM32U5_TIM1_CH3MODE + int "TIM1 Channel 3 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM1_CH3OUT + bool "TIM1 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +config STM32U5_TIM1_CH3NOUT + bool "TIM1 Channel 3 Complementary Output" + default n + depends on STM32U5_TIM1_CH3OUT + ---help--- + Enables channel 3 complementary output. + +endif # STM32U5_TIM1_CHANNEL3 + +config STM32U5_TIM1_CHANNEL5 + bool "TIM1 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32U5_TIM1_CHANNEL5 + +config STM32U5_TIM1_CH4MODE + int "TIM1 Channel 4 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM1_CH4OUT + bool "TIM1 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32U5_TIM1_CHANNEL5 + +endif # STM32U5_PWM_MULTICHAN + +if !STM32U5_PWM_MULTICHAN + +config STM32U5_TIM1_CHANNEL + int "TIM1 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM1 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32U5_TIM1_CHMODE + int "TIM1 Channel Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +endif # !STM32U5_PWM_MULTICHAN + +endif # STM32U5_TIM1_PWM + +config STM32U5_TIM2_PWM + bool "TIM2 PWM" + default n + depends on STM32U5_TIM2 + select PWM + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 2 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_TIM2 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_TIM2_PWM + +config STM32U5_TIM2_MODE + int "TIM2 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32U5_PWM_MULTICHAN + +config STM32U5_TIM2_CHANNEL1 + bool "TIM2 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32U5_TIM2_CHANNEL1 + +config STM32U5_TIM2_CH1MODE + int "TIM2 Channel 1 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM2_CH1OUT + bool "TIM2 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32U5_TIM2_CHANNEL1 + +config STM32U5_TIM2_CHANNEL2 + bool "TIM2 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32U5_TIM2_CHANNEL2 + +config STM32U5_TIM2_CH2MODE + int "TIM2 Channel 2 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM2_CH2OUT + bool "TIM2 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32U5_TIM2_CHANNEL2 + +config STM32U5_TIM2_CHANNEL3 + bool "TIM2 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32U5_TIM2_CHANNEL3 + +config STM32U5_TIM2_CH3MODE + int "TIM2 Channel 3 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM2_CH3OUT + bool "TIM2 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32U5_TIM2_CHANNEL3 + +config STM32U5_TIM2_CHANNEL5 + bool "TIM2 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32U5_TIM2_CHANNEL5 + +config STM32U5_TIM2_CH4MODE + int "TIM2 Channel 4 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM2_CH4OUT + bool "TIM2 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32U5_TIM2_CHANNEL5 + +endif # STM32U5_PWM_MULTICHAN + +if !STM32U5_PWM_MULTICHAN + +config STM32U5_TIM2_CHANNEL + int "TIM2 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM2 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32U5_TIM2_CHMODE + int "TIM2 Channel Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +endif # !STM32U5_PWM_MULTICHAN + +endif # STM32U5_TIM2_PWM + +config STM32U5_TIM3_PWM + bool "TIM3 PWM" + default n + depends on STM32U5_TIM3 + select PWM + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 3 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_TIM3 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_TIM3_PWM + +config STM32U5_TIM3_MODE + int "TIM3 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32U5_PWM_MULTICHAN + +config STM32U5_TIM3_CHANNEL1 + bool "TIM3 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32U5_TIM3_CHANNEL1 + +config STM32U5_TIM3_CH1MODE + int "TIM3 Channel 1 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM3_CH1OUT + bool "TIM3 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32U5_TIM3_CHANNEL1 + +config STM32U5_TIM3_CHANNEL2 + bool "TIM3 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32U5_TIM3_CHANNEL2 + +config STM32U5_TIM3_CH2MODE + int "TIM3 Channel 2 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM3_CH2OUT + bool "TIM3 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32U5_TIM3_CHANNEL2 + +config STM32U5_TIM3_CHANNEL3 + bool "TIM3 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32U5_TIM3_CHANNEL3 + +config STM32U5_TIM3_CH3MODE + int "TIM3 Channel 3 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM3_CH3OUT + bool "TIM3 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32U5_TIM3_CHANNEL3 + +config STM32U5_TIM3_CHANNEL5 + bool "TIM3 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32U5_TIM3_CHANNEL5 + +config STM32U5_TIM3_CH4MODE + int "TIM3 Channel 4 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM3_CH4OUT + bool "TIM3 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32U5_TIM3_CHANNEL5 + +endif # STM32U5_PWM_MULTICHAN + +if !STM32U5_PWM_MULTICHAN + +config STM32U5_TIM3_CHANNEL + int "TIM3 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM3 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32U5_TIM3_CHMODE + int "TIM3 Channel Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +endif # !STM32U5_PWM_MULTICHAN + +endif # STM32U5_TIM3_PWM + +config STM32U5_TIM4_PWM + bool "TIM4 PWM" + default n + depends on STM32U5_TIM4 + select PWM + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 4 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_TIM4 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_TIM4_PWM + +config STM32U5_TIM4_MODE + int "TIM4 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32U5_PWM_MULTICHAN + +config STM32U5_TIM4_CHANNEL1 + bool "TIM4 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32U5_TIM4_CHANNEL1 + +config STM32U5_TIM4_CH1MODE + int "TIM4 Channel 1 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM4_CH1OUT + bool "TIM4 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32U5_TIM4_CHANNEL1 + +config STM32U5_TIM4_CHANNEL2 + bool "TIM4 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32U5_TIM4_CHANNEL2 + +config STM32U5_TIM4_CH2MODE + int "TIM4 Channel 2 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM4_CH2OUT + bool "TIM4 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32U5_TIM4_CHANNEL2 + +config STM32U5_TIM4_CHANNEL3 + bool "TIM4 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32U5_TIM4_CHANNEL3 + +config STM32U5_TIM4_CH3MODE + int "TIM4 Channel 3 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM4_CH3OUT + bool "TIM4 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32U5_TIM4_CHANNEL3 + +config STM32U5_TIM4_CHANNEL5 + bool "TIM4 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32U5_TIM4_CHANNEL5 + +config STM32U5_TIM4_CH4MODE + int "TIM4 Channel 4 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM4_CH4OUT + bool "TIM4 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32U5_TIM4_CHANNEL5 + +endif # STM32U5_PWM_MULTICHAN + +if !STM32U5_PWM_MULTICHAN + +config STM32U5_TIM4_CHANNEL + int "TIM4 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM4 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32U5_TIM4_CHMODE + int "TIM4 Channel Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +endif # !STM32U5_PWM_MULTICHAN + +endif # STM32U5_TIM4_PWM + +config STM32U5_TIM5_PWM + bool "TIM5 PWM" + default n + depends on STM32U5_TIM5 + select PWM + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 5 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_TIM5 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_TIM5_PWM + +config STM32U5_TIM5_MODE + int "TIM5 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32U5_PWM_MULTICHAN + +config STM32U5_TIM5_CHANNEL1 + bool "TIM5 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32U5_TIM5_CHANNEL1 + +config STM32U5_TIM5_CH1MODE + int "TIM5 Channel 1 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM5_CH1OUT + bool "TIM5 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32U5_TIM5_CHANNEL1 + +config STM32U5_TIM5_CHANNEL2 + bool "TIM5 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32U5_TIM5_CHANNEL2 + +config STM32U5_TIM5_CH2MODE + int "TIM5 Channel 2 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM5_CH2OUT + bool "TIM5 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32U5_TIM5_CHANNEL2 + +config STM32U5_TIM5_CHANNEL3 + bool "TIM5 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32U5_TIM5_CHANNEL3 + +config STM32U5_TIM5_CH3MODE + int "TIM5 Channel 3 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM5_CH3OUT + bool "TIM5 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32U5_TIM5_CHANNEL3 + +config STM32U5_TIM5_CHANNEL5 + bool "TIM5 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32U5_TIM5_CHANNEL5 + +config STM32U5_TIM5_CH4MODE + int "TIM5 Channel 4 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM5_CH4OUT + bool "TIM5 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32U5_TIM5_CHANNEL5 + +endif # STM32U5_PWM_MULTICHAN + +if !STM32U5_PWM_MULTICHAN + +config STM32U5_TIM5_CHANNEL + int "TIM5 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM5 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32U5_TIM5_CHMODE + int "TIM5 Channel Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +endif # !STM32U5_PWM_MULTICHAN + +endif # STM32U5_TIM5_PWM + +config STM32U5_TIM8_PWM + bool "TIM8 PWM" + default n + depends on STM32U5_TIM8 + select PWM + select ARCH_HAVE_PWM_PULSECOUNT + ---help--- + Reserve timer 8 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_TIM8 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_TIM8_PWM + +config STM32U5_TIM8_MODE + int "TIM8 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32U5_PWM_MULTICHAN + +config STM32U5_TIM8_CHANNEL1 + bool "TIM8 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32U5_TIM8_CHANNEL1 + +config STM32U5_TIM8_CH1MODE + int "TIM8 Channel 1 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM8_CH1OUT + bool "TIM8 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32U5_TIM8_CH1NOUT + bool "TIM8 Channel 1 Complementary Output" + default n + depends on STM32U5_TIM8_CH1OUT + ---help--- + Enables channel 1 complementary output. + +endif # STM32U5_TIM8_CHANNEL1 + +config STM32U5_TIM8_CHANNEL2 + bool "TIM8 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32U5_TIM8_CHANNEL2 + +config STM32U5_TIM8_CH2MODE + int "TIM8 Channel 2 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM8_CH2OUT + bool "TIM8 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32U5_TIM8_CH2NOUT + bool "TIM8 Channel 2 Complementary Output" + default n + depends on STM32U5_TIM8_CH2OUT + ---help--- + Enables channel 2 complementary output. + +endif # STM32U5_TIM8_CHANNEL2 + +config STM32U5_TIM8_CHANNEL3 + bool "TIM8 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32U5_TIM8_CHANNEL3 + +config STM32U5_TIM8_CH3MODE + int "TIM8 Channel 3 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM8_CH3OUT + bool "TIM8 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +config STM32U5_TIM8_CH3NOUT + bool "TIM8 Channel 3 Complementary Output" + default n + depends on STM32U5_TIM8_CH3OUT + ---help--- + Enables channel 3 complementary output. + +endif # STM32U5_TIM8_CHANNEL3 + +config STM32U5_TIM8_CHANNEL5 + bool "TIM8 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32U5_TIM8_CHANNEL5 + +config STM32U5_TIM8_CH4MODE + int "TIM8 Channel 4 Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM8_CH4OUT + bool "TIM8 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32U5_TIM8_CHANNEL5 + +endif # STM32U5_PWM_MULTICHAN + +if !STM32U5_PWM_MULTICHAN + +config STM32U5_TIM8_CHANNEL + int "TIM8 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM8 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +config STM32U5_TIM8_CHMODE + int "TIM8 Channel Mode" + default 0 + range 0 5 + ---help--- + Specifies the channel mode. + +endif # !STM32U5_PWM_MULTICHAN + +endif # STM32U5_TIM8_PWM + +config STM32U5_TIM15_PWM + bool "TIM15 PWM" + default n + depends on STM32U5_TIM15 + select PWM + ---help--- + Reserve timer 15 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_TIM15 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_TIM15_PWM + +if STM32U5_PWM_MULTICHAN + +config STM32U5_TIM15_CHANNEL1 + bool "TIM15 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32U5_TIM15_CHANNEL1 + +config STM32U5_TIM15_CH1MODE + int "TIM15 Channel 1 Mode" + default 0 + range 0 3 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM15_CH1OUT + bool "TIM15 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32U5_TIM15_CH1NOUT + bool "TIM15 Channel 1 Complementary Output" + default n + depends on STM32U5_TIM15_CH1OUT + ---help--- + Enables channel 1 complementary output. + +endif # STM32U5_TIM15_CHANNEL1 + +config STM32U5_TIM15_CHANNEL2 + bool "TIM15 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32U5_TIM15_CHANNEL2 + +config STM32U5_TIM15_CH2MODE + int "TIM15 Channel 2 Mode" + default 0 + range 0 3 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM15_CH2OUT + bool "TIM15 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32U5_TIM15_CHANNEL2 + +endif # STM32U5_PWM_MULTICHAN + +if !STM32U5_PWM_MULTICHAN + +config STM32U5_TIM15_CHANNEL + int "TIM15 PWM Output Channel" + default 1 + range 1 2 + ---help--- + If TIM15 is enabled for PWM usage, you also need specifies the timer output + channel {1,2} + +config STM32U5_TIM15_CHMODE + int "TIM15 Channel Mode" + default 0 + range 0 3 + ---help--- + Specifies the channel mode. + +endif # !STM32U5_PWM_MULTICHAN + +endif # STM32U5_TIM15_PWM + +config STM32U5_TIM16_PWM + bool "TIM16 PWM" + default n + depends on STM32U5_TIM16 + select PWM + ---help--- + Reserve timer 16 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_TIM16 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_TIM16_PWM + +if STM32U5_PWM_MULTICHAN + +config STM32U5_TIM16_CHANNEL1 + bool "TIM16 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32U5_TIM16_CHANNEL1 + +config STM32U5_TIM16_CH1MODE + int "TIM16 Channel 1 Mode" + default 0 + range 0 1 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM16_CH1OUT + bool "TIM16 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32U5_TIM16_CH1NOUT + bool "TIM16 Channel 1 Complementary Output" + default n + depends on STM32U5_TIM16_CH1OUT + ---help--- + Enables channel 1 complementary output. + +endif # STM32U5_TIM16_CHANNEL1 + +endif # STM32U5_PWM_MULTICHAN + +if !STM32U5_PWM_MULTICHAN + +config STM32U5_TIM16_CHANNEL + int "TIM16 PWM Output Channel" + default 1 + range 1 1 + ---help--- + If TIM16 is enabled for PWM usage, you also need specifies the timer output + channel {1} + +config STM32U5_TIM16_CHMODE + int "TIM16 Channel Mode" + default 0 + range 0 1 + ---help--- + Specifies the channel mode. + +endif # !STM32U5_PWM_MULTICHAN + +endif # STM32U5_TIM16_PWM + +config STM32U5_TIM17_PWM + bool "TIM17 PWM" + default n + depends on STM32U5_TIM17 + select PWM + ---help--- + Reserve timer 17 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32U5_TIM17 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32U5_TIM17_PWM + +if STM32U5_PWM_MULTICHAN + +config STM32U5_TIM17_CHANNEL1 + bool "TIM17 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32U5_TIM17_CHANNEL1 + +config STM32U5_TIM17_CH1MODE + int "TIM17 Channel 1 Mode" + default 0 + range 0 1 + ---help--- + Specifies the channel mode. + +config STM32U5_TIM17_CH1OUT + bool "TIM17 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32U5_TIM17_CH1NOUT + bool "TIM17 Channel 1 Complementary Output" + default n + depends on STM32U5_TIM17_CH1OUT + ---help--- + Enables channel 1 complementary output. + +endif # STM32U5_TIM17_CHANNEL1 + +endif # STM32U5_PWM_MULTICHAN + +if !STM32U5_PWM_MULTICHAN + +config STM32U5_TIM17_CHANNEL + int "TIM17 PWM Output Channel" + default 1 + range 1 1 + ---help--- + If TIM17 is enabled for PWM usage, you also need specifies the timer output + channel {1} + +config STM32U5_TIM17_CHMODE + int "TIM17 Channel Mode" + default 0 + range 0 1 + ---help--- + Specifies the channel mode. + +endif # !STM32U5_PWM_MULTICHAN + +endif # STM32U5_TIM17_PWM + +config STM32U5_PWM_MULTICHAN + bool "PWM Multiple Output Channels" + default n + depends on STM32U5_TIM1_PWM || STM32U5_TIM2_PWM || STM32U5_TIM3_PWM || STM32U5_TIM4_PWM || STM32U5_TIM5_PWM || STM32U5_TIM8_PWM || STM32U5_TIM15_PWM || STM32U5_TIM16_PWM || STM32U5_TIM17_PWM + select ARCH_HAVE_PWM_MULTICHAN + ---help--- + Specifies that the PWM driver supports multiple output + channels per timer. + +config STM32U5_TIM1_ADC + bool "TIM1 ADC" + default n + depends on STM32U5_TIM1 && STM32U5_ADC + ---help--- + Reserve timer 1 for use by ADC + + Timer devices may be used for different purposes. If STM32U5_TIM1 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM1 ADC channel" + default STM32U5_TIM1_ADC1 + depends on STM32U5_TIM1_ADC + +config STM32U5_TIM1_ADC1 + bool "TIM1 ADC channel 1" + depends on STM32U5_ADC1 + select STM32U5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM1 to trigger ADC1 + +config STM32U5_TIM1_ADC2 + bool "TIM1 ADC channel 2" + depends on STM32U5_ADC2 + select STM32U5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM1 to trigger ADC2 + +config STM32U5_TIM1_ADC3 + bool "TIM1 ADC channel 3" + depends on STM32U5_ADC3 + select STM32U5_HAVE_ADC3_TIMER + ---help--- + Reserve TIM1 to trigger ADC3 + +endchoice + +config STM32U5_TIM2_ADC + bool "TIM2 ADC" + default n + depends on STM32U5_TIM2 && STM32U5_ADC + ---help--- + Reserve timer 2 for use by ADC + + Timer devices may be used for different purposes. If STM32U5_TIM2 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM2 ADC channel" + default STM32U5_TIM2_ADC1 + depends on STM32U5_TIM2_ADC + +config STM32U5_TIM2_ADC1 + bool "TIM2 ADC channel 1" + depends on STM32U5_ADC1 + select STM32U5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM2 to trigger ADC1 + +config STM32U5_TIM2_ADC2 + bool "TIM2 ADC channel 2" + depends on STM32U5_ADC2 + select STM32U5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM2 to trigger ADC2 + +config STM32U5_TIM2_ADC3 + bool "TIM2 ADC channel 3" + depends on STM32U5_ADC3 + select STM32U5_HAVE_ADC3_TIMER + ---help--- + Reserve TIM2 to trigger ADC3 + +endchoice + +config STM32U5_TIM3_ADC + bool "TIM3 ADC" + default n + depends on STM32U5_TIM3 && STM32U5_ADC + ---help--- + Reserve timer 3 for use by ADC + + Timer devices may be used for different purposes. If STM32U5_TIM3 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM3 ADC channel" + default STM32U5_TIM3_ADC1 + depends on STM32U5_TIM3_ADC + +config STM32U5_TIM3_ADC1 + bool "TIM3 ADC channel 1" + depends on STM32U5_ADC1 + select STM32U5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM3 to trigger ADC1 + +config STM32U5_TIM3_ADC2 + bool "TIM3 ADC channel 2" + depends on STM32U5_ADC2 + select STM32U5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM3 to trigger ADC2 + +config STM32U5_TIM3_ADC3 + bool "TIM3 ADC channel 3" + depends on STM32U5_ADC3 + select STM32U5_HAVE_ADC3_TIMER + ---help--- + Reserve TIM3 to trigger ADC3 + +endchoice + +config STM32U5_TIM4_ADC + bool "TIM4 ADC" + default n + depends on STM32U5_TIM4 && STM32U5_ADC + ---help--- + Reserve timer 4 for use by ADC + + Timer devices may be used for different purposes. If STM32U5_TIM4 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM4 ADC channel" + default STM32U5_TIM4_ADC1 + depends on STM32U5_TIM4_ADC + +config STM32U5_TIM4_ADC1 + bool "TIM4 ADC channel 1" + depends on STM32U5_ADC1 + select STM32U5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM4 to trigger ADC1 + +config STM32U5_TIM4_ADC2 + bool "TIM4 ADC channel 2" + depends on STM32U5_ADC2 + select STM32U5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM4 to trigger ADC2 + +config STM32U5_TIM4_ADC3 + bool "TIM4 ADC channel 3" + depends on STM32U5_ADC3 + select STM32U5_HAVE_ADC3_TIMER + ---help--- + Reserve TIM4 to trigger ADC3 + +endchoice + +config STM32U5_TIM6_ADC + bool "TIM6 ADC" + default n + depends on STM32U5_TIM6 && STM32U5_ADC + ---help--- + Reserve timer 6 for use by ADC + + Timer devices may be used for different purposes. If STM32U5_TIM6 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM6 ADC channel" + default STM32U5_TIM6_ADC1 + depends on STM32U5_TIM6_ADC + +config STM32U5_TIM6_ADC1 + bool "TIM6 ADC channel 1" + depends on STM32U5_ADC1 + select STM32U5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM6 to trigger ADC1 + +config STM32U5_TIM6_ADC2 + bool "TIM6 ADC channel 2" + depends on STM32U5_ADC2 + select STM32U5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM6 to trigger ADC2 + +config STM32U5_TIM6_ADC3 + bool "TIM6 ADC channel 3" + depends on STM32U5_ADC3 + select STM32U5_HAVE_ADC3_TIMER + ---help--- + Reserve TIM6 to trigger ADC3 + +endchoice + +config STM32U5_TIM8_ADC + bool "TIM8 ADC" + default n + depends on STM32U5_TIM8 && STM32U5_ADC + ---help--- + Reserve timer 8 for use by ADC + + Timer devices may be used for different purposes. If STM32U5_TIM8 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM8 ADC channel" + default STM32U5_TIM8_ADC1 + depends on STM32U5_TIM8_ADC + +config STM32U5_TIM8_ADC1 + bool "TIM8 ADC channel 1" + depends on STM32U5_ADC1 + select STM32U5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM8 to trigger ADC1 + +config STM32U5_TIM8_ADC2 + bool "TIM8 ADC channel 2" + depends on STM32U5_ADC2 + select STM32U5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM8 to trigger ADC2 + +config STM32U5_TIM8_ADC3 + bool "TIM8 ADC channel 3" + depends on STM32U5_ADC3 + select STM32U5_HAVE_ADC3_TIMER + ---help--- + Reserve TIM8 to trigger ADC3 + +endchoice + +config STM32U5_TIM15_ADC + bool "TIM15 ADC" + default n + depends on STM32U5_TIM15 && STM32U5_ADC + ---help--- + Reserve timer 15 for use by ADC + + Timer devices may be used for different purposes. If STM32U5_TIM15 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select TIM15 ADC channel" + default STM32U5_TIM15_ADC1 + depends on STM32U5_TIM15_ADC + +config STM32U5_TIM15_ADC1 + bool "TIM15 ADC channel 1" + depends on STM32U5_ADC1 + select STM32U5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM15 to trigger ADC1 + +config STM32U5_TIM15_ADC2 + bool "TIM15 ADC channel 2" + depends on STM32U5_ADC2 + select STM32U5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM15 to trigger ADC2 + +config STM32U5_TIM15_ADC3 + bool "TIM15 ADC channel 3" + depends on STM32U5_ADC3 + select STM32U5_HAVE_ADC3_TIMER + ---help--- + Reserve TIM15 to trigger ADC3 + +endchoice + +config STM32U5_HAVE_ADC1_TIMER + bool + +config STM32U5_HAVE_ADC2_TIMER + bool + +config STM32U5_HAVE_ADC3_TIMER + bool + +config STM32U5_ADC1_SAMPLE_FREQUENCY + int "ADC1 Sampling Frequency" + default 100 + depends on STM32U5_HAVE_ADC1_TIMER + ---help--- + ADC1 sampling frequency. Default: 100Hz + +config STM32U5_ADC1_TIMTRIG + int "ADC1 Timer Trigger" + default 0 + range 0 4 + depends on STM32U5_HAVE_ADC1_TIMER + ---help--- + Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO + +config STM32U5_ADC2_SAMPLE_FREQUENCY + int "ADC2 Sampling Frequency" + default 100 + depends on STM32U5_HAVE_ADC2_TIMER + ---help--- + ADC2 sampling frequency. Default: 100Hz + +config STM32U5_ADC2_TIMTRIG + int "ADC2 Timer Trigger" + default 0 + range 0 4 + depends on STM32U5_HAVE_ADC2_TIMER + ---help--- + Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO + +config STM32U5_ADC3_SAMPLE_FREQUENCY + int "ADC3 Sampling Frequency" + default 100 + depends on STM32U5_HAVE_ADC3_TIMER + ---help--- + ADC3 sampling frequency. Default: 100Hz + +config STM32U5_ADC3_TIMTRIG + int "ADC3 Timer Trigger" + default 0 + range 0 4 + depends on STM32U5_HAVE_ADC3_TIMER + ---help--- + Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO + +config STM32U5_TIM1_DAC + bool "TIM1 DAC" + default n + depends on STM32U5_TIM1 && STM32U5_DAC + ---help--- + Reserve timer 1 for use by DAC + + Timer devices may be used for different purposes. If STM32U5_TIM1 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM1 DAC channel" + default STM32U5_TIM1_DAC1 + depends on STM32U5_TIM1_DAC + +config STM32U5_TIM1_DAC1 + bool "TIM1 DAC channel 1" + ---help--- + Reserve TIM1 to trigger DAC1 + +config STM32U5_TIM1_DAC2 + bool "TIM1 DAC channel 2" + ---help--- + Reserve TIM1 to trigger DAC2 + +endchoice + +config STM32U5_TIM2_DAC + bool "TIM2 DAC" + default n + depends on STM32U5_TIM2 && STM32U5_DAC + ---help--- + Reserve timer 2 for use by DAC + + Timer devices may be used for different purposes. If STM32U5_TIM2 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM2 DAC channel" + default STM32U5_TIM2_DAC1 + depends on STM32U5_TIM2_DAC + +config STM32U5_TIM2_DAC1 + bool "TIM2 DAC channel 1" + ---help--- + Reserve TIM2 to trigger DAC1 + +config STM32U5_TIM2_DAC2 + bool "TIM2 DAC channel 2" + ---help--- + Reserve TIM2 to trigger DAC2 + +endchoice + +config STM32U5_TIM3_DAC + bool "TIM3 DAC" + default n + depends on STM32U5_TIM3 && STM32U5_DAC + ---help--- + Reserve timer 3 for use by DAC + + Timer devices may be used for different purposes. If STM32U5_TIM3 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM3 DAC channel" + default STM32U5_TIM3_DAC1 + depends on STM32U5_TIM3_DAC + +config STM32U5_TIM3_DAC1 + bool "TIM3 DAC channel 1" + ---help--- + Reserve TIM3 to trigger DAC1 + +config STM32U5_TIM3_DAC2 + bool "TIM3 DAC channel 2" + ---help--- + Reserve TIM3 to trigger DAC2 + +endchoice + +config STM32U5_TIM4_DAC + bool "TIM4 DAC" + default n + depends on STM32U5_TIM4 && STM32U5_DAC + ---help--- + Reserve timer 4 for use by DAC + + Timer devices may be used for different purposes. If STM32U5_TIM4 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM4 DAC channel" + default STM32U5_TIM4_DAC1 + depends on STM32U5_TIM4_DAC + +config STM32U5_TIM4_DAC1 + bool "TIM4 DAC channel 1" + ---help--- + Reserve TIM4 to trigger DAC1 + +config STM32U5_TIM4_DAC2 + bool "TIM4 DAC channel 2" + ---help--- + Reserve TIM4 to trigger DAC2 + +endchoice + +config STM32U5_TIM5_DAC + bool "TIM5 DAC" + default n + depends on STM32U5_TIM5 && STM32U5_DAC + ---help--- + Reserve timer 5 for use by DAC + + Timer devices may be used for different purposes. If STM32U5_TIM5 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM5 DAC channel" + default STM32U5_TIM5_DAC1 + depends on STM32U5_TIM5_DAC + +config STM32U5_TIM5_DAC1 + bool "TIM5 DAC channel 1" + ---help--- + Reserve TIM5 to trigger DAC1 + +config STM32U5_TIM5_DAC2 + bool "TIM5 DAC channel 2" + ---help--- + Reserve TIM5 to trigger DAC2 + +endchoice + +config STM32U5_TIM6_DAC + bool "TIM6 DAC" + default n + depends on STM32U5_TIM6 && STM32U5_DAC + ---help--- + Reserve timer 6 for use by DAC + + Timer devices may be used for different purposes. If STM32U5_TIM6 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM6 DAC channel" + default STM32U5_TIM6_DAC1 + depends on STM32U5_TIM6_DAC + +config STM32U5_TIM6_DAC1 + bool "TIM6 DAC channel 1" + ---help--- + Reserve TIM6 to trigger DAC1 + +config STM32U5_TIM6_DAC2 + bool "TIM6 DAC channel 2" + ---help--- + Reserve TIM6 to trigger DAC2 + +endchoice + +config STM32U5_TIM7_DAC + bool "TIM7 DAC" + default n + depends on STM32U5_TIM7 && STM32U5_DAC + ---help--- + Reserve timer 7 for use by DAC + + Timer devices may be used for different purposes. If STM32U5_TIM7 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM7 DAC channel" + default STM32U5_TIM7_DAC1 + depends on STM32U5_TIM7_DAC + +config STM32U5_TIM7_DAC1 + bool "TIM7 DAC channel 1" + ---help--- + Reserve TIM7 to trigger DAC1 + +config STM32U5_TIM7_DAC2 + bool "TIM7 DAC channel 2" + ---help--- + Reserve TIM7 to trigger DAC2 + +endchoice + +config STM32U5_TIM8_DAC + bool "TIM8 DAC" + default n + depends on STM32U5_TIM8 && STM32U5_DAC + ---help--- + Reserve timer 8 for use by DAC + + Timer devices may be used for different purposes. If STM32U5_TIM8 is + defined then the following may also be defined to indicate that the + timer is intended to be used for DAC conversion. Note that DAC usage + requires two definition: Not only do you have to assign the timer + for used by the DAC, but then you also have to configure which DAC + channel it is assigned to. + +choice + prompt "Select TIM8 DAC channel" + default STM32U5_TIM8_DAC1 + depends on STM32U5_TIM8_DAC + +config STM32U5_TIM8_DAC1 + bool "TIM8 DAC channel 1" + ---help--- + Reserve TIM8 to trigger DAC1 + +config STM32U5_TIM8_DAC2 + bool "TIM8 DAC channel 2" + ---help--- + Reserve TIM8 to trigger DAC2 + +endchoice + +config STM32U5_TIM1_CAP + bool "TIM1 Capture" + default n + depends on STM32U5_HAVE_TIM1 + ---help--- + Reserve timer 1 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32U5_TIM2_CAP + bool "TIM2 Capture" + default n + depends on STM32U5_HAVE_TIM2 + ---help--- + Reserve timer 2 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32U5_TIM3_CAP + bool "TIM3 Capture" + default n + depends on STM32U5_HAVE_TIM3 + ---help--- + Reserve timer 3 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32U5_TIM4_CAP + bool "TIM4 Capture" + default n + depends on STM32U5_HAVE_TIM4 + ---help--- + Reserve timer 4 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32U5_TIM5_CAP + bool "TIM5 Capture" + default n + depends on STM32U5_HAVE_TIM5 + ---help--- + Reserve timer 5 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32U5_TIM8_CAP + bool "TIM8 Capture" + default n + depends on STM32U5_HAVE_TIM8 + ---help--- + Reserve timer 8 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +endmenu # Timer Configuration + +menu "ADC Configuration" + depends on STM32U5_ADC + +config STM32U5_ADC1_DMA + bool "ADC1 DMA" + depends on STM32U5_ADC1 + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32U5_ADC2_DMA + bool "ADC2 DMA" + depends on STM32U5_ADC2 + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32U5_ADC3_DMA + bool "ADC3 DMA" + depends on STM32U5_ADC3 + default n + ---help--- + If DMA is selected, then the ADC may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +config STM32U5_ADC1_OUTPUT_DFSDM + bool "ADC1 output to DFSDM" + depends on STM32U5_ADC1 && STM32U5_DFSDM1 && (STM32U5_STM32U596XX || STM32U5_STM32U5XR) + default n + ---help--- + Route ADC1 output directly to DFSDM parallel inputs. + +config STM32U5_ADC2_OUTPUT_DFSDM + bool "ADC2 output to DFSDM" + depends on STM32U5_ADC2 && STM32U5_DFSDM1 && STM32U5_STM32U596XX + default n + ---help--- + Route ADC2 output directly to DFSDM parallel inputs. + +config STM32U5_ADC3_OUTPUT_DFSDM + bool "ADC3 output to DFSDM" + depends on STM32U5_ADC3 && STM32U5_DFSDM1 && STM32U5_STM32U596XX + default n + ---help--- + Route ADC3 output directly to DFSDM parallel inputs. + +endmenu + +menu "DAC Configuration" + depends on STM32U5_DAC + +config STM32U5_DAC1_DMA + bool "DAC1 DMA" + depends on STM32U5_DAC1 + default n + ---help--- + If DMA is selected, then a timer and output frequency must also be + provided to support the DMA transfer. The DMA transfer could be + supported by an EXTI trigger, but this feature is not currently + supported by the driver. + +if STM32U5_DAC1_DMA + +config STM32U5_DAC1_TIMER + int "DAC1 timer" + range 2 8 + +config STM32U5_DAC1_TIMER_FREQUENCY + int "DAC1 timer frequency" + default 100 + ---help--- + DAC1 output frequency. Default: 100Hz + +config STM32U5_DAC1_DMA_BUFFER_SIZE + int "DAC1 DMA buffer size" + default 1 + +endif + +config STM32U5_DAC1_OUTPUT_ADC + bool "DAC1 output to ADC" + depends on STM32U5_DAC1 + default n + ---help--- + Route DAC1 output to ADC input instead of external pin. + +config STM32U5_DAC2_DMA + bool "DAC2 DMA" + depends on STM32U5_DAC2 + default n + ---help--- + If DMA is selected, then a timer and output frequency must also be + provided to support the DMA transfer. The DMA transfer could be + supported by an EXTI trigger, but this feature is not currently + supported by the driver. + +if STM32U5_DAC2_DMA + +config STM32U5_DAC2_TIMER + int "DAC2 timer" + default 0 + range 2 8 + +config STM32U5_DAC2_TIMER_FREQUENCY + int "DAC2 timer frequency" + default 100 + ---help--- + DAC2 output frequency. Default: 100Hz + +config STM32U5_DAC2_DMA_BUFFER_SIZE + int "DAC2 DMA buffer size" + default 1 + +endif + +config STM32U5_DAC2_OUTPUT_ADC + bool "DAC2 output to ADC" + depends on STM32U5_DAC2 + default n + ---help--- + Route DAC2 output to ADC input instead of external pin. + +endmenu + +menu "DFSDM Configuration" + depends on STM32U5_DFSDM1 + +config STM32U5_DFSDM1_FLT0 + bool "DFSDM1 Filter 0" + default n + select STM32U5_DFSDM + +config STM32U5_DFSDM1_FLT1 + bool "DFSDM1 Filter 1" + default n + select STM32U5_DFSDM + +config STM32U5_DFSDM1_FLT2 + bool "DFSDM1 Filter 2" + default n + depends on !STM32U5_STM32U5X3 + select STM32U5_DFSDM + +config STM32U5_DFSDM1_FLT3 + bool "DFSDM1 Filter 3" + default n + depends on !STM32U5_STM32U5X3 + select STM32U5_DFSDM + +config STM32U5_DFSDM1_DMA + bool "DFSDM1 DMA" + depends on STM32U5_DFSDM + default n + ---help--- + If DMA is selected, then the DFSDM may be configured to support + DMA transfer, which is necessary if multiple channels are read + or if very high trigger frequencies are used. + +endmenu + +config STM32U5_SERIALDRIVER + bool + +config STM32U5_1WIREDRIVER + bool + +menu "[LP]U[S]ART Configuration" + depends on STM32U5_USART + +choice + prompt "LPUART1 Driver Configuration" + default STM32U5_LPUART1_SERIALDRIVER + depends on STM32U5_LPUART1 + +config STM32U5_LPUART1_SERIALDRIVER + bool "Standard serial driver" + select LPUART1_SERIALDRIVER + select STM32U5_SERIALDRIVER + +config STM32U5_LPUART1_1WIREDRIVER + bool "1-Wire driver" + select STM32U5_1WIREDRIVER + +endchoice # LPUART1 Driver Configuration + +if LPUART1_SERIALDRIVER + +config LPUART1_RS485 + bool "RS-485 on LPUART1" + default n + depends on STM32U5_LPUART1 + ---help--- + Enable RS-485 interface on LPUART1. Your board config will have to + provide GPIO_LPUART1_RS485_DIR pin definition. Currently it cannot be + used with LPUART1_RXDMA. + +config LPUART1_RS485_DIR_POLARITY + int "LPUART1 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on LPUART1_RS485 + ---help--- + Polarity of DIR pin for RS-485 on LPUART1. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config LPUART1_RXDMA + bool "LPUART1 Rx DMA" + default n + depends on STM32U5_LPUART1 && (STM32U5_DMA1 || STM32U5_DMA2 || STM32U5_DMAMUX) + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +endif # LPUART1_SERIALDRIVER + +choice + prompt "USART1 Driver Configuration" + default STM32U5_USART1_SERIALDRIVER + depends on STM32U5_USART1 + +config STM32U5_USART1_SERIALDRIVER + bool "Standard serial driver" + select USART1_SERIALDRIVER + select STM32U5_SERIALDRIVER + +config STM32U5_USART1_1WIREDRIVER + bool "1-Wire driver" + select STM32U5_1WIREDRIVER + +endchoice # USART1 Driver Configuration + +if USART1_SERIALDRIVER + +config USART1_RS485 + bool "RS-485 on USART1" + default n + depends on STM32U5_USART1 + ---help--- + Enable RS-485 interface on USART1. Your board config will have to + provide GPIO_USART1_RS485_DIR pin definition. Currently it cannot be + used with USART1_RXDMA. + +config USART1_RS485_DIR_POLARITY + int "USART1 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART1_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART1. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART1_RXDMA + bool "USART1 Rx DMA" + default n + depends on STM32U5_USART1 && (STM32U5_DMA1 || STM32U5_DMA2 || STM32U5_DMAMUX) + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +endif # USART1_SERIALDRIVER + +choice + prompt "USART2 Driver Configuration" + default STM32U5_USART2_SERIALDRIVER + depends on STM32U5_USART2 + +config STM32U5_USART2_SERIALDRIVER + bool "Standard serial driver" + select USART2_SERIALDRIVER + select STM32U5_SERIALDRIVER + +config STM32U5_USART2_1WIREDRIVER + bool "1-Wire driver" + select STM32U5_1WIREDRIVER + +endchoice # USART2 Driver Configuration + +if USART2_SERIALDRIVER + +config USART2_RS485 + bool "RS-485 on USART2" + default n + depends on STM32U5_USART2 + ---help--- + Enable RS-485 interface on USART2. Your board config will have to + provide GPIO_USART2_RS485_DIR pin definition. Currently it cannot be + used with USART2_RXDMA. + +config USART2_RS485_DIR_POLARITY + int "USART2 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART2_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART2. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART2_RXDMA + bool "USART2 Rx DMA" + default n + depends on STM32U5_USART2 && (STM32U5_DMA1 || STM32U5_DMAMUX) + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +endif # USART2_SERIALDRIVER + +choice + prompt "USART3 Driver Configuration" + default STM32U5_USART3_SERIALDRIVER + depends on STM32U5_USART3 + +config STM32U5_USART3_SERIALDRIVER + bool "Standard serial driver" + select USART3_SERIALDRIVER + select STM32U5_SERIALDRIVER + +config STM32U5_USART3_1WIREDRIVER + bool "1-Wire driver" + select STM32U5_1WIREDRIVER + +endchoice # USART3 Driver Configuration + +if USART3_SERIALDRIVER + +config USART3_RS485 + bool "RS-485 on USART3" + default n + depends on STM32U5_USART3 + ---help--- + Enable RS-485 interface on USART3. Your board config will have to + provide GPIO_USART3_RS485_DIR pin definition. Currently it cannot be + used with USART3_RXDMA. + +config USART3_RS485_DIR_POLARITY + int "USART3 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART3_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART3. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART3_RXDMA + bool "USART3 Rx DMA" + default n + depends on STM32U5_USART3 && (STM32U5_DMA1 || STM32U5_DMAMUX) + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +endif # USART3_SERIALDRIVER + +choice + prompt "UART4 Driver Configuration" + default STM32U5_UART4_SERIALDRIVER + depends on STM32U5_UART4 + +config STM32U5_UART4_SERIALDRIVER + bool "Standard serial driver" + select UART4_SERIALDRIVER + select STM32U5_SERIALDRIVER + +config STM32U5_UART4_1WIREDRIVER + bool "1-Wire driver" + select STM32U5_1WIREDRIVER + +endchoice # UART4 Driver Configuration + +if UART4_SERIALDRIVER + +config UART4_RS485 + bool "RS-485 on UART4" + default n + depends on STM32U5_UART4 + ---help--- + Enable RS-485 interface on UART4. Your board config will have to + provide GPIO_UART4_RS485_DIR pin definition. Currently it cannot be + used with UART4_RXDMA. + +config UART4_RS485_DIR_POLARITY + int "UART4 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART4_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART4. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART4_RXDMA + bool "UART4 Rx DMA" + default n + depends on STM32U5_UART4 && (STM32U5_DMA2 || STM32U5_DMAMUX) + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +endif # UART4_SERIALDRIVER + +choice + prompt "UART5 Driver Configuration" + default STM32U5_UART5_SERIALDRIVER + depends on STM32U5_UART5 + +config STM32U5_UART5_SERIALDRIVER + bool "Standard serial driver" + select UART5_SERIALDRIVER + select STM32U5_SERIALDRIVER + +config STM32U5_UART5_1WIREDRIVER + bool "1-Wire driver" + select STM32U5_1WIREDRIVER + +endchoice # UART5 Driver Configuration + +if UART5_SERIALDRIVER + +config UART5_RS485 + bool "RS-485 on UART5" + default n + depends on STM32U5_UART5 + ---help--- + Enable RS-485 interface on UART5. Your board config will have to + provide GPIO_UART5_RS485_DIR pin definition. Currently it cannot be + used with UART5_RXDMA. + +config UART5_RS485_DIR_POLARITY + int "UART5 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART5_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART5. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART5_RXDMA + bool "UART5 Rx DMA" + default n + depends on STM32U5_UART5 && (STM32U5_DMA2 || STM32U5_DMAMUX) + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +endif # UART5_SERIALDRIVER + +if STM32U5_SERIALDRIVER + +comment "Serial Driver Configuration" + +config STM32U5_SERIAL_RXDMA_BUFFER_SIZE + int "Rx DMA buffer size" + default 32 + depends on USART1_RXDMA || USART2_RXDMA || USART3_RXDMA || UART4_RXDMA || UART5_RXDMA + ---help--- + The DMA buffer size when using RX DMA to emulate a FIFO. + + When streaming data, the generic serial layer will be called + every time the FIFO receives half this number of bytes. + + Value given here will be rounded up to next multiple of 32 bytes. + +config STM32U5_SERIAL_DISABLE_REORDERING + bool "Disable reordering of ttySx devices." + depends on STM32U5_USART1 || STM32U5_USART2 || STM32U5_USART3 || STM32U5_UART4 || STM32U5_UART5 + 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 is in particular relevant if a project uses the USB console + in some boards and a serial console in other boards, but does not + want the side effect of having all serial port names change when just + the console is moved from serial to USB. + +config STM32U5_FLOWCONTROL_BROKEN + bool "Use Software UART RTS flow control" + depends on STM32U5_USART + default n + ---help--- + Enable UART RTS flow control using Software. Because STM + Current STM32 have broken HW based RTS behavior (they assert + nRTS after every byte received) Enable this setting workaround + this issue by using software based management of RTS + +config STM32U5_USART_BREAKS + bool "Add TIOxSBRK to support sending Breaks" + depends on STM32U5_USART + default n + ---help--- + Add TIOCxBRK routines to send a line break per the STM32 manual, the + break will be a pulse based on the value M. This is not a BSD compatible + break. + +config STM32U5_SERIALBRK_BSDCOMPAT + bool "Use GPIO To send Break" + depends on STM32U5_USART && STM32U5_USART_BREAKS + default n + ---help--- + Enable using GPIO on the TX pin to send a BSD compatible break: + TIOCSBRK will start the break and TIOCCBRK will end the break. + The current STM32 U[S]ARTS have no way to leave the break (TX=LOW) + on because the SW starts the break and then the HW automatically clears + the break. This makes it is difficult to sent a long break. + +config STM32U5_USART_SINGLEWIRE + bool "Single Wire Support" + default n + depends on STM32U5_USART + ---help--- + Enable single wire UART support. The option enables support for the + TIOCSSINGLEWIRE ioctl in the STM32U5 serial driver. + +config STM32U5_USART_INVERT + bool "Signal Invert Support" + default n + depends on STM32U5_USART + ---help--- + Enable signal inversion UART support. The option enables support for the + TIOCSINVERT ioctl in the STM32U5 serial driver. + +config STM32U5_USART_SWAP + bool "Swap RX/TX pins support" + default n + depends on STM32U5_USART + ---help--- + Enable RX/TX pin swapping support. The option enables support for the + TIOCSSWAP ioctl in the STM32U5 serial driver. + +if PM + +config STM32U5_PM_SERIAL_ACTIVITY + int "PM serial activity" + default 10 + ---help--- + PM activity reported to power management logic on every serial + interrupt. + +endif +endif # STM32U5_SERIALDRIVER + +endmenu # U[S]ART Configuration + +menu "SPI Configuration" + depends on STM32U5_SPI + +config STM32U5_SPI_INTERRUPTS + bool "Interrupt driver SPI" + default n + ---help--- + Select to enable interrupt driven SPI support. Non-interrupt-driven, + poll-waiting is recommended if the interrupt rate would be to high in + the interrupt driven case. + +config STM32U5_SPI_DMA + bool "SPI DMA" + default n + ---help--- + Use DMA to improve SPI transfer performance. Cannot be used with STM32U5_SPI_INTERRUPT. + +endmenu + +menu "I2C Configuration" + depends on STM32U5_I2C + +config STM32U5_I2C_DYNTIMEO + bool "Use dynamic timeouts" + default n + depends on STM32U5_I2C + +config STM32U5_I2C_DYNTIMEO_USECPERBYTE + int "Timeout Microseconds per Byte" + default 500 + depends on STM32U5_I2C_DYNTIMEO + +config STM32U5_I2C_DYNTIMEO_STARTSTOP + int "Timeout for Start/Stop (Milliseconds)" + default 1000 + depends on STM32U5_I2C_DYNTIMEO + +config STM32U5_I2CTIMEOSEC + int "Timeout seconds" + default 0 + depends on STM32U5_I2C + +config STM32U5_I2CTIMEOMS + int "Timeout Milliseconds" + default 500 + depends on STM32U5_I2C && !STM32U5_I2C_DYNTIMEO + +config STM32U5_I2CTIMEOTICKS + int "Timeout for Done and Stop (ticks)" + default 500 + depends on STM32U5_I2C && !STM32U5_I2C_DYNTIMEO + +endmenu + +menu "SD/MMC Configuration" + depends on STM32U5_SDMMC + +config STM32U5_SDMMC_XFRDEBUG + bool "SDMMC transfer debug" + depends on DEBUG_FS_INFO + default n + ---help--- + Enable special debug instrumentation analyze SDMMC data transfers. + This logic is as non-invasive as possible: It samples SDMMC + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. If DEBUG_DMA is also + enabled, then DMA register will be collected as well. Requires also + DEBUG_FS and CONFIG_DEBUG_INFO. + +config STM32U5_SDMMC_DMA + bool "Support DMA data transfers" + default n + select SDIO_DMA + depends on STM32U5_DMA + ---help--- + Support DMA data transfers. + +menu "SDMMC1 Configuration" + depends on STM32U5_SDMMC1 + +config STM32U5_SDMMC1_DMAPRIO + hex "SDMMC1 DMA priority" + default 0x00001000 + ---help--- + Select SDMMC1 DMA priority. + + Options are: 0x00000000 low, 0x00001000 medium, + 0x00002000 high, 0x00003000 very high. Default: medium. + +config SDMMC1_WIDTH_D1_ONLY + bool "Use D1 only on SDMMC1" + default n + ---help--- + Select 1-bit transfer mode. Default: 4-bit transfer mode. + +endmenu # SDMMC1 Configuration +endmenu # SD/MMC Configuration + +menu "CAN driver configuration" + depends on STM32U5_CAN1 || STM32U5_CAN2 + +config STM32U5_CAN1_BAUD + int "CAN1 BAUD" + default 250000 + depends on STM32U5_CAN1 + ---help--- + CAN1 BAUD rate. Required if CONFIG_STM32U5_CAN1 is defined. + +config STM32U5_CAN2_BAUD + int "CAN2 BAUD" + default 250000 + depends on STM32U5_CAN2 + ---help--- + CAN2 BAUD rate. Required if CONFIG_STM32U5_CAN2 is defined. + +config STM32U5_CAN_TSEG1 + int "TSEG1 quanta" + default 6 + ---help--- + The number of CAN time quanta in segment 1. Default: 6 + +config STM32U5_CAN_TSEG2 + int "TSEG2 quanta" + default 7 + ---help--- + The number of CAN time quanta in segment 2. Default: 7 + +config STM32U5_CAN_REGDEBUG + bool "CAN Register level debug" + depends on DEBUG_CAN_INFO + default n + ---help--- + Output detailed register-level CAN device debug information. + Requires also CONFIG_DEBUG_CAN_INFO. + +endmenu + +menu "QEncoder Driver" + depends on SENSORS_QENCODER + depends on STM32U5_TIM1 || STM32U5_TIM2 || STM32U5_TIM3 || STM32U5_TIM4 || STM32U5_TIM5 || STM32U5_TIM8 + +config STM32U5_TIM1_QE + bool "TIM1" + default n + depends on STM32U5_TIM1 + ---help--- + Reserve TIM1 for use by QEncoder. + +if STM32U5_TIM1_QE + +config STM32U5_TIM1_QEPSC + int "TIM1 pulse prescaler" + default 1 + ---help--- + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM1." (CONFIG_TIM1_QECLKOUT). + +endif + +config STM32U5_TIM2_QE + bool "TIM2" + default n + depends on STM32U5_TIM2 + ---help--- + Reserve TIM2 for use by QEncoder. + +if STM32U5_TIM2_QE + +config STM32U5_TIM2_QEPSC + int "TIM2 pulse prescaler" + default 1 + ---help--- + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM2." (CONFIG_TIM2_QECLKOUT). + +endif + +config STM32U5_TIM3_QE + bool "TIM3" + default n + depends on STM32U5_TIM3 + ---help--- + Reserve TIM3 for use by QEncoder. + +if STM32U5_TIM3_QE + +config STM32U5_TIM3_QEPSC + int "TIM3 pulse prescaler" + default 1 + ---help--- + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM3." (CONFIG_TIM3_QECLKOUT). + +endif + +config STM32U5_TIM4_QE + bool "TIM4" + default n + depends on STM32U5_TIM4 + ---help--- + Reserve TIM4 for use by QEncoder. + +if STM32U5_TIM4_QE + +config STM32U5_TIM4_QEPSC + int "TIM4 pulse prescaler" + default 1 + ---help--- + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM4." (CONFIG_TIM4_QECLKOUT). + +endif + +config STM32U5_TIM5_QE + bool "TIM5" + default n + depends on STM32U5_TIM5 + ---help--- + Reserve TIM5 for use by QEncoder. + +if STM32U5_TIM5_QE + +config STM32U5_TIM5_QEPSC + int "TIM5 pulse prescaler" + default 1 + ---help--- + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM5." (CONFIG_TIM5_QECLKOUT). + +endif + +config STM32U5_TIM8_QE + bool "TIM8" + default n + depends on STM32U5_TIM8 + ---help--- + Reserve TIM8 for use by QEncoder. + +if STM32U5_TIM8_QE + +config STM32U5_TIM8_QEPSC + int "TIM8 pulse prescaler" + default 1 + ---help--- + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM8." (CONFIG_TIM8_QECLKOUT). + +endif + +config STM32U5_QENCODER_FILTER + bool "Enable filtering on STM32 QEncoder input" + default y + +choice + depends on STM32U5_QENCODER_FILTER + prompt "Input channel sampling frequency" + default STM32U5_QENCODER_SAMPLE_FDTS_4 + +config STM32U5_QENCODER_SAMPLE_FDTS + bool "fDTS" + +config STM32U5_QENCODER_SAMPLE_CKINT + bool "fCK_INT" + +config STM32U5_QENCODER_SAMPLE_FDTS_2 + bool "fDTS/2" + +config STM32U5_QENCODER_SAMPLE_FDTS_4 + bool "fDTS/4" + +config STM32U5_QENCODER_SAMPLE_FDTS_8 + bool "fDTS/8" + +config STM32U5_QENCODER_SAMPLE_FDTS_16 + bool "fDTS/16" + +config STM32U5_QENCODER_SAMPLE_FDTS_32 + bool "fDTS/32" + +endchoice + +choice + depends on STM32U5_QENCODER_FILTER + prompt "Input channel event count" + default STM32U5_QENCODER_SAMPLE_EVENT_6 + +config STM32U5_QENCODER_SAMPLE_EVENT_1 + depends on STM32U5_QENCODER_SAMPLE_FDTS + bool "1" + +config STM32U5_QENCODER_SAMPLE_EVENT_2 + depends on STM32U5_QENCODER_SAMPLE_CKINT + bool "2" + +config STM32U5_QENCODER_SAMPLE_EVENT_4 + depends on STM32U5_QENCODER_SAMPLE_CKINT + bool "4" + +config STM32U5_QENCODER_SAMPLE_EVENT_5 + depends on STM32U5_QENCODER_SAMPLE_FDTS_16 || STM32U5_QENCODER_SAMPLE_FDTS_32 + bool "5" + +config STM32U5_QENCODER_SAMPLE_EVENT_6 + depends on !STM32U5_QENCODER_SAMPLE_FDTS && !STM32U5_QENCODER_SAMPLE_CKINT + bool "6" + +config STM32U5_QENCODER_SAMPLE_EVENT_8 + depends on !STM32U5_QENCODER_SAMPLE_FDTS + bool "8" + +endchoice + +endmenu + +menu "SAI Configuration" + depends on STM32U5_SAI + +choice + prompt "Operation mode" + default STM32U5_SAI_DMA + ---help--- + Select the operation mode the SAI driver should use. + +config STM32U5_SAI_POLLING + bool "Polling" + ---help--- + The SAI registers are polled for events. + +config STM32U5_SAI_INTERRUPTS + bool "Interrupt" + ---help--- + Select to enable interrupt driven SAI support. + +config STM32U5_SAI_DMA + bool "DMA" + ---help--- + Use DMA to improve SAI transfer performance. + +endchoice # Operation mode + +choice + prompt "SAI1 synchronization enable" + default STM32U5_SAI1_BOTH_ASYNC + depends on STM32U5_SAI1_A && STM32U5_SAI1_B + ---help--- + Select the synchronization mode of the SAI sub-blocks + +config STM32U5_SAI1_BOTH_ASYNC + bool "Both asynchronous" + +config STM32U5_SAI1_A_SYNC_WITH_B + bool "Block A is synchronous with Block B" + +config STM32U5_SAI1_B_SYNC_WITH_A + bool "Block B is synchronous with Block A" + +endchoice # SAI1 synchronization enable + +choice + prompt "SAI2 synchronization enable" + default STM32U5_SAI2_BOTH_ASYNC + depends on STM32U5_SAI2_A && STM32U5_SAI2_B + ---help--- + Select the synchronization mode of the SAI sub-blocks + +config STM32U5_SAI2_BOTH_ASYNC + bool "Both asynchronous" + +config STM32U5_SAI2_A_SYNC_WITH_B + bool "Block A is synchronous with Block B" + +config STM32U5_SAI2_B_SYNC_WITH_A + bool "Block B is synchronous with Block A" + +endchoice # SAI2 synchronization enable + +endmenu + +endif # ARCH_CHIP_STM32U5 diff --git a/arch/arm/src/stm32u5/Make.defs b/arch/arm/src/stm32u5/Make.defs new file mode 100644 index 0000000000..a9a629731c --- /dev/null +++ b/arch/arm/src/stm32u5/Make.defs @@ -0,0 +1,106 @@ +############################################################################## +# arch/arm/src/stm32u5/Make.defs +# +# 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 support so there +# isn't one. + +HEAD_ASRC = + +# Common ARM and Cortex-M4 files (copied from stm32/Make.defs) + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = arm_saveusercontext.S arm_fullcontextrestore.S +CMN_ASRCS += arm_testset.S arm_fetchadd.S vfork.S + +CMN_CSRCS = arm_assert.c arm_blocktask.c arm_copyfullstate.c arm_createstack.c +CMN_CSRCS += arm_doirq.c arm_exit.c arm_hardfault.c arm_initialize.c +CMN_CSRCS += arm_initialstate.c arm_interruptcontext.c arm_mdelay.c arm_memfault.c +CMN_CSRCS += arm_modifyreg8.c arm_modifyreg16.c arm_modifyreg32.c +CMN_CSRCS += arm_releasepending.c arm_releasestack.c arm_reprioritizertr.c +CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_stackframe.c +CMN_CSRCS += arm_svcall.c arm_systemreset.c arm_trigger_irq.c arm_udelay.c +CMN_CSRCS += arm_unblocktask.c arm_usestack.c arm_vfork.c arm_switchcontext.c +CMN_CSRCS += arm_puts.c + +# Configuration-dependent common files + +ifeq ($(CONFIG_ARMV8M_STACKCHECK),y) +CMN_CSRCS += arm_stackcheck.c +endif + +ifeq ($(CONFIG_ARMV8M_LAZYFPU),y) +CMN_ASRCS += arm_lazyexception.S +else +CMN_ASRCS += arm_exception.S +endif +CMN_CSRCS += arm_vectors.c + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += arm_fpu.S +CMN_CSRCS += arm_copyarmstate.c +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += arm_ramvec_initialize.c arm_ramvec_attach.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c +CMN_CSRCS += arm_pthread_exit.c +CMN_CSRCS += arm_signal_dispatch.c +CMN_UASRCS += arm_signal_handler.S +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += arm_checkstack.c +endif + +# Required STM32U5 files + +CHIP_ASRCS = +CHIP_CSRCS = stm32_allocateheap.c stm32_exti_gpio.c stm32_gpio.c +CHIP_CSRCS += stm32_irq.c stm32_lowputc.c stm32_rcc.c +CHIP_CSRCS += stm32_serial.c stm32_start.c stm32_waste.c stm32_uid.c +CHIP_CSRCS += stm32_spi.c stm32_lse.c stm32_lsi.c +CHIP_CSRCS += stm32_pwr.c stm32_tim.c stm32_flash.c stm32_timerisr.c + +ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) +CHIP_CSRCS += stm32_idle.c +endif + +ifeq ($(CONFIG_TIMER),y) +CHIP_CSRCS += stm32_tim_lowerhalf.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += stm32_userspace.c stm32_mpuinit.c +endif + +ifeq ($(CONFIG_DEBUG_FEATURES),y) +CHIP_CSRCS += stm32_dumpgpio.c +endif + +# Required chip type specific files + +ifeq ($(CONFIG_STM32U5_STM32U585XX),y) +CHIP_CSRCS += stm32u585xx_rcc.c +endif diff --git a/arch/arm/src/stm32u5/README.txt b/arch/arm/src/stm32u5/README.txt new file mode 100644 index 0000000000..4fc5b10b2f --- /dev/null +++ b/arch/arm/src/stm32u5/README.txt @@ -0,0 +1,22 @@ +This is a port of NuttX to the STM32U5 Family + +Used development board is the B-U585I-IOT02A + +Most code is copied and adapted from the STM32L5 port. + +The only supported STM32U5 family currently is: + +----------------------------------------------------------------- +| NuttX config | Manual | Chips +| STM32U5 | RM0456 | STM32U575xx and STM32U585xx +------------------------------------------------------------------ + +TODO list +--------- + +Extensive testing. Only initial sniff tests have been done. +A prober TODO list should be generated. + +References +---------- +[RM0456] STMicroelectronics, STM32U575/585 Arm(R)-based 32-bit MCUs, Rev 2 diff --git a/arch/arm/src/stm32u5/chip.h b/arch/arm/src/stm32u5/chip.h new file mode 100644 index 0000000000..6a30de2efe --- /dev/null +++ b/arch/arm/src/stm32u5/chip.h @@ -0,0 +1,51 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/chip.h + * + * 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_STM32U5_CHIP_H +#define __ARCH_ARM_SRC_STM32U5_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/stm32_pinmap.h" +#include "hardware/stm32_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/stm32u5/chip.h header file. + */ + +#define ARMV8M_PERIPHERAL_INTERRUPTS STM32_IRQ_NEXTINTS + +#endif /* __ARCH_ARM_SRC_STM32U5_CHIP_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_exti.h b/arch/arm/src/stm32u5/hardware/stm32_exti.h new file mode 100644 index 0000000000..3812bf7788 --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_exti.h @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_exti.h + * + * 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_STM32U5_HARDWARE_STM32_EXTI_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_EXTI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_EXTI_RTSR1_OFFSET 0x0000 /* Rising Trigger Selection 1 */ +#define STM32_EXTI_FTSR1_OFFSET 0x0004 /* Falling Trigger Selection 1 */ +#define STM32_EXTI_SWIER1_OFFSET 0x0008 /* Software Interrupt Event 1 */ +#define STM32_EXTI_RPR1_OFFSET 0x000c /* Rising Edge Pending 1 */ +#define STM32_EXTI_FPR1_OFFSET 0x0010 /* Falling Edge Pending 1 */ +#define STM32_EXTI_SECCFGR1_OFFSET 0x0014 /* Security Configuration 1 */ +#define STM32_EXTI_PRIVCFGR1_OFFSET 0x0018 /* Privilege Configuration 1 */ +#define STM32_EXTI_RTSR2_OFFSET 0x0020 /* Rising Trigger Selection 2 */ +#define STM32_EXTI_FTSR2_OFFSET 0x0024 /* Falling Trigger Selection 2 */ +#define STM32_EXTI_SWIER2_OFFSET 0x0028 /* Software Interrupt Event 2 */ +#define STM32_EXTI_RPR2_OFFSET 0x002c /* Rising Edge Pending 2 */ +#define STM32_EXTI_FPR2_OFFSET 0x0030 /* Falling Edge Pending 2 */ +#define STM32_EXTI_SECCFGR2_OFFSET 0x0034 /* Security Configuration 2 */ +#define STM32_EXTI_PRIVCFGR2_OFFSET 0x0038 /* Privilege Configuration 2 */ +#define STM32_EXTI_EXTICR1_OFFSET 0x0060 /* External Interrupt Selection 1 */ +#define STM32_EXTI_EXTICR2_OFFSET 0x0060 /* External Interrupt Selection 2 */ +#define STM32_EXTI_EXTICR3_OFFSET 0x0060 /* External Interrupt Selection 3 */ +#define STM32_EXTI_EXTICR4_OFFSET 0x0060 /* External Interrupt Selection 4 */ +#define STM32_EXTI_LOCKR_OFFSET 0x0070 /* Lock */ +#define STM32_EXTI_IMR1_OFFSET 0x0080 /* CPU Wakeup with Interrupt Mask 1 */ +#define STM32_EXTI_EMR1_OFFSET 0x0084 /* CPU Wakeup with Event Mask 1 */ +#define STM32_EXTI_IMR2_OFFSET 0x0090 /* CPU Wakeup with Interrupt Mask 2 */ +#define STM32_EXTI_EMR2_OFFSET 0x0094 /* CPU Wakeup with Event Mask 2 */ + +/* Register Addresses *******************************************************/ + +#define STM32_EXTI_RTSR1 (STM32_EXTI_BASE + STM32_EXTI_RTSR1_OFFSET) +#define STM32_EXTI_FTSR1 (STM32_EXTI_BASE + STM32_EXTI_FTSR1_OFFSET) +#define STM32_EXTI_SWIER1 (STM32_EXTI_BASE + STM32_EXTI_SWIER1_OFFSET) +#define STM32_EXTI_RPR1 (STM32_EXTI_BASE + STM32_EXTI_RPR1_OFFSET) +#define STM32_EXTI_FPR1 (STM32_EXTI_BASE + STM32_EXTI_FPR1_OFFSET) +#define STM32_EXTI_SECCFGR1 (STM32_EXTI_BASE + STM32_EXTI_SECCFGR1_OFFSET) +#define STM32_EXTI_PRIVCFGR1 (STM32_EXTI_BASE + STM32_EXTI_PRIVCFGR1_OFFSET) +#define STM32_EXTI_RTSR2 (STM32_EXTI_BASE + STM32_EXTI_RTSR2_OFFSET) +#define STM32_EXTI_FTSR2 (STM32_EXTI_BASE + STM32_EXTI_FTSR2_OFFSET) +#define STM32_EXTI_SWIER2 (STM32_EXTI_BASE + STM32_EXTI_SWIER2_OFFSET) +#define STM32_EXTI_RPR2 (STM32_EXTI_BASE + STM32_EXTI_RPR2_OFFSET) +#define STM32_EXTI_FPR2 (STM32_EXTI_BASE + STM32_EXTI_FPR2_OFFSET) +#define STM32_EXTI_SECCFGR2 (STM32_EXTI_BASE + STM32_EXTI_SECCFGR2_OFFSET) +#define STM32_EXTI_PRIVCFGR2 (STM32_EXTI_BASE + STM32_EXTI_PRIVCFGR2_OFFSET) +#define STM32_EXTI_EXTICR1 (STM32_EXTI_BASE + STM32_EXTI_EXTICR1_OFFSET) +#define STM32_EXTI_EXTICR2 (STM32_EXTI_BASE + STM32_EXTI_EXTICR2_OFFSET) +#define STM32_EXTI_EXTICR3 (STM32_EXTI_BASE + STM32_EXTI_EXTICR3_OFFSET) +#define STM32_EXTI_EXTICR4 (STM32_EXTI_BASE + STM32_EXTI_EXTICR4_OFFSET) +#define STM32_EXTI_LOCKR (STM32_EXTI_BASE + STM32_EXTI_LOCKR_OFFSET) +#define STM32_EXTI_IMR1 (STM32_EXTI_BASE + STM32_EXTI_IMR1_OFFSET) +#define STM32_EXTI_EMR1 (STM32_EXTI_BASE + STM32_EXTI_EMR1_OFFSET) +#define STM32_EXTI_IMR2 (STM32_EXTI_BASE + STM32_EXTI_IMR2_OFFSET) +#define STM32_EXTI_EMR2 (STM32_EXTI_BASE + STM32_EXTI_EMR2_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* EXTI lines > 15 are associated with internal devices: */ + +#define EXTI1_PVD (1 << 16) /* EXTI line 16: PVD output */ +#define EXTI1_RTC (1 << 17) /* EXTI line 17: RTC */ +#define EXTI1_RTC_SECURE (1 << 18) /* EXTI line 18: RTC secure */ +#define EXTI1_TAMP (1 << 19) /* EXTI line 19: TAMP */ +#define EXTI1_TAMP_SECURE (1 << 20) /* EXTI line 20: TAMP secure */ +#define EXTI1_COMP1 (1 << 21) /* EXTI line 21: COMP1 output */ +#define EXTI1_COMP2 (1 << 22) /* EXTI line 22: COMP2 output */ +#define EXTI1_I2C1 (1 << 23) /* EXTI line 23: I2C1 wakeup */ +#define EXTI1_I2C2 (1 << 24) /* EXTI line 24: I2C2 wakeup */ +#define EXTI1_I2C3 (1 << 25) /* EXTI line 25: I2C3 wakeup */ +#define EXTI1_USART1 (1 << 26) /* EXTI line 26: USART1 wakeup */ +#define EXTI1_USART2 (1 << 27) /* EXTI line 27: USART2 wakeup */ +#define EXTI1_USART3 (1 << 28) /* EXTI line 28: USART3 wakeup */ +#define EXTI1_USART4 (1 << 29) /* EXTI line 29: USART4 wakeup */ +#define EXTI1_USART5 (1 << 30) /* EXTI line 30: USART5 wakeup */ +#define EXTI1_LPUART1 (1 << 31) /* EXTI line 31: LPUART1 wakeup */ +#define EXTI2_LPTIM1 (1 << 0) /* EXTI line 32: LPTIM1 */ +#define EXTI2_LPTIM2 (1 << 1) /* EXTI line 33: LPTIM2 */ +#define EXTI2_USBFS (1 << 2) /* EXTI line 34: USB FS wakeup */ +#define EXTI2_PVM1 (1 << 3) /* EXTI line 35: PVM1 wakeup */ +#define EXTI2_PVM2 (1 << 4) /* EXTI line 36: PVM2 wakeup */ +#define EXTI2_PVM3 (1 << 5) /* EXTI line 37: PVM3 wakeup */ +#define EXTI2_PVM4 (1 << 6) /* EXTI line 38: PVM4 wakeup */ +#define EXTI2_RSVD (1 << 7) /* EXTI line 39: reserved */ +#define EXTI2_I2C4 (1 << 8) /* EXTI line 40: I2C4 wakeup */ +#define EXTI2_UCPD1 (1 << 9) /* EXTI line 41: UCPD1 wakeup */ +#define EXTI2_LPTIM3 (1 << 10) /* EXTI line 42: LPTIM3 wakeup */ + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_EXTI_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_flash.h b/arch/arm/src/stm32u5/hardware/stm32_flash.h new file mode 100644 index 0000000000..60da5d5742 --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_flash.h @@ -0,0 +1,305 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_flash.h + * + * 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_STM32U5_HARDWARE_STM32_FLASH_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_FLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Flash size is known from the chip selection: + * + * When CONFIG_STM32U5_FLASH_OVERRIDE_DEFAULT is set the + * CONFIG_STM32U5_FLASH_CONFIG_x selects the default FLASH size based on + * the chip part number. This value can be overridden with + * CONFIG_STM32U5_FLASH_OVERRIDE_x + * + * Parts STM32U585 and STM32U575 have 2048Kb of FLASH + */ + +#if !defined(CONFIG_STM32U5_FLASH_OVERRIDE_DEFAULT) && \ + !defined(CONFIG_STM32U5_FLASH_OVERRIDE_C) && \ + !defined(CONFIG_STM32U5_FLASH_OVERRIDE_E) && \ + !defined(CONFIG_STM32U5_FLASH_CONFIG_C) && \ + !defined(CONFIG_STM32U5_FLASH_CONFIG_E) +# define CONFIG_STM32U5_FLASH_OVERRIDE_E +# warning "Flash size not defined defaulting to 512KiB (E)" +#endif + +/* Override of the Flash has been chosen */ + +#if !defined(CONFIG_STM32U5_FLASH_OVERRIDE_DEFAULT) +# undef CONFIG_STM32U5_FLASH_CONFIG_C +# undef CONFIG_STM32U5_FLASH_CONFIG_E +# if defined(CONFIG_STM32U5_FLASH_OVERRIDE_C) +# define CONFIG_STM32U5_FLASH_CONFIG_C +# elif defined(CONFIG_STM32U5_FLASH_OVERRIDE_E) +# define CONFIG_STM32U5_FLASH_CONFIG_E +# endif +#endif + +/* Define the valid configuration */ + +#if defined(CONFIG_STM32U5_FLASH_CONFIG_I) /* 2048 kB */ +# define STM32_FLASH_NPAGES 256 +# define STM32_FLASH_PAGESIZE 8192 +#else +# error "unknown flash configuration!" +#endif + +#ifdef STM32_FLASH_PAGESIZE +# define STM32_FLASH_SIZE (STM32_FLASH_NPAGES * STM32_FLASH_PAGESIZE) +#endif + +/* Register Offsets *********************************************************/ + +#define STM32_FLASH_ACR_OFFSET 0x0000 +#define STM32_FLASH_NSKEYR_OFFSET 0x0008 +#define STM32_FLASH_SECKEYR_OFFSET 0x000c +#define STM32_FLASH_OPTKEYR_OFFSET 0x0010 +#define STM32_FLASH_PDKEY1R_OFFSET 0x0018 +#define STM32_FLASH_PDKEY2R_OFFSET 0x001c +#define STM32_FLASH_NSSR_OFFSET 0x0020 +#define STM32_FLASH_SECSR_OFFSET 0x0024 +#define STM32_FLASH_NSCR_OFFSET 0x0028 +#define STM32_FLASH_SECCR_OFFSET 0x002c +#define STM32_FLASH_ECCR_OFFSET 0x0030 +#define STM32_FLASH_OPSR_OFFSET 0x0034 +#define STM32_FLASH_OPTR_OFFSET 0x0040 +#define STM32_FLASH_NSBOOTADDR0R_OFFSET 0x0044 +#define STM32_FLASH_NSBOOTADDR1R_OFFSET 0x0048 +#define STM32_FLASH_SECBOOTADDR0R_OFFSET 0x004c +#define STM32_FLASH_SECWM1R1_OFFSET 0x0050 +#define STM32_FLASH_SECWM1R2_OFFSET 0x0054 +#define STM32_FLASH_WRP1AR_OFFSET 0x0058 +#define STM32_FLASH_WRP1BR_OFFSET 0x005c +#define STM32_FLASH_SECWM2R1_OFFSET 0x0060 +#define STM32_FLASH_SECWM2R2_OFFSET 0x0064 +#define STM32_FLASH_WRP2AR_OFFSET 0x0068 +#define STM32_FLASH_WRP2BR_OFFSET 0x006c +#define STM32_FLASH_OEM1KEYR1_OFFSET 0x0070 +#define STM32_FLASH_OEM1KEYR2_OFFSET 0x0074 +#define STM32_FLASH_OEM2KEYR1_OFFSET 0x0078 +#define STM32_FLASH_OEM2KEYR2_OFFSET 0x007c +#define STM32_FLASH_SECBB1R1_OFFSET 0x0080 +#define STM32_FLASH_SECBB1R2_OFFSET 0x0084 +#define STM32_FLASH_SECBB1R3_OFFSET 0x0088 +#define STM32_FLASH_SECBB1R4_OFFSET 0x008c +#define STM32_FLASH_SECBB2R1_OFFSET 0x00a0 +#define STM32_FLASH_SECBB2R2_OFFSET 0x00a4 +#define STM32_FLASH_SECBB2R3_OFFSET 0x00a8 +#define STM32_FLASH_SECBB2R4_OFFSET 0x00ac +#define STM32_FLASH_SECHDPCR_OFFSET 0x00c0 +#define STM32_FLASH_PRIVCFGR_OFFSET 0x00c4 +#define STM32_FLASH_PRIVBB1R1_OFFSET 0x00d0 +#define STM32_FLASH_PRIVBB1R2_OFFSET 0x00d4 +#define STM32_FLASH_PRIVBB1R3_OFFSET 0x00d8 +#define STM32_FLASH_PRIVBB1R4_OFFSET 0x00dc +#define STM32_FLASH_PRIVBB2R1_OFFSET 0x00f0 +#define STM32_FLASH_PRIVBB2R2_OFFSET 0x00f4 +#define STM32_FLASH_PRIVBB2R3_OFFSET 0x00f8 +#define STM32_FLASH_PRIVBB2R4_OFFSET 0x00fc + +/* Register Addresses *******************************************************/ + +#define STM32_FLASH_ACR (STM32_FLASHIF_BASE + STM32_FLASH_ACR_OFFSET) +#define STM32_FLASH_NSKEYR (STM32_FLASHIF_BASE + STM32_FLASH_NSKEYR_OFFSET) +#define STM32_FLASH_SECKEYR (STM32_FLASHIF_BASE + STM32_FLASH_SECKEYR_OFFSET) +#define STM32_FLASH_OPTKEYR (STM32_FLASHIF_BASE + STM32_FLASH_OPTKEYR_OFFSET) +#define STM32_FLASH_PDKEY1R (STM32_FLASHIF_BASE + STM32_FLASH_PDKEY1R_OFFSET) +#define STM32_FLASH_PDKEY2R (STM32_FLASHIF_BASE + STM32_FLASH_PDKEY2R_OFFSET) +#define STM32_FLASH_NSSR (STM32_FLASHIF_BASE + STM32_FLASH_NSSR_OFFSET) +#define STM32_FLASH_SECSR (STM32_FLASHIF_BASE + STM32_FLASH_SECSR_OFFSET) +#define STM32_FLASH_NSCR (STM32_FLASHIF_BASE + STM32_FLASH_NSCR_OFFSET) +#define STM32_FLASH_SECCR (STM32_FLASHIF_BASE + STM32_FLASH_SECCR_OFFSET) +#define STM32_FLASH_ECCR (STM32_FLASHIF_BASE + STM32_FLASH_ECCR_OFFSET) +#define STM32_FLASH_OPSR (STM32_FLASHIF_BASE + STM32_FLASH_OPSR_OFFSET) +#define STM32_FLASH_OPTR (STM32_FLASHIF_BASE + STM32_FLASH_OPTR_OFFSET) +#define STM32_FLASH_NSBOOTADDR0R (STM32_FLASHIF_BASE + STM32_FLASH_NSBOOTADDR0R_OFFSET) +#define STM32_FLASH_NSBOOTADDR1R (STM32_FLASHIF_BASE + STM32_FLASH_NSBOOTADDR1R_OFFSET) +#define STM32_FLASH_SECBOOTADDR0R (STM32_FLASHIF_BASE + STM32_FLASH_SECBOOTADDR0R_OFFSET) +#define STM32_FLASH_SECWM1R1 (STM32_FLASHIF_BASE + STM32_FLASH_SECWM1R1_OFFSET) +#define STM32_FLASH_SECWM1R2 (STM32_FLASHIF_BASE + STM32_FLASH_SECWM1R2_OFFSET) +#define STM32_FLASH_WRP1AR (STM32_FLASHIF_BASE + STM32_FLASH_WRP1AR_OFFSET) +#define STM32_FLASH_WRP1BR (STM32_FLASHIF_BASE + STM32_FLASH_WRP1BR_OFFSET) +#define STM32_FLASH_SECWM2R1 (STM32_FLASHIF_BASE + STM32_FLASH_SECWM2R1_OFFSET) +#define STM32_FLASH_SECWM2R2 (STM32_FLASHIF_BASE + STM32_FLASH_SECWM2R2_OFFSET) +#define STM32_FLASH_WRP2AR (STM32_FLASHIF_BASE + STM32_FLASH_WRP2AR_OFFSET) +#define STM32_FLASH_WRP2BR (STM32_FLASHIF_BASE + STM32_FLASH_WRP2BR_OFFSET) +#define STM32_FLASH_OEM1KEYR1 (STM32_FLASHIF_BASE + STM32_FLASH_OEM1KEYR1_OFFSET) +#define STM32_FLASH_OEM1KEYR2 (STM32_FLASHIF_BASE + STM32_FLASH_OEM1KEYR2_OFFSET) +#define STM32_FLASH_OEM2KEYR1 (STM32_FLASHIF_BASE + STM32_FLASH_OEM2KEYR1_OFFSET) +#define STM32_FLASH_OEM2KEYR2 (STM32_FLASHIF_BASE + STM32_FLASH_OEM2KEYR2_OFFSET) +#define STM32_FLASH_SECBB1R1 (STM32_FLASHIF_BASE + STM32_FLASH_SECBB1R1_OFFSET) +#define STM32_FLASH_SECBB1R2 (STM32_FLASHIF_BASE + STM32_FLASH_SECBB1R2_OFFSET) +#define STM32_FLASH_SECBB1R3 (STM32_FLASHIF_BASE + STM32_FLASH_SECBB1R3_OFFSET) +#define STM32_FLASH_SECBB1R4 (STM32_FLASHIF_BASE + STM32_FLASH_SECBB1R4_OFFSET) +#define STM32_FLASH_SECBB2R1 (STM32_FLASHIF_BASE + STM32_FLASH_SECBB2R1_OFFSET) +#define STM32_FLASH_SECBB2R2 (STM32_FLASHIF_BASE + STM32_FLASH_SECBB2R2_OFFSET) +#define STM32_FLASH_SECBB2R3 (STM32_FLASHIF_BASE + STM32_FLASH_SECBB2R3_OFFSET) +#define STM32_FLASH_SECBB2R4 (STM32_FLASHIF_BASE + STM32_FLASH_SECBB2R4_OFFSET) +#define STM32_FLASH_SECHDPCR (STM32_FLASHIF_BASE + STM32_FLASH_SECHDPCR_OFFSET) +#define STM32_FLASH_PRIVCFGR (STM32_FLASHIF_BASE + STM32_FLASH_PRIVCFGR_OFFSET) +#define STM32_FLASH_PRIVBB1R1 (STM32_FLASHIF_BASE + STM32_FLASH_PRIVBB1R1_OFFSET) +#define STM32_FLASH_PRIVBB1R2 (STM32_FLASHIF_BASE + STM32_FLASH_PRIVBB1R2_OFFSET) +#define STM32_FLASH_PRIVBB1R3 (STM32_FLASHIF_BASE + STM32_FLASH_PRIVBB1R3_OFFSET) +#define STM32_FLASH_PRIVBB1R4 (STM32_FLASHIF_BASE + STM32_FLASH_PRIVBB1R4_OFFSET) +#define STM32_FLASH_PRIVBB2R1 (STM32_FLASHIF_BASE + STM32_FLASH_PRIVBB2R1_OFFSET) +#define STM32_FLASH_PRIVBB2R2 (STM32_FLASHIF_BASE + STM32_FLASH_PRIVBB2R2_OFFSET) +#define STM32_FLASH_PRIVBB2R3 (STM32_FLASHIF_BASE + STM32_FLASH_PRIVBB2R3_OFFSET) +#define STM32_FLASH_PRIVBB2R4 (STM32_FLASHIF_BASE + STM32_FLASH_PRIVBB2R4_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Flash Access Control Register (ACR) */ + +#define FLASH_ACR_LATENCY_SHIFT (0) +#define FLASH_ACR_LATENCY_MASK (0xF << FLASH_ACR_LATENCY_SHIFT) +# define FLASH_ACR_LATENCY(n) ((n) << FLASH_ACR_LATENCY_SHIFT) /* Latency */ +# define FLASH_ACR_LATENCY_0 ( 0 << FLASH_ACR_LATENCY_SHIFT) /* 0000: Zero wait states */ +# define FLASH_ACR_LATENCY_1 ( 1 << FLASH_ACR_LATENCY_SHIFT) /* 0001: One wait state */ +# define FLASH_ACR_LATENCY_2 ( 2 << FLASH_ACR_LATENCY_SHIFT) /* 0010: Two wait states */ +# define FLASH_ACR_LATENCY_3 ( 3 << FLASH_ACR_LATENCY_SHIFT) /* 0011: Three wait states */ +# define FLASH_ACR_LATENCY_4 ( 4 << FLASH_ACR_LATENCY_SHIFT) /* 0100: Four wait states */ +# define FLASH_ACR_LATENCY_5 ( 5 << FLASH_ACR_LATENCY_SHIFT) /* 0101: Five wait states */ +# define FLASH_ACR_LATENCY_6 ( 6 << FLASH_ACR_LATENCY_SHIFT) /* 0110: Six wait states */ +# define FLASH_ACR_LATENCY_7 ( 7 << FLASH_ACR_LATENCY_SHIFT) /* 0111: Seven wait state */ +# define FLASH_ACR_LATENCY_8 ( 8 << FLASH_ACR_LATENCY_SHIFT) /* 1000: Eight wait states */ +# define FLASH_ACR_LATENCY_9 ( 9 << FLASH_ACR_LATENCY_SHIFT) /* 1001: Nine wait states */ +# define FLASH_ACR_LATENCY_10 (10 << FLASH_ACR_LATENCY_SHIFT) /* 1010: Ten wait states */ +# define FLASH_ACR_LATENCY_11 (11 << FLASH_ACR_LATENCY_SHIFT) /* 1011: Eleven wait states */ +# define FLASH_ACR_LATENCY_12 (12 << FLASH_ACR_LATENCY_SHIFT) /* 1100: Twelve wait states */ +# define FLASH_ACR_LATENCY_13 (13 << FLASH_ACR_LATENCY_SHIFT) /* 1101: Thirteen wait state */ +# define FLASH_ACR_LATENCY_14 (14 << FLASH_ACR_LATENCY_SHIFT) /* 1110: Fourteen states */ +# define FLASH_ACR_LATENCY_15 (15 << FLASH_ACR_LATENCY_SHIFT) /* 1111: Fifteen wait states */ +#define FLASH_ACR_PRFTEN (1 << 8) /* Bit 8: Prefetch enable */ +#define FLASH_ACR_LPRM (1 << 11) /* Bit 11: Low-power read mode */ +#define FLASH_ACR_PDREQ1 (1 << 12) /* Bit 12: Bank 1 power-down mode request */ +#define FLASH_ACR_PDREQ2 (1 << 13) /* Bit 13: Bank 2 power-down mode request */ +#define FLASH_ACR_SLEEP_PD (1 << 14) /* Bit 14: Flash mode during Sleep */ + +/* Flash non-secure status register (NSSR) */ + +#define FLASH_NSSR_EOP (1 << 0) /* Bit 0: Non-secure end of operation */ +#define FLASH_NSSR_OPERR (1 << 1) /* Bit 1: Non-secure peration error */ +#define FLASH_NSSR_PROGERR (1 << 3) /* Bit 3: Non-secure programming error */ +#define FLASH_NSSR_WRPERR (1 << 4) /* Bit 4: Non-secure write protection error */ +#define FLASH_NSSR_PGAERR (1 << 5) /* Bit 5: Non-secure rogramming alignment error */ +#define FLASH_NSSR_SIZERR (1 << 6) /* Bit 6: Non-secure size error */ +#define FLASH_NSSR_PGSERR (1 << 7) /* Bit 7: Non-secure programming sequence error */ +#define FLASH_NSSR_OPTWERR (1 << 13) /* Bit 13: Option write error */ +#define FLASH_NSSR_BSY (1 << 16) /* Bit 16: Non-secure busy */ +#define FLASH_NSSR_WDW (1 << 17) /* Bit 17: Non-secure wait data to write */ +#define FLASH_NSSR_OEM1LOCK (1 << 18) /* Bit 18: OEM1 lock */ +#define FLASH_NSSR_OEM2LOCK (1 << 19) /* Bit 19: OEM2 lock */ +#define FLASH_NSSR_PD1 (1 << 20) /* Bit 20: Bank 1 in power-down mode */ +#define FLASH_NSSR_PD2 (1 << 21) /* Bit 21: Bank 2 in power-down mode */ + +/* Flash non-secure control register (NSCR) */ + +#define FLASH_NSCR_PG (1 << 0) /* Bit 0 : Non-secure programming */ +#define FLASH_NSCR_PER (1 << 1) /* Bit 1 : Non-secure page Erase */ +#define FLASH_NSCR_MER1 (1 << 2) /* Bit 2 : Non-secure bank 1 mass erase */ +#define FLASH_NSCR_PNB_SHIFT (3) /* Bits 3-9: Non-secure page number selection */ +#define FLASH_NSCR_PNB_MASK (0x7F << FLASH_NSCR_PNB_SHIFT) +#define FLASH_NSCR_PNB(n) ((n) << FLASH_NSCR_PNB_SHIFT) /* Page n, n = 0..127 */ +#define FLASH_NSCR_BKER (1 << 11) /* Bit 11: Non-secure bank selection for page erase */ +#define FLASH_NSCR_BWR (1 << 14) /* Bit 14: Non-secure burst write programming mode */ +#define FLASH_NSCR_MER2 (1 << 15) /* Bit 15: Non-secure bank 2 mass erase */ +#define FLASH_NSCR_STRT (1 << 16) /* Bit 16: Non-secure start */ +#define FLASH_NSCR_OPTSTRT (1 << 17) /* Bit 17: Options modification start */ +#define FLASH_NSCR_EOPIE (1 << 24) /* Bit 24: Non-secure end of operation interrupt enable */ +#define FLASH_NSCR_ERRIE (1 << 25) /* Bit 25: Non-secure error interrupt enable */ +#define FLASH_NSCR_OBL_LAUNCH (1 << 27) /* Bit 27: Force the option byte loading */ +#define FLASH_NSCR_OPTLOCK (1 << 30) /* Bit 30: Option Lock */ +#define FLASH_NSCR_LOCK (1 << 31) /* Bit 31: Non-secure lock */ + +/* Flash option register (OPTR) */ + +#define FLASH_OPTR_RDP_SHIFT 0 /* Bits 0-7: Readout protection level */ +#define FLASH_OPTR_RDP_MASK (0xff << FLASH_OPTR_RDP_SHIFT) +#define FLASH_OPTR_RDP_LEVEL_0 (0xaa << FLASH_OPTR_RDP_SHIFT) /* 0xAA: Level 0 (readout protection not active) */ +#define FLASH_OPTR_RDP_LEVEL_0_5 (0x55 << FLASH_OPTR_RDP_SHIFT) /* 0x55: Level 0.5 (readout protection not active, only non-secure debug access is possible) */ +#define FLASH_OPTR_RDP_LEVEL_1 (0x11 << FLASH_OPTR_RDP_SHIFT) /* Others: Level 1 (memories readout protection active) */ +#define FLASH_OPTR_RDP_LEVEL_2 (0xCC << FLASH_OPTR_RDP_SHIFT) /* 0xCC: Level 2 (chip readout protection active) */ +#define FLASH_OPTR_BOR_LEVEL_SHIFT 8 /* Bits 8-10: BOR reset level */ +#define FLASH_OPTR_BOR_LEVEL_MASK (7 << FLASH_OPTR_BOR_LEVEL_SHIFT) +#define FLASH_OPTR_BOR_LEVEL_0 (0 << FLASH_OPTR_BOR_LEVEL_SHIFT) /* 000: BOR level 0 (reset level threshold around 1.7V) */ +#define FLASH_OPTR_BOR_LEVEL_1 (1 << FLASH_OPTR_BOR_LEVEL_SHIFT) /* 001: BOR level 1 (reset level threshold around 2.0V) */ +#define FLASH_OPTR_BOR_LEVEL_2 (2 << FLASH_OPTR_BOR_LEVEL_SHIFT) /* 010: BOR level 2 (reset level threshold around 2.2V) */ +#define FLASH_OPTR_BOR_LEVEL_3 (3 << FLASH_OPTR_BOR_LEVEL_SHIFT) /* 011: BOR level 3 (reset level threshold around 2.5V) */ +#define FLASH_OPTR_BOR_LEVEL_4 (4 << FLASH_OPTR_BOR_LEVEL_SHIFT) /* 100: BOR level 4 (reset level threshold around 2.8V) */ +#define FLASH_OPTR_NRST_STOP (1 << 12) /* Bit 12: Reset generation in Stop mode */ +#define FLASH_OPTR_NRST_STDBY (1 << 13) /* Bit 13: Reset generation in Standby mode */ +#define FLASH_OPTR_NRST_SHDW (1 << 14) /* Bit 14: Reset generation in Shutdown mode */ +#define FLASH_OPTR_SRAM1345_RST (1 << 15) /* Bit 15: SRAM1, SRAM3, SRAM4 and SRAM4 erase upon system reset */ +#define FLASH_OPTR_IWDG_SW (1 << 16) /* Bit 16: Independent watchdog selection */ +#define FLASH_OPTR_IWDG_STOP (1 << 17) /* Bit 17: Independent watchdog counter freeze in Stop mode */ +#define FLASH_OPTR_IWDG_STDBY (1 << 18) /* Bit 18: Independent watchdog counter freeze in Standby mode*/ +#define FLASH_OPTR_WWDG_SW (1 << 19) /* Bit 19: Window watchdog selection */ +#define FLASH_OPTR_SWAP_BANK (1 << 20) /* Bit 20: Swap banks */ +#define FLASH_OPTR_DUALBANK (1 << 21) /* Bit 21: Dual bank on 1-Mbyte flash memory devices */ +#define FLASH_OPTR_BKPRAM_ECC (1 << 22) /* Bit 22: Backup RAM ECC detection and correction enable */ +#define FLASH_OPTR_SRAM3_ECC (1 << 23) /* Bit 23: SRAM3 ECC detection and correction enable */ +#define FLASH_OPTR_SRAM2_ECC (1 << 24) /* Bit 24: SRAM2 ECC detection and correction enable */ +#define FLASH_OPTR_SRAM2_RST (1 << 25) /* Bit 25: SRAM2 Erase when system reset */ +#define FLASH_OPTR_NSWBOOT0 (1 << 26) /* Bit 26: Software BOOT0 */ +#define FLASH_OPTR_NBOOT0 (1 << 27) /* Bit 27: nBOOT0 option bit */ +#define FLASH_OPTR_PA15_PUPEN (1 << 28) /* Bit 28: PA15 pull-up enable */ +#define FLASH_OPTR_IO_VDD_HSLV (1 << 29) /* Bit 29: High-speed IO at low V_DD voltage configuration bit */ +#define FLASH_OPTR_IO_VDDIO2_HSLV (1 << 30) /* Bit 30: High-speed IO at low V_DDIO2 voltage configuration bit */ +#define FLASH_OPTR_TZEN (1 << 31) /* Bit 31: Global TrustZone security enable */ + +#if 0 + +/* Flash ECC Register (ECCR) */ + +#define FLASH_ECCR_ADDR_ECC_SHIFT (0) /* Bits 0-18: ECC fail address */ +#define FLASH_ECCR_ADDR_ECC_MASK (0x07ffff << FLASH_ECCR_ADDR_ECC_SHIFT) +#define FLASH_ECCR_BK_ECC (1 << 21) /* Bit 21: ECC fail bank */ +#define FLASH_ECCR_SYSF_ECC (1 << 22) /* Bit 22: System Flash ECC fail */ +#define FLASH_ECCR_ECCCIE (1 << 24) /* Bit 24: ECC correction interrupt enable */ +#define FLASH_ECCR_ECCC2 (1 << 28) /* Bit 28: ECC2 correction */ +#define FLASH_ECCR_ECCD2 (1 << 29) /* Bit 29: ECC2 detection */ +#define FLASH_ECCR_ECCC (1 << 30) /* Bit 30: ECC correction */ +#define FLASH_ECCR_ECCD (1 << 31) /* Bit 31: ECC detection */ + +#define FLASH_OPTR_BORLEV_SHIFT (8) /* Bits 8-10: BOR reset Level */ +#define FLASH_OPTR_BORLEV_MASK (7 << FLASH_OPTR_BORLEV_SHIFT) +#define FLASH_OPTR_VBOR0 (0 << FLASH_OPTR_BORLEV_SHIFT) /* 000: BOR Level 0 (1.7 V) */ +#define FLASH_OPTR_VBOR1 (1 << FLASH_OPTR_BORLEV_SHIFT) /* 001: BOR Level 1 (2.0 V) */ +#define FLASH_OPTR_VBOR2 (2 << FLASH_OPTR_BORLEV_SHIFT) /* 010: BOR Level 2 (2.2 V) */ +#define FLASH_OPTR_VBOR3 (3 << FLASH_OPTR_BORLEV_SHIFT) /* 011: BOR Level 3 (2.5 V) */ +#define FLASH_OPTR_VBOR4 (4 << FLASH_OPTR_BORLEV_SHIFT) /* 100: BOR Level 4 (2.8 V) */ +#define FLASH_OPTR_RDP_SHIFT (0) /* Bits 0-7: Read Protection Level */ +#define FLASH_OPTR_RDP_MASK (0xFF << FLASH_OPTR_RDP_SHIFT) +#define FLASH_OPTR_RDP_NONE (0xAA << FLASH_OPTR_RDP_SHIFT) +#define FLASH_OPTR_RDP_NSDBG (0x55 << FLASH_OPTR_RDP_SHIFT) +#define FLASH_OPTR_RDP_CHIP (0xCC << FLASH_OPTR_RDP_SHIFT) /* WARNING, CANNOT BE REVERSED !! */ +#endif + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_FLASH_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_gpio.h b/arch/arm/src/stm32u5/hardware/stm32_gpio.h new file mode 100644 index 0000000000..5d67400315 --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_gpio.h @@ -0,0 +1,387 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_gpio.h + * + * 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_STM32U5_HARDWARE_STM32_GPIO_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#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 */ + +/* Register Addresses *******************************************************/ + +#if STM32_NPORTS > 0 +# 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) +#endif + +#if STM32_NPORTS > 1 +# 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) +#endif + +#if STM32_NPORTS > 2 +# 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) +#endif + +#if STM32_NPORTS > 3 +# 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) +#endif + +#if STM32_NPORTS > 4 +# 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) +#endif + +#if STM32_NPORTS > 5 +# 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) +#endif + +#if STM32_NPORTS > 6 +# 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) +#endif + +#if STM32_NPORTS > 7 +# 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) +#endif + +#if STM32_NPORTS > 8 +# define STM32_GPIOI_MODER (STM32_GPIOI_BASE + STM32_GPIO_MODER_OFFSET) +# define STM32_GPIOI_OTYPER (STM32_GPIOI_BASE + STM32_GPIO_OTYPER_OFFSET) +# define STM32_GPIOI_OSPEED (STM32_GPIOI_BASE + STM32_GPIO_OSPEED_OFFSET) +# define STM32_GPIOI_PUPDR (STM32_GPIOI_BASE + STM32_GPIO_PUPDR_OFFSET) +# define STM32_GPIOI_IDR (STM32_GPIOI_BASE + STM32_GPIO_IDR_OFFSET) +# define STM32_GPIOI_ODR (STM32_GPIOI_BASE + STM32_GPIO_ODR_OFFSET) +# define STM32_GPIOI_BSRR (STM32_GPIOI_BASE + STM32_GPIO_BSRR_OFFSET) +# define STM32_GPIOI_LCKR (STM32_GPIOI_BASE + STM32_GPIO_LCKR_OFFSET) +# define STM32_GPIOI_AFRL (STM32_GPIOI_BASE + STM32_GPIO_AFRL_OFFSET) +# define STM32_GPIOI_AFRH (STM32_GPIOI_BASE + STM32_GPIO_AFRH_OFFSET) +# define STM32_GPIOI_BRR (STM32_GPIOI_BASE + STM32_GPIO_BRR_OFFSET) +# define STM32_GPIOI_SECCFGR (STM32_GPIOI_BASE + STM32_GPIO_SECCFGR_OFFSET) +#endif + +/* 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 */ + +#define GPIO_SECCFGR_SET(n) (1 << (n)) + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_GPIO_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_memorymap.h b/arch/arm/src/stm32u5/hardware/stm32_memorymap.h new file mode 100644 index 0000000000..4066608658 --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_memorymap.h @@ -0,0 +1,185 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_memorymap.h + * + * 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_STM32U5_STM32_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32U5_STM32_MEMORYMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* STM32U5XXX Address Blocks ************************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */ +#define STM32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ +#define STM32_FSMC_BASE12 0x60000000 /* 0x60000000-0x7fffffff: 512Mb FSMC bank1&2 block */ +# define STM32_FMC_BANK1 0x60000000 /* 0x60000000-0x6fffffff: 256Mb NOR/SRAM */ +#define STM32_FSMC_BASE34 0x80000000 /* 0x80000000-0x8fffffff: 512Mb FSMC bank3 / QSPI block */ +# define STM32_FMC_BANK3 0x80000000 /* 0x80000000-0x8fffffff: 256Mb NAND FLASH */ +# define STM32_OCTOSPI1_BANK 0x90000000 /* 0x90000000-0x9fffffff: 256Mb QUADSPI */ +#define STM32_CORTEX_BASE 0xE0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M4 block */ + +#define STM32_REGION_MASK 0xF0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32U5_REGION_MASK) == STM32U5_SRAM_BASE) +#define STM32_IS_EXTSRAM(a) ((((uint32_t)(a)) & STM32U5_REGION_MASK) == STM32U5_FMC_BANK1) + +/* Code Base Addresses ******************************************************/ + +#define STM32_BOOT_BASE 0x00000000 /* 0x00000000-0x000fffff: Aliased boot memory */ +#define STM32_FLASH_BASE 0x08000000 /* 0x08000000-0x081fffff: FLASH memory */ +#define STM32_SRAM1_BASE 0x20000000 /* 0x20000000-0x2002ffff: 192k SRAM1 */ +#define STM32_SRAM2_BASE 0x20030000 /* 0x20030000-0x2003ffff: 64k SRAM2 */ +#define STM32_SRAM3_BASE 0x20040000 /* 0x20040000-0x200bffff: 512k SRAM3 */ + +/* System Memory Addresses **************************************************/ + +#define STM32_SYSMEM_UID 0x0BFA0700 /* The 96-bit unique device identifier */ +#define STM32_SYSMEM_FSIZE 0x0BFA07A0 /* Size of Flash memory in Kbytes. */ +#define STM32_SYSMEM_PACKAGE 0x0BFA0500 /* Indicates the device's package type. */ + +/* Peripheral Base Addresses ************************************************/ + +#define STM32_APB1_BASE 0x40000000 /* 0x40000000-0x40012bff: APB1 */ +#define STM32_APB2_BASE 0x40012c00 /* 0x40012c00-0x4001ffff: APB2 */ +#define STM32_AHB1_BASE 0x40020000 /* 0x40020000-0x4201ffff: AHB1 */ +#define STM32_AHB2_BASE 0x42020000 /* 0x42020000-0x460003ff: AHB2 */ +#define STM32_APB3_BASE 0x46000400 /* 0x46000400-0x4601ffff: APB2 */ +#define STM32_AHB3_BASE 0x46020000 /* 0x46020000-0x4fffffff: AHB3 */ + +/* APB1 Base Addresses ******************************************************/ + +#define STM32_TIM2_BASE 0x40000000 +#define STM32_TIM3_BASE 0x40000400 +#define STM32_TIM4_BASE 0x40000800 +#define STM32_TIM5_BASE 0x40000c00 +#define STM32_TIM6_BASE 0x40001000 +#define STM32_TIM7_BASE 0x40001400 +#define STM32_WWDG_BASE 0x40002c00 +#define STM32_IWDG_BASE 0x40003000 +#define STM32_SPI2_BASE 0x40003800 +#define STM32_USART2_BASE 0x40004400 +#define STM32_USART3_BASE 0x40004800 +#define STM32_UART4_BASE 0x40004c00 +#define STM32_UART5_BASE 0x40005000 +#define STM32_I2C1_BASE 0x40005400 +#define STM32_I2C2_BASE 0x40005800 +#define STM32_CRS_BASE 0x40006000 +#define STM32_I2C4_BASE 0x40008400 +#define STM32_LPTIM2_BASE 0x40009400 +#define STM32_FDCAN1_BASE 0x4000a400 +#define STM32_FDCAN_RAM_BASE 0x4000ac00 +#define STM32_UCPD1_BASE 0x4000dc00 + +/* APB2 Base Addresses ******************************************************/ + +#define STM32_TIM1_BASE 0x40012c00 +#define STM32_SPI1_BASE 0x40013000 +#define STM32_TIM8_BASE 0x40013400 +#define STM32_USART1_BASE 0x40013800 +#define STM32_TIM15_BASE 0x40014000 +#define STM32_TIM16_BASE 0x40014400 +#define STM32_TIM17_BASE 0x40014800 +#define STM32_SAI1_BASE 0x40015400 +#define STM32_SAI2_BASE 0x40015800 + +/* AHB1 Base Addresses ******************************************************/ + +#define STM32_GPDMA1_BASE 0x40020000 +#define STM32_CORDIC_BASE 0x40021000 +#define STM32_FMAC_BASE 0x40021400 +#define STM32_FLASHIF_BASE 0x40022000 +#define STM32_CRC_BASE 0x40023000 +#define STM32_TSC_BASE 0x40024000 +#define STM32_MDF1_BASE 0x40025000 +#define STM32_RAMCFG_BASE 0x40026000 +#define STM32_DMA2D_BASE 0x4002b000 +#define STM32_ICACHE_BASE 0x40030400 +#define STM32_DCACHE1_BASE 0x40031400 +#define STM32_GTZC1_TZSC_BASE 0x40032400 +#define STM32_GTZC1_TZIC_BASE 0x40032800 +#define STM32_GTZC1_MPCBB1_BASE 0x40032c00 +#define STM32_GTZC1_MPCBB2_BASE 0x40033000 +#define STM32_GTZC1_MPCBB3_BASE 0x40033400 +#define STM32_BKPSRAM_BASE 0x40036400 + +/* AHB2 Base Addresses ******************************************************/ + +#define STM32_GPIOA_BASE 0x42020000 +#define STM32_GPIOB_BASE 0x42020400 +#define STM32_GPIOC_BASE 0x42020800 +#define STM32_GPIOD_BASE 0x42020c00 +#define STM32_GPIOE_BASE 0x42021000 +#define STM32_GPIOF_BASE 0x42021400 +#define STM32_GPIOG_BASE 0x42021800 +#define STM32_GPIOH_BASE 0x42021c00 +#define STM32_GPIOI_BASE 0x42022000 +#define STM32_ADC1_BASE 0x42028000 +#define STM32_DCMI_BASE 0x4202c000 +#define STM32_PSSI_BASE 0x4202c400 +#define STM32_OTG_FS_BASE 0x42040000 +#define STM32_AES_BASE 0x420c0000 +#define STM32_HASH_BASE 0x420c0400 +#define STM32_RNG_BASE 0x420c0800 +#define STM32_SAES_BASE 0x420c0c00 +#define STM32_PKA_BASE 0x420c2000 +#define STM32_OCTOSPIM_BASE 0x420c4000 +#define STM32_OTFDEC1_BASE 0x420c5000 +#define STM32_OTFDEC2_BASE 0x420c5400 +#define STM32_SDMMC1_BASE 0x420c8000 +#define STM32_DLYBSD1_BASE 0x420c8400 +#define STM32_DLYBSD2_BASE 0x420c8800 +#define STM32_SDMMC2_BASE 0x420c8c00 +#define STM32_DLYBOS1_BASE 0x420cf000 +#define STM32_DLYBOS2_BASE 0x420cf400 +#define STM32_FSMC_BASE 0x420d0400 +#define STM32_OCTOSPI1_BASE 0x420d1400 +#define STM32_OCTOSPI2_BASE 0x420d2400 + +/* APB3 Base Addresses ******************************************************/ + +#define STM32_SYSCFG_BASE 0x46000400 +#define STM32_SPI3_BASE 0x46002000 +#define STM32_LPUART1_BASE 0x46002400 +#define STM32_I2C3_BASE 0x46002c00 +#define STM32_LPTIM1_BASE 0x46004400 +#define STM32_LPTIM3_BASE 0x46004800 +#define STM32_LPTIM4_BASE 0x46004c00 +#define STM32_OPAMP_BASE 0x46005000 +#define STM32_COMP_BASE 0x46005400 +#define STM32_VREFBUF_BASE 0x46007400 +#define STM32_RTC_BASE 0x46007800 +#define STM32_TAMP_BASE 0x46007c00 + +/* AHB3 Base Addresses ******************************************************/ + +#define STM32_LPGPIO1_BASE 0x46020000 +#define STM32_PWR_BASE 0x46020800 +#define STM32_RCC_BASE 0x46020c00 +#define STM32_ADC4_BASE 0x46021000 +#define STM32_DAC1_BASE 0x46021800 +#define STM32_EXTI_BASE 0x46022000 +#define STM32_GTZC2_TZSC_BASE 0x46023000 +#define STM32_GTZC2_TZIC_BASE 0x46023400 +#define STM32_GTZC2_MPCBB4_BASE 0x46023800 +#define STM32_ADF1_BASE 0x46024000 +#define STM32_LPDMA1_BASE 0x46025000 + +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_MEMORYMAP_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_pinmap.h b/arch/arm/src/stm32u5/hardware/stm32_pinmap.h new file mode 100644 index 0000000000..858ab601f7 --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_pinmap.h @@ -0,0 +1,37 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_pinmap.h + * + * 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_STM32U5_HARDWARE_STM32_PINMAP_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_PINMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32U5_STM32U585XX) +# include "hardware/stm32u585xx_pinmap.h" +#else +# error "Unsupported STM32U5 pin map" +#endif + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_PINMAP_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_pwr.h b/arch/arm/src/stm32u5/hardware/stm32_pwr.h new file mode 100644 index 0000000000..ee84924371 --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_pwr.h @@ -0,0 +1,203 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_pwr.h + * + * 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_STM32U5_HARDWARE_STM32_PWR_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_PWR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_PWR_CR1_OFFSET 0x0000 /* PWR control register 1 */ +#define STM32_PWR_CR2_OFFSET 0x0004 /* PWR control register 2 */ +#define STM32_PWR_CR3_OFFSET 0x0008 /* PWR control register 3 */ +#define STM32_PWR_VOSR_OFFSET 0x000c /* PWR voltage scaling register */ +#define STM32_PWR_SVMCR_OFFSET 0x0010 /* PWR supply voltage monitoring control register */ +#define STM32_PWR_WUCR1_OFFSET 0x0014 /* PWR wakeup control register 1 */ +#define STM32_PWR_WUCR2_OFFSET 0x0018 /* PWR wakeup control register 2 */ +#define STM32_PWR_WUCR3_OFFSET 0x001c /* PWR wakeup control register 3 */ +#define STM32_PWR_BDCR1_OFFSET 0x0020 /* PWR Backup domain control register 1 */ +#define STM32_PWR_BDCR2_OFFSET 0x0024 /* PWR Backup domain control register 2 */ +#define STM32_PWR_DBPR_OFFSET 0x0028 /* PWR disable Backup domain register */ +#define STM32_PWR_UCPDR_OFFSET 0x002c /* PWR USB Type-C and Power Delivery register */ +#define STM32_PWR_SECCFGR_OFFSET 0x0030 /* PWR security configuration register */ +#define STM32_PWR_PRIVCFGR_OFFSET 0x0034 /* PWR privilege control register */ +#define STM32_PWR_SR_OFFSET 0x0038 /* PWR status register */ +#define STM32_PWR_SVMSR_OFFSET 0x003c /* PWR supply voltage monitoring register */ +#define STM32_PWR_BDSR_OFFSET 0x0040 /* PWR Backup domain status register */ +#define STM32_PWR_WUSR_OFFSET 0x0044 /* PWR wakeup status register */ +#define STM32_PWR_WUSCR_OFFSET 0x0048 /* PWR wakeup status clear register */ +#define STM32_PWR_APCR_OFFSET 0x004c /* PWR apply pull configuration register */ +#define STM32_PWR_PUCRA_OFFSET 0x0050 /* PWR Port A pull-up control register */ +#define STM32_PWR_PDCRA_OFFSET 0x0054 /* PWR Port A pull-down control register */ +#define STM32_PWR_PUCRB_OFFSET 0x0058 /* PWR Port B pull-up control register */ +#define STM32_PWR_PDCRB_OFFSET 0x005C /* PWR Port B pull-down control register */ +#define STM32_PWR_PUCRC_OFFSET 0x0060 /* PWR Port C pull-up control register */ +#define STM32_PWR_PDCRC_OFFSET 0x0064 /* PWR Port C pull-down control register */ +#define STM32_PWR_PUCRD_OFFSET 0x0068 /* PWR Port D pull-up control register */ +#define STM32_PWR_PDCRD_OFFSET 0x006C /* PWR Port D pull-down control register */ +#define STM32_PWR_PUCRE_OFFSET 0x0070 /* PWR Port E pull-up control register */ +#define STM32_PWR_PDCRE_OFFSET 0x0074 /* PWR Port E pull-down control register */ +#define STM32_PWR_PUCRF_OFFSET 0x0078 /* PWR Port F pull-up control register */ +#define STM32_PWR_PDCRF_OFFSET 0x007C /* PWR Port F pull-down control register */ +#define STM32_PWR_PUCRG_OFFSET 0x0080 /* PWR Port G pull-up control register */ +#define STM32_PWR_PDCRG_OFFSET 0x0084 /* PWR Port G pull-down control register */ +#define STM32_PWR_PUCRH_OFFSET 0x0088 /* PWR Port H pull-up control register */ +#define STM32_PWR_PDCRH_OFFSET 0x008C /* PWR Port H pull-down control register */ +#define STM32_PWR_PUCRI_OFFSET 0x0090 /* PWR Port I pull-up control register */ +#define STM32_PWR_PDCRI_OFFSET 0x0094 /* PWR Port I pull-down control 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_VOSR (STM32_PWR_BASE + STM32_PWR_VOSR_OFFSET) +#define STM32_PWR_SVMCR (STM32_PWR_BASE + STM32_PWR_SVMCR_OFFSET) +#define STM32_PWR_WUCR1 (STM32_PWR_BASE + STM32_PWR_WUCR1_OFFSET) +#define STM32_PWR_WUCR2 (STM32_PWR_BASE + STM32_PWR_WUCR2_OFFSET) +#define STM32_PWR_WUCR3 (STM32_PWR_BASE + STM32_PWR_WUCR3_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_DBPR (STM32_PWR_BASE + STM32_PWR_DBPR_OFFSET) +#define STM32_PWR_UCPDR (STM32_PWR_BASE + STM32_PWR_UCPDR_OFFSET) +#define STM32_PWR_SECCFGR (STM32_PWR_BASE + STM32_PWR_SECCFGR_OFFSET) +#define STM32_PWR_PRIVCFGR (STM32_PWR_BASE + STM32_PWR_PRIVCFGR_OFFSET) +#define STM32_PWR_SR (STM32_PWR_BASE + STM32_PWR_SR_OFFSET) +#define STM32_PWR_SVMSR (STM32_PWR_BASE + STM32_PWR_SVMSR_OFFSET) +#define STM32_PWR_BDSR (STM32_PWR_BASE + STM32_PWR_BDSR_OFFSET) +#define STM32_PWR_WUSR (STM32_PWR_BASE + STM32_PWR_WUSR_OFFSET) +#define STM32_PWR_WUSCR (STM32_PWR_BASE + STM32_PWR_WUSCR_OFFSET) +#define STM32_PWR_APCR (STM32_PWR_BASE + STM32_PWR_APCR_OFFSET) +#define STM32_PWR_PUCRA (STM32_PWR_BASE + STM32_PWR_PUCRA_OFFSET) +#define STM32_PWR_PDCRA (STM32_PWR_BASE + STM32_PWR_PDCRA_OFFSET) +#define STM32_PWR_PUCRB (STM32_PWR_BASE + STM32_PWR_PUCRB_OFFSET) +#define STM32_PWR_PDCRB (STM32_PWR_BASE + STM32_PWR_PDCRB_OFFSET) +#define STM32_PWR_PUCRC (STM32_PWR_BASE + STM32_PWR_PUCRC_OFFSET) +#define STM32_PWR_PDCRC (STM32_PWR_BASE + STM32_PWR_PDCRC_OFFSET) +#define STM32_PWR_PUCRD (STM32_PWR_BASE + STM32_PWR_PUCRD_OFFSET) +#define STM32_PWR_PDCRD (STM32_PWR_BASE + STM32_PWR_PDCRD_OFFSET) +#define STM32_PWR_PUCRE (STM32_PWR_BASE + STM32_PWR_PUCRE_OFFSET) +#define STM32_PWR_PDCRE (STM32_PWR_BASE + STM32_PWR_PDCRE_OFFSET) +#define STM32_PWR_PUCRF (STM32_PWR_BASE + STM32_PWR_PUCRF_OFFSET) +#define STM32_PWR_PDCRF (STM32_PWR_BASE + STM32_PWR_PDCRF_OFFSET) +#define STM32_PWR_PUCRG (STM32_PWR_BASE + STM32_PWR_PUCRG_OFFSET) +#define STM32_PWR_PDCRG (STM32_PWR_BASE + STM32_PWR_PDCRG_OFFSET) +#define STM32_PWR_PUCRH (STM32_PWR_BASE + STM32_PWR_PUCRH_OFFSET) +#define STM32_PWR_PDCRH (STM32_PWR_BASE + STM32_PWR_PDCRH_OFFSET) +#define STM32_PWR_PUCRI (STM32_PWR_BASE + STM32_PWR_PUCRI_OFFSET) +#define STM32_PWR_PDCRI (STM32_PWR_BASE + STM32_PWR_PDCRI_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* PWR control register 1 */ + +#define PWR_CR1_LPMS_SHIFT 0 +#define PWR_CR1_LPMS_MASK (7 << PWR_CR1_LPMS_SHIFT) /* Bits 0-2: Low-power mode selection */ +# define PWR_CR1_LPMS_STOP0 (0 << PWR_CR1_LPMS_SHIFT) /* 000: Stop 0 mode */ +# define PWR_CR1_LPMS_STOP1 (1 << PWR_CR1_LPMS_SHIFT) /* 001: Stop 1 mode */ +# define PWR_CR1_LPMS_STOP2 (2 << PWR_CR1_LPMS_SHIFT) /* 010: Stop 2 mode */ +# define PWR_CR1_LPMS_STOP3 (3 << PWR_CR1_LPMS_SHIFT) /* 011: Stop 3 mode */ +# define PWR_CR1_LPMS_STANDBY (4 << PWR_CR1_LPMS_SHIFT) /* 10x: Standby mode */ +# define PWR_CR1_LPMS_SHUTDOWN (6 << PWR_CR1_LPMS_SHIFT) /* 11x: Shutdown mode */ +#define PWR_CR1_RRSB1 (1 << 5) /* Bit 5: SRAM2 page 1 retention in Stop 3 and Standby mode */ +#define PWR_CR1_RRSB2 (1 << 6) /* Bit 6: SRAM2 page 2 retention in Stop 3 and Standby mode */ +#define PWR_CR1_ULPMEN (1 << 7) /* Bit 7: BOR ultra-low power mode */ +#define PWR_CR1_SRAM1PD (1 << 8) /* Bit 8: SRAM1 power down */ +#define PWR_CR1_SRAM2PD (1 << 9) /* Bit 9: SRAM2 power down */ +#define PWR_CR1_SRAM3PD (1 << 10) /* Bit 10: SRAM3 power down */ +#define PWR_CR1_SRAM4PD (1 << 11) /* Bit 11: SRAM4 power down */ + +/* PWR control register 2 */ + +#define PWR_CR2_SRAM1PDS1 (1 << 0) /* Bit 0: SRAM1 page 1 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM1PDS2 (1 << 1) /* Bit 1: SRAM1 page 2 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM1PDS3 (1 << 2) /* Bit 2: SRAM1 page 3 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM2PDS1 (1 << 4) /* Bit 4: SRAM2 page 1 (8 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM2PDS2 (1 << 5) /* Bit 5: SRAM2 page 2 (56 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM4PDS (1 << 6) /* Bit 6: SRAM4 power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_ICRAMPDS (1 << 8) /* Bit 8: ICACHE SRAM power-down Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_DC1RAMPDS (1 << 9) /* Bit 9: DCACHE1 SRAM power-down Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_DMA2DRAMPDS (1 << 10) /* Bit 10: DMA2D SRAM power-down Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_PRAMPDS (1 << 11) /* Bit 11: FMAC, FDCAN and USB peripherals SRAM power-down Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_PKARAMPDS (1 << 12) /* Bit 12: PKA SRAM power-down Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM4FWU (1 << 13) /* Bit 13: SRAM4 fast wakeup from Stop 0, Stop 1 and Stop 2 modes */ +#define PWR_CR2_FLASHFWU (1 << 14) /* Bit 14: Flash memory fast wakeup from Stop 0, Stop 1 and Stop 2 modes */ +#define PWR_CR2_SRAM3PDS1 (1 << 16) /* Bit 16: SRAM3 page 1 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM3PDS2 (1 << 17) /* Bit 17: SRAM3 page 2 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM3PDS3 (1 << 18) /* Bit 18: SRAM3 page 3 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM3PDS4 (1 << 19) /* Bit 19: SRAM3 page 4 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM3PDS5 (1 << 20) /* Bit 20: SRAM3 page 5 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM3PDS6 (1 << 21) /* Bit 21: SRAM3 page 6 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM3PDS7 (1 << 22) /* Bit 22: SRAM3 page 7 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRAM3PDS8 (1 << 23) /* Bit 23: SRAM3 page 8 (64 Kbytes) power-down in Stop modes (Stop 0, 1, 2, 3) */ +#define PWR_CR2_SRDRUN (1 << 31) /* Bit 31: SmartRun domain in Run mode */ + +/* PWR control register 3 */ + +#define PWR_CR3_REGSEL (1 << 1) /* Bit 1: Regulator selection */ +#define PWR_CR3_REGSEL_LDO 0 +#define PWR_CR3_REGSEL_SMPS PWR_CR3_REGSEL +#define PWR_CR3_FSTEN (1 << 2) /* Bit 2: Fast soft start */ + +/* PWR voltage scaling register */ + +#define PWR_VOSR_BOOSTRDY (1 << 14) /* Bit 14: EPOD booster ready */ +#define PWR_VOSR_VOSRDY (1 << 15) /* Bit 15: Ready bit for V_CORE voltage scaling output selection */ +#define PWR_VOSR_VOS_SHIFT 16 +#define PWR_VOSR_VOS_MASK (3 << PWR_VOSR_VOS_SHIFT) /* Bits 16-17: Voltage scaling range selection */ +#define PWR_VOSR_VOS_RANGE4 (0 << PWR_VOSR_VOS_SHIFT) /* 00: Range 4 (lowest power) */ +#define PWR_VOSR_VOS_RANGE3 (1 << PWR_VOSR_VOS_SHIFT) /* 01: Range 3 */ +#define PWR_VOSR_VOS_RANGE2 (2 << PWR_VOSR_VOS_SHIFT) /* 10: Range 2 */ +#define PWR_VOSR_VOS_RANGE1 (3 << PWR_VOSR_VOS_SHIFT) /* 11: Range 1 (highest frequency) */ +#define PWR_VOSR_BOOSTEN (1 << 18) /* Bit 18: EPOD booster enable */ + +/* PWR Disable backup domain register */ + +#define PWR_DBPR_DBP (1 << 0) /* Bit 0: Disable Backup domain write protection. */ + +/* PWR Supply voltage monitoring status register */ + +#define PWR_SVMSR_REGS (1 << 1) /* Bit 1: Regulator selection */ +#define PWR_SVMSR_REGS_LDO 0 /* 0: LDO selected */ +#define PWR_SVMSR_REGS_SMPS PWR_SVMSR_REGS /* 1: SMPS selected */ +#define PWR_SVMSR_PVDO (1 << 4) /* Bit 4: Programmable voltage detector output */ +#define PWR_SVMSR_ACTVOSRDY (1 << 15) /* Bit 15: Voltage level ready for currenty used VOS */ +#define PWR_SVMSR_ACTVOS_SHIFT 16 +#define PWR_SVMSR_ACTVOS_MASK (3 << PWR_SVMSR_ACTVOS_SHIFT) /* Bits 16-17: VOS currently applied to V_CORE */ +#define PWR_SVMSR_ACTVOS_RANGE4 (0 << PWR_SVMSR_ACTVOS_SHIFT) /* 00: Range 4 (lowest power) */ +#define PWR_SVMSR_ACTVOS_RANGE3 (1 << PWR_SVMSR_ACTVOS_SHIFT) /* 01: Range 3 */ +#define PWR_SVMSR_ACTVOS_RANGE2 (2 << PWR_SVMSR_ACTVOS_SHIFT) /* 10: Range 2 */ +#define PWR_SVMSR_ACTVOS_RANGE1 (3 << PWR_SVMSR_ACTVOS_SHIFT) /* 11: Range 1 (highest frequency) */ +#define PWR_SVMSR_VDDUSBRDY (1 << 24) /* Bit 24: V_DDUSB ready */ +#define PWR_SVMSR_VDDIO2RDY (1 << 25) /* Bit 25: V_DDIO2 ready */ +#define PWR_SVMSR_VDDA1RDY (1 << 26) /* Bit 26: V_DDA is equal or above ~1.6V */ +#define PWR_SVMSR_VDDA2RDY (1 << 27) /* Bit 27: V_DDA is equal or above ~1.8V */ + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_PWR_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_spi.h b/arch/arm/src/stm32u5/hardware/stm32_spi.h new file mode 100644 index 0000000000..6a98c3e13a --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_spi.h @@ -0,0 +1,37 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_spi.h + * + * 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_STM32U5_HARDWARE_STM32_SPI_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32U5_STM32U585XX) +# include "hardware/stm32u585xx_spi.h" +#else +# error "Unsupported STM32 U5 sub family" +#endif + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_SPI_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_syscfg.h b/arch/arm/src/stm32u5/hardware/stm32_syscfg.h new file mode 100644 index 0000000000..342cdc513f --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_syscfg.h @@ -0,0 +1,37 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_syscfg.h + * + * 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_STM32U5_HARDWARE_STM32_SYSCFG_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_SYSCFG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32U5_STM32U585XX) +# include "hardware/stm32u585xx_syscfg.h" +#else +# error "Unsupported STM32U5 chip" +#endif + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_SYSCFG_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_tim.h b/arch/arm/src/stm32u5/hardware/stm32_tim.h new file mode 100644 index 0000000000..86bc60776c --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_tim.h @@ -0,0 +1,1060 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_tim.h + * + * 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_STM32U5_HARDWARE_STM32_TIM_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_TIM_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +/* Basic Timers - TIM6 and TIM7 */ + +#define STM32U5_BTIM_CR1_OFFSET 0x0000 /* Control register 1 (16-bit) */ +#define STM32U5_BTIM_CR2_OFFSET 0x0004 /* Control register 2 (16-bit) */ +#define STM32U5_BTIM_DIER_OFFSET 0x000c /* DMA/Interrupt enable register (16-bit) */ +#define STM32U5_BTIM_SR_OFFSET 0x0010 /* Status register (16-bit) */ +#define STM32U5_BTIM_EGR_OFFSET 0x0014 /* Event generation register (16-bit) */ +#define STM32U5_BTIM_CNT_OFFSET 0x0024 /* Counter (16-bit) */ +#define STM32U5_BTIM_PSC_OFFSET 0x0028 /* Prescaler (16-bit) */ +#define STM32U5_BTIM_ARR_OFFSET 0x002c /* Auto-reload register (16-bit) */ + +/* 16-/32-bit General Timers - TIM2, TIM3, TIM4, TIM5, and TIM15-17. + * TIM3 and 4 are 16-bit. + * TIM2 and 5 are 32-bit. + * TIM15, 16 and 17 are 16-bit. + */ + +#define STM32U5_GTIM_CR1_OFFSET 0x0000 /* Control register 1 (16-bit) */ +#define STM32U5_GTIM_CR2_OFFSET 0x0004 /* Control register 2 (16-bit) */ +#define STM32U5_GTIM_SMCR_OFFSET 0x0008 /* Slave mode control register (16-bit, TIM2-5,15 only) */ +#define STM32U5_GTIM_DIER_OFFSET 0x000c /* DMA/Interrupt enable register (16-bit) */ +#define STM32U5_GTIM_SR_OFFSET 0x0010 /* Status register (16-bit) */ +#define STM32U5_GTIM_EGR_OFFSET 0x0014 /* Event generation register (16-bit) */ +#define STM32U5_GTIM_CCMR1_OFFSET 0x0018 /* Capture/compare mode register 1 (32-bit) */ +#define STM32U5_GTIM_CCMR2_OFFSET 0x001c /* Capture/compare mode register 2 (32-bit, TIM2-5 only) */ +#define STM32U5_GTIM_CCER_OFFSET 0x0020 /* Capture/compare enable register (16-bit) */ +#define STM32U5_GTIM_CNT_OFFSET 0x0024 /* Counter (16-bit or 32-bit TIM2/5) */ +#define STM32U5_GTIM_PSC_OFFSET 0x0028 /* Prescaler (16-bit) */ +#define STM32U5_GTIM_ARR_OFFSET 0x002c /* Auto-reload register (16-bit or 32-bit TIM2/5) */ +#define STM32U5_GTIM_CCR1_OFFSET 0x0034 /* Capture/compare register 1 (16-bit or 32-bit TIM2/5) */ +#define STM32U5_GTIM_CCR2_OFFSET 0x0038 /* Capture/compare register 2 (16-bit TIM2-5,15 only or 32-bit TIM2/5) */ +#define STM32U5_GTIM_CCR3_OFFSET 0x003c /* Capture/compare register 3 (16-bit TIM2-5 only or 32-bit TIM2/5) */ +#define STM32U5_GTIM_CCR4_OFFSET 0x0040 /* Capture/compare register 4 (16-bit TIM2-5 only or 32-bit TIM2/5) */ +#define STM32U5_GTIM_DCR_OFFSET 0x0048 /* DMA control register (16-bit) */ +#define STM32U5_GTIM_DMAR_OFFSET 0x004c /* DMA address for burst mode (16-bit) */ +#define STM32U5_GTIM_OR1_OFFSET 0x0050 /* Option register 1 */ +#define STM32U5_GTIM_OR2_OFFSET 0x0060 /* Option register 2 */ + +/* TIM15, 16, and 17 only. + */ + +#define STM32U5_GTIM_RCR_OFFSET 0x0030 /* Repetition counter register (TIM16/TIM17) */ +#define STM32U5_GTIM_BDTR_OFFSET 0x0044 /* Break and dead-time register (TIM16/TIM17) */ + +/* Advanced Timers - TIM1 and TIM8 */ + +#define STM32U5_ATIM_CR1_OFFSET 0x0000 /* Control register 1 (16-bit) */ +#define STM32U5_ATIM_CR2_OFFSET 0x0004 /* Control register 2 (16-bit*) */ +#define STM32U5_ATIM_SMCR_OFFSET 0x0008 /* Slave mode control register (16-bit) */ +#define STM32U5_ATIM_DIER_OFFSET 0x000c /* DMA/Interrupt enable register (16-bit) */ +#define STM32U5_ATIM_SR_OFFSET 0x0010 /* Status register (16-bit*) */ +#define STM32U5_ATIM_EGR_OFFSET 0x0014 /* Event generation register (16-bit) */ +#define STM32U5_ATIM_CCMR1_OFFSET 0x0018 /* Capture/compare mode register 1 (16-bit*) */ +#define STM32U5_ATIM_CCMR2_OFFSET 0x001c /* Capture/compare mode register 2 (16-bit*) */ +#define STM32U5_ATIM_CCER_OFFSET 0x0020 /* Capture/compare enable register (16-bit*) */ +#define STM32U5_ATIM_CNT_OFFSET 0x0024 /* Counter (16-bit) */ +#define STM32U5_ATIM_PSC_OFFSET 0x0028 /* Prescaler (16-bit) */ +#define STM32U5_ATIM_ARR_OFFSET 0x002c /* Auto-reload register (16-bit) */ +#define STM32U5_ATIM_RCR_OFFSET 0x0030 /* Repetition counter register (16-bit) */ +#define STM32U5_ATIM_CCR1_OFFSET 0x0034 /* Capture/compare register 1 (16-bit) */ +#define STM32U5_ATIM_CCR2_OFFSET 0x0038 /* Capture/compare register 2 (16-bit) */ +#define STM32U5_ATIM_CCR3_OFFSET 0x003c /* Capture/compare register 3 (16-bit) */ +#define STM32U5_ATIM_CCR4_OFFSET 0x0040 /* Capture/compare register 4 (16-bit) */ +#define STM32U5_ATIM_BDTR_OFFSET 0x0044 /* Break and dead-time register (16-bit*) */ +#define STM32U5_ATIM_DCR_OFFSET 0x0048 /* DMA control register (16-bit) */ +#define STM32U5_ATIM_DMAR_OFFSET 0x004c /* DMA address for burst mode (16-bit) */ +#define STM32U5_ATIM_OR1_OFFSET 0x0050 /* Timer option register 1 */ +#define STM32U5_ATIM_CCMR3_OFFSET 0x0054 /* Capture/compare mode register 3 (32-bit) */ +#define STM32U5_ATIM_CCR5_OFFSET 0x0058 /* Capture/compare register 4 (16-bit) */ +#define STM32U5_ATIM_CCR6_OFFSET 0x005c /* Capture/compare register 4 (32-bit) */ +#define STM32U5_ATIM_OR2_OFFSET 0x0050 /* Timer option register 2 */ +#define STM32U5_ATIM_OR3_OFFSET 0x0050 /* Timer option register 3 */ + +/* Register Addresses *******************************************************/ + +/* Advanced Timers - TIM1 and TIM8 */ + +#define STM32U5_TIM1_CR1 (STM32U5_TIM1_BASE + STM32U5_ATIM_CR1_OFFSET) +#define STM32U5_TIM1_CR2 (STM32U5_TIM1_BASE + STM32U5_ATIM_CR2_OFFSET) +#define STM32U5_TIM1_SMCR (STM32U5_TIM1_BASE + STM32U5_ATIM_SMCR_OFFSET) +#define STM32U5_TIM1_DIER (STM32U5_TIM1_BASE + STM32U5_ATIM_DIER_OFFSET) +#define STM32U5_TIM1_SR (STM32U5_TIM1_BASE + STM32U5_ATIM_SR_OFFSET) +#define STM32U5_TIM1_EGR (STM32U5_TIM1_BASE + STM32U5_ATIM_EGR_OFFSET) +#define STM32U5_TIM1_CCMR1 (STM32U5_TIM1_BASE + STM32U5_ATIM_CCMR1_OFFSET) +#define STM32U5_TIM1_CCMR2 (STM32U5_TIM1_BASE + STM32U5_ATIM_CCMR2_OFFSET) +#define STM32U5_TIM1_CCER (STM32U5_TIM1_BASE + STM32U5_ATIM_CCER_OFFSET) +#define STM32U5_TIM1_CNT (STM32U5_TIM1_BASE + STM32U5_ATIM_CNT_OFFSET) +#define STM32U5_TIM1_PSC (STM32U5_TIM1_BASE + STM32U5_ATIM_PSC_OFFSET) +#define STM32U5_TIM1_ARR (STM32U5_TIM1_BASE + STM32U5_ATIM_ARR_OFFSET) +#define STM32U5_TIM1_RCR (STM32U5_TIM1_BASE + STM32U5_ATIM_RCR_OFFSET) +#define STM32U5_TIM1_CCR1 (STM32U5_TIM1_BASE + STM32U5_ATIM_CCR1_OFFSET) +#define STM32U5_TIM1_CCR2 (STM32U5_TIM1_BASE + STM32U5_ATIM_CCR2_OFFSET) +#define STM32U5_TIM1_CCR3 (STM32U5_TIM1_BASE + STM32U5_ATIM_CCR3_OFFSET) +#define STM32U5_TIM1_CCR4 (STM32U5_TIM1_BASE + STM32U5_ATIM_CCR4_OFFSET) +#define STM32U5_TIM1_BDTR (STM32U5_TIM1_BASE + STM32U5_ATIM_BDTR_OFFSET) +#define STM32U5_TIM1_DCR (STM32U5_TIM1_BASE + STM32U5_ATIM_DCR_OFFSET) +#define STM32U5_TIM1_DMAR (STM32U5_TIM1_BASE + STM32U5_ATIM_DMAR_OFFSET) +#define STM32U5_TIM1_OR1 (STM32U5_TIM1_BASE + STM32U5_ATIM_OR1_OFFSET) +#define STM32U5_TIM1_CCMR3 (STM32U5_TIM1_BASE + STM32U5_ATIM_CCMR3_OFFSET) +#define STM32U5_TIM1_CCR5 (STM32U5_TIM1_BASE + STM32U5_ATIM_CCR5_OFFSET) +#define STM32U5_TIM1_CCR6 (STM32U5_TIM1_BASE + STM32U5_ATIM_CCR6_OFFSET) +#define STM32U5_TIM1_OR2 (STM32U5_TIM1_BASE + STM32U5_ATIM_OR2_OFFSET) +#define STM32U5_TIM1_OR3 (STM32U5_TIM1_BASE + STM32U5_ATIM_OR3_OFFSET) + +#define STM32U5_TIM8_CR1 (STM32U5_TIM8_BASE + STM32U5_ATIM_CR1_OFFSET) +#define STM32U5_TIM8_CR2 (STM32U5_TIM8_BASE + STM32U5_ATIM_CR2_OFFSET) +#define STM32U5_TIM8_SMCR (STM32U5_TIM8_BASE + STM32U5_ATIM_SMCR_OFFSET) +#define STM32U5_TIM8_DIER (STM32U5_TIM8_BASE + STM32U5_ATIM_DIER_OFFSET) +#define STM32U5_TIM8_SR (STM32U5_TIM8_BASE + STM32U5_ATIM_SR_OFFSET) +#define STM32U5_TIM8_EGR (STM32U5_TIM8_BASE + STM32U5_ATIM_EGR_OFFSET) +#define STM32U5_TIM8_CCMR1 (STM32U5_TIM8_BASE + STM32U5_ATIM_CCMR1_OFFSET) +#define STM32U5_TIM8_CCMR2 (STM32U5_TIM8_BASE + STM32U5_ATIM_CCMR2_OFFSET) +#define STM32U5_TIM8_CCER (STM32U5_TIM8_BASE + STM32U5_ATIM_CCER_OFFSET) +#define STM32U5_TIM8_CNT (STM32U5_TIM8_BASE + STM32U5_ATIM_CNT_OFFSET) +#define STM32U5_TIM8_PSC (STM32U5_TIM8_BASE + STM32U5_ATIM_PSC_OFFSET) +#define STM32U5_TIM8_ARR (STM32U5_TIM8_BASE + STM32U5_ATIM_ARR_OFFSET) +#define STM32U5_TIM8_RCR (STM32U5_TIM8_BASE + STM32U5_ATIM_RCR_OFFSET) +#define STM32U5_TIM8_CCR1 (STM32U5_TIM8_BASE + STM32U5_ATIM_CCR1_OFFSET) +#define STM32U5_TIM8_CCR2 (STM32U5_TIM8_BASE + STM32U5_ATIM_CCR2_OFFSET) +#define STM32U5_TIM8_CCR3 (STM32U5_TIM8_BASE + STM32U5_ATIM_CCR3_OFFSET) +#define STM32U5_TIM8_CCR4 (STM32U5_TIM8_BASE + STM32U5_ATIM_CCR4_OFFSET) +#define STM32U5_TIM8_BDTR (STM32U5_TIM8_BASE + STM32U5_ATIM_BDTR_OFFSET) +#define STM32U5_TIM8_DCR (STM32U5_TIM8_BASE + STM32U5_ATIM_DCR_OFFSET) +#define STM32U5_TIM8_DMAR (STM32U5_TIM8_BASE + STM32U5_ATIM_DMAR_OFFSET) +#define STM32U5_TIM8_OR1 (STM32U5_TIM8_BASE + STM32U5_ATIM_OR1_OFFSET) +#define STM32U5_TIM8_CCMR3 (STM32U5_TIM8_BASE + STM32U5_ATIM_CCMR3_OFFSET) +#define STM32U5_TIM8_CCR5 (STM32U5_TIM8_BASE + STM32U5_ATIM_CCR5_OFFSET) +#define STM32U5_TIM8_CCR6 (STM32U5_TIM8_BASE + STM32U5_ATIM_CCR6_OFFSET) +#define STM32U5_TIM8_OR2 (STM32U5_TIM8_BASE + STM32U5_ATIM_OR2_OFFSET) +#define STM32U5_TIM8_OR3 (STM32U5_TIM8_BASE + STM32U5_ATIM_OR3_OFFSET) + +/* 16-/32-bit General Timers - TIM2, TIM3, TIM4, TIM5, and TIM15-17. + * TIM3 and 4 are 16-bit. + * TIM2 and 5 are 32-bit. + * TIM15, 16 and 17 are 16-bit. + */ + +#define STM32U5_TIM2_CR1 (STM32U5_TIM2_BASE + STM32U5_GTIM_CR1_OFFSET) +#define STM32U5_TIM2_CR2 (STM32U5_TIM2_BASE + STM32U5_GTIM_CR2_OFFSET) +#define STM32U5_TIM2_SMCR (STM32U5_TIM2_BASE + STM32U5_GTIM_SMCR_OFFSET) +#define STM32U5_TIM2_DIER (STM32U5_TIM2_BASE + STM32U5_GTIM_DIER_OFFSET) +#define STM32U5_TIM2_SR (STM32U5_TIM2_BASE + STM32U5_GTIM_SR_OFFSET) +#define STM32U5_TIM2_EGR (STM32U5_TIM2_BASE + STM32U5_GTIM_EGR_OFFSET) +#define STM32U5_TIM2_CCMR1 (STM32U5_TIM2_BASE + STM32U5_GTIM_CCMR1_OFFSET) +#define STM32U5_TIM2_CCMR2 (STM32U5_TIM2_BASE + STM32U5_GTIM_CCMR2_OFFSET) +#define STM32U5_TIM2_CCER (STM32U5_TIM2_BASE + STM32U5_GTIM_CCER_OFFSET) +#define STM32U5_TIM2_CNT (STM32U5_TIM2_BASE + STM32U5_GTIM_CNT_OFFSET) +#define STM32U5_TIM2_PSC (STM32U5_TIM2_BASE + STM32U5_GTIM_PSC_OFFSET) +#define STM32U5_TIM2_ARR (STM32U5_TIM2_BASE + STM32U5_GTIM_ARR_OFFSET) +#define STM32U5_TIM2_CCR1 (STM32U5_TIM2_BASE + STM32U5_GTIM_CCR1_OFFSET) +#define STM32U5_TIM2_CCR2 (STM32U5_TIM2_BASE + STM32U5_GTIM_CCR2_OFFSET) +#define STM32U5_TIM2_CCR3 (STM32U5_TIM2_BASE + STM32U5_GTIM_CCR3_OFFSET) +#define STM32U5_TIM2_CCR4 (STM32U5_TIM2_BASE + STM32U5_GTIM_CCR4_OFFSET) +#define STM32U5_TIM2_DCR (STM32U5_TIM2_BASE + STM32U5_GTIM_DCR_OFFSET) +#define STM32U5_TIM2_DMAR (STM32U5_TIM2_BASE + STM32U5_GTIM_DMAR_OFFSET) +#define STM32U5_TIM2_OR (STM32U5_TIM2_BASE + STM32U5_GTIM_OR_OFFSET) + +#define STM32U5_TIM3_CR1 (STM32U5_TIM3_BASE + STM32U5_GTIM_CR1_OFFSET) +#define STM32U5_TIM3_CR2 (STM32U5_TIM3_BASE + STM32U5_GTIM_CR2_OFFSET) +#define STM32U5_TIM3_SMCR (STM32U5_TIM3_BASE + STM32U5_GTIM_SMCR_OFFSET) +#define STM32U5_TIM3_DIER (STM32U5_TIM3_BASE + STM32U5_GTIM_DIER_OFFSET) +#define STM32U5_TIM3_SR (STM32U5_TIM3_BASE + STM32U5_GTIM_SR_OFFSET) +#define STM32U5_TIM3_EGR (STM32U5_TIM3_BASE + STM32U5_GTIM_EGR_OFFSET) +#define STM32U5_TIM3_CCMR1 (STM32U5_TIM3_BASE + STM32U5_GTIM_CCMR1_OFFSET) +#define STM32U5_TIM3_CCMR2 (STM32U5_TIM3_BASE + STM32U5_GTIM_CCMR2_OFFSET) +#define STM32U5_TIM3_CCER (STM32U5_TIM3_BASE + STM32U5_GTIM_CCER_OFFSET) +#define STM32U5_TIM3_CNT (STM32U5_TIM3_BASE + STM32U5_GTIM_CNT_OFFSET) +#define STM32U5_TIM3_PSC (STM32U5_TIM3_BASE + STM32U5_GTIM_PSC_OFFSET) +#define STM32U5_TIM3_ARR (STM32U5_TIM3_BASE + STM32U5_GTIM_ARR_OFFSET) +#define STM32U5_TIM3_CCR1 (STM32U5_TIM3_BASE + STM32U5_GTIM_CCR1_OFFSET) +#define STM32U5_TIM3_CCR2 (STM32U5_TIM3_BASE + STM32U5_GTIM_CCR2_OFFSET) +#define STM32U5_TIM3_CCR3 (STM32U5_TIM3_BASE + STM32U5_GTIM_CCR3_OFFSET) +#define STM32U5_TIM3_CCR4 (STM32U5_TIM3_BASE + STM32U5_GTIM_CCR4_OFFSET) +#define STM32U5_TIM3_DCR (STM32U5_TIM3_BASE + STM32U5_GTIM_DCR_OFFSET) +#define STM32U5_TIM3_DMAR (STM32U5_TIM3_BASE + STM32U5_GTIM_DMAR_OFFSET) + +#define STM32U5_TIM4_CR1 (STM32U5_TIM4_BASE + STM32U5_GTIM_CR1_OFFSET) +#define STM32U5_TIM4_CR2 (STM32U5_TIM4_BASE + STM32U5_GTIM_CR2_OFFSET) +#define STM32U5_TIM4_SMCR (STM32U5_TIM4_BASE + STM32U5_GTIM_SMCR_OFFSET) +#define STM32U5_TIM4_DIER (STM32U5_TIM4_BASE + STM32U5_GTIM_DIER_OFFSET) +#define STM32U5_TIM4_SR (STM32U5_TIM4_BASE + STM32U5_GTIM_SR_OFFSET) +#define STM32U5_TIM4_EGR (STM32U5_TIM4_BASE + STM32U5_GTIM_EGR_OFFSET) +#define STM32U5_TIM4_CCMR1 (STM32U5_TIM4_BASE + STM32U5_GTIM_CCMR1_OFFSET) +#define STM32U5_TIM4_CCMR2 (STM32U5_TIM4_BASE + STM32U5_GTIM_CCMR2_OFFSET) +#define STM32U5_TIM4_CCER (STM32U5_TIM4_BASE + STM32U5_GTIM_CCER_OFFSET) +#define STM32U5_TIM4_CNT (STM32U5_TIM4_BASE + STM32U5_GTIM_CNT_OFFSET) +#define STM32U5_TIM4_PSC (STM32U5_TIM4_BASE + STM32U5_GTIM_PSC_OFFSET) +#define STM32U5_TIM4_ARR (STM32U5_TIM4_BASE + STM32U5_GTIM_ARR_OFFSET) +#define STM32U5_TIM4_CCR1 (STM32U5_TIM4_BASE + STM32U5_GTIM_CCR1_OFFSET) +#define STM32U5_TIM4_CCR2 (STM32U5_TIM4_BASE + STM32U5_GTIM_CCR2_OFFSET) +#define STM32U5_TIM4_CCR3 (STM32U5_TIM4_BASE + STM32U5_GTIM_CCR3_OFFSET) +#define STM32U5_TIM4_CCR4 (STM32U5_TIM4_BASE + STM32U5_GTIM_CCR4_OFFSET) +#define STM32U5_TIM4_DCR (STM32U5_TIM4_BASE + STM32U5_GTIM_DCR_OFFSET) +#define STM32U5_TIM4_DMAR (STM32U5_TIM4_BASE + STM32U5_GTIM_DMAR_OFFSET) + +#define STM32U5_TIM5_CR1 (STM32U5_TIM5_BASE + STM32U5_GTIM_CR1_OFFSET) +#define STM32U5_TIM5_CR2 (STM32U5_TIM5_BASE + STM32U5_GTIM_CR2_OFFSET) +#define STM32U5_TIM5_SMCR (STM32U5_TIM5_BASE + STM32U5_GTIM_SMCR_OFFSET) +#define STM32U5_TIM5_DIER (STM32U5_TIM5_BASE + STM32U5_GTIM_DIER_OFFSET) +#define STM32U5_TIM5_SR (STM32U5_TIM5_BASE + STM32U5_GTIM_SR_OFFSET) +#define STM32U5_TIM5_EGR (STM32U5_TIM5_BASE + STM32U5_GTIM_EGR_OFFSET) +#define STM32U5_TIM5_CCMR1 (STM32U5_TIM5_BASE + STM32U5_GTIM_CCMR1_OFFSET) +#define STM32U5_TIM5_CCMR2 (STM32U5_TIM5_BASE + STM32U5_GTIM_CCMR2_OFFSET) +#define STM32U5_TIM5_CCER (STM32U5_TIM5_BASE + STM32U5_GTIM_CCER_OFFSET) +#define STM32U5_TIM5_CNT (STM32U5_TIM5_BASE + STM32U5_GTIM_CNT_OFFSET) +#define STM32U5_TIM5_PSC (STM32U5_TIM5_BASE + STM32U5_GTIM_PSC_OFFSET) +#define STM32U5_TIM5_ARR (STM32U5_TIM5_BASE + STM32U5_GTIM_ARR_OFFSET) +#define STM32U5_TIM5_CCR1 (STM32U5_TIM5_BASE + STM32U5_GTIM_CCR1_OFFSET) +#define STM32U5_TIM5_CCR2 (STM32U5_TIM5_BASE + STM32U5_GTIM_CCR2_OFFSET) +#define STM32U5_TIM5_CCR3 (STM32U5_TIM5_BASE + STM32U5_GTIM_CCR3_OFFSET) +#define STM32U5_TIM5_CCR4 (STM32U5_TIM5_BASE + STM32U5_GTIM_CCR4_OFFSET) +#define STM32U5_TIM5_DCR (STM32U5_TIM5_BASE + STM32U5_GTIM_DCR_OFFSET) +#define STM32U5_TIM5_DMAR (STM32U5_TIM5_BASE + STM32U5_GTIM_DMAR_OFFSET) +#define STM32U5_TIM5_OR (STM32U5_TIM5_BASE + STM32U5_GTIM_OR_OFFSET) + +#define STM32U5_TIM15_CR1 (STM32U5_TIM15_BASE + STM32U5_GTIM_CR1_OFFSET) +#define STM32U5_TIM15_CR2 (STM32U5_TIM15_BASE + STM32U5_GTIM_CR2_OFFSET) +#define STM32U5_TIM15_SMCR (STM32U5_TIM15_BASE + STM32U5_GTIM_SMCR_OFFSET) +#define STM32U5_TIM15_DIER (STM32U5_TIM15_BASE + STM32U5_GTIM_DIER_OFFSET) +#define STM32U5_TIM15_SR (STM32U5_TIM15_BASE + STM32U5_GTIM_SR_OFFSET) +#define STM32U5_TIM15_EGR (STM32U5_TIM15_BASE + STM32U5_GTIM_EGR_OFFSET) +#define STM32U5_TIM15_CCMR1 (STM32U5_TIM15_BASE + STM32U5_GTIM_CCMR1_OFFSET) +#define STM32U5_TIM15_CCER (STM32U5_TIM15_BASE + STM32U5_GTIM_CCER_OFFSET) +#define STM32U5_TIM15_CNT (STM32U5_TIM15_BASE + STM32U5_GTIM_CNT_OFFSET) +#define STM32U5_TIM15_PSC (STM32U5_TIM15_BASE + STM32U5_GTIM_PSC_OFFSET) +#define STM32U5_TIM15_ARR (STM32U5_TIM15_BASE + STM32U5_GTIM_ARR_OFFSET) +#define STM32U5_TIM15_RCR (STM32U5_TIM15_BASE + STM32U5_GTIM_RCR_OFFSET) +#define STM32U5_TIM15_CCR1 (STM32U5_TIM15_BASE + STM32U5_GTIM_CCR1_OFFSET) +#define STM32U5_TIM15_CCR2 (STM32U5_TIM15_BASE + STM32U5_GTIM_CCR2_OFFSET) +#define STM32U5_TIM15_BDTR (STM32U5_TIM15_BASE + STM32U5_GTIM_BDTR_OFFSET) +#define STM32U5_TIM15_DCR (STM32U5_TIM15_BASE + STM32U5_GTIM_DCR_OFFSET) +#define STM32U5_TIM15_DMAR (STM32U5_TIM15_BASE + STM32U5_GTIM_DMAR_OFFSET) + +#define STM32U5_TIM16_CR1 (STM32U5_TIM16_BASE + STM32U5_GTIM_CR1_OFFSET) +#define STM32U5_TIM16_CR2 (STM32U5_TIM16_BASE + STM32U5_GTIM_CR2_OFFSET) +#define STM32U5_TIM16_DIER (STM32U5_TIM16_BASE + STM32U5_GTIM_DIER_OFFSET) +#define STM32U5_TIM16_SR (STM32U5_TIM16_BASE + STM32U5_GTIM_SR_OFFSET) +#define STM32U5_TIM16_EGR (STM32U5_TIM16_BASE + STM32U5_GTIM_EGR_OFFSET) +#define STM32U5_TIM16_CCMR1 (STM32U5_TIM16_BASE + STM32U5_GTIM_CCMR1_OFFSET) +#define STM32U5_TIM16_CCER (STM32U5_TIM16_BASE + STM32U5_GTIM_CCER_OFFSET) +#define STM32U5_TIM16_CNT (STM32U5_TIM16_BASE + STM32U5_GTIM_CNT_OFFSET) +#define STM32U5_TIM16_PSC (STM32U5_TIM16_BASE + STM32U5_GTIM_PSC_OFFSET) +#define STM32U5_TIM16_ARR (STM32U5_TIM16_BASE + STM32U5_GTIM_ARR_OFFSET) +#define STM32U5_TIM16_RCR (STM32U5_TIM16_BASE + STM32U5_GTIM_RCR_OFFSET) +#define STM32U5_TIM16_CCR1 (STM32U5_TIM16_BASE + STM32U5_GTIM_CCR1_OFFSET) +#define STM32U5_TIM16_BDTR (STM32U5_TIM16_BASE + STM32U5_GTIM_BDTR_OFFSET) +#define STM32U5_TIM16_DCR (STM32U5_TIM16_BASE + STM32U5_GTIM_DCR_OFFSET) +#define STM32U5_TIM16_DMAR (STM32U5_TIM16_BASE + STM32U5_GTIM_DMAR_OFFSET) +#define STM32U5_TIM16_OR (STM32U5_TIM16_BASE + STM32U5_GTIM_OR_OFFSET) + +#define STM32U5_TIM17_CR1 (STM32U5_TIM17_BASE + STM32U5_GTIM_CR1_OFFSET) +#define STM32U5_TIM17_CR2 (STM32U5_TIM17_BASE + STM32U5_GTIM_CR2_OFFSET) +#define STM32U5_TIM17_DIER (STM32U5_TIM17_BASE + STM32U5_GTIM_DIER_OFFSET) +#define STM32U5_TIM17_SR (STM32U5_TIM17_BASE + STM32U5_GTIM_SR_OFFSET) +#define STM32U5_TIM17_EGR (STM32U5_TIM17_BASE + STM32U5_GTIM_EGR_OFFSET) +#define STM32U5_TIM17_CCMR1 (STM32U5_TIM17_BASE + STM32U5_GTIM_CCMR1_OFFSET) +#define STM32U5_TIM17_CCER (STM32U5_TIM17_BASE + STM32U5_GTIM_CCER_OFFSET) +#define STM32U5_TIM17_CNT (STM32U5_TIM17_BASE + STM32U5_GTIM_CNT_OFFSET) +#define STM32U5_TIM17_PSC (STM32U5_TIM17_BASE + STM32U5_GTIM_PSC_OFFSET) +#define STM32U5_TIM17_ARR (STM32U5_TIM17_BASE + STM32U5_GTIM_ARR_OFFSET) +#define STM32U5_TIM17_RCR (STM32U5_TIM17_BASE + STM32U5_GTIM_RCR_OFFSET) +#define STM32U5_TIM17_CCR1 (STM32U5_TIM17_BASE + STM32U5_GTIM_CCR1_OFFSET) +#define STM32U5_TIM17_BDTR (STM32U5_TIM17_BASE + STM32U5_GTIM_BDTR_OFFSET) +#define STM32U5_TIM17_DCR (STM32U5_TIM17_BASE + STM32U5_GTIM_DCR_OFFSET) +#define STM32U5_TIM17_DMAR (STM32U5_TIM17_BASE + STM32U5_GTIM_DMAR_OFFSET) + +/* Basic Timers - TIM6 and TIM7 */ + +#define STM32U5_TIM6_CR1 (STM32U5_TIM6_BASE + STM32U5_BTIM_CR1_OFFSET) +#define STM32U5_TIM6_CR2 (STM32U5_TIM6_BASE + STM32U5_BTIM_CR2_OFFSET) +#define STM32U5_TIM6_DIER (STM32U5_TIM6_BASE + STM32U5_BTIM_DIER_OFFSET) +#define STM32U5_TIM6_SR (STM32U5_TIM6_BASE + STM32U5_BTIM_SR_OFFSET) +#define STM32U5_TIM6_EGR (STM32U5_TIM6_BASE + STM32U5_BTIM_EGR_OFFSET) +#define STM32U5_TIM6_CNT (STM32U5_TIM6_BASE + STM32U5_BTIM_CNT_OFFSET) +#define STM32U5_TIM6_PSC (STM32U5_TIM6_BASE + STM32U5_BTIM_PSC_OFFSET) +#define STM32U5_TIM6_ARR (STM32U5_TIM6_BASE + STM32U5_BTIM_ARR_OFFSET) + +#define STM32U5_TIM7_CR1 (STM32U5_TIM7_BASE + STM32U5_BTIM_CR1_OFFSET) +#define STM32U5_TIM7_CR2 (STM32U5_TIM7_BASE + STM32U5_BTIM_CR2_OFFSET) +#define STM32U5_TIM7_DIER (STM32U5_TIM7_BASE + STM32U5_BTIM_DIER_OFFSET) +#define STM32U5_TIM7_SR (STM32U5_TIM7_BASE + STM32U5_BTIM_SR_OFFSET) +#define STM32U5_TIM7_EGR (STM32U5_TIM7_BASE + STM32U5_BTIM_EGR_OFFSET) +#define STM32U5_TIM7_CNT (STM32U5_TIM7_BASE + STM32U5_BTIM_CNT_OFFSET) +#define STM32U5_TIM7_PSC (STM32U5_TIM7_BASE + STM32U5_BTIM_PSC_OFFSET) +#define STM32U5_TIM7_ARR (STM32U5_TIM7_BASE + STM32U5_BTIM_ARR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Control register 1 */ + +#define ATIM_CR1_CEN (1 << 0) /* Bit 0: Counter enable */ +#define ATIM_CR1_UDIS (1 << 1) /* Bit 1: Update disable */ +#define ATIM_CR1_URS (1 << 2) /* Bit 2: Update request source */ +#define ATIM_CR1_OPM (1 << 3) /* Bit 3: One pulse mode */ +#define ATIM_CR1_DIR (1 << 4) /* Bit 4: Direction */ +#define ATIM_CR1_CMS_SHIFT (5) /* Bits 6-5: Center-aligned mode selection */ +#define ATIM_CR1_CMS_MASK (3 << ATIM_CR1_CMS_SHIFT) +# define ATIM_CR1_EDGE (0 << ATIM_CR1_CMS_SHIFT) /* 00: Edge-aligned mode */ +# define ATIM_CR1_CENTER1 (1 << ATIM_CR1_CMS_SHIFT) /* 01: Center-aligned mode 1 */ +# define ATIM_CR1_CENTER2 (2 << ATIM_CR1_CMS_SHIFT) /* 10: Center-aligned mode 2 */ +# define ATIM_CR1_CENTER3 (3 << ATIM_CR1_CMS_SHIFT) /* 11: Center-aligned mode 3 */ +#define ATIM_CR1_ARPE (1 << 7) /* Bit 7: Auto-reload preload enable */ +#define ATIM_CR1_CKD_SHIFT (8) /* Bits 9-8: Clock division */ +#define ATIM_CR1_CKD_MASK (3 << ATIM_CR1_CKD_SHIFT) +# define ATIM_CR1_TCKINT (0 << ATIM_CR1_CKD_SHIFT) /* 00: tDTS=tCK_INT */ +# define ATIM_CR1_2TCKINT (1 << ATIM_CR1_CKD_SHIFT) /* 01: tDTS=2*tCK_INT */ +# define ATIM_CR1_4TCKINT (2 << ATIM_CR1_CKD_SHIFT) /* 10: tDTS=4*tCK_INT */ +#define ATIM_CR1_UIFREMAP (1 << 11) /* Bit 11: UIF status bit remapping */ + +/* Control register 2 */ + +#define ATIM_CR2_CCPC (1 << 0) /* Bit 0: Capture/Compare Preloaded Control */ +#define ATIM_CR2_CCUS (1 << 2) /* Bit 2: Capture/Compare Control Update Selection */ +#define ATIM_CR2_CCDS (1 << 3) /* Bit 3: Capture/Compare DMA Selection */ +#define ATIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection */ +#define ATIM_CR2_MMS_MASK (7 << ATIM_CR2_MMS_SHIFT) +# define ATIM_CR2_MMS_RESET (0 << ATIM_CR2_MMS_SHIFT) /* 000: Reset - TIMx_EGR UG bit is TRGO */ +# define ATIM_CR2_MMS_ENABLE (1 << ATIM_CR2_MMS_SHIFT) /* 001: Enable - CNT_EN is TRGO */ +# define ATIM_CR2_MMS_UPDATE (2 << ATIM_CR2_MMS_SHIFT) /* 010: Update event is TRGO */ +# define ATIM_CR2_MMS_COMPP (3 << ATIM_CR2_MMS_SHIFT) /* 010: Compare Pulse - CC1IF flag */ +# define ATIM_CR2_MMS_OC1REF (4 << ATIM_CR2_MMS_SHIFT) /* 100: Compare OC1REF is TRGO */ +# define ATIM_CR2_MMS_OC2REF (5 << ATIM_CR2_MMS_SHIFT) /* 101: Compare OC2REF is TRGO */ +# define ATIM_CR2_MMS_OC3REF (6 << ATIM_CR2_MMS_SHIFT) /* 110: Compare OC3REF is TRGO */ +# define ATIM_CR2_MMS_OC4REF (7 << ATIM_CR2_MMS_SHIFT) /* 111: Compare OC4REF is TRGO */ +#define ATIM_CR2_TI1S (1 << 7) /* Bit 7: TI1 Selection */ +#define ATIM_CR2_OIS1 (1 << 8) /* Bit 8: Output Idle state 1 (OC1 output) */ +#define ATIM_CR2_OIS1N (1 << 9) /* Bit 9: Output Idle state 1 (OC1N output) */ +#define ATIM_CR2_OIS2 (1 << 10) /* Bit 10: Output Idle state 2 (OC2 output) */ +#define ATIM_CR2_OIS2N (1 << 11) /* Bit 11: Output Idle state 2 (OC2N output) */ +#define ATIM_CR2_OIS3 (1 << 12) /* Bit 12: Output Idle state 3 (OC3 output) */ +#define ATIM_CR2_OIS3N (1 << 13) /* Bit 13: Output Idle state 3 (OC3N output) */ +#define ATIM_CR2_OIS4 (1 << 14) /* Bit 14: Output Idle state 4 (OC4 output) */ +#define ATIM_CR2_OIS5 (1 << 16) /* Bit 16: OOutput Idle state 5 (OC5 output) */ +#define ATIM_CR2_OIS6 (1 << 18) /* Bit 18: Output Idle state 6 (OC6 output) */ +#define ATIM_CR2_MMS2_SHIFT (20) /* Bits 20-23: Master Mode Selection 2 */ +#define ATIM_CR2_MMS2_MASK (15 << ATIM_CR2_MMS2_SHIFT) +# define ATIM_CR2_MMS2_RESET (0 << ATIM_CR2_MMS2_SHIFT) /* 0000: Reset - TIMx_EGR UG bit is TRG9 */ +# define ATIM_CR2_MMS2_ENABLE (1 << ATIM_CR2_MMS2_SHIFT) /* 0001: Enable - CNT_EN is TRGO2 */ +# define ATIM_CR2_MMS2_UPDATE (2 << ATIM_CR2_MMS2_SHIFT) /* 0010: Update event is TRGH0*/ +# define ATIM_CR2_MMS2_COMPP (3 << ATIM_CR2_MMS2_SHIFT) /* 0010: Compare Pulse - CC1IF flag */ +# define ATIM_CR2_MMS2_OC1REF (4 << ATIM_CR2_MMS2_SHIFT) /* 0100: Compare OC1REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC2REF (5 << ATIM_CR2_MMS2_SHIFT) /* 0101: Compare OC2REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC3REF (6 << ATIM_CR2_MMS2_SHIFT) /* 0110: Compare OC3REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC4REF (7 << ATIM_CR2_MMS2_SHIFT) /* 0111: Compare OC4REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC5REF (8 << ATIM_CR2_MMS2_SHIFT) /* 1000: Compare OC5REF is TRGO2 */ +# define ATIM_CR2_MMS2_OC6REF (9 << ATIM_CR2_MMS2_SHIFT) /* 1001: Compare OC6REF is TRGO2 */ +# define ATIM_CR2_MMS2_CMPOC4 (10 << ATIM_CR2_MMS2_SHIFT) /* 1010: Compare pulse - OC4REF edge is TRGO2 */ +# define ATIM_CR2_MMS2_CMPOC6 (11 << ATIM_CR2_MMS2_SHIFT) /* 1011: Compare pulse - OC6REF edge is TRGO2 */ +# define ATIM_CR2_MMS2_CMPOC4R6R (12 << ATIM_CR2_MMS2_SHIFT) /* 1100: Compare pulse - OC4REF/OC6REF rising */ +# define ATIM_CR2_MMS2_CMPOC4R6F (13 << ATIM_CR2_MMS2_SHIFT) /* 1101: Compare pulse - OC4REF rising/OC6REF falling */ +# define ATIM_CR2_MMS2_CMPOC5R6R (14 << ATIM_CR2_MMS2_SHIFT) /* 1110: Compare pulse - OC5REF/OC6REF rising */ +# define ATIM_CR2_MMS2_CMPOC5R6F (15 << ATIM_CR2_MMS2_SHIFT) /* 1111: Compare pulse - OC5REF rising/OC6REF falling */ + +/* Slave mode control register */ + +#define ATIM_SMCR_SMS_SHIFT (0) /* Bits 0-2: Slave mode selection */ +#define ATIM_SMCR_SMS_MASK (7 << ATIM_SMCR_SMS_SHIFT) +# define ATIM_SMCR_DISAB (0 << ATIM_SMCR_SMS_SHIFT) /* 000: Slave mode disabled */ +# define ATIM_SMCR_ENCMD1 (1 << ATIM_SMCR_SMS_SHIFT) /* 001: Encoder mode 1 */ +# define ATIM_SMCR_ENCMD2 (2 << ATIM_SMCR_SMS_SHIFT) /* 010: Encoder mode 2 */ +# define ATIM_SMCR_ENCMD3 (3 << ATIM_SMCR_SMS_SHIFT) /* 011: Encoder mode 3 */ +# define ATIM_SMCR_RESET (4 << ATIM_SMCR_SMS_SHIFT) /* 100: Reset Mode */ +# define ATIM_SMCR_GATED (5 << ATIM_SMCR_SMS_SHIFT) /* 101: Gated Mode */ +# define ATIM_SMCR_TRIGGER (6 << ATIM_SMCR_SMS_SHIFT) /* 110: Trigger Mode */ +# define ATIM_SMCR_EXTCLK1 (7 << ATIM_SMCR_SMS_SHIFT) /* 111: External Clock Mode 1 */ +#define ATIM_SMCR_OCCS (1 << 3) /* Bit 3: OCREF clear selection */ +#define ATIM_SMCR_TS_SHIFT (4) /* Bits 4-6: Trigger selection */ +#define ATIM_SMCR_TS_MASK (7 << ATIM_SMCR_TS_SHIFT) +# define ATIM_SMCR_ITR0 (0 << ATIM_SMCR_TS_SHIFT) /* 000: Internal trigger 0 (ITR0) */ +# define ATIM_SMCR_ITR1 (1 << ATIM_SMCR_TS_SHIFT) /* 001: Internal trigger 1 (ITR1) */ +# define ATIM_SMCR_ITR2 (2 << ATIM_SMCR_TS_SHIFT) /* 010: Internal trigger 2 (ITR2) */ +# define ATIM_SMCR_ITR3 (3 << ATIM_SMCR_TS_SHIFT) /* 011: Internal trigger 3 (ITR3) */ +# define ATIM_SMCR_T1FED (4 << ATIM_SMCR_TS_SHIFT) /* 100: TI1 Edge Detector (TI1F_ED) */ +# define ATIM_SMCR_TI1FP1 (5 << ATIM_SMCR_TS_SHIFT) /* 101: Filtered Timer Input 1 (TI1FP1) */ +# define ATIM_SMCR_T12FP2 (6 << ATIM_SMCR_TS_SHIFT) /* 110: Filtered Timer Input 2 (TI2FP2) */ +# define ATIM_SMCR_ETRF (7 << ATIM_SMCR_TS_SHIFT) /* 111: External Trigger input (ETRF) */ +#define ATIM_SMCR_MSM (1 << 7) /* Bit 7: Master/slave mode */ +#define ATIM_SMCR_ETF_SHIFT (8) /* Bits 8-11: External trigger filter */ +#define ATIM_SMCR_ETF_MASK (0x0f << ATIM_SMCR_ETF_SHIFT) +# define ATIM_SMCR_NOFILT (0 << ATIM_SMCR_ETF_SHIFT) /* 0000: No filter, sampling is done at fDTS */ +# define ATIM_SMCR_FCKINT2 (1 << ATIM_SMCR_ETF_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define ATIM_SMCR_FCKINT4 (2 << ATIM_SMCR_ETF_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define ATIM_SMCR_FCKINT8 (3 << ATIM_SMCR_ETF_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define ATIM_SMCR_FDTSd26 (4 << ATIM_SMCR_ETF_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define ATIM_SMCR_FDTSd28 (5 << ATIM_SMCR_ETF_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define ATIM_SMCR_FDTSd46 (6 << ATIM_SMCR_ETF_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define ATIM_SMCR_FDTSd48 (7 << ATIM_SMCR_ETF_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define ATIM_SMCR_FDTSd86 (8 << ATIM_SMCR_ETF_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define ATIM_SMCR_FDTSd88 (9 << ATIM_SMCR_ETF_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define ATIM_SMCR_FDTSd165 (10 << ATIM_SMCR_ETF_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define ATIM_SMCR_FDTSd166 (11 << ATIM_SMCR_ETF_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define ATIM_SMCR_FDTSd168 (12 << ATIM_SMCR_ETF_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define ATIM_SMCR_FDTSd325 (13 << ATIM_SMCR_ETF_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define ATIM_SMCR_FDTSd326 (14 << ATIM_SMCR_ETF_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define ATIM_SMCR_FDTSd328 (15 << ATIM_SMCR_ETF_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ +#define ATIM_SMCR_ETPS_SHIFT (12) /* Bits 12-13: External trigger prescaler */ +#define ATIM_SMCR_ETPS_MASK (3 << ATIM_SMCR_ETPS_SHIFT) +# define ATIM_SMCR_PSCOFF (0 << ATIM_SMCR_ETPS_SHIFT) /* 00: Prescaler OFF */ +# define ATIM_SMCR_ETRPd2 (1 << ATIM_SMCR_ETPS_SHIFT) /* 01: ETRP frequency divided by 2 */ +# define ATIM_SMCR_ETRPd4 (2 << ATIM_SMCR_ETPS_SHIFT) /* 10: ETRP frequency divided by 4 */ +# define ATIM_SMCR_ETRPd8 (3 << ATIM_SMCR_ETPS_SHIFT) /* 11: ETRP frequency divided by 8 */ +#define ATIM_SMCR_ECE (1 << 14) /* Bit 14: External clock enable */ +#define ATIM_SMCR_ETP (1 << 15) /* Bit 15: External trigger polarity */ +#define ATIM_SMCR_SMS (1 << 16) /* Bit 16: Slave mode selection - bit 3 */ + +/* DMA/Interrupt enable register */ + +#define ATIM_DIER_UIE (1 << 0) /* Bit 0: Update interrupt enable */ +#define ATIM_DIER_CC1IE (1 << 1) /* Bit 1: Capture/Compare 1 interrupt enable */ +#define ATIM_DIER_CC2IE (1 << 2) /* Bit 2: Capture/Compare 2 interrupt enable */ +#define ATIM_DIER_CC3IE (1 << 3) /* Bit 3: Capture/Compare 3 interrupt enable */ +#define ATIM_DIER_CC4IE (1 << 4) /* Bit 4: Capture/Compare 4 interrupt enable */ +#define ATIM_DIER_COMIE (1 << 5) /* Bit 5: COM interrupt enable */ +#define ATIM_DIER_TIE (1 << 6) /* Bit 6: Trigger interrupt enable */ +#define ATIM_DIER_BIE (1 << 7) /* Bit 7: Break interrupt enable */ +#define ATIM_DIER_UDE (1 << 8) /* Bit 8: Update DMA request enable */ +#define ATIM_DIER_CC1DE (1 << 9) /* Bit 9: Capture/Compare 1 DMA request enable */ +#define ATIM_DIER_CC2DE (1 << 10) /* Bit 10: Capture/Compare 2 DMA request enable */ +#define ATIM_DIER_CC3DE (1 << 11) /* Bit 11: Capture/Compare 3 DMA request enable */ +#define ATIM_DIER_CC4DE (1 << 12) /* Bit 12: Capture/Compare 4 DMA request enable */ +#define ATIM_DIER_COMDE (1 << 13) /* Bit 13: COM DMA request enable */ +#define ATIM_DIER_TDE (1 << 14) /* Bit 14: Trigger DMA request enable */ + +/* Status register */ + +#define ATIM_SR_UIF (1 << 0) /* Bit 0: Update interrupt Flag */ +#define ATIM_SR_CC1IF (1 << 1) /* Bit 1: Capture/Compare 1 interrupt Flag */ +#define ATIM_SR_CC2IF (1 << 2) /* Bit 2: Capture/Compare 2 interrupt Flag */ +#define ATIM_SR_CC3IF (1 << 3) /* Bit 3: Capture/Compare 3 interrupt Flag */ +#define ATIM_SR_CC4IF (1 << 4) /* Bit 4: Capture/Compare 4 interrupt Flag */ +#define ATIM_SR_COMIF (1 << 5) /* Bit 5: COM interrupt Flag */ +#define ATIM_SR_TIF (1 << 6) /* Bit 6: Trigger interrupt Flag */ +#define ATIM_SR_BIF (1 << 7) /* Bit 7: Break interrupt Flag */ +#define ATIM_SR_B2IF (1 << 8) /* Bit 8: Break 2 interrupt Flag */ +#define ATIM_SR_CC1OF (1 << 9) /* Bit 9: Capture/Compare 1 Overcapture Flag */ +#define ATIM_SR_CC2OF (1 << 10) /* Bit 10: Capture/Compare 2 Overcapture Flag */ +#define ATIM_SR_CC3OF (1 << 11) /* Bit 11: Capture/Compare 3 Overcapture Flag */ +#define ATIM_SR_CC4OF (1 << 12) /* Bit 12: Capture/Compare 4 Overcapture Flag */ +#define ATIM_SR_SBIF (1 << 13) /* Bit 13: System break interrupt Flag */ +#define ATIM_SR_CC5IF (1 << 16) /* Bit 16: Compare 5 interrupt flag */ +#define ATIM_SR_CC6IF (1 << 17) /* Bit 17: Compare 6 interrupt flag */ + +/* Event generation register */ + +#define ATIM_EGR_UG (1 << 0) /* Bit 0: Update Generation */ +#define ATIM_EGR_CC1G (1 << 1) /* Bit 1: Capture/Compare 1 Generation */ +#define ATIM_EGR_CC2G (1 << 2) /* Bit 2: Capture/Compare 2 Generation */ +#define ATIM_EGR_CC3G (1 << 3) /* Bit 3: Capture/Compare 3 Generation */ +#define ATIM_EGR_CC4G (1 << 4) /* Bit 4: Capture/Compare 4 Generation */ +#define ATIM_EGR_COMG (1 << 5) /* Bit 5: Capture/Compare Control Update Generation */ +#define ATIM_EGR_TG (1 << 6) /* Bit 6: Trigger Generation */ +#define ATIM_EGR_BG (1 << 7) /* Bit 7: Break Generation */ +#define ATIM_EGR_B2G (1 << 8) /* Bit 8: Break 2 Generation */ + +/* Capture/compare mode register 1 -- Output compare mode */ + +#define ATIM_CCMR1_CC1S_SHIFT (0) /* Bits 1-0: Capture/Compare 1 Selection */ +#define ATIM_CCMR1_CC1S_MASK (3 << ATIM_CCMR1_CC1S_SHIFT) +#define ATIM_CCMR1_OC1FE (1 << 2) /* Bit 2: Output Compare 1 Fast enable */ +#define ATIM_CCMR1_OC1PE (1 << 3) /* Bit 3: Output Compare 1 Preload enable */ +#define ATIM_CCMR1_OC1M_SHIFT (4) /* Bits 6-4: Output Compare 1 Mode */ +#define ATIM_CCMR1_OC1M_MASK (7 << ATIM_CCMR1_OC1M_SHIFT) +#define ATIM_CCMR1_OC1CE (1 << 7) /* Bit 7: Output Compare 1Clear Enable */ +#define ATIM_CCMR1_CC2S_SHIFT (8) /* Bits 8-9: Capture/Compare 2 Selection */ +#define ATIM_CCMR1_CC2S_MASK (3 << ATIM_CCMR1_CC2S_SHIFT) +#define ATIM_CCMR1_OC2FE (1 << 10) /* Bit 10: Output Compare 2 Fast enable */ +#define ATIM_CCMR1_OC2PE (1 << 11) /* Bit 11: Output Compare 2 Preload enable */ +#define ATIM_CCMR1_OC2M_SHIFT (12) /* Bits 14-12: Output Compare 2 Mode */ +#define ATIM_CCMR1_OC2M_MASK (7 << ATIM_CCMR1_OC2M_SHIFT) +#define ATIM_CCMR1_OC2CE (1 << 15) /* Bit 15: Output Compare 2 Clear Enable */ +#define ATIM_CCMR1_OC1M (1 << 16) /* Bit 16: Output Compare 1 mode - bit 3 */ +#define ATIM_CCMR1_OC2M (1 << 24) /* Bit 24: Output Compare 2 mode - bit 3 */ + +/* Common CCMR (unshifted) Capture/Compare Selection bit-field definitions */ + +#define ATIM_CCMR_CCS_CCOUT (0) /* 00: CCx channel output */ +#define ATIM_CCMR_CCS_CCIN1 (1) /* 01: CCx channel input, ICx is TIx */ +#define ATIM_CCMR_CCS_CCIN2 (2) /* 10: CCx channel input, ICx is TIy */ +#define ATIM_CCMR_CCS_CCINTRC (3) /* 11: CCx channel input, ICx is TRC */ + +/* Common CCMR (unshifted) Compare Mode bit field definitions */ + +#define ATIM_CCMR_MODE_FRZN (0) /* 000: Frozen */ +#define ATIM_CCMR_MODE_CHACT (1) /* 001: Channel x active on match */ +#define ATIM_CCMR_MODE_CHINACT (2) /* 010: Channel x inactive on match */ +#define ATIM_CCMR_MODE_OCREFTOG (3) /* 011: OCxREF toggle ATIM_CNT=ATIM_CCRx */ +#define ATIM_CCMR_MODE_OCREFLO (4) /* 100: OCxREF forced low */ +#define ATIM_CCMR_MODE_OCREFHI (5) /* 101: OCxREF forced high */ +#define ATIM_CCMR_MODE_PWM1 (6) /* 110: PWM mode 1 */ +#define ATIM_CCMR_MODE_PWM2 (7) /* 111: PWM mode 2 */ +#define ATIM_CCMR_MODE_COMBINED1 (12) /* 1100: Combined PWM mode 1 */ +#define ATIM_CCMR_MODE_COMBINED2 (13) /* 1101: Combined PWM mode 2 */ +#define ATIM_CCMR_MODE_ASYMMETRIC1 (14) /* 1110: Asymmetric PWM mode 1 */ +#define ATIM_CCMR_MODE_ASYMMETRIC2 (15) /* 1111: Asymmetric PWM mode 2 */ + +/* Capture/compare mode register 1 -- Input capture mode */ + +#define ATIM_CCMR1_IC1PSC_SHIFT (2) /* Bits 3-2: Input Capture 1 Prescaler */ +#define ATIM_CCMR1_IC1PSC_MASK (3 << ATIM_CCMR1_IC1PSC_SHIFT) +#define ATIM_CCMR1_IC1F_SHIFT (4) /* Bits 7-4: Input Capture 1 Filter */ +#define ATIM_CCMR1_IC1F_MASK (0x0f << ATIM_CCMR1_IC1F_SHIFT) +#define ATIM_CCMR1_IC2PSC_SHIFT (10) /* Bits 11:10: Input Capture 2 Prescaler */ +#define ATIM_CCMR1_IC2PSC_MASK (3 << ATIM_CCMR1_IC2PSC_SHIFT) +#define ATIM_CCMR1_IC2F_SHIFT (12) /* Bits 15-12: Input Capture 2 Filter */ +#define ATIM_CCMR1_IC2F_MASK (0x0f << ATIM_CCMR1_IC2F_SHIFT) + +/* Common CCMR (unshifted) Input Capture Prescaler bit-field definitions */ + +#define ATIM_CCMR_ICPSC_NOPSC (0) /* 00: no prescaler, capture each edge */ +#define ATIM_CCMR_ICPSC_EVENTS2 (1) /* 01: capture once every 2 events */ +#define ATIM_CCMR_ICPSC_EVENTS4 (2) /* 10: capture once every 4 events */ +#define ATIM_CCMR_ICPSC_EVENTS8 (3) /* 11: capture once every 8 events */ + +/* Common CCMR (unshifted) Input Capture Filter bit-field definitions */ + +#define ATIM_CCMR_ICF_NOFILT (0) /* 0000: No filter, sampling at fDTS */ +#define ATIM_CCMR_ICF_FCKINT2 (1) /* 0001: fSAMPLING=fCK_INT, N=2 */ +#define ATIM_CCMR_ICF_FCKINT4 (2) /* 0010: fSAMPLING=fCK_INT, N=4 */ +#define ATIM_CCMR_ICF_FCKINT8 (3) /* 0011: fSAMPLING=fCK_INT, N=8 */ +#define ATIM_CCMR_ICF_FDTSd26 (4) /* 0100: fSAMPLING=fDTS/2, N=6 */ +#define ATIM_CCMR_ICF_FDTSd28 (5) /* 0101: fSAMPLING=fDTS/2, N=8 */ +#define ATIM_CCMR_ICF_FDTSd46 (6) /* 0110: fSAMPLING=fDTS/4, N=6 */ +#define ATIM_CCMR_ICF_FDTSd48 (7) /* 0111: fSAMPLING=fDTS/4, N=8 */ +#define ATIM_CCMR_ICF_FDTSd86 (8) /* 1000: fSAMPLING=fDTS/8, N=6 */ +#define ATIM_CCMR_ICF_FDTSd88 (9) /* 1001: fSAMPLING=fDTS/8, N=8 */ +#define ATIM_CCMR_ICF_FDTSd165 (10) /* 1010: fSAMPLING=fDTS/16, N=5 */ +#define ATIM_CCMR_ICF_FDTSd166 (11) /* 1011: fSAMPLING=fDTS/16, N=6 */ +#define ATIM_CCMR_ICF_FDTSd168 (12) /* 1100: fSAMPLING=fDTS/16, N=8 */ +#define ATIM_CCMR_ICF_FDTSd325 (13) /* 1101: fSAMPLING=fDTS/32, N=5 */ +#define ATIM_CCMR_ICF_FDTSd326 (14) /* 1110: fSAMPLING=fDTS/32, N=6 */ +#define ATIM_CCMR_ICF_FDTSd328 (15) /* 1111: fSAMPLING=fDTS/32, N=8 */ + +/* Capture/compare mode register 2 - Output Compare mode */ + +#define ATIM_CCMR2_CC3S_SHIFT (0) /* Bits 1-0: Capture/Compare 3 Selection */ +#define ATIM_CCMR2_CC3S_MASK (3 << ATIM_CCMR2_CC3S_SHIFT) +#define ATIM_CCMR2_OC3FE (1 << 2) /* Bit 2: Output Compare 3 Fast enable */ +#define ATIM_CCMR2_OC3PE (1 << 3) /* Bit 3: Output Compare 3 Preload enable */ +#define ATIM_CCMR2_OC3M_SHIFT (4) /* Bits 6-4: Output Compare 3 Mode */ +#define ATIM_CCMR2_OC3M_MASK (7 << ATIM_CCMR2_OC3M_SHIFT) +#define ATIM_CCMR2_OC3CE (1 << 7) /* Bit 7: Output Compare 3 Clear Enable */ +#define ATIM_CCMR2_CC4S_SHIFT (8) /* Bits 9-8: Capture/Compare 4 Selection */ +#define ATIM_CCMR2_CC4S_MASK (3 << ATIM_CCMR2_CC4S_SHIFT) +#define ATIM_CCMR2_OC4FE (1 << 10) /* Bit 10: Output Compare 4 Fast enable */ +#define ATIM_CCMR2_OC4PE (1 << 11) /* Bit 11: Output Compare 4 Preload enable */ +#define ATIM_CCMR2_OC4M_SHIFT (12) /* Bits 14-12: Output Compare 4 Mode */ +#define ATIM_CCMR2_OC4M_MASK (7 << ATIM_CCMR2_OC4M_SHIFT) +#define ATIM_CCMR2_OC4CE (1 << 15) /* Bit 15: Output Compare 4 Clear Enable */ +#define ATIM_CCMR2_OC3M (1 << 16) /* Bit 16: Output Compare 3 mode - bit 3 */ +#define ATIM_CCMR2_OC4M (1 << 24) /* Bit 24: Output Compare 4 mode - bit 3 */ + +/* Capture/compare mode register 2 - Input Capture Mode */ + +#define ATIM_CCMR2_IC3PSC_SHIFT (2) /* Bits 3-2: Input Capture 3 Prescaler */ +#define ATIM_CCMR1_IC3PSC_MASK (3 << ATIM_CCMR2_IC3PSC_SHIFT) +#define ATIM_CCMR2_IC3F_SHIFT (4) /* Bits 7-4: Input Capture 3 Filter */ +#define ATIM_CCMR2_IC3F_MASK (0x0f << ATIM_CCMR2_IC3F_SHIFT) +#define ATIM_CCMR2_IC4PSC_SHIFT (10) /* Bits 11:10: Input Capture 4 Prescaler */ +#define ATIM_CCMR2_IC4PSC_MASK (3 << ATIM_CCMR2_IC4PSC_SHIFT) +#define ATIM_CCMR2_IC4F_SHIFT (12) /* Bits 15-12: Input Capture 4 Filter */ +#define ATIM_CCMR2_IC4F_MASK (0x0f << ATIM_CCMR2_IC4F_SHIFT) + +/* Capture/compare mode register 3 -- Output compare mode */ + +#define ATIM_CCMR3_OC5FE (1 << 2) /* Bit 2: Output Compare 5 Fast enable */ +#define ATIM_CCMR3_OC5PE (1 << 3) /* Bit 3: Output Compare 5 Preload enable */ +#define ATIM_CCMR3_OC5M_SHIFT (4) /* Bits 6-4: Output Compare 5 Mode */ +#define ATIM_CCMR3_OC5M_MASK (7 << ATIM_CCMR3_OC5M_SHIFT) +#define ATIM_CCMR3_OC5CE (1 << 7) /* Bit 7: Output Compare 5 Clear Enable */ +#define ATIM_CCMR3_OC6FE (1 << 10) /* Bit 10: Output Compare 6 Fast enable */ +#define ATIM_CCMR3_OC6PE (1 << 11) /* Bit 11: Output Compare 6 Preload enable */ +#define ATIM_CCMR3_OC6M_SHIFT (12) /* Bits 14-12: Output Compare 7 Mode */ +#define ATIM_CCMR3_OC6M_MASK (7 << ATIM_CCMR3_OC6M_SHIFT) +#define ATIM_CCMR3_OC6CE (1 << 15) /* Bit 15: Output Compare 7 Clear Enable */ +#define ATIM_CCMR3_OC5M (1 << 16) /* Bit 16: Output Compare 5 mode - bit 3 */ +#define ATIM_CCMR3_OC6M (1 << 24) /* Bit 24: Output Compare 6 mode - bit 3 */ + +/* Capture/compare enable register */ + +#define ATIM_CCER_CC1E (1 << 0) /* Bit 0: Capture/Compare 1 output enable */ +#define ATIM_CCER_CC1P (1 << 1) /* Bit 1: Capture/Compare 1 output Polarity */ +#define ATIM_CCER_CC1NE (1 << 2) /* Bit 2: Capture/Compare 1 Complementary output enable */ +#define ATIM_CCER_CC1NP (1 << 3) /* Bit 3: Capture/Compare 1 Complementary output polarity */ +#define ATIM_CCER_CC2E (1 << 4) /* Bit 4: Capture/Compare 2 output enable */ +#define ATIM_CCER_CC2P (1 << 5) /* Bit 5: Capture/Compare 2 output Polarity */ +#define ATIM_CCER_CC2NE (1 << 6) /* Bit 6: Capture/Compare 2 Complementary output enable */ +#define ATIM_CCER_CC2NP (1 << 7) /* Bit 7: Capture/Compare 2 Complementary output polarity */ +#define ATIM_CCER_CC3E (1 << 8) /* Bit 8: Capture/Compare 3 output enable */ +#define ATIM_CCER_CC3P (1 << 9) /* Bit 9: Capture/Compare 3 output Polarity */ +#define ATIM_CCER_CC3NE (1 << 10) /* Bit 10: Capture/Compare 3 Complementary output enable */ +#define ATIM_CCER_CC3NP (1 << 11) /* Bit 11: Capture/Compare 3 Complementary output polarity */ +#define ATIM_CCER_CC4E (1 << 12) /* Bit 12: Capture/Compare 4 output enable */ +#define ATIM_CCER_CC4P (1 << 13) /* Bit 13: Capture/Compare 4 output Polarity */ +#define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 Complementary output polarity */ +#define ATIM_CCER_CC5E (1 << 16) /* Bit 16: Capture/Compare 5 output enable */ +#define ATIM_CCER_CC5P (1 << 17) /* Bit 17: Capture/Compare 5 output Polarity */ +#define ATIM_CCER_CC6E (1 << 20) /* Bit 20: Capture/Compare 6 output enable */ +#define ATIM_CCER_CC6P (1 << 21) /* Bit 21: Capture/Compare 6 output Polarity */ +#define ATIM_CCER_CCXBASE(ch) (ch << 2) /* Each channel uses 4-bits */ + +/* 16-bit counter register */ + +#define ATIM_CNT_SHIFT (0) /* Bits 0-15: Timer counter value */ +#define ATIM_CNT_MASK (0xffff << ATIM_CNT_SHIFT) +#define ATIM_CCER_UIFCPY (1 << 31) /* Bit 31: UIF copy */ + +/* Repetition counter register */ + +#define ATIM_RCR_REP_SHIFT (0) /* Bits 0-15: Repetition Counter Value */ +#define ATIM_RCR_REP_MASK (0xffff << ATIM_RCR_REP_SHIFT) +#define ATIM_RCR_REP_MAX 32768 /* REVISIT */ + +/* Capture/compare registers (CCR) */ + +#define ATIM_CCR5_GC5C1 (1 << 29) /* Bit 29: Group Channel 5 and Channel 1 */ +#define ATIM_CCR5_GC5C2 (1 << 30) /* Bit 30: Group Channel 5 and Channel 2 */ +#define ATIM_CCR5_GC5C3 (1 << 31) /* Bit 31: Group Channel 5 and Channel 3 */ + +#define ATIM_CCR_MASK (0xffff) + +/* Break and dead-time register */ + +#define ATIM_BDTR_DTG_SHIFT (0) /* Bits 7:0 [7:0]: Dead-Time Generator set-up */ +#define ATIM_BDTR_DTG_MASK (0xff << ATIM_BDTR_DTG_SHIFT) +#define ATIM_BDTR_LOCK_SHIFT (8) /* Bits 9:8 [1:0]: Lock Configuration */ +#define ATIM_BDTR_LOCK_MASK (3 << ATIM_BDTR_LOCK_SHIFT) +# define ATIM_BDTR_LOCKOFF (0 << ATIM_BDTR_LOCK_SHIFT) /* 00: LOCK OFF - No bit is write protected */ +# define ATIM_BDTR_LOCK1 (1 << ATIM_BDTR_LOCK_SHIFT) /* 01: LOCK Level 1 protection */ +# define ATIM_BDTR_LOCK2 (2 << ATIM_BDTR_LOCK_SHIFT) /* 10: LOCK Level 2 protection */ +# define ATIM_BDTR_LOCK3 (3 << ATIM_BDTR_LOCK_SHIFT) /* 11: LOCK Level 3 protection */ +#define ATIM_BDTR_OSSI (1 << 10) /* Bit 10: Off-State Selection for Idle mode */ +#define ATIM_BDTR_OSSR (1 << 11) /* Bit 11: Off-State Selection for Run mode */ +#define ATIM_BDTR_BKE (1 << 12) /* Bit 12: Break enable */ +#define ATIM_BDTR_BKP (1 << 13) /* Bit 13: Break Polarity */ +#define ATIM_BDTR_AOE (1 << 14) /* Bit 14: Automatic Output enable */ +#define ATIM_BDTR_MOE (1 << 15) /* Bit 15: Main Output enable */ +#define ATIM_BDTR_BKF_SHIFT (16) /* Bits 16-19: Break filter */ +#define ATIM_BDTR_BKF_MASK (15 << ATIM_BDTR_BKF_SHIFT) +# define ATIM_BDTR_BKF_NOFILT (0 << ATIM_BDTR_BKF_SHIFT) /* 0000: No filter, BRK acts asynchronously */ +# define ATIM_BDTR_BKF_FCKINT2 (1 << ATIM_BDTR_BKF_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define ATIM_BDTR_BKF_FCKINT4 (2 << ATIM_BDTR_BKF_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define ATIM_BDTR_BKF_FCKINT8 (3 << ATIM_BDTR_BKF_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define ATIM_BDTR_BKF_FDTSd26 (4 << ATIM_BDTR_BKF_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define ATIM_BDTR_BKF_FDTSd28 (5 << ATIM_BDTR_BKF_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define ATIM_BDTR_BKF_FDTSd36 (6 << ATIM_BDTR_BKF_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define ATIM_BDTR_BKF_FDTSd38 (7 << ATIM_BDTR_BKF_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define ATIM_BDTR_BKF_FDTSd86 (8 << ATIM_BDTR_BKF_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define ATIM_BDTR_BKF_FDTSd88 (9 << ATIM_BDTR_BKF_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define ATIM_BDTR_BKF_FDTSd165 (10 << ATIM_BDTR_BKF_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define ATIM_BDTR_BKF_FDTSd166 (11 << ATIM_BDTR_BKF_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define ATIM_BDTR_BKF_FDTSd168 (12 << ATIM_BDTR_BKF_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define ATIM_BDTR_BKF_FDTSd325 (13 << ATIM_BDTR_BKF_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define ATIM_BDTR_BKF_FDTSd326 (14 << ATIM_BDTR_BKF_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define ATIM_BDTR_BKF_FDTSd328 (15 << ATIM_BDTR_BKF_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ +#define ATIM_BDTR_BK2F_SHIFT (20) /* Bits 20-23: Break 2 filter */ +#define ATIM_BDTR_BK2F_MASK (15 << ATIM_BDTR_BK2F_SHIFT) +# define ATIM_BDTR_BK2F_NOFILT (0 << ATIM_BDTR_BK2F_SHIFT) /* 0000: No filter, BRK 2 acts asynchronously */ +# define ATIM_BDTR_BK2F_FCKINT2 (1 << ATIM_BDTR_BK2F_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define ATIM_BDTR_BK2F_FCKINT4 (2 << ATIM_BDTR_BK2F_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define ATIM_BDTR_BK2F_FCKINT8 (3 << ATIM_BDTR_BK2F_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd26 (4 << ATIM_BDTR_BK2F_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd28 (5 << ATIM_BDTR_BK2F_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd36 (6 << ATIM_BDTR_BK2F_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd38 (7 << ATIM_BDTR_BK2F_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd86 (8 << ATIM_BDTR_BK2F_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd88 (9 << ATIM_BDTR_BK2F_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd165 (10 << ATIM_BDTR_BK2F_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define ATIM_BDTR_BK2F_FDTSd166 (11 << ATIM_BDTR_BK2F_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd168 (12 << ATIM_BDTR_BK2F_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define ATIM_BDTR_BK2F_FDTSd325 (13 << ATIM_BDTR_BK2F_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define ATIM_BDTR_BK2F_FDTSd326 (14 << ATIM_BDTR_BK2F_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define ATIM_BDTR_BK2F_FDTSd328 (15 << ATIM_BDTR_BK2F_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ +#define ATIM_BDTR_BK2E (1 << 24) /* Bit 24: Break 2 enable */ +#define ATIM_BDTR_BK2P (1 << 25) /* Bit 25: Break 2 polarity */ +#define ATIM_BDTR_BKDSRM (1 << 26) /* Bit 26: Break Disarm */ +#define ATIM_BDTR_BK2DSRM (1 << 27) /* Bit 27: Break 2 Disarm */ +#define ATIM_BDTR_BKBID (1 << 28) /* Bit 28: Break Bidirectional */ +#define ATIM_BDTR_BK2BID (1 << 29) /* Bit 29: Break 2 Bidirectional */ + +/* DMA control register */ + +#define ATIM_DCR_DBA_SHIFT (0) /* Bits 4-0: DMA Base Address */ +#define ATIM_DCR_DBA_MASK (0x1f << ATIM_DCR_DBA_SHIFT) +#define ATIM_DCR_DBL_SHIFT (8) /* Bits 12-8: DMA Burst Length */ +#define ATIM_DCR_DBL_MASK (0x1f << ATIM_DCR_DBL_SHIFT) +# define ATIM_DCR_DBL(n) (((n)-1) << ATIM_DCR_DBL_SHIFT) /* n transfers, n = 1..18 */ + +/* Control register 1 (TIM2-5) */ + +#define GTIM_CR1_CEN (1 << 0) /* Bit 0: Counter enable */ +#define GTIM_CR1_UDIS (1 << 1) /* Bit 1: Update Disable */ +#define GTIM_CR1_URS (1 << 2) /* Bit 2: Update Request Source */ +#define GTIM_CR1_OPM (1 << 3) /* Bit 3: One Pulse Mode (TIM2-5, 9, and 12 only) */ +#define GTIM_CR1_DIR (1 << 4) /* Bit 4: Direction (TIM2-5 only) */ +#define GTIM_CR1_CMS_SHIFT (5) /* Bits 6-5: Center-aligned Mode Selection (TIM2-5 only) */ +#define GTIM_CR1_CMS_MASK (3 << GTIM_CR1_CMS_SHIFT) +# define GTIM_CR1_EDGE (0 << GTIM_CR1_CMS_SHIFT) /* 00: Edge-aligned mode. */ +# define GTIM_CR1_CENTER1 (1 << GTIM_CR1_CMS_SHIFT) /* 01: Center-aligned mode 1 */ +# define GTIM_CR1_CENTER2 (2 << GTIM_CR1_CMS_SHIFT) /* 10: Center-aligned mode 2 */ +# define GTIM_CR1_CENTER3 (3 << GTIM_CR1_CMS_SHIFT) /* 11: Center-aligned mode 3 */ +#define GTIM_CR1_ARPE (1 << 7) /* Bit 7: Auto-Reload Preload enable */ +#define GTIM_CR1_CKD_SHIFT (8) /* Bits 9-8: Clock Division */ +#define GTIM_CR1_CKD_MASK (3 << GTIM_CR1_CKD_SHIFT) +# define GTIM_CR1_TCKINT (0 << GTIM_CR1_CKD_SHIFT) /* 00: tDTS = tCK_INT */ +# define GTIM_CR1_2TCKINT (1 << GTIM_CR1_CKD_SHIFT) /* 01: tDTS = 2 x tCK_INT */ +# define GTIM_CR1_4TCKINT (2 << GTIM_CR1_CKD_SHIFT) /* 10: tDTS = 4 x tCK_INT */ +#define GTIM_CR1_UIFREMAP (1 << 11) /* Bit 11: UIF status bit remapping */ + +/* Control register 2 (TIM2-5, and TIM15-17 only) */ + +#define GTIM_CR2_CCPC (1 << 0) /* Bit 0: Capture/compare preloaded control (TIM15-17 only) */ +#define GTIM_CR2_CCUS (1 << 2) /* Bit 2: Capture/compare control update selection (TIM15-17 only) */ +#define GTIM_CR2_CCDS (1 << 3) /* Bit 3: Capture/Compare DMA Selection (TIM2-5,1,&16 only) */ +#define GTIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection (not TIM16) */ +#define GTIM_CR2_MMS_MASK (7 << GTIM_CR2_MMS_SHIFT) +# define GTIM_CR2_MMS_RESET (0 << GTIM_CR2_MMS_SHIFT) /* 000: Reset */ +# define GTIM_CR2_MMS_ENABLE (1 << GTIM_CR2_MMS_SHIFT) /* 001: Enable */ +# define GTIM_CR2_MMS_UPDATE (2 << GTIM_CR2_MMS_SHIFT) /* 010: Update */ +# define GTIM_CR2_MMS_COMPP (3 << GTIM_CR2_MMS_SHIFT) /* 011: Compare Pulse */ +# define GTIM_CR2_MMS_OC1REF (4 << GTIM_CR2_MMS_SHIFT) /* 100: Compare - OC1REF signal is used as trigger output (TRGO) */ +# define GTIM_CR2_MMS_OC2REF (5 << GTIM_CR2_MMS_SHIFT) /* 101: Compare - OC2REF signal is used as trigger output (TRGO) */ +# define GTIM_CR2_MMS_OC3REF (6 << GTIM_CR2_MMS_SHIFT) /* 110: Compare - OC3REF signal is used as trigger output (TRGO, TIM2-5 and TIM15 only) */ +# define GTIM_CR2_MMS_OC4REF (7 << GTIM_CR2_MMS_SHIFT) /* 111: Compare - OC4REF signal is used as trigger output (TRGO, TIM2-5 and TIM15 only) */ +#define GTIM_CR2_TI1S (1 << 7) /* Bit 7: TI1 Selection (not TIM16) */ +#define GTIM_CR2_OIS1 (1 << 8) /* Bit 8: COutput Idle state 1 (OC1 output) (TIM15-17 only) */ +#define GTIM_CR2_OIS1N (1 << 9) /* Bit 9: Output Idle state 1 (OC1N output) (TIM15-17 only) */ +#define GTIM_CR2_OIS2 (1 << 10) /* Bit 10: Output idle state 2 (OC2 output) (TIM15 only) */ + +/* Slave mode control register (TIM2-5 and TIM15 only) */ + +#define GTIM_SMCR_SMS_SHIFT (0) /* Bits 2-0: Slave Mode Selection */ +#define GTIM_SMCR_SMS_MASK (7 << GTIM_SMCR_SMS_SHIFT) +# define GTIM_SMCR_DISAB (0 << GTIM_SMCR_SMS_SHIFT) /* 000: Slave mode disabled */ +# define GTIM_SMCR_ENCMD1 (1 << GTIM_SMCR_SMS_SHIFT) /* 001: Encoder mode 1 */ +# define GTIM_SMCR_ENCMD2 (2 << GTIM_SMCR_SMS_SHIFT) /* 010: Encoder mode 2 */ +# define GTIM_SMCR_ENCMD3 (3 << GTIM_SMCR_SMS_SHIFT) /* 011: Encoder mode 3 */ +# define GTIM_SMCR_RESET (4 << GTIM_SMCR_SMS_SHIFT) /* 100: Reset Mode */ +# define GTIM_SMCR_GATED (5 << GTIM_SMCR_SMS_SHIFT) /* 101: Gated Mode */ +# define GTIM_SMCR_TRIGGER (6 << GTIM_SMCR_SMS_SHIFT) /* 110: Trigger Mode */ +# define GTIM_SMCR_EXTCLK1 (7 << GTIM_SMCR_SMS_SHIFT) /* 111: External Clock Mode 1 */ +#define GTIM_SMCR_TS_SHIFT (4) /* Bits 6-4: Trigger Selection */ +#define GTIM_SMCR_TS_MASK (7 << GTIM_SMCR_TS_SHIFT) +# define GTIM_SMCR_ITR0 (0 << GTIM_SMCR_TS_SHIFT) /* 000: Internal Trigger 0 (ITR0). TIM1 */ +# define GTIM_SMCR_ITR1 (1 << GTIM_SMCR_TS_SHIFT) /* 001: Internal Trigger 1 (ITR1). TIM2 */ +# define GTIM_SMCR_ITR2 (2 << GTIM_SMCR_TS_SHIFT) /* 010: Internal Trigger 2 (ITR2). TIM3 */ +# define GTIM_SMCR_ITR3 (3 << GTIM_SMCR_TS_SHIFT) /* 011: Internal Trigger 3 (ITR3). TIM4 */ +# define GTIM_SMCR_TI1FED (4 << GTIM_SMCR_TS_SHIFT) /* 100: TI1 Edge Detector (TI1F_ED) */ +# define GTIM_SMCR_TI1FP1 (5 << GTIM_SMCR_TS_SHIFT) /* 101: Filtered Timer Input 1 (TI1FP1) */ +# define GTIM_SMCR_TI2FP2 (6 << GTIM_SMCR_TS_SHIFT) /* 110: Filtered Timer Input 2 (TI2FP2) */ +# define GTIM_SMCR_ETRF (7 << GTIM_SMCR_TS_SHIFT) /* 111: External Trigger input (ETRF) */ +#define GTIM_SMCR_MSM (1 << 7) /* Bit 7: Master/Slave mode */ +#define GTIM_SMCR_ETF_SHIFT (8) /* Bits 11-8: External Trigger Filter (not TIM15) */ +#define GTIM_SMCR_ETF_MASK (0x0f << GTIM_SMCR_ETF_SHIFT) +# define GTIM_SMCR_NOFILT (0 << GTIM_SMCR_ETF_SHIFT) /* 0000: No filter, sampling is done at fDTS */ +# define GTIM_SMCR_FCKINT2 (1 << GTIM_SMCR_ETF_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define GTIM_SMCR_FCKINT4 (2 << GTIM_SMCR_ETF_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define GTIM_SMCR_FCKINT8 (3 << GTIM_SMCR_ETF_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define GTIM_SMCR_FDTSd26 (4 << GTIM_SMCR_ETF_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define GTIM_SMCR_FDTSd28 (5 << GTIM_SMCR_ETF_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define GTIM_SMCR_FDTSd36 (6 << GTIM_SMCR_ETF_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define GTIM_SMCR_FDTSd38 (7 << GTIM_SMCR_ETF_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define GTIM_SMCR_FDTSd86 (8 << GTIM_SMCR_ETF_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define GTIM_SMCR_FDTSd88 (9 << GTIM_SMCR_ETF_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define GTIM_SMCR_FDTSd165 (10 << GTIM_SMCR_ETF_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define GTIM_SMCR_FDTSd166 (11 << GTIM_SMCR_ETF_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define GTIM_SMCR_FDTSd168 (12 << GTIM_SMCR_ETF_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define GTIM_SMCR_FDTSd325 (13 << GTIM_SMCR_ETF_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define GTIM_SMCR_FDTSd326 (14 << GTIM_SMCR_ETF_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define GTIM_SMCR_FDTSd328 (15 << GTIM_SMCR_ETF_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ +#define GTIM_SMCR_ETPS_SHIFT (12) /* Bits 13-12: External Trigger Prescaler (not TIM15) */ +#define GTIM_SMCR_ETPS_MASK (3 << GTIM_SMCR_ETPS_SHIFT) +# define GTIM_SMCR_PSCOFF (0 << GTIM_SMCR_ETPS_SHIFT) /* 00: Prescaler OFF */ +# define GTIM_SMCR_ETRPd2 (1 << GTIM_SMCR_ETPS_SHIFT) /* 01: ETRP frequency divided by 2 */ +# define GTIM_SMCR_ETRPd4 (2 << GTIM_SMCR_ETPS_SHIFT) /* 10: ETRP frequency divided by 4 */ +# define GTIM_SMCR_ETRPd8 (3 << GTIM_SMCR_ETPS_SHIFT) /* 11: ETRP frequency divided by 8 */ +#define GTIM_SMCR_ECE (1 << 14) /* Bit 14: External Clock enable */ +#define GTIM_SMCR_ETP (1 << 15) /* Bit 15: External Trigger Polarity */ +#define GTIM_SMCR_SMS (1 << 16) /* Bit 16: Slave mode selection - bit 3 */ + +/* DMA/Interrupt enable register (TIM2-5) */ + +#define GTIM_DIER_UIE (1 << 0) /* Bit 0: Update interrupt enable */ +#define GTIM_DIER_CC1IE (1 << 1) /* Bit 1: Capture/Compare 1 interrupt enable */ +#define GTIM_DIER_CC2IE (1 << 2) /* Bit 2: Capture/Compare 2 interrupt enable (TIM2-5,9,12,&15 only) */ +#define GTIM_DIER_CC3IE (1 << 3) /* Bit 3: Capture/Compare 3 interrupt enable (TIM2-5 only) */ +#define GTIM_DIER_CC4IE (1 << 4) /* Bit 4: Capture/Compare 4 interrupt enable (TIM2-5 only) */ +#define GTIM_DIER_COMIE (1 << 5) /* Bit 5: COM interrupt enable (TIM15-17 only) */ +#define GTIM_DIER_TIE (1 << 6) /* Bit 6: Trigger interrupt enable (TIM2-5,9,&12 only) */ +#define GTIM_DIER_BIE (1 << 7) /* Bit 7: Break interrupt enable (TIM15-17 only) */ +#define GTIM_DIER_UDE (1 << 8) /* Bit 8: Update DMA request enable (TIM2-5&15-17 only) */ +#define GTIM_DIER_CC1DE (1 << 9) /* Bit 9: Capture/Compare 1 DMA request enable (TIM2-5&15-17 only) */ +#define GTIM_DIER_CC2DE (1 << 10) /* Bit 10: Capture/Compare 2 DMA request enable (TIM2-5&15 only) */ +#define GTIM_DIER_CC3DE (1 << 11) /* Bit 11: Capture/Compare 3 DMA request enable (TIM2-5 only) */ +#define GTIM_DIER_CC4DE (1 << 12) /* Bit 12: Capture/Compare 4 DMA request enable (TIM2-5 only) */ +#define GTIM_DIER_COMDE (1 << 13) /* Bit 13: COM DMA request enable (TIM15-17 only) */ +#define GTIM_DIER_TDE (1 << 14) /* Bit 14: Trigger DMA request enable (TIM2-5&15-17 only) */ + +/* Status register */ + +#define GTIM_SR_UIF (1 << 0) /* Bit 0: Update interrupt flag */ +#define GTIM_SR_CC1IF (1 << 1) /* Bit 1: Capture/compare 1 interrupt flag */ +#define GTIM_SR_CC2IF (1 << 2) /* Bit 2: Capture/Compare 2 interrupt flag (TIM2-5,9,12,&15 only) */ +#define GTIM_SR_CC3IF (1 << 3) /* Bit 3: Capture/Compare 3 interrupt flag (TIM2-5 only) */ +#define GTIM_SR_CC4IF (1 << 4) /* Bit 4: Capture/Compare 4 interrupt flag (TIM2-5 only) */ +#define GTIM_SR_COMIF (1 << 5) /* Bit 5: COM interrupt flag (TIM15-17 only) */ +#define GTIM_SR_TIF (1 << 6) /* Bit 6: Trigger interrupt Flag (TIM2-5,9,12&15-17 only) */ +#define GTIM_SR_BIF (1 << 7) /* Bit 7: Break interrupt flag (TIM15-17 only) */ +#define GTIM_SR_CC1OF (1 << 9) /* Bit 9: Capture/Compare 1 Overcapture flag */ +#define GTIM_SR_CC2OF (1 << 10) /* Bit 10: Capture/Compare 2 Overcapture flag (TIM2-5,9,12&15 only) */ +#define GTIM_SR_CC3OF (1 << 11) /* Bit 11: Capture/Compare 3 Overcapture flag (TIM2-5 only) */ +#define GTIM_SR_CC4OF (1 << 12) /* Bit 12: Capture/Compare 4 Overcapture flag (TIM2-5 only) */ + +/* Event generation register (TIM2-5, TIM15-17) */ + +#define GTIM_EGR_UG (1 << 0) /* Bit 0: Update generation */ +#define GTIM_EGR_CC1G (1 << 1) /* Bit 1: Capture/compare 1 generation */ +#define GTIM_EGR_CC2G (1 << 2) /* Bit 2: Capture/compare 2 generation (TIM2-5,15 only) */ +#define GTIM_EGR_CC3G (1 << 3) /* Bit 3: Capture/compare 3 generation (TIM2-5 only) */ +#define GTIM_EGR_CC4G (1 << 4) /* Bit 4: Capture/compare 4 generation (TIM2-5 only) */ +#define GTIM_EGR_COMIG (1 << 5) /* Bit 5: Capture/Compare control update generation (TIM15-17 only) */ +#define GTIM_EGR_TG (1 << 6) /* Bit 6: Trigger generation (TIM2-5,16-17 only) */ +#define GTIM_EGR_BG (1 << 7) /* Bit 7: Break generation (TIM15-17 only) */ + +/* Capture/compare mode register 1 - Output compare mode (TIM2-5) */ + +#define GTIM_CCMR1_CC1S_SHIFT (0) /* Bits 1-0: Capture/Compare 1 Selection */ +#define GTIM_CCMR1_CC1S_MASK (3 << GTIM_CCMR1_CC1S_SHIFT) +#define GTIM_CCMR1_OC1FE (1 << 2) /* Bit 2: Output Compare 1 Fast enable */ +#define GTIM_CCMR1_OC1PE (1 << 3) /* Bit 3: Output Compare 1 Preload enable */ +#define GTIM_CCMR1_OC1M_SHIFT (4) /* Bits 6-4: Output Compare 1 Mode */ +#define GTIM_CCMR1_OC1M_MASK (7 << GTIM_CCMR1_OC1M_SHIFT) +#define GTIM_CCMR1_OC1CE (1 << 7) /* Bit 7: Output Compare 1Clear Enable */ +#define GTIM_CCMR1_CC2S_SHIFT (8) /* Bits 9-8: Capture/Compare 2 Selection */ +#define GTIM_CCMR1_CC2S_MASK (3 << GTIM_CCMR1_CC2S_SHIFT) +#define GTIM_CCMR1_OC2FE (1 << 10) /* Bit 10: Output Compare 2 Fast enable */ +#define GTIM_CCMR1_OC2PE (1 << 11) /* Bit 11: Output Compare 2 Preload enable */ +#define GTIM_CCMR1_OC2M_SHIFT (12) /* Bits 14-12: Output Compare 2 Mode */ +#define GTIM_CCMR1_OC2M_MASK (7 << GTIM_CCMR1_OC2M_SHIFT) +#define GTIM_CCMR1_OC2CE (1 << 15) /* Bit 15: Output Compare 2 Clear Enable */ +#define GTIM_CCMR1_OC1M (1 << 16) /* Bit 16: Output Compare 1 mode - bit 3 */ +#define GTIM_CCMR1_OC2M (1 << 24) /* Bit 24: Output Compare 2 mode - bit 3 */ + +/* Common CCMR (unshifted) Capture/Compare Selection bit-field definitions */ + +#define GTIM_CCMR_CCS_CCOUT (0) /* 00: CCx channel output */ +#define GTIM_CCMR_CCS_CCIN1 (1) /* 01: CCx channel input, ICx is TIx */ +#define GTIM_CCMR_CCS_CCIN2 (2) /* 10: CCx channel input, ICx is TIy */ +#define GTIM_CCMR_CCS_CCINTRC (3) /* 11: CCx channel input, ICx is TRC */ + +/* Common CCMR (unshifted) Compare Mode bit field definitions */ + +#define GTIM_CCMR_MODE_FRZN (0) /* 000: Frozen */ +#define GTIM_CCMR_MODE_CHACT (1) /* 001: Channel x active on match */ +#define GTIM_CCMR_MODE_CHINACT (2) /* 010: Channel x inactive on match */ +#define GTIM_CCMR_MODE_OCREFTOG (3) /* 011: OCxREF toggle ATIM_CNT=ATIM_CCRx */ +#define GTIM_CCMR_MODE_OCREFLO (4) /* 100: OCxREF forced low */ +#define GTIM_CCMR_MODE_OCREFHI (5) /* 101: OCxREF forced high */ +#define GTIM_CCMR_MODE_PWM1 (6) /* 110: PWM mode 1 */ +#define GTIM_CCMR_MODE_PWM2 (7) /* 111: PWM mode 2 */ + +/* Capture/compare mode register 1 - Input capture mode + * (TIM2-5 and TIM9-14) + */ + +#define GTIM_CCMR1_IC1PSC_SHIFT (2) /* Bits 3-2: Input Capture 1 Prescaler */ +#define GTIM_CCMR1_IC1PSC_MASK (3 << GTIM_CCMR1_IC1PSC_SHIFT) +#define GTIM_CCMR1_IC1F_SHIFT (4) /* Bits 7-4: Input Capture 1 Filter */ +#define GTIM_CCMR1_IC1F_MASK (0x0f << GTIM_CCMR1_IC1F_SHIFT) +#define GTIM_CCMR1_IC2PSC_SHIFT (10) /* Bits 11-10: Input Capture 2 Prescaler */ +#define GTIM_CCMR1_IC2PSC_MASK (3 << GTIM_CCMR1_IC2PSC_SHIFT) +#define GTIM_CCMR1_IC2F_SHIFT (12) /* Bits 15-12: Input Capture 2 Filter */ +#define GTIM_CCMR1_IC2F_MASK (0x0f << GTIM_CCMR1_IC2F_SHIFT) + +/* Common CCMR (unshifted) Input Capture Prescaler bit-field definitions */ + +#define GTIM_CCMR_ICPSC_NOPSC (0) /* 00: no prescaler, capture each edge */ +#define GTIM_CCMR_ICPSC_EVENTS2 (1) /* 01: capture once every 2 events */ +#define GTIM_CCMR_ICPSC_EVENTS4 (2) /* 10: capture once every 4 events */ +#define GTIM_CCMR_ICPSC_EVENTS8 (3) /* 11: capture once every 8 events */ + +/* Common CCMR (unshifted) Input Capture Filter bit-field definitions */ + +#define GTIM_CCMR_ICF_NOFILT (0) /* 0000: No filter, sampling at fDTS */ +#define GTIM_CCMR_ICF_FCKINT2 (1) /* 0001: fSAMPLING=fCK_INT, N=2 */ +#define GTIM_CCMR_ICF_FCKINT4 (2) /* 0010: fSAMPLING=fCK_INT, N=4 */ +#define GTIM_CCMR_ICF_FCKINT8 (3) /* 0011: fSAMPLING=fCK_INT, N=8 */ +#define GTIM_CCMR_ICF_FDTSd26 (4) /* 0100: fSAMPLING=fDTS/2, N=6 */ +#define GTIM_CCMR_ICF_FDTSd28 (5) /* 0101: fSAMPLING=fDTS/2, N=8 */ +#define GTIM_CCMR_ICF_FDTSd46 (6) /* 0110: fSAMPLING=fDTS/4, N=6 */ +#define GTIM_CCMR_ICF_FDTSd48 (7) /* 0111: fSAMPLING=fDTS/4, N=8 */ +#define GTIM_CCMR_ICF_FDTSd86 (8) /* 1000: fSAMPLING=fDTS/8, N=6 */ +#define GTIM_CCMR_ICF_FDTSd88 (9) /* 1001: fSAMPLING=fDTS/8, N=8 */ +#define GTIM_CCMR_ICF_FDTSd165 (10) /* 1010: fSAMPLING=fDTS/16, N=5 */ +#define GTIM_CCMR_ICF_FDTSd166 (11) /* 1011: fSAMPLING=fDTS/16, N=6 */ +#define GTIM_CCMR_ICF_FDTSd168 (12) /* 1100: fSAMPLING=fDTS/16, N=8 */ +#define GTIM_CCMR_ICF_FDTSd325 (13) /* 1101: fSAMPLING=fDTS/32, N=5 */ +#define GTIM_CCMR_ICF_FDTSd326 (14) /* 1110: fSAMPLING=fDTS/32, N=6 */ +#define GTIM_CCMR_ICF_FDTSd328 (15) /* 1111: fSAMPLING=fDTS/32, N=8 */ + +/* Capture/compare mode register 2 - Output Compare mode (TIM2-5 only) */ + +#define GTIM_CCMR2_CC3S_SHIFT (0) /* Bits 1-0: Capture/Compare 3 Selection */ +#define GTIM_CCMR2_CC3S_MASK (3 << GTIM_CCMR2_CC3S_SHIFT) +#define GTIM_CCMR2_OC3FE (1 << 2) /* Bit 2: Output Compare 3 Fast enable */ +#define GTIM_CCMR2_OC3PE (1 << 3) /* Bit 3: Output Compare 3 Preload enable */ +#define GTIM_CCMR2_OC3M_SHIFT (4) /* Bits 6-4: Output Compare 3 Mode */ +#define GTIM_CCMR2_OC3M_MASK (7 << GTIM_CCMR2_OC3M_SHIFT) +#define GTIM_CCMR2_OC3CE (1 << 7) /* Bit 7: Output Compare 3 Clear Enable */ +#define GTIM_CCMR2_CC4S_SHIFT (8) /* Bits 9-8: Capture/Compare 4 Selection */ +#define GTIM_CCMR2_CC4S_MASK (3 << GTIM_CCMR2_CC4S_SHIFT) +#define GTIM_CCMR2_OC4FE (1 << 10) /* Bit 10: Output Compare 4 Fast enable */ +#define GTIM_CCMR2_OC4PE (1 << 11) /* Bit 11: Output Compare 4 Preload enable */ +#define GTIM_CCMR2_OC4M_SHIFT (12) /* Bits 14-12: Output Compare 4 Mode */ +#define GTIM_CCMR2_OC4M_MASK (7 << GTIM_CCMR2_OC4M_SHIFT) +#define GTIM_CCMR2_OC4CE (1 << 15) /* Bit 15: Output Compare 4 Clear Enable */ + +/* Capture/compare mode register 2 - Input capture mode (TIM2-5 only) */ + +#define GTIM_CCMR2_IC3PSC_SHIFT (2) /* Bits 3-2: Input Capture 3 Prescaler */ +#define GTIM_CCMR2_IC3PSC_MASK (3 << GTIM_CCMR2_IC3PSC_SHIFT) +#define GTIM_CCMR2_IC3F_SHIFT (4) /* Bits 7-4: Input Capture 3 Filter */ +#define GTIM_CCMR2_IC3F_MASK (0x0f << GTIM_CCMR2_IC3F_SHIFT) +#define GTIM_CCMR2_IC4PSC_SHIFT (10) /* Bits 11-10: Input Capture 4 Prescaler */ +#define GTIM_CCMR2_IC4PSC_MASK (3 << GTIM_CCMR2_IC4PSC_SHIFT) +#define GTIM_CCMR2_IC4F_SHIFT (12) /* Bits 15-12: Input Capture 4 Filter */ +#define GTIM_CCMR2_IC4F_MASK (0x0f << GTIM_CCMR2_IC4F_SHIFT) + +/* Capture/compare enable register (TIM1 and TIM8, TIM2-5) */ + +#define GTIM_CCER_CC1E (1 << 0) /* Bit 0: Capture/Compare 1 output enable */ +#define GTIM_CCER_CC1P (1 << 1) /* Bit 1: Capture/Compare 1 output polarity */ +#define GTIM_CCER_CC1NE (1 << 2) /* Bit 2: Capture/Compare 1 complementary output enable (TIM1 and TIM8 only) */ +#define GTIM_CCER_CC1NP (1 << 3) /* Bit 3: Capture/Compare 1 output Polarity (F2,F3,F4 and TIM15-17) */ +#define GTIM_CCER_CC2E (1 << 4) /* Bit 4: Capture/Compare 2 output enable (TIM2-5,9&12 only) */ +#define GTIM_CCER_CC2P (1 << 5) /* Bit 5: Capture/Compare 2 output polarity (TIM2-5,9&12 only) */ +#define GTIM_CCER_CC2NE (1 << 6) /* Bit 6: Capture/Compare 2 complementary output enable (TIM1 and TIM8 only) */ +#define GTIM_CCER_CC2NP (1 << 7) /* Bit 7: Capture/Compare 2 output Polarity (F2,F3,F4 and TIM2-5,9,12&15 only) */ +#define GTIM_CCER_CC3E (1 << 8) /* Bit 8: Capture/Compare 3 output enable (TIM2-5 only) */ +#define GTIM_CCER_CC3P (1 << 9) /* Bit 9: Capture/Compare 3 output Polarity (TIM2-5 only) */ +#define GTIM_CCER_CC3NE (1 << 10) /* Bit 10: Capture/Compare 3 complementary output enable (TIM1 and TIM8 only) */ +#define GTIM_CCER_CC3NP (1 << 11) /* Bit 11: Capture/Compare 3 output Polarity (F2,F4 and TIM2-5 only) */ +#define GTIM_CCER_CC4E (1 << 12) /* Bit 12: Capture/Compare 4 output enable (TIM2-5 only) */ +#define GTIM_CCER_CC4P (1 << 13) /* Bit 13: Capture/Compare 4 output Polarity (TIM2-5 only) */ +#define GTIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 output Polarity */ +#define GTIM_CCER_CCXBASE(ch) (ch << 2) /* Each channel uses 4-bits */ + +/* 16-bit counter register */ + +#define GTIM_CNT_SHIFT (0) /* Bits 0-15: Timer counter value */ +#define GTIM_CNT_MASK (0xffff << ATIM_CNT_SHIFT) + +/* Repetition counter (TIM15-17 only) */ + +#define GTIM_RCR_REP_SHIFT (0) /* Bits 0-7: Repetition Counter Value */ +#define GTIM_RCR_REP_MASK (0xff << GTIM_RCR_REP_SHIFT) + +#define GTIM_RCR_REP_MAX 128 + +/* Break and dead-time register (TIM15-17 only */ + +#define GTIM_BDTR_DTG_SHIFT (0) /* Bits 7:0 [7:0]: Dead-Time Generator set-up */ +#define GTIM_BDTR_DTG_MASK (0xff << GTIM_BDTR_DTG_SHIFT) +#define GTIM_BDTR_LOCK_SHIFT (8) /* Bits 9:8 [1:0]: Lock Configuration */ +#define GTIM_BDTR_LOCK_MASK (3 << GTIM_BDTR_LOCK_SHIFT) +# define GTIM_BDTR_LOCKOFF (0 << GTIM_BDTR_LOCK_SHIFT) /* 00: LOCK OFF - No bit is write protected */ +# define GTIM_BDTR_LOCK1 (1 << GTIM_BDTR_LOCK_SHIFT) /* 01: LOCK Level 1 protection */ +# define GTIM_BDTR_LOCK2 (2 << GTIM_BDTR_LOCK_SHIFT) /* 10: LOCK Level 2 protection */ +# define GTIM_BDTR_LOCK3 (3 << GTIM_BDTR_LOCK_SHIFT) /* 11: LOCK Level 3 protection */ +#define GTIM_BDTR_OSSI (1 << 10) /* Bit 10: Off-State Selection for Idle mode */ +#define GTIM_BDTR_OSSR (1 << 11) /* Bit 11: Off-State Selection for Run mode */ +#define GTIM_BDTR_BKE (1 << 12) /* Bit 12: Break enable */ +#define GTIM_BDTR_BKP (1 << 13) /* Bit 13: Break Polarity */ +#define GTIM_BDTR_AOE (1 << 14) /* Bit 14: Automatic Output enable */ +#define GTIM_BDTR_MOE (1 << 15) /* Bit 15: Main Output enable */ +#define GTIM_BDTR_BKF_SHIFT (16) /* Bits 16-19: Break filter */ +#define GTIM_BDTR_BKF_MASK (15 << GTIM_BDTR_BKF_SHIFT) +# define GTIM_BDTR_BKF_NOFILT (0 << GTIM_BDTR_BKF_SHIFT) /* 0000: No filter, BRK acts asynchronously */ +# define GTIM_BDTR_BKF_FCKINT2 (1 << GTIM_BDTR_BKF_SHIFT) /* 0001: fSAMPLING=fCK_INT, N=2 */ +# define GTIM_BDTR_BKF_FCKINT4 (2 << GTIM_BDTR_BKF_SHIFT) /* 0010: fSAMPLING=fCK_INT, N=4 */ +# define GTIM_BDTR_BKF_FCKINT8 (3 << GTIM_BDTR_BKF_SHIFT) /* 0011: fSAMPLING=fCK_INT, N=8 */ +# define GTIM_BDTR_BKF_FDTSd26 (4 << GTIM_BDTR_BKF_SHIFT) /* 0100: fSAMPLING=fDTS/2, N=6 */ +# define GTIM_BDTR_BKF_FDTSd28 (5 << GTIM_BDTR_BKF_SHIFT) /* 0101: fSAMPLING=fDTS/2, N=8 */ +# define GTIM_BDTR_BKF_FDTSd36 (6 << GTIM_BDTR_BKF_SHIFT) /* 0110: fSAMPLING=fDTS/4, N=6 */ +# define GTIM_BDTR_BKF_FDTSd38 (7 << GTIM_BDTR_BKF_SHIFT) /* 0111: fSAMPLING=fDTS/4, N=8 */ +# define GTIM_BDTR_BKF_FDTSd86 (8 << GTIM_BDTR_BKF_SHIFT) /* 1000: fSAMPLING=fDTS/8, N=6 */ +# define GTIM_BDTR_BKF_FDTSd88 (9 << GTIM_BDTR_BKF_SHIFT) /* 1001: fSAMPLING=fDTS/8, N=8 */ +# define GTIM_BDTR_BKF_FDTSd165 (10 << GTIM_BDTR_BKF_SHIFT) /* 1010: fSAMPLING=fDTS/16, N=5 */ +# define GTIM_BDTR_BKF_FDTSd166 (11 << GTIM_BDTR_BKF_SHIFT) /* 1011: fSAMPLING=fDTS/16, N=6 */ +# define GTIM_BDTR_BKF_FDTSd168 (12 << GTIM_BDTR_BKF_SHIFT) /* 1100: fSAMPLING=fDTS/16, N=8 */ +# define GTIM_BDTR_BKF_FDTSd325 (13 << GTIM_BDTR_BKF_SHIFT) /* 1101: fSAMPLING=fDTS/32, N=5 */ +# define GTIM_BDTR_BKF_FDTSd326 (14 << GTIM_BDTR_BKF_SHIFT) /* 1110: fSAMPLING=fDTS/32, N=6 */ +# define GTIM_BDTR_BKF_FDTSd328 (15 << GTIM_BDTR_BKF_SHIFT) /* 1111: fSAMPLING=fDTS/32, N=8 */ + +/* DMA control register */ + +#define GTIM_DCR_DBA_SHIFT (0) /* Bits 4-0: DMA Base Address */ +#define GTIM_DCR_DBA_MASK (0x1f << GTIM_DCR_DBA_SHIFT) +#define GTIM_DCR_DBL_SHIFT (8) /* Bits 12-8: DMA Burst Length */ +#define GTIM_DCR_DBL_MASK (0x1f << GTIM_DCR_DBL_SHIFT) + +/* Control register 1 */ + +#define BTIM_CR1_CEN (1 << 0) /* Bit 0: Counter enable */ +#define BTIM_CR1_UDIS (1 << 1) /* Bit 1: Update Disable */ +#define BTIM_CR1_URS (1 << 2) /* Bit 2: Update Request Source */ +#define BTIM_CR1_OPM (1 << 3) /* Bit 3: One Pulse Mode */ +#define BTIM_CR1_ARPE (1 << 7) /* Bit 7: Auto-Reload Preload enable */ +#define BTIM_CR1_UIFREMAP (1 << 11) /* Bit 11: UIF status bit remapping */ + +/* Control register 2 */ + +#define BTIM_CR2_MMS_SHIFT (4) /* Bits 6-4: Master Mode Selection */ +#define BTIM_CR2_MMS_MASK (7 << BTIM_CR2_MMS_SHIFT) +# define BTIM_CR2_RESET (0 << BTIM_CR2_MMS_SHIFT) /* 000: Reset */ +# define BTIM_CR2_ENAB (1 << BTIM_CR2_MMS_SHIFT) /* 001: Enable */ +# define BTIM_CR2_UPDT (2 << BTIM_CR2_MMS_SHIFT) /* 010: Update */ + +/* DMA/Interrupt enable register */ + +#define BTIM_DIER_UIE (1 << 0) /* Bit 0: Update interrupt enable */ +#define BTIM_DIER_UDE (1 << 8) /* Bit 8: Update DMA request enable */ + +/* Status register */ + +#define BTIM_SR_UIF (1 << 0) /* Bit 0: Update interrupt flag */ + +/* Event generation register */ + +#define BTIM_EGR_UG (1 << 0) /* Bit 0: Update generation */ + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_TIM_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32_uart.h b/arch/arm/src/stm32u5/hardware/stm32_uart.h new file mode 100644 index 0000000000..91bec370fc --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32_uart.h @@ -0,0 +1,308 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32_uart.h + * + * 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_STM32U5_HARDWARE_STM32_UART_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * 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 */ +#define STM32_USART_AUTOCR_OFFSET 0x0030 /* Autonomous mode control register */ + +/* Register Addresses *******************************************************/ + +#if STM32_NUSART > 0 +# 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) +#endif + +#if STM32_NUSART > 1 +# define STM32_USART2_CR1 (STM32_USART2_BASE + STM32_USART_CR1_OFFSET) +# define STM32_USART2_CR2 (STM32_USART2_BASE + STM32_USART_CR2_OFFSET) +# define STM32_USART2_CR3 (STM32_USART2_BASE + STM32_USART_CR3_OFFSET) +# define STM32_USART2_BRR (STM32_USART2_BASE + STM32_USART_BRR_OFFSET) +# define STM32_USART2_GTPR (STM32_USART2_BASE + STM32_USART_GTPR_OFFSET) +# define STM32_USART2_RTOR (STM32_USART2_BASE + STM32_USART_RTOR_OFFSET) +# define STM32_USART2_RQR (STM32_USART2_BASE + STM32_USART_RQR_OFFSET) +# define STM32_USART2_ISR (STM32_USART2_BASE + STM32_USART_ISR_OFFSET) +# define STM32_USART2_ICR (STM32_USART2_BASE + STM32_USART_ICR_OFFSET) +# define STM32_USART2_RDR (STM32_USART2_BASE + STM32_USART_RDR_OFFSET) +# define STM32_USART2_TDR (STM32_USART2_BASE + STM32_USART_TDR_OFFSET) +# define STM32_USART2_PRESC (STM32_USART2_BASE + STM32_USART_PRESC_OFFSET) +#endif + +#if STM32_NUSART > 2 +# define STM32_USART3_CR1 (STM32_USART3_BASE + STM32_USART_CR1_OFFSET) +# define STM32_USART3_CR2 (STM32_USART3_BASE + STM32_USART_CR2_OFFSET) +# define STM32_USART3_CR3 (STM32_USART3_BASE + STM32_USART_CR3_OFFSET) +# define STM32_USART3_BRR (STM32_USART3_BASE + STM32_USART_BRR_OFFSET) +# define STM32_USART3_GTPR (STM32_USART3_BASE + STM32_USART_GTPR_OFFSET) +# define STM32_USART3_RTOR (STM32_USART3_BASE + STM32_USART_RTOR_OFFSET) +# define STM32_USART3_RQR (STM32_USART3_BASE + STM32_USART_RQR_OFFSET) +# define STM32_USART3_ISR (STM32_USART3_BASE + STM32_USART_ISR_OFFSET) +# define STM32_USART3_ICR (STM32_USART3_BASE + STM32_USART_ICR_OFFSET) +# define STM32_USART3_RDR (STM32_USART3_BASE + STM32_USART_RDR_OFFSET) +# define STM32_USART3_TDR (STM32_USART3_BASE + STM32_USART_TDR_OFFSET) +# define STM32_USART3_PRESC (STM32_USART3_BASE + STM32_USART_PRESC_OFFSET) +#endif + +#if STM32_NUSART > 3 +# define STM32_UART4_CR1 (STM32_UART4_BASE + STM32_USART_CR1_OFFSET) +# define STM32_UART4_CR2 (STM32_UART4_BASE + STM32_USART_CR2_OFFSET) +# define STM32_UART4_CR3 (STM32_UART4_BASE + STM32_USART_CR3_OFFSET) +# define STM32_UART4_BRR (STM32_UART4_BASE + STM32_USART_BRR_OFFSET) +# define STM32_UART4_GTPR (STM32_UART4_BASE + STM32_USART_GTPR_OFFSET) +# define STM32_UART4_RTOR (STM32_UART4_BASE + STM32_USART_RTOR_OFFSET) +# define STM32_UART4_RQR (STM32_UART4_BASE + STM32_USART_RQR_OFFSET) +# define STM32_UART4_ISR (STM32_UART4_BASE + STM32_USART_ISR_OFFSET) +# define STM32_UART4_ICR (STM32_UART4_BASE + STM32_USART_ICR_OFFSET) +# define STM32_UART4_RDR (STM32_UART4_BASE + STM32_USART_RDR_OFFSET) +# define STM32_UART4_TDR (STM32_UART4_BASE + STM32_USART_TDR_OFFSET) +# define STM32_UART4_PRESC (STM32_UART4_BASE + STM32_USART_PRESC_OFFSET) +#endif + +#if STM32_NUSART > 4 +# define STM32_UART5_CR1 (STM32_UART5_BASE + STM32_USART_CR1_OFFSET) +# define STM32_UART5_CR2 (STM32_UART5_BASE + STM32_USART_CR2_OFFSET) +# define STM32_UART5_CR3 (STM32_UART5_BASE + STM32_USART_CR3_OFFSET) +# define STM32_UART5_BRR (STM32_UART5_BASE + STM32_USART_BRR_OFFSET) +# define STM32_UART5_GTPR (STM32_UART5_BASE + STM32_USART_GTPR_OFFSET) +# define STM32_UART5_RTOR (STM32_UART5_BASE + STM32_USART_RTOR_OFFSET) +# define STM32_UART5_RQR (STM32_UART5_BASE + STM32_USART_RQR_OFFSET) +# define STM32_UART5_ISR (STM32_UART5_BASE + STM32_USART_ISR_OFFSET) +# define STM32_UART5_ICR (STM32_UART5_BASE + STM32_USART_ICR_OFFSET) +# define STM32_UART5_RDR (STM32_UART5_BASE + STM32_USART_RDR_OFFSET) +# define STM32_UART5_TDR (STM32_UART5_BASE + STM32_USART_TDR_OFFSET) +# define STM32_UART5_PRESC (STM32_UART5_BASE + STM32_USART_PRESC_OFFSET) +#endif + +/* 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_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 -> frame must start with 10xxxxxx */ +#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) + +/* Receiver timeout register */ + +/* Request Register */ + +#define USART_CR1_SBRKQ (1 << 1) /* Bit 1: Send Break */ + +/* 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_STM32U5_HARDWARE_STM32_UART_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32u585xx_dbgmcu.h b/arch/arm/src/stm32u5/hardware/stm32u585xx_dbgmcu.h new file mode 100644 index 0000000000..8528eb4be1 --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32u585xx_dbgmcu.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32u585xx_dbgmcu.h + * + * 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_STM32U5_HARDWARE_STM32U585XX_DBGMCU_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585XX_DBGMCU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Addresses *******************************************************/ + +#define STM32_DBGMCU_IDCODE 0xe0044000 /* MCU identifier */ +#define STM32_DBGMCU_CR 0xe0044004 /* MCU debug */ +#define STM32_DBGMCU_APB1_FZ 0xe0044008 /* Debug MCU APB1 freeze register */ +#define STM32_DBGMCU_APB1_FZ2 0xe004400c /* Debug MCU APB1 freeze register 2 */ +#define STM32_DBGMCU_APB2_FZ 0xe0044010 /* Debug MCU APB2 freeze register */ + +/* Register Bitfield Definitions ********************************************/ + +/* MCU identifier */ + +#define DBGMCU_IDCODE_DEVID_SHIFT (0) /* Bits 11-0: Device Identifier */ +#define DBGMCU_IDCODE_DEVID_MASK (0x0fff << DBGMCU_IDCODE_DEVID_SHIFT) +#define DBGMCU_IDCODE_REVID_SHIFT (16) /* Bits 31-16: Revision Identifier */ +#define DBGMCU_IDCODE_REVID_MASK (0xffff << DBGMCU_IDCODE_REVID_SHIFT) + +/* MCU debug */ + +#define DBGMCU_CR_STOP (1 << 1) /* Bit 1: Allows debug in Stop mode */ +#define DBGMCU_CR_STANDBY (1 << 2) /* Bit 2: Allows debug in Standby mode */ +#define DBGMCU_CR_TRACEIOEN (1 << 4) /* Bit 4: Trace pin enable */ +#define DBGMCU_CR_TRACEEN (1 << 5) /* Bit 5: Trace port and clock enable */ +#define DBGMCU_CR_TRACEMODE_SHIFT (6) /* Bits 7-6: Trace mode pin assignment */ +#define DBGMCU_CR_TRACEMODE_MASK (3 << DBGMCU_CR_TRACEMODE_SHIFT) +#define DBGMCU_CR_ASYNCH (0 << DBGMCU_CR_TRACEMODE_SHIFT) /* Asynchronous Mode */ +#define DBGMCU_CR_SYNCH1 (1 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=1 */ +#define DBGMCU_CR_SYNCH2 (2 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=2 */ +#define DBGMCU_CR_SYNCH4 (3 << DBGMCU_CR_TRACEMODE_SHIFT) /* Synchronous Mode, TRACEDATA size=4 */ + +/* Debug MCU APB1 freeze register */ + +#define DBGMCU_APB1_TIM2STOP (1 << 0) /* Bit 0: TIM2 stopped when core is halted */ +#define DBGMCU_APB1_TIM3STOP (1 << 1) /* Bit 1: TIM3 stopped when core is halted */ +#define DBGMCU_APB1_TIM4STOP (1 << 2) /* Bit 2: TIM4 stopped when core is halted */ +#define DBGMCU_APB1_TIM5STOP (1 << 3) /* Bit 3: TIM5 stopped when core is halted */ +#define DBGMCU_APB1_TIM6STOP (1 << 4) /* Bit 4: TIM6 stopped when core is halted */ +#define DBGMCU_APB1_TIM7STOP (1 << 5) /* Bit 5: TIM7 stopped when core is halted */ +#define DBGMCU_APB1_RTCSTOP (1 << 10) /* Bit 10: RTC stopped when Core is halted */ +#define DBGMCU_APB1_WWDGSTOP (1 << 11) /* Bit 11: Window Watchdog stopped when core is halted */ +#define DBGMCU_APB1_IWDGSTOP (1 << 12) /* Bit 12: Independent Watchdog stopped when core is halted */ +#define DBGMCU_APB1_I2C1STOP (1 << 21) /* Bit 21: I2C1 SMBUS timeout mode stopped when Core is halted */ +#define DBGMCU_APB1_I2C2STOP (1 << 22) /* Bit 22: I2C2 SMBUS timeout mode stopped when Core is halted */ +#define DBGMCU_APB1_I2C3STOP (1 << 23) /* Bit 23: I2C3 SMBUS timeout mode stopped when Core is halted */ +#define DBGMCU_APB1_LPTIM1STOP (1 << 31) /* Bit 31: LPTIM1 stopper when core is halted */ + +/* Debug MCU APB1 freeze register 2 */ + +#define DBGMCU_APB1_FZ2_LPTIM2STOP (1 << 5) /* Bit 5: LPTIM2 stopped when core is halted */ +#define DBGMCU_APB1_FZ2_LPTIM3STOP (1 << 6) /* Bit 6: LPTIM3 stopped when core is halted */ +#define DBGMCU_APB1_FZ2_I2C4STOP (1 << 1) /* Bit 1: I2C4 stopped when core is halted */ + +/* Debug MCU APB2 freeze register */ + +#define DBGMCU_APB2_TIM1STOP (1 << 11) /* Bit 11: TIM1 stopped when core is halted */ +#define DBGMCU_APB2_TIM8STOP (1 << 13) /* Bit 13: TIM8 stopped when core is halted */ +#define DBGMCU_APB2_TIM15STOP (1 << 16) /* Bit 16: TIM15 stopped when core is halted */ +#define DBGMCU_APB2_TIM16STOP (1 << 17) /* Bit 17: TIM16 stopped when core is halted */ +#define DBGMCU_APB2_TIM17STOP (1 << 18) /* Bit 18: TIM17 stopped when core is halted */ + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585XXDBGMCU_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32u585xx_pinmap.h b/arch/arm/src/stm32u5/hardware/stm32u585xx_pinmap.h new file mode 100644 index 0000000000..7b912e7c13 --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32u585xx_pinmap.h @@ -0,0 +1,1180 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32u585xx_pinmap.h + * + * 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_STM32U5_HARDWARE_STM32U585XX_PINMAP_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585XX_PINMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Alternate Pin Functions. All members of the STM32U585xx family share the + * same pin multiplexing (although they may differ in the pins physically + * available). See DB3734, Table 28 "Alternate Function AF0 + * to AF7" and Table 29 "Alternate Function AF8 to AF15". + * + * 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 FDCAN1_RX connects vis PA11 on some board, then the following + * definitions should appear inthe board.h header file for that board: + * + * #define GPIO_FDCAN1_RX GPIO_FDCAN1_RX_1 + * + * The driver will then automatically configure PA11 as the FDCAN1 RX pin. + * + * Note that this header file does not specify pull-up or -down resistors + * (GPIO_FLOAT, GPIO_PULLUP, GPIO_PULLDOWN), output frequency + * (GPIO_SPEED_2MHZ, GPIO_SPEED_25MHZ, GPIO_SPEED_50MHZ, GPIO_SPEED_100MHZ), + * or whether the pin is to be operated in push-pull or open-drain mode + * (GPIO_PUSHPULL, GPIO_OPENDRAIN). As all of this is application specific, + * it should be specified in corresponding board.h file. + */ + +/* ADC1 - Analog-to-digital converter */ + +#define GPIO_ADC1_IN1_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN2_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN3_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN4_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN5_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN6_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN7_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN8_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN9_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN10_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN11_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN12_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN13_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN14_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ADC1_IN15_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN16_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC1_IN17_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) + +/* ADC4 - Analog-to-digital converter */ + +#define GPIO_ADC4_IN1_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC4_IN2_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC4_IN3_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC4_IN4_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC4_IN5_1 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN14) +#define GPIO_ADC4_IN6_1 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN15) +#define GPIO_ADC4_IN7_1 (GPIO_ANALOG|GPIO_PORTG|GPIO_PIN0) +#define GPIO_ADC4_IN8_1 (GPIO_ANALOG|GPIO_PORTG|GPIO_PIN1) +#define GPIO_ADC4_IN9_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC4_IN10_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC4_IN11_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC4_IN15_1 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN11) +#define GPIO_ADC4_IN16_1 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN12) +#define GPIO_ADC4_IN17_1 (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN13) +#define GPIO_ADC4_IN18_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC4_IN19_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC4_IN20_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC4_IN22_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC4_IN23_1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +/* ADF1 - Audio digital filter */ + +#define GPIO_ADF1_CCK0_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN3) +#define GPIO_ADF1_CCK0_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN9) +#define GPIO_ADF1_CCK1_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN10) +#define GPIO_ADF1_SDI0_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN4) +#define GPIO_ADF1_SDI0_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN11) +#define GPIO_ADF1_SDI0_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN10) + +/* COMP1 - Comparator */ + +#define GPIO_COMP1_OUT_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN0) +#define GPIO_COMP1_OUT_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN10) + +/* COMP2 - Comparator */ + +#define GPIO_COMP2_OUT_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN5) +#define GPIO_COMP2_OUT_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN11) + +/* CRS - Clock recovery system */ + +#define GPIO_CRS_SYNC_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN10) +#define GPIO_CRS_SYNC_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN3) + +/* DBG - Debug support */ + +#define GPIO_JTCK_SWCLK_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14) +#define GPIO_JTDI_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN15) +#define GPIO_JTDO_TRACESWO_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN13) +#define GPIO_JTMS_SWDIO_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13) +#define GPIO_NJTRST_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TRACECLK_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TRACED0_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED1_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN10) +#define GPIO_TRACED1_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED2_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN2) +#define GPIO_TRACED2_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN12) +#define GPIO_TRACED3_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN6) + +/* DCMI - Digital camera interface */ + +#define GPIO_DCMI_D0_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN10) +#define GPIO_DCMI_D0_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN6) +#define GPIO_DCMI_D0_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN9) +#define GPIO_DCMI_D1_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN9) +#define GPIO_DCMI_D1_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN7) +#define GPIO_DCMI_D1_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN10) +#define GPIO_DCMI_D2_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTC|GPIO_PIN11) +#define GPIO_DCMI_D2_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN8) +#define GPIO_DCMI_D2_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN0) +#define GPIO_DCMI_D2_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN11) +#define GPIO_DCMI_D3_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTC|GPIO_PIN9) +#define GPIO_DCMI_D3_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN1) +#define GPIO_DCMI_D3_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN12) +#define GPIO_DCMI_D4_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN11) +#define GPIO_DCMI_D4_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN4) +#define GPIO_DCMI_D4_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN14) +#define GPIO_DCMI_D5_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN3) +#define GPIO_DCMI_D5_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN6) +#define GPIO_DCMI_D5_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN4) +#define GPIO_DCMI_D6_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN8) +#define GPIO_DCMI_D6_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN5) +#define GPIO_DCMI_D6_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN6) +#define GPIO_DCMI_D7_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN9) +#define GPIO_DCMI_D7_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN6) +#define GPIO_DCMI_D7_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN7) +#define GPIO_DCMI_D8_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN10) +#define GPIO_DCMI_D8_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN6) +#define GPIO_DCMI_D8_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN1) +#define GPIO_DCMI_D9_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN12) +#define GPIO_DCMI_D9_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN7) +#define GPIO_DCMI_D9_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN2) +#define GPIO_DCMI_D10_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN6) +#define GPIO_DCMI_D10_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN6) +#define GPIO_DCMI_D10_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN3) +#define GPIO_DCMI_D11_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN2) +#define GPIO_DCMI_D11_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN10) +#define GPIO_DCMI_D11_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN15) +#define GPIO_DCMI_D12_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN5) +#define GPIO_DCMI_D12_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN4) +#define GPIO_DCMI_D12_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN11) +#define GPIO_DCMI_D13_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTG|GPIO_PIN5) +#define GPIO_DCMI_D13_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN0) +#define GPIO_DCMI_HSYNC_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DCMI_HSYNC_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN8) +#define GPIO_DCMI_HSYNC_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN8) +#define GPIO_DCMI_PIXCLK_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN6) +#define GPIO_DCMI_PIXCLK_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN9) +#define GPIO_DCMI_PIXCLK_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN5) +#define GPIO_DCMI_VSYNC_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN7) +#define GPIO_DCMI_VSYNC_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN5) + +/* EVENTOUT - Armv8-M Send Event instruction (SEV) */ + +#define GPIO_PA0_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN0) +#define GPIO_PA1_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN1) +#define GPIO_PA2_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN2) +#define GPIO_PA3_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN3) +#define GPIO_PA4_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN4) +#define GPIO_PA5_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN5) +#define GPIO_PA6_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN6) +#define GPIO_PA7_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN7) +#define GPIO_PA8_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN8) +#define GPIO_PA9_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN9) +#define GPIO_PA10_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN10) +#define GPIO_PA11_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN11) +#define GPIO_PA12_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN12) +#define GPIO_PA13_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN13) +#define GPIO_PA14_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN14) +#define GPIO_PA15_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN15) +#define GPIO_PB0_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN0) +#define GPIO_PB1_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN1) +#define GPIO_PB2_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN2) +#define GPIO_PB3_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN3) +#define GPIO_PB4_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN4) +#define GPIO_PB5_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN5) +#define GPIO_PB6_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN6) +#define GPIO_PB7_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN7) +#define GPIO_PB8_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN8) +#define GPIO_PB9_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN9) +#define GPIO_PB10_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN10) +#define GPIO_PB11_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN11) +#define GPIO_PB12_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN12) +#define GPIO_PB13_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN13) +#define GPIO_PB14_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN14) +#define GPIO_PB15_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN15) +#define GPIO_PC0_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN0) +#define GPIO_PC1_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN1) +#define GPIO_PC2_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN2) +#define GPIO_PC3_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN3) +#define GPIO_PC4_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN4) +#define GPIO_PC5_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN5) +#define GPIO_PC6_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN6) +#define GPIO_PC7_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN7) +#define GPIO_PC8_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN8) +#define GPIO_PC9_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN9) +#define GPIO_PC10_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN10) +#define GPIO_PC11_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN11) +#define GPIO_PC12_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN12) +#define GPIO_PC13_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN13) +#define GPIO_PC14_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN14) +#define GPIO_PC15_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN15) +#define GPIO_PD0_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN0) +#define GPIO_PD1_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN1) +#define GPIO_PD2_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN2) +#define GPIO_PD3_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN3) +#define GPIO_PD4_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN4) +#define GPIO_PD5_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN5) +#define GPIO_PD6_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN6) +#define GPIO_PD7_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN7) +#define GPIO_PD8_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN8) +#define GPIO_PD9_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN9) +#define GPIO_PD10_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN10) +#define GPIO_PD11_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN11) +#define GPIO_PD12_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN12) +#define GPIO_PD13_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN13) +#define GPIO_PD14_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN14) +#define GPIO_PD15_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTD|GPIO_PIN15) +#define GPIO_PE0_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN0) +#define GPIO_PE1_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN1) +#define GPIO_PE2_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN2) +#define GPIO_PE3_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN3) +#define GPIO_PE4_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN4) +#define GPIO_PE5_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN5) +#define GPIO_PE6_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN6) +#define GPIO_PE7_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN7) +#define GPIO_PE8_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN8) +#define GPIO_PE9_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN9) +#define GPIO_PE10_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN10) +#define GPIO_PE11_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN11) +#define GPIO_PE12_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN12) +#define GPIO_PE13_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN13) +#define GPIO_PE14_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN14) +#define GPIO_PE15_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTE|GPIO_PIN15) +#define GPIO_PF0_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN0) +#define GPIO_PF1_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN1) +#define GPIO_PF2_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN2) +#define GPIO_PF3_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN3) +#define GPIO_PF4_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN4) +#define GPIO_PF5_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN5) +#define GPIO_PF6_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN6) +#define GPIO_PF7_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN7) +#define GPIO_PF8_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN8) +#define GPIO_PF9_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN9) +#define GPIO_PF10_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN10) +#define GPIO_PF11_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN11) +#define GPIO_PF12_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN12) +#define GPIO_PF13_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN13) +#define GPIO_PF14_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN14) +#define GPIO_PF15_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTF|GPIO_PIN15) +#define GPIO_PG0_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN0) +#define GPIO_PG1_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN1) +#define GPIO_PG2_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN2) +#define GPIO_PG3_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN3) +#define GPIO_PG4_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN4) +#define GPIO_PG5_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN5) +#define GPIO_PG6_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN6) +#define GPIO_PG7_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN7) +#define GPIO_PG8_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN8) +#define GPIO_PG9_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN9) +#define GPIO_PG10_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN10) +#define GPIO_PG11_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN11) +#define GPIO_PG12_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN12) +#define GPIO_PG13_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN13) +#define GPIO_PG14_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN14) +#define GPIO_PG15_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN15) +#define GPIO_PG15_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTG|GPIO_PIN15) +#define GPIO_PH0_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN0) +#define GPIO_PH1_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN1) +#define GPIO_PH2_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN2) +#define GPIO_PH3_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN3) +#define GPIO_PH4_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN4) +#define GPIO_PH5_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN5) +#define GPIO_PH6_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN6) +#define GPIO_PH7_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN7) +#define GPIO_PH8_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN8) +#define GPIO_PH9_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN9) +#define GPIO_PH10_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN10) +#define GPIO_PH11_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN11) +#define GPIO_PH12_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN12) +#define GPIO_PH13_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN13) +#define GPIO_PH14_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN14) +#define GPIO_PH15_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTH|GPIO_PIN15) +#define GPIO_PI0_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN0) +#define GPIO_PI1_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN1) +#define GPIO_PI2_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN2) +#define GPIO_PI3_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN3) +#define GPIO_PI4_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN4) +#define GPIO_PI5_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN5) +#define GPIO_PI6_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN6) +#define GPIO_PI7_EVENTOUT_1 (GPIO_ALT|GPIO_AF15|GPIO_PORTI|GPIO_PIN7) + +/* FDCAN1 - FD controller area network */ + +#define GPIO_FDCAN1_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTA|GPIO_PIN11) +#define GPIO_FDCAN1_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN8) +#define GPIO_FDCAN1_RX_3 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN0) +#define GPIO_FDCAN1_RX_4 (GPIO_ALT|GPIO_AF9|GPIO_PORTF|GPIO_PIN7) +#define GPIO_FDCAN1_RX_5 (GPIO_ALT|GPIO_AF9|GPIO_PORTH|GPIO_PIN14) +#define GPIO_FDCAN1_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTA|GPIO_PIN12) +#define GPIO_FDCAN1_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN9) +#define GPIO_FDCAN1_TX_3 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN1) +#define GPIO_FDCAN1_TX_4 (GPIO_ALT|GPIO_AF9|GPIO_PORTF|GPIO_PIN8) +#define GPIO_FDCAN1_TX_5 (GPIO_ALT|GPIO_AF9|GPIO_PORTH|GPIO_PIN13) + +/* FMC - Flexible static memory controller */ + +#define GPIO_FMC_A0_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN0) +#define GPIO_FMC_A1_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN1) +#define GPIO_FMC_A2_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN2) +#define GPIO_FMC_A3_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN3) +#define GPIO_FMC_A4_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN4) +#define GPIO_FMC_A5_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN5) +#define GPIO_FMC_A6_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN12) +#define GPIO_FMC_A7_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN13) +#define GPIO_FMC_A8_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN14) +#define GPIO_FMC_A9_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN15) +#define GPIO_FMC_A10_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN0) +#define GPIO_FMC_A11_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN1) +#define GPIO_FMC_A12_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN2) +#define GPIO_FMC_A13_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN3) +#define GPIO_FMC_A14_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN4) +#define GPIO_FMC_A15_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN5) +#define GPIO_FMC_A16_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN11) +#define GPIO_FMC_A17_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN12) +#define GPIO_FMC_A18_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN13) +#define GPIO_FMC_A19_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN3) +#define GPIO_FMC_A20_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN4) +#define GPIO_FMC_A21_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN5) +#define GPIO_FMC_A22_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN6) +#define GPIO_FMC_A23_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN2) +#define GPIO_FMC_A24_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN13) +#define GPIO_FMC_A25_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN14) +#define GPIO_FMC_CLK_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN3) +#define GPIO_FMC_D0_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN14) +#define GPIO_FMC_D1_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN15) +#define GPIO_FMC_D2_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN0) +#define GPIO_FMC_D3_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN1) +#define GPIO_FMC_D4_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN7) +#define GPIO_FMC_D5_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN8) +#define GPIO_FMC_D6_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN9) +#define GPIO_FMC_D7_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN10) +#define GPIO_FMC_D8_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN11) +#define GPIO_FMC_D9_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN12) +#define GPIO_FMC_D10_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN13) +#define GPIO_FMC_D11_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN14) +#define GPIO_FMC_D12_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN15) +#define GPIO_FMC_D13_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN8) +#define GPIO_FMC_D14_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN9) +#define GPIO_FMC_D15_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN10) +#define GPIO_FMC_INT_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN7) +#define GPIO_FMC_NE1_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN7) +#define GPIO_FMC_NE2_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FMC_NE3_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN10) +#define GPIO_FMC_NE4_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN12) +#define GPIO_FMC_NBL0_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN0) +#define GPIO_FMC_NBL1_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN15) +#define GPIO_FMC_NBL1_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN1) +#define GPIO_FMC_NL_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN7) +#define GPIO_FMC_NOE_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN4) +#define GPIO_FMC_NCE_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN7) +#define GPIO_FMC_NCE_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FMC_NWAIT_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN6) +#define GPIO_FMC_NWE_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN5) + +/* I2C1 - Inter-integrated circuit interface */ + +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTG|GPIO_PIN14) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SDA_4 (GPIO_ALT|GPIO_AF4|GPIO_PORTG|GPIO_PIN13) +#define GPIO_I2C1_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN1) +#define GPIO_I2C1_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN14) +#define GPIO_I2C1_SMBA_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2C1_SMBA_4 (GPIO_ALT|GPIO_AF4|GPIO_PORTG|GPIO_PIN15) + +/* I2C2 - Inter-integrated circuit interface */ + +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SCL_4 (GPIO_ALT|GPIO_AF4|GPIO_PORTH|GPIO_PIN4) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SDA_4 (GPIO_ALT|GPIO_AF4|GPIO_PORTH|GPIO_PIN5) +#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN2) +#define GPIO_I2C2_SMBA_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTH|GPIO_PIN6) + +/* I2C3 - Inter-integrated circuit interface */ + +#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN7) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTC|GPIO_PIN0) +#define GPIO_I2C3_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTG|GPIO_PIN7) +#define GPIO_I2C3_SCL_4 (GPIO_ALT|GPIO_AF4|GPIO_PORTH|GPIO_PIN7) +#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN4) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2C3_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTG|GPIO_PIN8) +#define GPIO_I2C3_SDA_4 (GPIO_ALT|GPIO_AF4|GPIO_PORTH|GPIO_PIN8) +#define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN2) +#define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTG|GPIO_PIN6) +#define GPIO_I2C3_SMBA_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTH|GPIO_PIN9) + +/* I2C4 - Inter-integrated circuit interface */ + +#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN12) +#define GPIO_I2C4_SCL_4 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN14) +#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN13) +#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN15) +#define GPIO_I2C4_SMBA_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN14) +#define GPIO_I2C4_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN11) +#define GPIO_I2C4_SMBA_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN13) + +/* LPGPIO1 - Low-power general-purpose I/Os */ + +#define GPIO_LPGPIO1_P0_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN1) +#define GPIO_LPGPIO1_P1_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN3) +#define GPIO_LPGPIO1_P2_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN6) +#define GPIO_LPGPIO1_P3_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LPGPIO1_P4_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN10) +#define GPIO_LPGPIO1_P5_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN2) +#define GPIO_LPGPIO1_P6_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN13) +#define GPIO_LPGPIO1_P7_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN2) +#define GPIO_LPGPIO1_P8_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LPGPIO1_P9_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN0) +#define GPIO_LPGPIO1_P10_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN12) +#define GPIO_LPGPIO1_P11_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN3) +#define GPIO_LPGPIO1_P12_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN4) +#define GPIO_LPGPIO1_P13_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN0) +#define GPIO_LPGPIO1_P14_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN1) +#define GPIO_LPGPIO1_P15_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN2) + +/* LPTIM1 - Low-power timer */ + +#define GPIO_LPTIM1_CH1_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN14) +#define GPIO_LPTIM1_CH1_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN2) +#define GPIO_LPTIM1_CH1_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTB|GPIO_PIN3) +#define GPIO_LPTIM1_CH1_4 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN1) +#define GPIO_LPTIM1_CH1_5 (GPIO_ALT|GPIO_AF1|GPIO_PORTG|GPIO_PIN15) +#define GPIO_LPTIM1_CH2_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN1) +#define GPIO_LPTIM1_CH2_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN4) +#define GPIO_LPTIM1_CH2_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTG|GPIO_PIN14) +#define GPIO_LPTIM1_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN6) +#define GPIO_LPTIM1_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN3) +#define GPIO_LPTIM1_ETR_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTG|GPIO_PIN12) +#define GPIO_LPTIM1_IN1_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN5) +#define GPIO_LPTIM1_IN1_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN0) +#define GPIO_LPTIM1_IN1_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTG|GPIO_PIN10) +#define GPIO_LPTIM1_IN2_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN7) +#define GPIO_LPTIM1_IN2_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN2) +#define GPIO_LPTIM1_IN2_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTG|GPIO_PIN11) + +/* LPTIM2 - Low-power timer */ + +#define GPIO_LPTIM2_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN10) +#define GPIO_LPTIM2_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN8) +#define GPIO_LPTIM2_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN13) +#define GPIO_LPTIM2_CH2_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTD|GPIO_PIN10) +#define GPIO_LPTIM2_CH2_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN6) +#define GPIO_LPTIM2_CH2_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN7) +#define GPIO_LPTIM2_ETR_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN5) +#define GPIO_LPTIM2_ETR_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN3) +#define GPIO_LPTIM2_ETR_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN11) +#define GPIO_LPTIM2_IN1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LPTIM2_IN1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN0) +#define GPIO_LPTIM2_IN1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN12) +#define GPIO_LPTIM2_IN2_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN10) +#define GPIO_LPTIM2_IN2_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTB|GPIO_PIN15) +#define GPIO_LPTIM2_IN2_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTD|GPIO_PIN9) + +/* LPTIM3 - Low-power timer */ + +#define GPIO_LPTIM3_CH1_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN0) +#define GPIO_LPTIM3_CH1_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTB|GPIO_PIN10) +#define GPIO_LPTIM3_CH1_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTC|GPIO_PIN3) +#define GPIO_LPTIM3_CH1_4 (GPIO_ALT|GPIO_AF2|GPIO_PORTF|GPIO_PIN5) +#define GPIO_LPTIM3_CH1_5 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN8) +#define GPIO_LPTIM3_CH1_6 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN14) +#define GPIO_LPTIM3_CH2_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LPTIM3_CH2_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTF|GPIO_PIN2) +#define GPIO_LPTIM3_CH2_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN9) +#define GPIO_LPTIM3_CH2_4 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN15) +#define GPIO_LPTIM3_ETR_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTB|GPIO_PIN14) +#define GPIO_LPTIM3_ETR_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LPTIM3_ETR_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTF|GPIO_PIN4) +#define GPIO_LPTIM3_ETR_4 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN10) +#define GPIO_LPTIM3_IN1_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTB|GPIO_PIN13) +#define GPIO_LPTIM3_IN1_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTC|GPIO_PIN11) +#define GPIO_LPTIM3_IN1_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTF|GPIO_PIN3) +#define GPIO_LPTIM3_IN1_4 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN9) + +/* LPUART1 - Low-power universal asynchronous receiver transmitter */ + +#define GPIO_LPUART1_CTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN6) +#define GPIO_LPUART1_CTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN13) +#define GPIO_LPUART1_CTS_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN5) +#define GPIO_LPUART1_RTS_DE_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LPUART1_RTS_DE_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN12) +#define GPIO_LPUART1_RTS_DE_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN6) +#define GPIO_LPUART1_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN3) +#define GPIO_LPUART1_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN10) +#define GPIO_LPUART1_RX_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN0) +#define GPIO_LPUART1_RX_4 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN8) +#define GPIO_LPUART1_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN2) +#define GPIO_LPUART1_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN11) +#define GPIO_LPUART1_TX_3 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN1) +#define GPIO_LPUART1_TX_4 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN7) + +/* MDF1 - Multi-function digital filter */ + +#define GPIO_MDF1_CCK0_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN8) +#define GPIO_MDF1_CCK0_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN9) +#define GPIO_MDF1_CCK0_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN7) +#define GPIO_MDF1_CCK1_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN2) +#define GPIO_MDF1_CCK1_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN10) +#define GPIO_MDF1_CKI0_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN2) +#define GPIO_MDF1_CKI0_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN4) +#define GPIO_MDF1_CKI1_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN13) +#define GPIO_MDF1_CKI1_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN7) +#define GPIO_MDF1_CKI2_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN15) +#define GPIO_MDF1_CKI2_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN8) +#define GPIO_MDF1_CKI3_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN6) +#define GPIO_MDF1_CKI3_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN5) +#define GPIO_MDF1_CKI4_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN1) +#define GPIO_MDF1_CKI4_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN11) +#define GPIO_MDF1_CKI5_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN7) +#define GPIO_MDF1_CKI5_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN13) +#define GPIO_MDF1_SDI0_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN1) +#define GPIO_MDF1_SDI0_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN3) +#define GPIO_MDF1_SDI1_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN12) +#define GPIO_MDF1_SDI1_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN6) +#define GPIO_MDF1_SDI2_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN14) +#define GPIO_MDF1_SDI2_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN7) +#define GPIO_MDF1_SDI3_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN7) +#define GPIO_MDF1_SDI3_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN4) +#define GPIO_MDF1_SDI4_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN0) +#define GPIO_MDF1_SDI4_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN10) +#define GPIO_MDF1_SDI5_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN6) +#define GPIO_MDF1_SDI5_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN12) + +/* OCTOSPIM_P1 - OCTOSPI I/O manager - Port 1 */ + +#define GPIO_OCTOSPIM_P1_CLK_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTF|GPIO_PIN10) +#define GPIO_OCTOSPIM_P1_CLK_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN3) +#define GPIO_OCTOSPIM_P1_CLK_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN10) +#define GPIO_OCTOSPIM_P1_CLK_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN10) +#define GPIO_OCTOSPIM_P1_DQS_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN3) +#define GPIO_OCTOSPIM_P1_DQS_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTG|GPIO_PIN6) +#define GPIO_OCTOSPIM_P1_DQS_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN1) +#define GPIO_OCTOSPIM_P1_DQS_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN2) +#define GPIO_OCTOSPIM_P1_IO0_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN1) +#define GPIO_OCTOSPIM_P1_IO0_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN12) +#define GPIO_OCTOSPIM_P1_IO0_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN8) +#define GPIO_OCTOSPIM_P1_IO1_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN0) +#define GPIO_OCTOSPIM_P1_IO1_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN13) +#define GPIO_OCTOSPIM_P1_IO1_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN9) +#define GPIO_OCTOSPIM_P1_IO2_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN7) +#define GPIO_OCTOSPIM_P1_IO2_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN14) +#define GPIO_OCTOSPIM_P1_IO2_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN7) +#define GPIO_OCTOSPIM_P1_IO3_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN6) +#define GPIO_OCTOSPIM_P1_IO3_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN15) +#define GPIO_OCTOSPIM_P1_IO3_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN6) +#define GPIO_OCTOSPIM_P1_IO4_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN2) +#define GPIO_OCTOSPIM_P1_IO4_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN1) +#define GPIO_OCTOSPIM_P1_IO4_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN4) +#define GPIO_OCTOSPIM_P1_IO5_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTG|GPIO_PIN11) +#define GPIO_OCTOSPIM_P1_IO5_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN0) +#define GPIO_OCTOSPIM_P1_IO5_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN2) +#define GPIO_OCTOSPIM_P1_IO5_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN5) +#define GPIO_OCTOSPIM_P1_IO6_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN3) +#define GPIO_OCTOSPIM_P1_IO6_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN6) +#define GPIO_OCTOSPIM_P1_IO7_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN0) +#define GPIO_OCTOSPIM_P1_IO7_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN4) +#define GPIO_OCTOSPIM_P1_IO7_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN7) +#define GPIO_OCTOSPIM_P1_NCLK_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN5) +#define GPIO_OCTOSPIM_P1_NCLK_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTF|GPIO_PIN11) +#define GPIO_OCTOSPIM_P1_NCLK_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN12) +#define GPIO_OCTOSPIM_P1_NCLK_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN9) +#define GPIO_OCTOSPIM_P1_NCS_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN4) +#define GPIO_OCTOSPIM_P1_NCS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN11) +#define GPIO_OCTOSPIM_P1_NCS_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN0) +#define GPIO_OCTOSPIM_P1_NCS_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN2) +#define GPIO_OCTOSPIM_P1_NCS_5 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN11) +#define GPIO_OCTOSPIM_P1_NCS_6 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN11) + +/* OCTOSPIM_P2 - OCTOSPI I/O manager - Port 2 */ + +#define GPIO_OCTOSPIM_P2_CLK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN4) +#define GPIO_OCTOSPIM_P2_CLK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN6) +#define GPIO_OCTOSPIM_P2_CLK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN6) +#define GPIO_OCTOSPIM_P2_DQS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN12) +#define GPIO_OCTOSPIM_P2_DQS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN7) +#define GPIO_OCTOSPIM_P2_DQS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN15) +#define GPIO_OCTOSPIM_P2_DQS_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN4) +#define GPIO_OCTOSPIM_P2_IO0_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN0) +#define GPIO_OCTOSPIM_P2_IO0_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTI|GPIO_PIN3) +#define GPIO_OCTOSPIM_P2_IO1_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN1) +#define GPIO_OCTOSPIM_P2_IO1_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTI|GPIO_PIN2) +#define GPIO_OCTOSPIM_P2_IO2_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN2) +#define GPIO_OCTOSPIM_P2_IO2_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTI|GPIO_PIN1) +#define GPIO_OCTOSPIM_P2_IO3_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN3) +#define GPIO_OCTOSPIM_P2_IO3_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN8) +#define GPIO_OCTOSPIM_P2_IO4_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN0) +#define GPIO_OCTOSPIM_P2_IO4_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN9) +#define GPIO_OCTOSPIM_P2_IO5_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN1) +#define GPIO_OCTOSPIM_P2_IO5_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN10) +#define GPIO_OCTOSPIM_P2_IO6_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN9) +#define GPIO_OCTOSPIM_P2_IO6_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN11) +#define GPIO_OCTOSPIM_P2_IO6_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN15) +#define GPIO_OCTOSPIM_P2_IO7_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN10) +#define GPIO_OCTOSPIM_P2_IO7_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN12) +#define GPIO_OCTOSPIM_P2_NCLK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN5) +#define GPIO_OCTOSPIM_P2_NCLK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN7) +#define GPIO_OCTOSPIM_P2_NCLK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN7) +#define GPIO_OCTOSPIM_P2_NCS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN12) +#define GPIO_OCTOSPIM_P2_NCS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN6) +#define GPIO_OCTOSPIM_P2_NCS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN12) +#define GPIO_OCTOSPIM_P2_NCS_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN5) +#define GPIO_OCTOSPIM_P2_NCS_5 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN3) + +/* OTG_FS - USB on-the-go full-speed */ + +#define GPIO_OTG_FS_DM_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN11) +#define GPIO_OTG_FS_DP_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN12) +#define GPIO_OTG_FS_ID_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN10) +#define GPIO_OTG_FS_NOE_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN13) +#define GPIO_OTG_FS_NOE_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN9) +#define GPIO_OTG_FS_SOF_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN8) +#define GPIO_OTG_FS_SOF_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN14) + +/* PSSI - Parallel synchronous slave interface */ + +#define GPIO_PSSI_D0_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN10) +#define GPIO_PSSI_D0_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN6) +#define GPIO_PSSI_D0_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN9) +#define GPIO_PSSI_D1_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN9) +#define GPIO_PSSI_D1_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN7) +#define GPIO_PSSI_D1_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN10) +#define GPIO_PSSI_D2_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTC|GPIO_PIN11) +#define GPIO_PSSI_D2_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN8) +#define GPIO_PSSI_D2_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN0) +#define GPIO_PSSI_D2_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN11) +#define GPIO_PSSI_D3_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTC|GPIO_PIN9) +#define GPIO_PSSI_D3_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN1) +#define GPIO_PSSI_D3_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN12) +#define GPIO_PSSI_D4_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN11) +#define GPIO_PSSI_D4_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN4) +#define GPIO_PSSI_D4_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN14) +#define GPIO_PSSI_D5_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN3) +#define GPIO_PSSI_D5_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN6) +#define GPIO_PSSI_D5_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN4) +#define GPIO_PSSI_D6_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN8) +#define GPIO_PSSI_D6_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN5) +#define GPIO_PSSI_D6_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN6) +#define GPIO_PSSI_D7_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN9) +#define GPIO_PSSI_D7_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN6) +#define GPIO_PSSI_D7_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN7) +#define GPIO_PSSI_D8_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN10) +#define GPIO_PSSI_D8_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN6) +#define GPIO_PSSI_D8_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN1) +#define GPIO_PSSI_D9_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN12) +#define GPIO_PSSI_D9_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN7) +#define GPIO_PSSI_D9_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN2) +#define GPIO_PSSI_D10_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN6) +#define GPIO_PSSI_D10_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN6) +#define GPIO_PSSI_D10_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN3) +#define GPIO_PSSI_D11_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN2) +#define GPIO_PSSI_D11_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN10) +#define GPIO_PSSI_D11_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN15) +#define GPIO_PSSI_D12_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN5) +#define GPIO_PSSI_D12_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN4) +#define GPIO_PSSI_D12_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN11) +#define GPIO_PSSI_D13_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTG|GPIO_PIN5) +#define GPIO_PSSI_D13_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN0) +#define GPIO_PSSI_D14_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN5) +#define GPIO_PSSI_D14_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN8) +#define GPIO_PSSI_D14_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN4) +#define GPIO_PSSI_D15_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTC|GPIO_PIN5) +#define GPIO_PSSI_D15_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN9) +#define GPIO_PSSI_D15_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN10) +#define GPIO_PSSI_DE_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN4) +#define GPIO_PSSI_DE_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN8) +#define GPIO_PSSI_DE_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN8) +#define GPIO_PSSI_PDCK_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN6) +#define GPIO_PSSI_PDCK_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTD|GPIO_PIN9) +#define GPIO_PSSI_PDCK_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTH|GPIO_PIN5) +#define GPIO_PSSI_RDY_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN7) +#define GPIO_PSSI_RDY_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTI|GPIO_PIN5) + +/* PWR - Power control */ + +#define GPIO_CDSTOP_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN6) +#define GPIO_CDSTOP_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN7) +#define GPIO_CSLEEP_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN5) +#define GPIO_CSLEEP_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SRDSTOP_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN7) +#define GPIO_SRDSTOP_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN8) + +/* RTC - Real-time clock */ + +#define GPIO_RTC_REFIN_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN15) + +/* RCC - Reset and clock control */ + +#define GPIO_MCO_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN8) + +/* SAI1 - Serial audio interface */ + +#define GPIO_SAI1_CK1_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN3) +#define GPIO_SAI1_CK1_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SAI1_CK1_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN2) +#define GPIO_SAI1_CK1_4 (GPIO_ALT|GPIO_AF3|GPIO_PORTG|GPIO_PIN7) +#define GPIO_SAI1_CK2_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN8) +#define GPIO_SAI1_CK2_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN5) +#define GPIO_SAI1_D1_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN10) +#define GPIO_SAI1_D1_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SAI1_D1_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SAI1_D1_4 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN6) +#define GPIO_SAI1_D2_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SAI1_D2_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN4) +#define GPIO_SAI1_D3_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN5) +#define GPIO_SAI1_D3_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN3) +#define GPIO_SAI1_FS_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN9) +#define GPIO_SAI1_FS_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SAI1_FS_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN4) +#define GPIO_SAI1_FS_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SAI1_FS_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN14) +#define GPIO_SAI1_FS_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN6) +#define GPIO_SAI1_FS_B_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN9) +#define GPIO_SAI1_FS_B_5 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN9) +#define GPIO_SAI1_MCLK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN3) +#define GPIO_SAI1_MCLK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SAI1_MCLK_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN2) +#define GPIO_SAI1_MCLK_A_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN7) +#define GPIO_SAI1_MCLK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SAI1_MCLK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN10) +#define GPIO_SAI1_MCLK_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN7) +#define GPIO_SAI1_SCK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN8) +#define GPIO_SAI1_SCK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SAI1_SCK_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN5) +#define GPIO_SAI1_SCK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SAI1_SCK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN8) +#define GPIO_SAI1_SCK_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN8) +#define GPIO_SAI1_SD_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN10) +#define GPIO_SAI1_SD_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN1) +#define GPIO_SAI1_SD_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SAI1_SD_A_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SAI1_SD_A_5 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN6) +#define GPIO_SAI1_SD_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN13) +#define GPIO_SAI1_SD_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SAI1_SD_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN3) +#define GPIO_SAI1_SD_B_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN7) +#define GPIO_SAI1_SD_B_5 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN6) + +/* SAI2 - Serial audio interface */ + +#define GPIO_SAI2_FS_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SAI2_FS_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN0) +#define GPIO_SAI2_FS_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN12) +#define GPIO_SAI2_FS_A_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN10) +#define GPIO_SAI2_FS_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SAI2_FS_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN3) +#define GPIO_SAI2_MCLK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SAI2_MCLK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SAI2_MCLK_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN9) +#define GPIO_SAI2_MCLK_A_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN11) +#define GPIO_SAI2_MCLK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN7) +#define GPIO_SAI2_MCLK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SAI2_MCLK_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN4) +#define GPIO_SAI2_SCK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SAI2_SCK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN10) +#define GPIO_SAI2_SCK_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN9) +#define GPIO_SAI2_SCK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SAI2_SCK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN2) +#define GPIO_SAI2_SD_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SAI2_SD_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN11) +#define GPIO_SAI2_SD_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN12) +#define GPIO_SAI2_SD_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SAI2_SD_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN5) + +/* SDMMC1 - Secure digital input/output MultiMediaCard interface */ + +#define GPIO_SDMMC1_CDIR_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDMMC1_CK_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SDMMC1_CKIN_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDMMC1_CMD_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN2) +#define GPIO_SDMMC1_D0DIR_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDMMC1_D123DIR_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN7) +#define GPIO_SDMMC1_D0_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN8) +#define GPIO_SDMMC1_D1_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN9) +#define GPIO_SDMMC1_D2_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SDMMC1_D3_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SDMMC1_D4_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDMMC1_D5_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDMMC1_D5_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN0) +#define GPIO_SDMMC1_D6_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDMMC1_D7_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN7) + +/* SDMMC2 - Secure digital input/output MultiMediaCard interface */ + +#define GPIO_SDMMC2_CMD_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN0) +#define GPIO_SDMMC2_CMD_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN7) +#define GPIO_SDMMC2_CK_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN1) +#define GPIO_SDMMC2_CK_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SDMMC2_D0_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SDMMC2_D1_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SDMMC2_D2_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SDMMC2_D3_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SDMMC2_D4_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDMMC2_D5_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDMMC2_D6_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDMMC2_D7_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN7) + +/* SPI1 - Serial peripheral interface */ + +#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN10) +#define GPIO_SPI1_MISO_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI1_MISO_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTE|GPIO_PIN14) +#define GPIO_SPI1_MISO_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN3) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN12) +#define GPIO_SPI1_MOSI_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI1_MOSI_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTE|GPIO_PIN15) +#define GPIO_SPI1_MOSI_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN4) +#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI1_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN0) +#define GPIO_SPI1_NSS_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTE|GPIO_PIN12) +#define GPIO_SPI1_NSS_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN5) +#define GPIO_SPI1_RDY_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN2) +#define GPIO_SPI1_RDY_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN8) +#define GPIO_SPI1_RDY_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN2) +#define GPIO_SPI1_RDY_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTE|GPIO_PIN11) +#define GPIO_SPI1_RDY_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN6) +#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN1) +#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI1_SCK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN2) +#define GPIO_SPI1_SCK_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTE|GPIO_PIN13) +#define GPIO_SPI1_SCK_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN2) + +/* SPI2 - Serial peripheral interface */ + +#define GPIO_SPI2_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN2) +#define GPIO_SPI2_MISO_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN3) +#define GPIO_SPI2_MISO_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN2) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN1) +#define GPIO_SPI2_MOSI_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SPI2_MOSI_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN4) +#define GPIO_SPI2_MOSI_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN3) +#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN0) +#define GPIO_SPI2_NSS_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN0) +#define GPIO_SPI2_RDY_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN11) +#define GPIO_SPI2_RDY_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN0) +#define GPIO_SPI2_RDY_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN5) +#define GPIO_SPI2_RDY_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN4) +#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN9) +#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_SCK_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN1) +#define GPIO_SPI2_SCK_5 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN3) +#define GPIO_SPI2_SCK_6 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN1) + +/* SPI3 - Serial peripheral interface */ + +#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SPI3_MISO_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN10) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI3_MOSI_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SPI3_MOSI_4 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN11) +#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_NSS_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN12) +#define GPIO_SPI3_RDY_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN0) +#define GPIO_SPI3_RDY_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN7) +#define GPIO_SPI3_RDY_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN13) +#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN9) +#define GPIO_SPI3_SCK_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN9) + +/* TSC - Touch sensing controller */ + +#define GPIO_TSC_G1_IO1_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN12) +#define GPIO_TSC_G1_IO2_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TSC_G1_IO3_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TSC_G1_IO4_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN3) +#define GPIO_TSC_G2_IO1_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TSC_G2_IO2_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TSC_G2_IO3_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TSC_G2_IO4_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TSC_G3_IO1_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN2) +#define GPIO_TSC_G3_IO2_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN10) +#define GPIO_TSC_G3_IO3_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN11) +#define GPIO_TSC_G3_IO4_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN12) +#define GPIO_TSC_G4_IO1_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TSC_G4_IO2_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TSC_G4_IO3_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TSC_G4_IO4_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TSC_G5_IO1_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTE|GPIO_PIN10) +#define GPIO_TSC_G5_IO2_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TSC_G5_IO3_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTE|GPIO_PIN12) +#define GPIO_TSC_G5_IO4_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TSC_G6_IO1_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN10) +#define GPIO_TSC_G6_IO2_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN11) +#define GPIO_TSC_G6_IO3_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN12) +#define GPIO_TSC_G6_IO4_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN13) +#define GPIO_TSC_G7_IO1_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTE|GPIO_PIN2) +#define GPIO_TSC_G7_IO2_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTE|GPIO_PIN3) +#define GPIO_TSC_G7_IO3_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTE|GPIO_PIN4) +#define GPIO_TSC_G7_IO4_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTE|GPIO_PIN5) +#define GPIO_TSC_G8_IO1_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTF|GPIO_PIN14) +#define GPIO_TSC_G8_IO2_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTF|GPIO_PIN15) +#define GPIO_TSC_G8_IO3_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTG|GPIO_PIN0) +#define GPIO_TSC_G8_IO4_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTG|GPIO_PIN1) +#define GPIO_TSC_SYNC_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TSC_SYNC_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTD|GPIO_PIN2) + +/* TIM1 - Advanced-control timers */ + +#define GPIO_TIM1_BKIN_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM1_BKIN_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM1_BKIN_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_BKIN2_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_BKIN2_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_CH1_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH1_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTG|GPIO_PIN15) +#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN18) +#define GPIO_TIM1_CH2_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH2_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTG|GPIO_PIN14) +#define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN10) +#define GPIO_TIM1_CH3_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN12) +#define GPIO_TIM1_CH4_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_CH4N_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN5) +#define GPIO_TIM1_CH4N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM1_ETR_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN7) +#define GPIO_TIM1_ETR_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTG|GPIO_PIN12) + +/* TIM2 - General-purpose timers */ + +#define GPIO_TIM2_CH1_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH1_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH2_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH3_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH4_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_ETR_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_ETR_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_ETR_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN0) + +/* TIM5 - General-purpose timers */ + +#define GPIO_TIM5_CH1_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM5_CH1_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTH|GPIO_PIN10) +#define GPIO_TIM5_CH2_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTF|GPIO_PIN7) +#define GPIO_TIM5_CH2_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTH|GPIO_PIN11) +#define GPIO_TIM5_CH3_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTF|GPIO_PIN8) +#define GPIO_TIM5_CH3_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTH|GPIO_PIN12) +#define GPIO_TIM5_CH4_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM5_CH4_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTI|GPIO_PIN0) +#define GPIO_TIM5_ETR_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN6) + +/* TIM8 - Advanced-control timers */ + +#define GPIO_TIM8_BKIN_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_BKIN_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM8_BKIN_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN4) +#define GPIO_TIM8_BKIN2_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM8_BKIN2_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH1_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH1_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN5) +#define GPIO_TIM8_CH2_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH2_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN6) +#define GPIO_TIM8_CH3_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH3_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN7) +#define GPIO_TIM8_CH4_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH4_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN2) +#define GPIO_TIM8_CH1N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM8_CH1N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM8_CH1N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN13) +#define GPIO_TIM8_CH2N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM8_CH2N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM8_CH2N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN14) +#define GPIO_TIM8_CH3N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM8_CH3N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM8_CH3N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN15) +#define GPIO_TIM8_CH4N_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN2) +#define GPIO_TIM8_CH4N_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN0) +#define GPIO_TIM8_CH4N_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN12) +#define GPIO_TIM8_ETR_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM8_ETR_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN3) + +/* TIM15 - General-purpose timers */ + +#define GPIO_TIM15_BKIN_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM15_BKIN_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM15_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM15_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM15_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM15_CH1_4 (GPIO_ALT|GPIO_AF14|GPIO_PORTG|GPIO_PIN10) +#define GPIO_TIM15_CH1N_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM15_CH1N_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM15_CH1N_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTG|GPIO_PIN9) +#define GPIO_TIM15_CH2_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM15_CH2_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM15_CH2_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTF|GPIO_PIN10) +#define GPIO_TIM15_CH2_4 (GPIO_ALT|GPIO_AF14|GPIO_PORTG|GPIO_PIN12) + +/* TIM16 - General-purpose timers */ + +#define GPIO_TIM16_BKIN_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM16_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM16_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTE|GPIO_PIN0) +#define GPIO_TIM16_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM16_CH1N_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN5) + +/* TIM17 - General-purpose timers */ + +#define GPIO_TIM17_BKIN_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM17_BKIN_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM17_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM17_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTE|GPIO_PIN1) +#define GPIO_TIM17_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM17_CH1N_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN7) + +/* UCPD1 - USB Type-C / USB Power Delivery interface */ + +#define GPIO_UCPD1_FRSTX1_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN2) +#define GPIO_UCPD1_FRSTX1_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTG|GPIO_PIN6) +#define GPIO_UCPD1_FRSTX1_3 (GPIO_ALT|GPIO_AF11|GPIO_PORTG|GPIO_PIN7) +#define GPIO_UCPD1_FRSTX2_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN2) +#define GPIO_UCPD1_FRSTX2_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UCPD1_FRSTX2_3 (GPIO_ALT|GPIO_AF11|GPIO_PORTF|GPIO_PIN13) + +/* UART4 - Universal asynchronous receiver transmitter */ + +#define GPIO_UART4_CTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN7) +#define GPIO_UART4_RTS_DE_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN15) +#define GPIO_UART4_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN1) +#define GPIO_UART4_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN0) +#define GPIO_UART4_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN10) + +/* UART5 - Universal asynchronous receiver transmitter */ + +#define GPIO_UART5_RTS_DE_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN4) +#define GPIO_UART5_CTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN5) +#define GPIO_UART5_RX_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN12) + +/* USART1 - Universal synchronous/asynchronous receiver transmitter */ + +#define GPIO_USART1_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN8) +#define GPIO_USART1_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN4) +#define GPIO_USART1_CK_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN13) +#define GPIO_USART1_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN4) +#define GPIO_USART1_CTS_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN11) +#define GPIO_USART1_RTS_DE_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_RTS_DE_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN3) +#define GPIO_USART1_RTS_DE_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN12) +#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN7) +#define GPIO_USART1_RX_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN10) +#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN6) +#define GPIO_USART1_TX_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN9) + +/* USART2 - Universal synchronous/asynchronous receiver transmitter */ + +#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN4) +#define GPIO_USART2_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN7) +#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN3) +#define GPIO_USART2_RTS_DE_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART2_RTS_DE_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN4) +#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_RX_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN15) +#define GPIO_USART2_RX_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN6) +#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN2) +#define GPIO_USART2_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN5) + +/* USART3 - Universal synchronous/asynchronous receiver transmitter */ + +#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN0) +#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN12) +#define GPIO_USART3_CK_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN12) +#define GPIO_USART3_CK_4 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN10) +#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN6) +#define GPIO_USART3_CTS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN13) +#define GPIO_USART3_CTS_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN11) +#define GPIO_USART3_RTS_DE_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN15) +#define GPIO_USART3_RTS_DE_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN1) +#define GPIO_USART3_RTS_DE_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN14) +#define GPIO_USART3_RTS_DE_4 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN2) +#define GPIO_USART3_RTS_DE_5 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN12) +#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN5) +#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN11) +#define GPIO_USART3_RX_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN5) +#define GPIO_USART3_RX_4 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN11) +#define GPIO_USART3_RX_5 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN9) +#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN7) +#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN10) +#define GPIO_USART3_TX_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN4) +#define GPIO_USART3_TX_4 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN10) +#define GPIO_USART3_TX_5 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN8) + +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585XX_PINMAP_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32u585xx_rcc.h b/arch/arm/src/stm32u5/hardware/stm32u585xx_rcc.h new file mode 100644 index 0000000000..7f7c200ad1 --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32u585xx_rcc.h @@ -0,0 +1,1203 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32u585xx_rcc.h + * + * 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_STM32U5_HARDWARE_STM32U585xx_RCC_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585xx_RCC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_STM32U5_STM32U585XX) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* RCC clock control register */ +#define STM32_RCC_ICSCR1_OFFSET 0x0008 /* RCC internal clock sources calibration register 1 */ +#define STM32_RCC_ICSCR2_OFFSET 0x000c /* RCC internal clock sources calibration register 2 */ +#define STM32_RCC_ICSCR3_OFFSET 0x0010 /* RCC internal clock sources calibration register 3 */ +#define STM32_RCC_CRRCR_OFFSET 0x0014 /* RCC clock recovery RC register */ +#define STM32_RCC_CFGR1_OFFSET 0x001c /* RCC clock configuration register 1 */ +#define STM32_RCC_CFGR2_OFFSET 0x0020 /* RCC clock configuration register 2 */ +#define STM32_RCC_CFGR3_OFFSET 0x0024 /* RCC clock configuration register 3 */ +#define STM32_RCC_PLL1CFGR_OFFSET 0x0028 /* RCC PLL1 configuration register */ +#define STM32_RCC_PLL2CFGR_OFFSET 0x002c /* RCC PLL2 configuration register */ +#define STM32_RCC_PLL3CFGR_OFFSET 0x0030 /* RCC PLL3 configuration register */ +#define STM32_RCC_PLL1DIVR_OFFSET 0x0034 /* RCC PLL1 dividers register */ +#define STM32_RCC_PLL1FRACR_OFFSET 0x0038 /* RCC PLL1 fractional divider register */ +#define STM32_RCC_PLL2DIVR_OFFSET 0x003c /* RCC PLL2 dividers register */ +#define STM32_RCC_PLL2FRACR_OFFSET 0x0040 /* RCC PLL2 fractional divider register */ +#define STM32_RCC_PLL3DIVR_OFFSET 0x0044 /* RCC PLL3 dividers register */ +#define STM32_RCC_PLL3FRACR_OFFSET 0x0048 /* RCC PLL3 fractional divider register */ +#define STM32_RCC_CIER_OFFSET 0x0050 /* RCC clock interrupt enable register */ +#define STM32_RCC_CIFR_OFFSET 0x0054 /* RCC clock interrupt flag register */ +#define STM32_RCC_CICR_OFFSET 0x0058 /* RCC clock interrupt clear register */ +#define STM32_RCC_AHB1RSTR_OFFSET 0x0060 /* RCC AHB1 peripheral reset register */ +#define STM32_RCC_AHB2RSTR1_OFFSET 0x0064 /* RCC AHB2 peripheral reset register 1 */ +#define STM32_RCC_AHB2RSTR2_OFFSET 0x0068 /* RCC AHB2 peripheral reset register 2 */ +#define STM32_RCC_AHB3RSTR_OFFSET 0x006c /* RCC AHB3 peripheral reset register */ +#define STM32_RCC_APB1RSTR1_OFFSET 0x0074 /* RCC APB1 peripheral reset register 1 */ +#define STM32_RCC_APB1RSTR2_OFFSET 0x0078 /* RCC APB1 peripheral reset register 2 */ +#define STM32_RCC_APB2RSTR_OFFSET 0x007c /* RCC APB2 peripheral reset register */ +#define STM32_RCC_APB3RSTR_OFFSET 0x0080 /* RCC APB3 peripheral reset register */ +#define STM32_RCC_AHB1ENR_OFFSET 0x0088 /* RCC AHB1 peripheral clock enable register */ +#define STM32_RCC_AHB2ENR1_OFFSET 0x008c /* RCC AHB2 peripheral clock enable register 1 */ +#define STM32_RCC_AHB2ENR2_OFFSET 0x0090 /* RCC AHB2 peripheral clock enable register 2 */ +#define STM32_RCC_AHB3ENR_OFFSET 0x0094 /* RCC AHB3 peripheral clock enable register */ +#define STM32_RCC_APB1ENR1_OFFSET 0x009c /* RCC APB1 peripheral clock enable register 1 */ +#define STM32_RCC_APB1ENR2_OFFSET 0x00a0 /* RCC APB1 peripheral clock enable register 2 */ +#define STM32_RCC_APB2ENR_OFFSET 0x00a4 /* RCC APB2 peripheral clock enable register */ +#define STM32_RCC_APB3ENR_OFFSET 0x00a8 /* RCC APB3 peripheral clock enable register */ +#define STM32_RCC_AHB1SMENR_OFFSET 0x00b0 /* RCC AHB1 peripheral clocks enable in Sleep and Stop modes register */ +#define STM32_RCC_AHB2SMENR1_OFFSET 0x00b4 /* RCC AHB2 peripheral clocks enable in Sleep and Stop modes register 1 */ +#define STM32_RCC_AHB2SMENR2_OFFSET 0x00b8 /* RCC AHB2 peripheral clocks enable in Sleep and Stop modes register 2 */ +#define STM32_RCC_AHB3SMENR_OFFSET 0x00bc /* RCC AHB3 peripheral clocks enable in Sleep and Stop modes register */ +#define STM32_RCC_APB1SMENR1_OFFSET 0x00c4 /* RCC APB1 peripheral clocks enable in Sleep and Stop modes register 1 */ +#define STM32_RCC_APB1SMENR2_OFFSET 0x00c8 /* RCC APB1 peripheral clocks enable in Sleep and Stop modes register 2 */ +#define STM32_RCC_APB2SMENR_OFFSET 0x00cc /* RCC APB2 peripheral clocks enable in Sleep and Stop modes register */ +#define STM32_RCC_APB3SMENR_OFFSET 0x00d0 /* RCC APB3 peripheral clocks enable in Sleep and Stop modes register */ +#define STM32_RCC_SRDAMR_OFFSET 0x00d8 /* RCC SmartRun domain peripheral autonomous mode register */ +#define STM32_RCC_CCIPR1_OFFSET 0x00e0 /* RCC peripherals independent clock configuration register 1 */ +#define STM32_RCC_CCIPR2_OFFSET 0x00e4 /* RCC peripherals independent clock configuration register 2 */ +#define STM32_RCC_CCIPR3_OFFSET 0x00e8 /* RCC peripherals independent clock configuration register 3 */ +#define STM32_RCC_BDCR_OFFSET 0x00f0 /* RCC Backup domain control register */ +#define STM32_RCC_CSR_OFFSET 0x00f4 /* RCC control/status register */ +#define STM32_RCC_SECCFGR_OFFSET 0x0110 /* RCC secure configuration register */ +#define STM32_RCC_PRIVCFGR_OFFSET 0x0114 /* RCC privilege configuration register */ + +/* Register Addresses *******************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE + STM32_RCC_CR_OFFSET) +#define STM32_RCC_ICSCR1 (STM32_RCC_BASE + STM32_RCC_ICSCR1_OFFSET) +#define STM32_RCC_ICSCR2 (STM32_RCC_BASE + STM32_RCC_ICSCR2_OFFSET) +#define STM32_RCC_ICSCR3 (STM32_RCC_BASE + STM32_RCC_ICSCR3_OFFSET) +#define STM32_RCC_CRRCR (STM32_RCC_BASE + STM32_RCC_CRRCR_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_CFGR3 (STM32_RCC_BASE + STM32_RCC_CFGR3_OFFSET) +#define STM32_RCC_PLL1CFGR (STM32_RCC_BASE + STM32_RCC_PLL1CFGR_OFFSET) +#define STM32_RCC_PLL2CFGR (STM32_RCC_BASE + STM32_RCC_PLL2CFGR_OFFSET) +#define STM32_RCC_PLL3CFGR (STM32_RCC_BASE + STM32_RCC_PLL3CFGR_OFFSET) +#define STM32_RCC_PLL1DIVR (STM32_RCC_BASE + STM32_RCC_PLL1DIVR_OFFSET) +#define STM32_RCC_PLL1FRACR (STM32_RCC_BASE + STM32_RCC_PLL1FRACR_OFFSET) +#define STM32_RCC_PLL2DIVR (STM32_RCC_BASE + STM32_RCC_PLL2DIVR_OFFSET) +#define STM32_RCC_PLL2FRACR (STM32_RCC_BASE + STM32_RCC_PLL2FRACR_OFFSET) +#define STM32_RCC_PLL3DIVR (STM32_RCC_BASE + STM32_RCC_PLL3DIVR_OFFSET) +#define STM32_RCC_PLL3FRACR (STM32_RCC_BASE + STM32_RCC_PLL3FRACR_OFFSET) +#define STM32_RCC_CIER (STM32_RCC_BASE + STM32_RCC_CIER_OFFSET) +#define STM32_RCC_CIFR (STM32_RCC_BASE + STM32_RCC_CIFR_OFFSET) +#define STM32_RCC_CICR (STM32_RCC_BASE + STM32_RCC_CICR_OFFSET) +#define STM32_RCC_AHB1RSTR (STM32_RCC_BASE + STM32_RCC_AHB1RSTR_OFFSET) +#define STM32_RCC_AHB2RSTR1 (STM32_RCC_BASE + STM32_RCC_AHB2RSTR1_OFFSET) +#define STM32_RCC_AHB2RSTR2 (STM32_RCC_BASE + STM32_RCC_AHB2RSTR2_OFFSET) +#define STM32_RCC_AHB3RSTR (STM32_RCC_BASE + STM32_RCC_AHB3RSTR_OFFSET) +#define STM32_RCC_APB1RSTR1 (STM32_RCC_BASE + STM32_RCC_APB1RSTR1_OFFSET) +#define STM32_RCC_APB1RSTR2 (STM32_RCC_BASE + STM32_RCC_APB1RSTR2_OFFSET) +#define STM32_RCC_APB2RSTR (STM32_RCC_BASE + STM32_RCC_APB2RSTR_OFFSET) +#define STM32_RCC_APB3RSTR (STM32_RCC_BASE + STM32_RCC_APB3RSTR_OFFSET) +#define STM32_RCC_AHB1ENR (STM32_RCC_BASE + STM32_RCC_AHB1ENR_OFFSET) +#define STM32_RCC_AHB2ENR1 (STM32_RCC_BASE + STM32_RCC_AHB2ENR1_OFFSET) +#define STM32_RCC_AHB2ENR2 (STM32_RCC_BASE + STM32_RCC_AHB2ENR2_OFFSET) +#define STM32_RCC_AHB3ENR (STM32_RCC_BASE + STM32_RCC_AHB3ENR_OFFSET) +#define STM32_RCC_APB1ENR1 (STM32_RCC_BASE + STM32_RCC_APB1ENR1_OFFSET) +#define STM32_RCC_APB1ENR2 (STM32_RCC_BASE + STM32_RCC_APB1ENR2_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE + STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_APB3ENR (STM32_RCC_BASE + STM32_RCC_APB3ENR_OFFSET) +#define STM32_RCC_AHB1SMENR (STM32_RCC_BASE + STM32_RCC_AHB1SMENR_OFFSET) +#define STM32_RCC_AHB2SMENR1 (STM32_RCC_BASE + STM32_RCC_AHB2SMENR1_OFFSET) +#define STM32_RCC_AHB2SMENR2 (STM32_RCC_BASE + STM32_RCC_AHB2SMENR2_OFFSET) +#define STM32_RCC_AHB3SMENR (STM32_RCC_BASE + STM32_RCC_AHB3SMENR_OFFSET) +#define STM32_RCC_APB1SMENR1 (STM32_RCC_BASE + STM32_RCC_APB1SMENR1_OFFSET) +#define STM32_RCC_APB1SMENR2 (STM32_RCC_BASE + STM32_RCC_APB1SMENR2_OFFSET) +#define STM32_RCC_APB2SMENR (STM32_RCC_BASE + STM32_RCC_APB2SMENR_OFFSET) +#define STM32_RCC_APB3SMENR (STM32_RCC_BASE + STM32_RCC_APB3SMENR_OFFSET) +#define STM32_RCC_SRDAMR (STM32_RCC_BASE + STM32_RCC_SRDAMR_OFFSET) +#define STM32_RCC_CCIPR1 (STM32_RCC_BASE + STM32_RCC_CCIPR1_OFFSET) +#define STM32_RCC_CCIPR2 (STM32_RCC_BASE + STM32_RCC_CCIPR2_OFFSET) +#define STM32_RCC_CCIPR3 (STM32_RCC_BASE + STM32_RCC_CCIPR3_OFFSET) +#define STM32_RCC_BDCR (STM32_RCC_BASE + STM32_RCC_BDCR_OFFSET) +#define STM32_RCC_CSR (STM32_RCC_BASE + STM32_RCC_CSR_OFFSET) +#define STM32_RCC_SECCFGR (STM32_RCC_BASE + STM32_RCC_SECCFGR_OFFSET) +#define STM32_RCC_PRIVCFGR (STM32_RCC_BASE + STM32_RCC_PRIVCFGR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* RCC clock control register */ + +#define RCC_CR_MSISON (1 << 0) /* Bit 0: MSIS clock enable */ +#define RCC_CR_MSIKERON (1 << 1) /* Bit 1: MSI enable for some peripheral kernels */ +#define RCC_CR_MSISRDY (1 << 2) /* Bit 2: MSIS clock ready flag */ +#define RCC_CR_MSIPLLEN (1 << 3) /* Bit 3: MSI clock PLL enable */ +#define RCC_CR_MSIKON (1 << 4) /* Bit 4: MSIK clock enable */ +#define RCC_CR_MSIKRDY (1 << 5) /* Bit 4: MSIK clock ready flag */ +#define RCC_CR_MSIPLLSEL (1 << 6) /* Bit 6: MSI clock with PLL mode selection */ +# define RCC_CR_MSIPLLSEL_MSIK (0) /* 0: PLL mode applied to MSIK clock output */ +# define RCC_CR_MSIPLLSEL_MSIS (1 << 6) /* 1: PLL mode applied to MSIS clock output */ +#define RCC_CR_MSIPLLFAST (1 << 7) /* Bit 7: MSI PLL fast start-up */ +#define RCC_CR_HSION (1 << 8) /* Bit 8: Internal High Speed clock enable */ +#define RCC_CR_HSIKERON (1 << 9) /* Bit 9: HSI16 always enable for peripheral kernels */ +#define RCC_CR_HSIRDY (1 << 10) /* Bit 10: Internal High Speed clock ready flag */ +#define RCC_CR_HSI48ON (1 << 12) /* Bit 12: HSI48 clock enable */ +#define RCC_CR_HSI48RDY (1 << 13) /* Bit 13: HSI48 clock ready flag */ +#define RCC_CR_SHSION (1 << 14) /* Bit 14: SHSI clock enable */ +#define RCC_CR_SHSIRDY (1 << 15) /* Bit 15: SHSI clock ready flag */ +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */ +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */ +#define RCC_HSEEXT (1 << 20) /* Bit 20: HSE external clock bypass mode */ +#define RCC_CR_PLL1ON (1 << 24) /* Bit 24: PLL1 enable */ +#define RCC_CR_PLL1RDY (1 << 25) /* Bit 25: PLL1 clock ready flag */ +#define RCC_CR_PLL2ON (1 << 26) /* Bit 26: PLL2 enable */ +#define RCC_CR_PLL2RDY (1 << 27) /* Bit 27: PLL2 clock ready flag */ +#define RCC_CR_PLL3ON (1 << 28) /* Bit 28: PLL3 enable */ +#define RCC_CR_PLL3RDY (1 << 29) /* Bit 29: PLL3 clock ready flag */ + +/* RCC internal clock sources calibration register 1 */ + +#define RCC_ICSCR1_MSICAL3_SHIFT (0) /* Bits 0-4: MSIRC3 clock calibration for MSI ranges 12 to 15 */ +#define RCC_ICSCR1_MSICAL3_MASK (0x1f << RCC_ICSCR1_MSICAL3_SHIFT) +#define RCC_ICSCR1_MSICAL3(n) ((n) << RCC_ICSCR1_MSICAL3_SHIFT) +#define RCC_ICSCR1_MSICAL2_SHIFT (5) /* Bits 5-9: MSIRC2 clock calibration for MSI ranges 8 to 11 */ +#define RCC_ICSCR1_MSICAL2_MASK (0x1f << RCC_ICSCR1_MSICAL2_SHIFT) +#define RCC_ICSCR1_MSICAL2(n) ((n) << RCC_ICSCR1_MSICAL2_SHIFT) +#define RCC_ICSCR1_MSICAL1_SHIFT (0) /* Bits 10-14: MSIRC1 clock calibration for MSI ranges 4 to 7 */ +#define RCC_ICSCR1_MSICAL1_MASK (0x1f << RCC_ICSCR1_MSICAL1_SHIFT) +#define RCC_ICSCR1_MSICAL1(n) ((n) << RCC_ICSCR1_MSICAL1_SHIFT) +#define RCC_ICSCR1_MSICAL0_SHIFT (0) /* Bits 15-19: MSIRC0 clock calibration for MSI ranges 0 to 3 */ +#define RCC_ICSCR1_MSICAL0_MASK (0x1f << RCC_ICSCR1_MSICAL0_SHIFT) +#define RCC_ICSCR1_MSICAL0(n) ((n) << RCC_ICSCR1_MSICAL0_SHIFT) +#define RCC_ICSCR1_MSIBIAS (1 << 22) /* Bit 22: MSI bias mode selection */ +#define RCC_ICSCR1_MSIRGSEL_MASK (1 << 23) /* Bit 23: MSI clock range selection */ +#define RCC_ICSCR1_MSIRGSEL_CSR 0 +#define RCC_ICSCR1_MSIRGSEL_ICSCR1 RCC_ICSCR1_MSIRGSEL_MASK +#define RCC_ICSCR1_MSIKRANGE_SHIFT (24) /* Bits 24-27: MSIK clock ranges */ +#define RCC_ICSCR1_MSIKRANGE_MASK (0xf << RCC_ICSCR1_MSIKRANGE_SHIFT) +#define RCC_ICSCR1_MSIKRANGE(n) ((n) << RCC_ICSCR1_MSIKRANGE_SHIFT) +#define RCC_ICSCR1_MSIKRANGE_48MHZ RCC_ICSCR1_MSIKRANGE(0x0) +#define RCC_ICSCR1_MSIKRANGE_24MHZ RCC_ICSCR1_MSIKRANGE(0x1) +#define RCC_ICSCR1_MSIKRANGE_16MHZ RCC_ICSCR1_MSIKRANGE(0x2) +#define RCC_ICSCR1_MSIKRANGE_12MHZ RCC_ICSCR1_MSIKRANGE(0x3) +#define RCC_ICSCR1_MSIKRANGE_4MHZ RCC_ICSCR1_MSIKRANGE(0x4) +#define RCC_ICSCR1_MSIKRANGE_2MHZ RCC_ICSCR1_MSIKRANGE(0x5) +#define RCC_ICSCR1_MSIKRANGE_1330KHZ RCC_ICSCR1_MSIKRANGE(0x6) +#define RCC_ICSCR1_MSIKRANGE_1MHZ RCC_ICSCR1_MSIKRANGE(0x7) +#define RCC_ICSCR1_MSIKRANGE_3072KHZ RCC_ICSCR1_MSIKRANGE(0x8) +#define RCC_ICSCR1_MSIKRANGE_1536KHZ RCC_ICSCR1_MSIKRANGE(0x9) +#define RCC_ICSCR1_MSIKRANGE_1024KHZ RCC_ICSCR1_MSIKRANGE(0xa) +#define RCC_ICSCR1_MSIKRANGE_768KHZ RCC_ICSCR1_MSIKRANGE(0xb) +#define RCC_ICSCR1_MSIKRANGE_400KHZ RCC_ICSCR1_MSIKRANGE(0xc) +#define RCC_ICSCR1_MSIKRANGE_200KHZ RCC_ICSCR1_MSIKRANGE(0xd) +#define RCC_ICSCR1_MSIKRANGE_133KHZ RCC_ICSCR1_MSIKRANGE(0xe) +#define RCC_ICSCR1_MSIKRANGE_100KHZ RCC_ICSCR1_MSIKRANGE(0xf) +#define RCC_ICSCR1_MSISRANGE_SHIFT (28) /* Bits 28-31: MSIS clock ranges */ +#define RCC_ICSCR1_MSISRANGE_MASK (0xf << RCC_ICSCR1_MSISRANGE_SHIFT) +#define RCC_ICSCR1_MSISRANGE(n) ((n) << RCC_ICSCR1_MSISRANGE_SHIFT) +#define RCC_ICSCR1_MSISRANGE_48MHZ RCC_ICSCR1_MSISRANGE(0x0) +#define RCC_ICSCR1_MSISRANGE_24MHZ RCC_ICSCR1_MSISRANGE(0x1) +#define RCC_ICSCR1_MSISRANGE_16MHZ RCC_ICSCR1_MSISRANGE(0x2) +#define RCC_ICSCR1_MSISRANGE_12MHZ RCC_ICSCR1_MSISRANGE(0x3) +#define RCC_ICSCR1_MSISRANGE_4MHZ RCC_ICSCR1_MSISRANGE(0x4) +#define RCC_ICSCR1_MSISRANGE_2MHZ RCC_ICSCR1_MSISRANGE(0x5) +#define RCC_ICSCR1_MSISRANGE_1330KHZ RCC_ICSCR1_MSISRANGE(0x6) +#define RCC_ICSCR1_MSISRANGE_1MHZ RCC_ICSCR1_MSISRANGE(0x7) +#define RCC_ICSCR1_MSISRANGE_3072KHZ RCC_ICSCR1_MSISRANGE(0x8) +#define RCC_ICSCR1_MSISRANGE_1536KHZ RCC_ICSCR1_MSISRANGE(0x9) +#define RCC_ICSCR1_MSISRANGE_1024KHZ RCC_ICSCR1_MSISRANGE(0xa) +#define RCC_ICSCR1_MSISRANGE_768KHZ RCC_ICSCR1_MSISRANGE(0xb) +#define RCC_ICSCR1_MSISRANGE_400KHZ RCC_ICSCR1_MSISRANGE(0xc) +#define RCC_ICSCR1_MSISRANGE_200KHZ RCC_ICSCR1_MSISRANGE(0xd) +#define RCC_ICSCR1_MSISRANGE_133KHZ RCC_ICSCR1_MSISRANGE(0xe) +#define RCC_ICSCR1_MSISRANGE_100KHZ RCC_ICSCR1_MSISRANGE(0xf) + +/* RCC clock configuration register 1 */ + +#define RCC_CFGR1_SW_SHIFT (0) /* Bits 0-1: System clock Switch */ +#define RCC_CFGR1_SW_MASK (3 << RCC_CFGR1_SW_SHIFT) +# define RCC_CFGR1_SW_MSIS (0 << RCC_CFGR1_SW_SHIFT) /* 00: MSIS selected as system clock */ +# define RCC_CFGR1_SW_HSI16 (1 << RCC_CFGR1_SW_SHIFT) /* 00: HSI16 selected as system clock */ +# define RCC_CFGR1_SW_HSE (2 << RCC_CFGR1_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR1_SW_PLL (3 << RCC_CFGR1_SW_SHIFT) /* 10: PLL pll1_r_ck selected as system clock */ + +#define RCC_CFGR1_SWS_SHIFT (2) /* Bits 2-3: System Clock Switch Status */ +#define RCC_CFGR1_SWS_MASK (3 << RCC_CFGR1_SWS_SHIFT) +# define RCC_CFGR1_SWS_MSIS (0 << RCC_CFGR1_SWS_SHIFT) /* 00: MSIS oscillator used as system clock */ +# define RCC_CFGR1_SWS_HSI16 (1 << RCC_CFGR1_SWS_SHIFT) /* 00: HSI16 oscillator used as system clock */ +# define RCC_CFGR1_SWS_HSE (2 << RCC_CFGR1_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR1_SWS_PLL (3 << RCC_CFGR1_SWS_SHIFT) /* 10: PLL used as system clock */ + +#define RCC_CFGR1_STOPWUCK (1 << 4) /* Bit 4: Wakeup from Stop and CSS backup clock selection */ +# define RCC_CFGR1_STOPWUCK_MSIS (0 << 4) /* 0: MSIS */ +# define RCC_CFGR1_STOPWUCK_HSI16 (1 << 4) /* 0: HSI16 */ + +#define RCC_CFGR_STOPKERWUCK (1 << 5) /* Bit 5: Wakeup from Stop kernel clock automatic enable selection */ +# define RCC_CFGR1_STOPKERWUCK_MSIK (0 << 5) /* 0: MSIK */ +# define RCC_CFGR1_STOPKERWUCK_HSI16 (1 << 5) /* 0: HSI16 */ + +#define RCC_CFGR1_MCOSEL_SHIFT (24) /* Bits 24-27: Microcontroller Clock Output */ +#define RCC_CFGR1_MCOSEL_MASK (0x0f << RCC_CFGR1_MCOSEL_SHIFT) +# define RCC_CFGR1_MCOSEL_NONE (0 << RCC_CFGR1_MCOSEL_SHIFT) /* 0000: Disabled */ +# define RCC_CFGR1_MCOSEL_SYSCLK (1 << RCC_CFGR1_MCOSEL_SHIFT) /* 0001: SYSCLK system clock selected */ +# define RCC_CFGR1_MCOSEL_MSIS (2 << RCC_CFGR1_MCOSEL_SHIFT) /* 0010: MSIS clock selected */ +# define RCC_CFGR1_MCOSEL_HSI16 (3 << RCC_CFGR1_MCOSEL_SHIFT) /* 0011: HSI16 clock selected */ +# define RCC_CFGR1_MCOSEL_HSE (4 << RCC_CFGR1_MCOSEL_SHIFT) /* 0100: HSE clock selected */ +# define RCC_CFGR1_MCOSEL_PLL (5 << RCC_CFGR1_MCOSEL_SHIFT) /* 0101: Main PLL clock pll1_r_ck selected */ +# define RCC_CFGR1_MCOSEL_LSI (6 << RCC_CFGR1_MCOSEL_SHIFT) /* 0110: LSI clock selected */ +# define RCC_CFGR1_MCOSEL_LSE (7 << RCC_CFGR1_MCOSEL_SHIFT) /* 0111: LSE clock selected */ +# define RCC_CFGR1_MCOSEL_HSI48 (8 << RCC_CFGR1_MCOSEL_SHIFT) /* 1000: HSI48 clock selected */ +# define RCC_CFGR1_MCOSEL_MSIK (9 << RCC_CFGR1_MCOSEL_SHIFT) /* 1001: MSIK clock selected */ + +#define RCC_CFGR1_MCOPRE_SHIFT (28) /* Bits 28-30: MCO prescaler */ +#define RCC_CFGR1_MCOPRE_MASK (7 << RCC_CFGR1_MCOPRE_SHIFT) +# define RCC_CFGR1_MCOPRE_NONE (0 << RCC_CFGR1_MCOPRE_SHIFT) /* 000: no division */ +# define RCC_CFGR1_MCOPRE_DIV2 (1 << RCC_CFGR1_MCOPRE_SHIFT) /* 001: division by 2 */ +# define RCC_CFGR1_MCOPRE_DIV4 (2 << RCC_CFGR1_MCOPRE_SHIFT) /* 010: division by 4 */ +# define RCC_CFGR1_MCOPRE_DIV8 (3 << RCC_CFGR1_MCOPRE_SHIFT) /* 011: division by 8 */ +# define RCC_CFGR1_MCOPRE_DIV16 (4 << RCC_CFGR1_MCOPRE_SHIFT) /* 100: division by 16 */ + +/* RCC PLL1 configuration register */ + +#define RCC_PLL1CFGR_PLL1SRC_SHIFT (0) /* Bits 0-1: PLL1 entry clock source */ +#define RCC_PLL1CFGR_PLL1SRC_MASK (3 << RCC_PLL1CFGR_PLL1SRC_SHIFT) +#define RCC_PLL1CFGR_PLL1SRC_NONE (0 << RCC_PLL1CFGR_PLL1SRC_SHIFT) /* 00: No clock send to PLL1 */ +#define RCC_PLL1CFGR_PLL1SRC_MSIS (1 << RCC_PLL1CFGR_PLL1SRC_SHIFT) /* 01: MSIS clock selected as PLL1 clock entry */ +#define RCC_PLL1CFGR_PLL1SRC_HSI16 (2 << RCC_PLL1CFGR_PLL1SRC_SHIFT) /* 10: HSI16 clock selected as PLL1 clock entry */ +#define RCC_PLL1CFGR_PLL1SRC_HSE (3 << RCC_PLL1CFGR_PLL1SRC_SHIFT) /* 11: HSE clock selected as PLL1 clock entry */ +#define RCC_PLL1CFGR_PLL1RGE_SHIFT (2) /* Bits 2-3: PLL1 input frequency range */ +#define RCC_PLL1CFGR_PLL1RGE_MASK (3 << RCC_PLL1CFGR_PLL1RGE_SHIFT) +#define RCC_PLL1CFGR_PLL1RGE_4_TO_8MHZ (0 << RCC_PLL1CFGR_PLL1RGE_SHIFT) /* 00-01-10: PLL1 input (ref1_ck) clock range frequency between 4 and 8 MHz */ +#define RCC_PLL1CFGR_PLL1RGE_8_TO_16MHZ (3 << RCC_PLL1CFGR_PLL1RGE_SHIFT) /* 11: PLL1 input (ref1_ck) clock range frequeny between 8 and 16 MHz */ +#define RCC_PLL1CFGR_PLL1FRACEN (1 << 4) /* Bit 4: PLL1 fractional latch enable */ +#define RCC_PLL1CFGR_PLL1M_SHIFT (8) /* Bits 8-11: Prescaler for PLL1 */ +#define RCC_PLL1CFGR_PLL1M_MASK (0xf << RCC_PLL1CFGR_PLL1M_SHIFT) +#define RCC_PLL1CFGR_PLL1M(n) (((n) - 1) << RCC_PLL1CFGR_PLL1M_SHIFT) +#define RCC_PLL1CFGR_PLL1MBOOST_SHIFT (12) /* Bits 12-15: Prescaler for EPOD booster input clock */ +#define RCC_PLL1CFGR_PLL1MBOOST_MASK (0xf << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) +#define RCC_PLL1CFGR_PLL1MBOOST_DIV_1 (0 << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) /* 0000: division by 1 (bypass) */ +#define RCC_PLL1CFGR_PLL1MBOOST_DIV_2 (1 << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) /* 0001: division by 2 */ +#define RCC_PLL1CFGR_PLL1MBOOST_DIV_4 (2 << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) /* 0010: division by 4 */ +#define RCC_PLL1CFGR_PLL1MBOOST_DIV_6 (3 << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) /* 0011: division by 6 */ +#define RCC_PLL1CFGR_PLL1MBOOST_DIV_8 (4 << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) /* 0100: division by 8 */ +#define RCC_PLL1CFGR_PLL1MBOOST_DIV_10 (5 << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) /* 0101: division by 10 */ +#define RCC_PLL1CFGR_PLL1MBOOST_DIV_12 (6 << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) /* 0110: division by 12 */ +#define RCC_PLL1CFGR_PLL1MBOOST_DIV_14 (7 << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) /* 0111: division by 14 */ +#define RCC_PLL1CFGR_PLL1MBOOST_DIV_16 (8 << RCC_PLL1CFGR_PLL1MBOOST_SHIFT) /* 1000: division by 16 */ +#define RCC_PLL1CFGR_PLL1PEN (1 << 16) /* Bit 16: PLL1 DIVP divider output enable */ +#define RCC_PLL1CFGR_PLL1QEN (1 << 17) /* Bit 17: PLL1 DIVQ divider output enable */ +#define RCC_PLL1CFGR_PLL1REN (1 << 18) /* Bit 18: PLL1 DIVR divider output enable */ + +/* RCC PLL1 dividers register */ + +#define RCC_PLL1DIVR_PLL1N_SHIFT (0) /* Bits 0-8: Multiplication factor for PLL1 VCO */ +#define RCC_PLL1DIVR_PLL1N_MASK (0x1ff << RCC_PLL1DIVR_PLL1N_SHIFT) +#define RCC_PLL1DIVR_PLL1N(n) (((n) - 1) << RCC_PLL1DIVR_PLL1N_SHIFT) +#define RCC_PLL1DIVR_PLL1P_SHIFT (9) /* Bits 9-15: PLL1 DIVP division factor */ +#define RCC_PLL1DIVR_PLL1P_MASK (0x7f << RCC_PLL1DIVR_PLL1P_SHIFT) +#define RCC_PLL1DIVR_PLL1P(n) (((n) - 1) << RCC_PLL1DIVR_PLL1P_SHIFT) +#define RCC_PLL1DIVR_PLL1Q_SHIFT (16) /* Bits 16-22: PLL1 DIVQ division factor */ +#define RCC_PLL1DIVR_PLL1Q_MASK (0x7f << RCC_PLL1DIVR_PLL1Q_SHIFT) +#define RCC_PLL1DIVR_PLL1Q(n) (((n) - 1) << RCC_PLL1DIVR_PLL1Q_SHIFT) +#define RCC_PLL1DIVR_PLL1R_SHIFT (24) /* Bits 24-30: PLL1 DIVR division factor */ +#define RCC_PLL1DIVR_PLL1R_MASK (0x7f << RCC_PLL1DIVR_PLL1R_SHIFT) +#define RCC_PLL1DIVR_PLL1R(n) (((n) - 1) << RCC_PLL1DIVR_PLL1R_SHIFT) + +/* APB2 peripheral reset register */ + +#define RCC_APB2RSTR_TIM1RST (1 << 11) /* Bit 11: TIM1 reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI1 reset */ +#define RCC_APB2RSTR_TIM8RST (1 << 13) /* Bit 13: TIM8 reset */ +#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ +#define RCC_APB2RSTR_TIM15RST (1 << 16) /* Bit 16: TIM15 reset */ +#define RCC_APB2RSTR_TIM16RST (1 << 17) /* Bit 17: TIM16 reset */ +#define RCC_APB2RSTR_TIM17RST (1 << 18) /* Bit 18: TIM17 reset */ +#define RCC_APB2RSTR_SAI1RST (1 << 21) /* Bit 21: SAI1 reset */ +#define RCC_APB2RSTR_SAI2RST (1 << 22) /* Bit 22: SAI2 reset */ + +/* AHB1 Peripheral Clock enable register */ + +#define RCC_AHB1ENR_GPDMA1EN (1 << 0) /* Bit 0: GPDMA1 clock enable */ +#define RCC_AHB1ENR_CORDICEN (1 << 1) /* Bit 1: CORDIC clock enable */ +#define RCC_AHB1ENR_FMACEN (1 << 2) /* Bit 2: FMAC clock enable */ +#define RCC_AHB1ENR_MDF1EN (1 << 2) /* Bit 2: MDF1 clock enable */ +#define RCC_AHB1ENR_FLASHEN (1 << 8) /* Bit 8: Flash memory interface clock enable */ +#define RCC_AHB1ENR_CRCEN (1 << 12) /* Bit 12: CRC clock enable */ +#define RCC_AHB1ENR_TSCEN (1 << 16) /* Bit 16: Touch Sensing Controller enable */ +#define RCC_AHB1ENR_RAMCFGCEN (1 << 17) /* Bit 17: RAMCFG clock enable */ +#define RCC_AHB1ENR_DMA2DEN (1 << 18) /* Bit 18: DMA2D clock enable */ +#define RCC_AHB1ENR_GTZC1EN (1 << 24) /* Bit 24: GTZC1 clock enable */ +#define RCC_AHB1ENR_BKPSRAMEN (1 << 31) /* Bit 31: BKPUPSRAM clock enable */ +#define RCC_AHB1ENR_DCACHE1EN (1 << 30) /* Bit 30: DCACHE1 clock enable */ +#define RCC_AHB1ENR_SRAM1EN (1 << 31) /* Bit 31: SRAM1 clock enable */ + +/* AHB2 Peripheral Clock enable register 1 */ + +#define RCC_AHB2ENR1_GPIOEN(n) (1 << (n)) +#define RCC_AHB2ENR1_GPIOAEN (1 << 0) /* Bit 0: IO port A enable */ +#define RCC_AHB2ENR1_GPIOBEN (1 << 1) /* Bit 1: IO port B enable */ +#define RCC_AHB2ENR1_GPIOCEN (1 << 2) /* Bit 2: IO port C enable */ +#define RCC_AHB2ENR1_GPIODEN (1 << 3) /* Bit 3: IO port D enable */ +#define RCC_AHB2ENR1_GPIOEEN (1 << 4) /* Bit 4: IO port E enable */ +#define RCC_AHB2ENR1_GPIOFEN (1 << 5) /* Bit 5: IO port F enable */ +#define RCC_AHB2ENR1_GPIOGEN (1 << 6) /* Bit 6: IO port G enable */ +#define RCC_AHB2ENR1_GPIOHEN (1 << 7) /* Bit 7: IO port H enable */ +#define RCC_AHB2ENR1_GPIOIEN (1 << 8) /* Bit 8: IO port I enable */ +#define RCC_AHB2ENR1_ADC1EN (1 << 10) /* Bit 10: ADC1 interface enable */ +#define RCC_AHB2ENR1_DCMI_PCSSI_EN (1 << 12) /* Bit 12: DCMI and PSSI enable */ +#define RCC_AHB2ENR1_OTGEN (1 << 14) /* Bit 14: OTG_FS module enable */ +#define RCC_AHB2ENR1_AESEN (1 << 16) /* Bit 16: AES Cryptographic module enable */ +#define RCC_AHB2ENR1_HASHEN (1 << 17) /* Bit 17: HASH module enable */ +#define RCC_AHB2ENR1_RNGEN (1 << 18) /* Bit 18: Random number generator module enable */ +#define RCC_AHB2ENR1_PKAEN (1 << 19) /* Bit 19: PKA clock enable */ +#define RCC_AHB2ENR1_SAESEN (1 << 20) /* Bit 20: SAES clock enable */ +#define RCC_AHB2ENR1_OCTOSPIMEN (1 << 21) /* Bit 21: OCTOSPIM clock enable */ +#define RCC_AHB2ENR1_OTFDEC1EN (1 << 23) /* Bit 21: OTFDEC1 clock enable */ +#define RCC_AHB2ENR1_OTFDEC2EN (1 << 24) /* Bit 21: OTFDEC2 clock enable */ +#define RCC_AHB2ENR1_SDMMC1EN (1 << 27) /* Bit 27: SDMMC1 clock enable */ +#define RCC_AHB2ENR1_SDMMC2EN (1 << 28) /* Bit 28: SDMMC2 clock enable */ +#define RCC_AHB2ENR1_SRAM2EN (1 << 30) /* Bit 30: SRAM2 clock enable */ +#define RCC_AHB2ENR1_SRAM3EN (1 << 31) /* Bit 31: SRAM3 clock enable */ + +/* AHB2 Peripheral Clock enable register 2 */ + +#define RCC_AHB2ENR2_FSMCEN (1 << 0) /* Bit 0: FSMC clock enable */ +#define RCC_AHB2ENR2_OCTOSPI1EN (1 << 4) /* Bit 4: OCTOSPI1 clock enable */ +#define RCC_AHB2ENR2_OCTOSPI2EN (1 << 8) /* Bit 8: OCTOSPI2 clock enable */ + +/* RCC AHB3 peripheral clock enable register */ + +#define RCC_AHB3ENR_LPGPIO1EN (1 << 0) /* Bit 0: LPGPIO1 clock enable */ +#define RCC_AHB3ENR_PWREN (1 << 2) /* Bit 2: PWR clock enable */ +#define RCC_AHB3ENR_ADC4EN (1 << 5) /* Bit 5: ADC4 clock enable */ +#define RCC_AHB3ENR_DAC1EN (1 << 6) /* Bit 6: DAC1 clock enable */ +#define RCC_AHB3ENR_LPDMA1EN (1 << 9) /* Bit 9: LPDMA1 clock enable */ +#define RCC_AHB3ENR_ADF1EN (1 << 10) /* Bit 10: ADF1 clock enable */ +#define RCC_AHB3ENR_GTZC2EN (1 << 12) /* Bit 12: GTZC2 clock enable */ +#define RCC_AHB3ENR_SRAM4EN (1 << 31) /* Bit 31: SRAM4 clock enable */ + +/* APB1 Peripheral Clock enable register 1 */ + +#define RCC_APB1ENR1_TIM2EN (1 << 0) /* Bit 0: TIM2 clock enable */ +#define RCC_APB1ENR1_TIM3EN (1 << 1) /* Bit 1: TIM3 clock enable */ +#define RCC_APB1ENR1_TIM4EN (1 << 2) /* Bit 2: TIM4 clock enable */ +#define RCC_APB1ENR1_TIM5EN (1 << 3) /* Bit 3: TIM5 clock enable */ +#define RCC_APB1ENR1_TIM6EN (1 << 4) /* Bit 4: TIM6 clock enable */ +#define RCC_APB1ENR1_TIM7EN (1 << 5) /* Bit 5: TIM7 clock enable */ +#define RCC_APB1ENR1_WWDGEN (1 << 11) /* Bit 11: WWDG clock enable */ +#define RCC_APB1ENR1_SPI2EN (1 << 14) /* Bit 14: SPI2 clock enable */ +#define RCC_APB1ENR1_USART2EN (1 << 17) /* Bit 17: USART2 clock enable */ +#define RCC_APB1ENR1_USART3EN (1 << 18) /* Bit 18: USART3 clock enable */ +#define RCC_APB1ENR1_USART4EN (1 << 19) /* Bit 19: USART4 clock enable */ +#define RCC_APB1ENR1_USART5EN (1 << 20) /* Bit 20: USART5 clock enable */ +#define RCC_APB1ENR1_I2C1EN (1 << 21) /* Bit 21: I2C1 clock enable */ +#define RCC_APB1ENR1_I2C2EN (1 << 22) /* Bit 22: I2C2 clock enable */ +#define RCC_APB1ENR1_CRSEN (1 << 24) /* Bit 24: CRSEN clock enable */ + +/* APB1 Peripheral Clock enable register 2 */ + +#define RCC_APB1ENR2_I2C4EN (1 << 1) /* Bit 1: I2C4 clock enable */ +#define RCC_APB1ENR2_LPTIM2EN (1 << 5) /* Bit 5: LPTIM2 clock enable */ +#define RCC_APB1ENR2_FDCAN1EN (1 << 9) /* Bit 9: FDCAN1EN clock enable */ +#define RCC_APB1ENR2_UCPD1EN (1 << 23) /* Bit 23: UCPD1EN clock enable */ + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_TIM1EN (1 << 11) /* Bit 11: TIM1 clock enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI1 clock enable */ +#define RCC_APB2ENR_TIM8EN (1 << 13) /* Bit 13: TIM8 clock enable */ +#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 clock enable */ +#define RCC_APB2ENR_TIM15EN (1 << 16) /* Bit 16: TIM15 clock enable */ +#define RCC_APB2ENR_TIM16EN (1 << 17) /* Bit 17: TIM16 clock enable */ +#define RCC_APB2ENR_TIM17EN (1 << 18) /* Bit 18: TIM17 clock enable */ +#define RCC_APB2ENR_SAI1EN (1 << 21) /* Bit 21: SAI1 clock enable */ +#define RCC_APB2ENR_SAI2EN (1 << 22) /* Bit 22: SAI2 clock enable */ + +/* APB3 Peripheral Clock enable register */ + +#define RCC_APB3ENR_SYSCFGEN (1 << 1) /* Bit 1: SYSCFG clock enable */ +#define RCC_APB3ENR_SPI3EN (1 << 5) /* Bit 5: SPI3 clock enable */ +#define RCC_APB3ENR_LPUART1EN (1 << 6) /* Bit 6: LPUART1 clock enable */ +#define RCC_APB3ENR_I2C3EN (1 << 7) /* Bit 7: I2C3 clock enable */ +#define RCC_APB3ENR_LPTIM1EN (1 << 11) /* Bit 11: LPTIM1 clock enable */ +#define RCC_APB3ENR_LPTIM3EN (1 << 12) /* Bit 12: LPTIM3 clock enable */ +#define RCC_APB3ENR_LPTIM4EN (1 << 13) /* Bit 13: LPTIM4 clock enable */ +#define RCC_APB3ENR_OPAMPEN (1 << 14) /* Bit 14: OPAMP clock enable */ +#define RCC_APB3ENR_COMPEN (1 << 15) /* Bit 15: COMP clock enable */ +#define RCC_APB3ENR_VREFEN (1 << 20) /* Bit 20: VREF clock enable */ +#define RCC_APB3ENR_RTCAPBEN (1 << 21) /* Bit 21: RTC and TAMP APB clock enable */ + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ + +#define RCC_BDCR_LSEDRV_SHIFT (3) /* Bits 3-4: LSE oscillator drive capability */ +#define RCC_BDCR_LSEDRV_MASK (3 << RCC_BDCR_LSEDRV_SHIFT) +# define RCC_BDCR_LSEDRV_LOW (0 << RCC_BDCR_LSEDRV_SHIFT) /* 00: Lower driving capability */ +# define RCC_BDCR_LSEDRV_MEDLO (1 << RCC_BDCR_LSEDRV_SHIFT) /* 01: Medium Low driving capability */ +# define RCC_BDCR_LSEDRV_MEDHI (2 << RCC_BDCR_LSEDRV_SHIFT) /* 10: Medium High driving capability*/ +# define RCC_BDCR_LSEDRV_HIGH (3 << RCC_BDCR_LSEDRV_SHIFT) /* 11: Higher driving capability */ + +#define RCC_BDCR_LSECSSON (1 << 5) /* Bit 5: CSS on LSE enable */ +#define RCC_BDCR_LSECSSD (1 << 6) /* Bit 6: CSS on LSE failure Detection */ +#define RCC_BDCR_LSESYSEN (1 << 7) /* Bit 7: LSE system clock (LSESYS) enable */ + +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 32 used as RTC clock */ + +#define RCC_BDCR_LSESYSRDY (1 << 11) /* Bit 11: LSE system clock (LSESYS) ready */ +#define RCC_BDCR_LSEGFON (1 << 12) /* Bit 12: LSE clock glitch filter enable */ + +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ +#define RCC_BDCR_LSCOEN (1 << 24) /* Bit 24: Low speed clock output enable */ +#define RCC_BDCR_LSCOSEL (1 << 25) /* Bit 25: Low speed clock output selection */ +# define RCC_BCDR_LSCOSEL_LSI 0 /* LSI selected */ +# define RCC_BDCR_LSCOSEL_LSE RCC_BDCR_LSCOSEL /* LSE selected */ + +#define RCC_BDCR_LSION (1 << 26) /* Bit 26: Low Speed Internal oscillator enable */ +#define RCC_BDCR_LSIRDY (1 << 27) /* Bit 27: Low Speed Internal oscillator Ready */ +#define RCC_BDCR_LSIPREDIV (1 << 28) /* Bit 28: Low-speed clock divider configuration */ +# define RCC_BCDR_LSIPREDIV_NONE 0 /* LSI not divided */ +# define RCC_BCDR_LSIPREDIV_128 1 /* LSI divided by 128 */ + +#if 0 +#define RCC_CR_MSIRGSEL (1 << 3) /* Bit 3: MSI clock range selection */ +#define RCC_CR_MSIRANGE_SHIFT (4) /* Bits 7-4: MSI clock range */ +#define RCC_CR_MSIRANGE_MASK (0x0f << RCC_CR_MSIRANGE_SHIFT) +# define RCC_CR_MSIRANGE_100K (0 << RCC_CR_MSIRANGE_SHIFT) /* 0000: around 100 kHz */ +# define RCC_CR_MSIRANGE_200K (1 << RCC_CR_MSIRANGE_SHIFT) /* 0001: around 200 kHz */ +# define RCC_CR_MSIRANGE_400K (2 << RCC_CR_MSIRANGE_SHIFT) /* 0010: around 400 kHz */ +# define RCC_CR_MSIRANGE_800K (3 << RCC_CR_MSIRANGE_SHIFT) /* 0011: around 800 kHz */ +# define RCC_CR_MSIRANGE_1M (4 << RCC_CR_MSIRANGE_SHIFT) /* 0100: around 1 MHz */ +# define RCC_CR_MSIRANGE_2M (5 << RCC_CR_MSIRANGE_SHIFT) /* 0101: around 2 MHz */ +# define RCC_CR_MSIRANGE_4M (6 << RCC_CR_MSIRANGE_SHIFT) /* 0110: around 4 MHz */ +# define RCC_CR_MSIRANGE_8M (7 << RCC_CR_MSIRANGE_SHIFT) /* 0111: around 8 MHz */ +# define RCC_CR_MSIRANGE_16M (8 << RCC_CR_MSIRANGE_SHIFT) /* 1000: around 16 MHz */ +# define RCC_CR_MSIRANGE_24M (9 << RCC_CR_MSIRANGE_SHIFT) /* 1001: around 24 MHz */ +# define RCC_CR_MSIRANGE_32M (10 << RCC_CR_MSIRANGE_SHIFT) /* 1010: around 32 MHz */ +# define RCC_CR_MSIRANGE_48M (11 << RCC_CR_MSIRANGE_SHIFT) /* 1011: around 48 MHz */ +#define RCC_CR_PRIV (1 << 31) /* Bit 21: RCC privilege */ + +/* Internal Clock Sources Calibration */ + +#define RCC_CR_HSITRIM_SHIFT (24) /* Bits 30-24: Internal High Speed clock trimming */ +#define RCC_CR_HSITRIM_MASK (0x7f << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSICAL_SHIFT (16) /* Bits 23-16: Internal High Speed clock Calibration */ +#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_MSITRIM_SHIFT (8) /* Bits 15-8: Internal Multi Speed clock trimming */ +#define RCC_CR_MSITRIM_MASK (0xff << RCC_CR_MSITRIM_SHIFT) +#define RCC_CR_MSICAL_SHIFT (0) /* Bits 7-0: Internal Multi Speed clock Calibration */ +#define RCC_CR_MSICAL_MASK (0xff << RCC_CR_MSICAL_SHIFT) + +/* RCC clock configuration register 1 */ + +#define RCC_CFGR1_SW_SHIFT (0) /* Bits 0-1: System clock Switch */ +#define RCC_CFGR1_SW_MASK (3 << RCC_CFGR1_SW_SHIFT) +# define RCC_CFGR1_SW_MSIS (0 << RCC_CFGR1_SW_SHIFT) /* 00: MSIS selected as system clock */ +# define RCC_CFGR1_SW_HSI16 (1 << RCC_CFGR1_SW_SHIFT) /* 00: HSI16 selected as system clock */ +# define RCC_CFGR1_SW_HSE (2 << RCC_CFGR1_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR1_SW_PLL (3 << RCC_CFGR1_SW_SHIFT) /* 10: PLL pll1_r_ck selected as system clock */ + +#define RCC_CFGR1_SWS_SHIFT (2) /* Bits 2-3: System Clock Switch Status */ +#define RCC_CFGR1_SWS_MASK (3 << RCC_CFGR1_SWS_SHIFT) +# define RCC_CFGR1_SWS_MSIS (0 << RCC_CFGR1_SWS_SHIFT) /* 00: MSIS oscillator used as system clock */ +# define RCC_CFGR1_SWS_HSI16 (1 << RCC_CFGR1_SWS_SHIFT) /* 00: HSI16 oscillator used as system clock */ +# define RCC_CFGR1_SWS_HSE (2 << RCC_CFGR1_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR1_SWS_PLL (3 << RCC_CFGR1_SWS_SHIFT) /* 10: PLL used as system clock */ + +#define RCC_CFGR1_STOPWUCK (1 << 4) /* Bit 4: Wakeup from Stop and CSS backup clock selection */ +# define RCC_CFGR1_STOPWUCK_MSIS (0 << 4) /* 0: MSIS */ +# define RCC_CFGR1_STOPWUCK_HSI16 (1 << 4) /* 0: HSI16 */ + +#define RCC_CFGR_STOPKERWUCK (1 << 5) /* Bit 5: Wakeup from Stop kernel clock automatic enable selection */ +# define RCC_CFGR1_STOPKERWUCK_MSIK (0 << 5) /* 0: MSIK */ +# define RCC_CFGR1_STOPKERWUCK_HSI16 (1 << 5) /* 0: HSI16 */ + +#define RCC_CFGR1_MCOSEL_SHIFT (24) /* Bits 24-27: Microcontroller Clock Output */ +#define RCC_CFGR1_MCOSEL_MASK (0x0f << RCC_CFGR1_MCOSEL_SHIFT) +# define RCC_CFGR1_MCOSEL_NONE (0 << RCC_CFGR1_MCOSEL_SHIFT) /* 0000: Disabled */ +# define RCC_CFGR1_MCOSEL_SYSCLK (1 << RCC_CFGR1_MCOSEL_SHIFT) /* 0001: SYSCLK system clock selected */ +# define RCC_CFGR1_MCOSEL_MSIS (2 << RCC_CFGR1_MCOSEL_SHIFT) /* 0010: MSIS clock selected */ +# define RCC_CFGR1_MCOSEL_HSI16 (3 << RCC_CFGR1_MCOSEL_SHIFT) /* 0011: HSI16 clock selected */ +# define RCC_CFGR1_MCOSEL_HSE (4 << RCC_CFGR1_MCOSEL_SHIFT) /* 0100: HSE clock selected */ +# define RCC_CFGR1_MCOSEL_PLL (5 << RCC_CFGR1_MCOSEL_SHIFT) /* 0101: Main PLL clock pll1_r_ck selected */ +# define RCC_CFGR1_MCOSEL_LSI (6 << RCC_CFGR1_MCOSEL_SHIFT) /* 0110: LSI clock selected */ +# define RCC_CFGR1_MCOSEL_LSE (7 << RCC_CFGR1_MCOSEL_SHIFT) /* 0111: LSE clock selected */ +# define RCC_CFGR1_MCOSEL_HSI48 (8 << RCC_CFGR1_MCOSEL_SHIFT) /* 1000: HSI48 clock selected */ +# define RCC_CFGR1_MCOSEL_MSIK (9 << RCC_CFGR1_MCOSEL_SHIFT) /* 1001: MSIK clock selected */ + +#define RCC_CFGR1_MCOPRE_SHIFT (28) /* Bits 28-30: MCO prescaler */ +#define RCC_CFGR1_MCOPRE_MASK (7 << RCC_CFGR1_MCOPRE_SHIFT) +# define RCC_CFGR1_MCOPRE_NONE (0 << RCC_CFGR1_MCOPRE_SHIFT) /* 000: no division */ +# define RCC_CFGR1_MCOPRE_DIV2 (1 << RCC_CFGR1_MCOPRE_SHIFT) /* 001: division by 2 */ +# define RCC_CFGR1_MCOPRE_DIV4 (2 << RCC_CFGR1_MCOPRE_SHIFT) /* 010: division by 4 */ +# define RCC_CFGR1_MCOPRE_DIV8 (3 << RCC_CFGR1_MCOPRE_SHIFT) /* 011: division by 8 */ +# define RCC_CFGR1_MCOPRE_DIV16 (4 << RCC_CFGR1_MCOPRE_SHIFT) /* 100: division by 16 */ + +/* RCC clock configuration register 2 */ + +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 4-7: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK ( 0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 ( 8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 ( 9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ + +#define RCC_CFGR_PPRE1_SHIFT (8) /* Bits 8-10: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ + +#define RCC_CFGR_PPRE2_SHIFT (11) /* Bits 11-13: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ + +/* PLL configuration register */ + +#define RCC_PLLCFG_PLLSRC_SHIFT (0) /* Bit 0-1: Main PLL(PLL) and audio PLLs (PLLSAIx) + * entry clock source */ +#define RCC_PLLCFG_PLLSRC_MASK (3 << RCC_PLLCFG_PLLSRC_SHIFT) +# define RCC_PLLCFG_PLLSRC_NONE (0 << RCC_PLLCFG_PLLSRC_SHIFT) /* 000: No clock sent to PLLs */ +# define RCC_PLLCFG_PLLSRC_MSI (1 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: MSI selected as PLL source */ +# define RCC_PLLCFG_PLLSRC_HSI16 (2 << RCC_PLLCFG_PLLSRC_SHIFT) /* 010: HSI16 selected as PLL source */ +# define RCC_PLLCFG_PLLSRC_HSE (3 << RCC_PLLCFG_PLLSRC_SHIFT) /* 011: HSE selected as PLL source */ + +#define RCC_PLLCFG_PLLM_SHIFT (4) /* Bits 4-7: Main PLL (PLL) input clock divider */ +#define RCC_PLLCFG_PLLM_MASK (0x0f << RCC_PLLCFG_PLLM_SHIFT) +# define RCC_PLLCFG_PLLM(n) ((n-1) << RCC_PLLCFG_PLLM_SHIFT) /* m = 1..16 */ + +#define RCC_PLLCFG_PLLN_SHIFT (8) /* Bits 8-14: Main PLL (PLL) VCO multiplier */ +#define RCC_PLLCFG_PLLN_MASK (0x7f << RCC_PLLCFG_PLLN_SHIFT) +# define RCC_PLLCFG_PLLN(n) ((n) << RCC_PLLCFG_PLLN_SHIFT) /* n = 8..86 */ + +#define RCC_PLLCFG_PLLPEN (1 << 16) /* Bit 16: Main PLL PLLSAI3CLK output enable */ + +#define RCC_PLLCFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI3CLK */ +# define RCC_PLLCFG_PLLP_7 0 /* 0: PLLP = 7 */ +# define RCC_PLLCFG_PLLP_17 RCC_PLLCFG_PLLP /* 1: PLLP = 17 */ + +#define RCC_PLLCFG_PLLQEN (1 << 20) /* Bit 20: Main PLL PLL48M1CLK output enable */ + +#define RCC_PLLCFG_PLLQ_SHIFT (21) /* Bits 21-22: Main PLL division factor for PLL48M1CLK (48 MHz clock) */ +#define RCC_PLLCFG_PLLQ_MASK (3 << RCC_PLLCFG_PLLQ_SHIFT) +# define RCC_PLLCFG_PLLQ(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLQ_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLCFG_PLLQ_2 (0 << RCC_PLLCFG_PLLQ_SHIFT) /* 00: PLLQ = 2 */ +# define RCC_PLLCFG_PLLQ_4 (1 << RCC_PLLCFG_PLLQ_SHIFT) /* 01: PLLQ = 4 */ +# define RCC_PLLCFG_PLLQ_6 (2 << RCC_PLLCFG_PLLQ_SHIFT) /* 10: PLLQ = 6 */ +# define RCC_PLLCFG_PLLQ_8 (3 << RCC_PLLCFG_PLLQ_SHIFT) /* 11: PLLQ = 8 */ + +#define RCC_PLLCFG_PLLREN (1 << 24) /* Bit 24: Main PLL PLLCLK output enable */ + +#define RCC_PLLCFG_PLLR_SHIFT (25) /* Bits 25-26: Main PLL division factor for PLLCLK (system clock) */ +#define RCC_PLLCFG_PLLR_MASK (3 << RCC_PLLCFG_PLLR_SHIFT) +# define RCC_PLLCFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLR_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLCFG_PLLR_2 (0 << RCC_PLLCFG_PLLR_SHIFT) /* 00: PLLR = 2 */ +# define RCC_PLLCFG_PLLR_4 (1 << RCC_PLLCFG_PLLR_SHIFT) /* 01: PLLR = 4 */ +# define RCC_PLLCFG_PLLR_6 (2 << RCC_PLLCFG_PLLR_SHIFT) /* 10: PLLR = 6 */ +# define RCC_PLLCFG_PLLR_8 (3 << RCC_PLLCFG_PLLR_SHIFT) /* 11: PLLR = 8 */ + +#define RCC_PLLCFG_PLLPDIV_SHIFT (27) /* Bits 31-27: Main PLL division factor for PLLSAI3CLK */ +#define RCC_PLLCFG_PLLPDIV_MASK (0x1f << RCC_PLLCFG_PLLPDIV_SHIFT) +# define RCC_PLLCFG_PLLPDIV(n) ((n) << RCC_PLLCFG_PLLDIV_SHIFT) /* n = 2..31 for VCO / 2 .. VCO / 31 */ +# define RCC_PLLCFG_PLLP_CNTRLD RCC_PLLCFG_PLLPDIV(0) + +#define RCC_PLLCFG_RESET (0x00001000) /* PLLCFG reset value */ + +/* PLLSAI1 Configuration register */ + +#define RCC_PLLSAI1CFG_PLLSRC_SHIFT (0) /* Bit 0-1: Main PLSAI1 entry clock source */ +#define RCC_PLLSAI1CFG_PLLSRC_MASK (3 << RCC_PLLSAI1CFG_PLLSRC_SHIFT) +# define RCC_PLLSAI1CFG_PLLSRC_NONE (0 << RCC_PLLSAI1CFG_PLLSRC_SHIFT) /* 000: No clock sent to PLLs */ +# define RCC_PLLSAI1CFG_PLLSRC_MSI (1 << RCC_PLLSAI1CFG_PLLSRC_SHIFT) /* 001: MSI selected as PLL source */ +# define RCC_PLLSAI1CFG_PLLSRC_HSI16 (2 << RCC_PLLSAI1CFG_PLLSRC_SHIFT) /* 010: HSI16 selected as PLL source */ +# define RCC_PLLSAI1CFG_PLLSRC_HSE (3 << RCC_PLLSAI1CFG_PLLSRC_SHIFT) /* 011: HSE selected as PLL source */ + +#define RCC_PLLSAI1CFG_PLLM_SHIFT (4) /* Bits 4-7: Division factor for PLLSAI1 input clock */ +#define RCC_PLLSAI1CFG_PLLM_MASK (0x0f << RCC_PLLSAI1CFG_PLLM_SHIFT) +# define RCC_PLLSAI1CFG_PLLM(n) ((n-1) << RCC_PLLSAI1CFG_PLLM_SHIFT) /* m = 1..16 */ + +#define RCC_PLLSAI1CFG_PLLN_SHIFT (8) /* Bits 8-14: SAI1 PLL (PLLSAI1) VCO multiplier */ +#define RCC_PLLSAI1CFG_PLLN_MASK (0x7f << RCC_PLLSAI1CFG_PLLN_SHIFT) +# define RCC_PLLSAI1CFG_PLLN(n) ((n) << RCC_PLLSAI1CFG_PLLN_SHIFT) /* n = 8..86 */ + +#define RCC_PLLSAI1CFG_PLLPEN (1 << 16) /* Bit 16: SAI1 PLL PLLSAI1CLK output enable */ + +#define RCC_PLLSAI1CFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI1CLK */ +# define RCC_PLLSAI1CFG_PLLP_7 0 /* 0: PLLP = 7 */ +# define RCC_PLLSAI1CFG_PLLP_17 RCC_PLLSAI1CFG_PLLP /* 1: PLLP = 17 */ + +#define RCC_PLLSAI1CFG_PLLQEN (1 << 20) /* Bit 20: Main PLL PLL48M2CLK output enable */ + +#define RCC_PLLSAI1CFG_PLLQ_SHIFT (21) +#define RCC_PLLSAI1CFG_PLLQ_MASK (3 << RCC_PLLSAI1CFG_PLLQ_SHIFT) +# define RCC_PLLSAI1CFG_PLLQ(n) ((((n)>>1)-1)<< RCC_PLLSAI1CFG_PLLQ_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLSAI1CFG_PLLQ_2 (0 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 00: PLLQ = 2 */ +# define RCC_PLLSAI1CFG_PLLQ_4 (1 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 01: PLLQ = 4 */ +# define RCC_PLLSAI1CFG_PLLQ_6 (2 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 10: PLLQ = 6 */ +# define RCC_PLLSAI1CFG_PLLQ_8 (3 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 11: PLLQ = 8 */ + +#define RCC_PLLSAI1CFG_PLLREN (1 << 24) /* Bit 24: SAI1 PLL PLLADC1CLK output enable */ + +#define RCC_PLLSAI1CFG_PLLR_SHIFT (25) +#define RCC_PLLSAI1CFG_PLLR_MASK (3 << RCC_PLLSAI1CFG_PLLR_SHIFT) +# define RCC_PLLSAI1CFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLSAI1CFG_PLLR_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLSAI1CFG_PLLR_2 (0 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 00: PLLR = 2 */ +# define RCC_PLLSAI1CFG_PLLR_4 (1 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 01: PLLR = 4 */ +# define RCC_PLLSAI1CFG_PLLR_6 (2 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 10: PLLR = 6 */ +# define RCC_PLLSAI1CFG_PLLR_8 (3 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 11: PLLR = 8 */ + +#define RCC_PLLSAI1CFG_PLLPDIV_SHIFT (27) /* Bits 31-27: PLLSAI1 division factor for PLLSAI1CLK */ +#define RCC_PLLSAI1CFG_PLLPDIV_MASK (0x1f << RCC_PLLSAI1CFG_PLLPDIV_SHIFT) +# define RCC_PLLSAI1CFG_PLLPDIV(n) ((n) << RCC_PLLSAI1CFG_PLLDIV_SHIFT) /* n = 2..31 for VCO / 2 .. VCO / 31 */ +# define RCC_PLLSAI1CFG_PLLP_CNTRLD RCC_PLLSAI1CFG_PLLPDIV(0) + +/* PLLSAI2 Configuration register */ + +#define RCC_PLLSAI2CFG_PLLSRC_SHIFT (0) /* Bit 0-1: Main PLSAI2 entry clock source */ +#define RCC_PLLSAI2CFG_PLLSRC_MASK (3 << RCC_PLLSAI2CFG_PLLSRC_SHIFT) +# define RCC_PLLSAI2CFG_PLLSRC_NONE (0 << RCC_PLLSAI2CFG_PLLSRC_SHIFT) /* 000: No clock sent to PLLs */ +# define RCC_PLLSAI2CFG_PLLSRC_MSI (1 << RCC_PLLSAI2CFG_PLLSRC_SHIFT) /* 001: MSI selected as PLL source */ +# define RCC_PLLSAI2CFG_PLLSRC_HSI16 (2 << RCC_PLLSAI2CFG_PLLSRC_SHIFT) /* 010: HSI16 selected as PLL source */ +# define RCC_PLLSAI2CFG_PLLSRC_HSE (3 << RCC_PLLSAI2CFG_PLLSRC_SHIFT) /* 011: HSE selected as PLL source */ + +#define RCC_PLLSAI2CFG_PLLM_SHIFT (4) /* Bits 4-7: Division factor for PLLSAI1 input clock */ +#define RCC_PLLSAI2CFG_PLLM_MASK (0x0f << RCC_PLLSAI1CFG_PLLM_SHIFT) +# define RCC_PLLSA21CFG_PLLM(n) ((n-1) << RCC_PLLSAI1CFG_PLLM_SHIFT) /* m = 1..16 */ + +#define RCC_PLLSAI2CFG_PLLN_SHIFT (8) /* Bits 8-14: SAI2 PLL (PLLSAI2) VCO multiplier */ +#define RCC_PLLSAI2CFG_PLLN_MASK (0x7f << RCC_PLLSAI2CFG_PLLN_SHIFT) +# define RCC_PLLSAI2CFG_PLLN(n) ((n) << RCC_PLLSAI2CFG_PLLN_SHIFT) /* n = 8..86 */ + +#define RCC_PLLSAI2CFG_PLLPEN (1 << 16) /* Bit 16: SAI1 PLL PLLSAI2CLK output enable */ + +#define RCC_PLLSAI2CFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI2CLK */ +# define RCC_PLLSAI2CFG_PLLP_7 0 /* 0: PLLP = 7 */ +# define RCC_PLLSAI2CFG_PLLP_17 RCC_PLLSAI2CFG_PLLP /* 1: PLLP = 17 */ + +#define RCC_PLLSAI2CFG_PLLPDIV_SHIFT (27) /* Bits 31-27: PLLSAI2 division factor for PLLSAI2CLK */ +#define RCC_PLLSAI2CFG_PLLPDIV_MASK (0x1f << RCC_PLLSAI2CFG_PLLPDIV_SHIFT) +# define RCC_PLLSAI2CFG_PLLPDIV(n) ((n) << RCC_PLLSAI2CFG_PLLDIV_SHIFT) /* n = 2..31 for VCO / 2 .. VCO / 31 */ +# define RCC_PLLSAI2CFG_PLLP_CNTRLD RCC_PLLSAI2CFG_PLLPDIV(0) + +/* Clock interrupt enable register */ + +#define RCC_CIER_LSIRDYIE (1 << 0) /* Bit 0: LSI Ready Interrupt Enable */ +#define RCC_CIER_LSERDYIE (1 << 1) /* Bit 1: LSE Ready Interrupt Enable */ +#define RCC_CIER_MSIRDYIE (1 << 2) /* Bit 2: MSI Ready Interrupt Enable */ +#define RCC_CIER_HSIRDYIE (1 << 3) /* Bit 3: HSI Ready Interrupt Enable */ +#define RCC_CIER_HSERDYIE (1 << 4) /* Bit 4: HSE Ready Interrupt Enable */ +#define RCC_CIER_PLLRDYIE (1 << 5) /* Bit 5: PLL Ready Interrupt Enable */ +#define RCC_CIER_PLLSAI1RDYIE (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt enable */ +#define RCC_CIER_PLLSAI2RDYIE (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt enable */ +#define RCC_CIER_HSI48RDYIE (1 << 10) /* Bit 10: HSI48 Ready Interrupt Enable */ + +/* Clock interrupt flag register */ + +#define RCC_CIFR_LSIRDYIF (1 << 0) /* Bit 0: LSI Ready Interrupt Flag */ +#define RCC_CIFR_LSERDYIF (1 << 1) /* Bit 1: LSE Ready Interrupt Flag */ +#define RCC_CIFR_MSIRDYIF (1 << 2) /* Bit 2: MSI Ready Interrupt Flag */ +#define RCC_CIFR_HSIRDYIF (1 << 3) /* Bit 3: HSI Ready Interrupt Flag */ +#define RCC_CIFR_HSERDYIF (1 << 4) /* Bit 4: HSE Ready Interrupt Flag */ +#define RCC_CIFR_PLLRDYIF (1 << 5) /* Bit 5: PLL Ready Interrupt Flag */ +#define RCC_CIFR_PLLSAI1RDYIF (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt Flag */ +#define RCC_CIFR_PLLSAI2RDYIF (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt Flag */ +#define RCC_CIFR_CSSF (1 << 8) /* Bit 8: Clock Security System Interrupt Flag */ +#define RCC_CIFR_HSI48RDYIF (1 << 10) /* Bit 10: HSI48 Ready Interrupt Flag */ + +/* Clock interrupt clear register */ + +#define RCC_CICR_LSIRDYIC (1 << 0) /* Bit 0: LSI Ready Interrupt Clear */ +#define RCC_CICR_LSERDYIC (1 << 1) /* Bit 1: LSE Ready Interrupt Clear */ +#define RCC_CICR_MSIRDYIC (1 << 2) /* Bit 2: MSI Ready Interrupt Clear */ +#define RCC_CICR_HSIRDYIC (1 << 3) /* Bit 3: HSI Ready Interrupt Clear */ +#define RCC_CICR_HSERDYIC (1 << 4) /* Bit 4: HSE Ready Interrupt Clear */ +#define RCC_CICR_PLLRDYIC (1 << 5) /* Bit 5: PLL Ready Interrupt Clear */ +#define RCC_CICR_PLLSAI1RDYIC (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt Clear */ +#define RCC_CICR_PLLSAI2RDYIC (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt Clear */ +#define RCC_CICR_CSSC (1 << 8) /* Bit 8: Clock Security System Interrupt Clear */ +#define RCC_CICR_HSI48RDYIC (1 << 10) /* Bit 10: HSI48 Oscillator Ready Interrupt Clear */ + +/* AHB1 peripheral reset register */ + +#define RCC_AHB1RSTR_DMA1RST (1 << 0) /* Bit 0: DMA1 reset */ +#define RCC_AHB1RSTR_DMA2RST (1 << 1) /* Bit 1: DMA2 reset */ +#define RCC_AHB1RSTR_DMAMUX1RST (1 << 2) /* Bit 2: DMAMUX1 reset */ +#define RCC_AHB1RSTR_FLASHRST (1 << 8) /* Bit 8: Flash memory interface reset */ +#define RCC_AHB1RSTR_CRCRST (1 << 12) /* Bit 12: CRC reset */ +#define RCC_AHB1RSTR_TSCRST (1 << 16) /* Bit 16: Touch Sensing Controller reset */ + +/* AHB2 peripheral reset register */ + +#define RCC_AHB2RSTR_GPIORST(n) (1 << (n)) +#define RCC_AHB2RSTR_GPIOARST (1 << 0) /* Bit 0: IO port A reset */ +#define RCC_AHB2RSTR_GPIOBRST (1 << 1) /* Bit 1: IO port B reset */ +#define RCC_AHB2RSTR_GPIOCRST (1 << 2) /* Bit 2: IO port C reset */ +#define RCC_AHB2RSTR_GPIODRST (1 << 3) /* Bit 3: IO port D reset */ +#define RCC_AHB2RSTR_GPIOERST (1 << 4) /* Bit 4: IO port E reset */ +#define RCC_AHB2RSTR_GPIOFRST (1 << 5) /* Bit 5: IO port F reset */ +#define RCC_AHB2RSTR_GPIOGRST (1 << 6) /* Bit 6: IO port G reset */ +#define RCC_AHB2RSTR_GPIOHRST (1 << 7) /* Bit 7: IO port H reset */ +#define RCC_AHB2RSTR_ADCRST (1 << 13) /* Bit 13: ADC interface reset (common to all ADCs) */ +#define RCC_AHB2RSTR_AESRST (1 << 16) /* Bit 16: AES Cryptographic module reset */ +#define RCC_AHB2RSTR_HASHRST (1 << 17) /* Bit 17: HASH module reset */ +#define RCC_AHB2RSTR_RNGRST (1 << 18) /* Bit 18: Random number generator module reset */ +#define RCC_AHB2RSTR_PKARST (1 << 19) /* Bit 19: Public Key Accelerator module reset */ +#define RCC_AHB2RSTR_OTFDEC1RST (1 << 21) /* Bit 21: On-the-fly decryption module reset */ +#define RCC_AHB2RSTR_SDMMC1RST (1 << 31) /* Bit 22: SDMMC1 module reset */ + +/* AHB3 peripheral reset register */ + +#define RCC_AHB3RSTR_FMCRST (1 << 0) /* Bit 0: Flexible memory controller module reset */ +#define RCC_AHB3RSTR_OSPI1RST (1 << 8) /* Bit 8: Octo SPI1 module reset */ + +/* APB1 Peripheral reset register 1 */ + +#define RCC_APB1RSTR1_TIM2RST (1 << 0) /* Bit 0: TIM2 reset */ +#define RCC_APB1RSTR1_TIM3RST (1 << 1) /* Bit 1: TIM3 reset */ +#define RCC_APB1RSTR1_TIM4RST (1 << 2) /* Bit 2: TIM4 reset */ +#define RCC_APB1RSTR1_TIM5RST (1 << 3) /* Bit 3: TIM5 reset */ +#define RCC_APB1RSTR1_TIM6RST (1 << 4) /* Bit 4: TIM6 reset */ +#define RCC_APB1RSTR1_TIM7RST (1 << 5) /* Bit 5: TIM7 reset */ +#define RCC_APB1RSTR1_SPI2RST (1 << 14) /* Bit 14: SPI2 reset */ +#define RCC_APB1RSTR1_SPI3RST (1 << 15) /* Bit 15: SPI3 reset */ +#define RCC_APB1RSTR1_USART2RST (1 << 17) /* Bit 17: USART2 reset */ +#define RCC_APB1RSTR1_USART3RST (1 << 18) /* Bit 18: USART3 reset */ +#define RCC_APB1RSTR1_UART4RST (1 << 19) /* Bit 19: UART4 reset */ +#define RCC_APB1RSTR1_UART5RST (1 << 20) /* Bit 20: UART5 reset */ +#define RCC_APB1RSTR1_I2C1RST (1 << 21) /* Bit 21: I2C1 reset */ +#define RCC_APB1RSTR1_I2C2RST (1 << 22) /* Bit 22: I2C2 reset */ +#define RCC_APB1RSTR1_I2C3RST (1 << 23) /* Bit 23: I2C3 reset */ +#define RCC_APB1RSTR1_CRSRST (1 << 24) /* Bit 24: CRS reset */ +#define RCC_APB1RSTR1_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR1_DAC1RST (1 << 29) /* Bit 29: DAC1 reset */ +#define RCC_APB1RSTR1_OPAMPRST (1 << 30) /* Bit 30: OPAMP reset */ +#define RCC_APB1RSTR1_LPTIM1RST (1 << 31) /* Bit 31: Low-power Timer 1 reset */ + +/* APB1 Peripheral reset register 2 */ + +#define RCC_APB1RSTR2_LPUART1RST (1 << 0) /* Bit 0: Low-power UART 1 reset */ +#define RCC_APB1RSTR2_I2C4RST (1 << 1) /* Bit 1: I2C4 reset */ +#define RCC_APB1RSTR2_LPTIM2RST (1 << 5) /* Bit 5: Low-power Timer 2 reset */ +#define RCC_APB1RSTR2_LPTIM3RST (1 << 6) /* Bit 6: Low-power Timer 3 reset */ +#define RCC_APB1RSTR2_FDCAN1RST (1 << 9) /* Bit 9: FDCAN1 reset */ +#define RCC_APB1RSTR2_USBFSRST (1 << 21) /* Bit 21: USB FS reset */ +#define RCC_APB1RSTR2_UCPD1RST (1 << 23) /* Bit 21: UCPD1 reset */ + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) /* Bit 0: System configuration controller reset */ +#define RCC_APB2RSTR_TIM1RST (1 << 11) /* Bit 11: TIM1 reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI1 reset */ +#define RCC_APB2RSTR_TIM8RST (1 << 13) /* Bit 13: TIM8 reset */ +#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ +#define RCC_APB2RSTR_TIM15RST (1 << 16) /* Bit 16: TIM15 reset */ +#define RCC_APB2RSTR_TIM16RST (1 << 17) /* Bit 17: TIM16 reset */ +#define RCC_APB2RSTR_TIM17RST (1 << 18) /* Bit 18: TIM17 reset */ +#define RCC_APB2RSTR_SAI1RST (1 << 21) /* Bit 21: SAI1 reset */ +#define RCC_APB2RSTR_SAI2RST (1 << 22) /* Bit 22: SAI2 reset */ +#define RCC_APB2RSTR_DFSDMRST (1 << 24) /* Bit 24: DFSDM reset */ + +/* AHB1 Peripheral Clock enable register */ + +#define RCC_AHB1ENR_DMA1EN (1 << 0) /* Bit 0: DMA1 enable */ +#define RCC_AHB1ENR_DMA2EN (1 << 1) /* Bit 1: DMA2 enable */ +#define RCC_AHB1ENR_DMAMUX1EN (1 << 2) /* Bit 2: DMAMUX1 enable */ +#define RCC_AHB1ENR_FLASHEN (1 << 8) /* Bit 8: Flash memory interface enable */ +#define RCC_AHB1ENR_CRCEN (1 << 12) /* Bit 12: CRC enable */ +#define RCC_AHB1ENR_TSCEN (1 << 16) /* Bit 16: Touch Sensing Controller enable */ +#define RCC_AHB1ENR_GTZCEN (1 << 22) /* Bit 22: GTZC clock enable */ + +/* AHB3 Peripheral Clock enable register */ + +#define RCC_AHB3ENR_FMCEN (1 << 0) /* Bit 0: Flexible memory controller module enable */ +#define RCC_AHB3ENR_OSPI1EN (1 << 8) /* Bit 8: OCTOSPI1 module enable */ + +/* APB1 Peripheral Clock enable register 1 */ + +#define RCC_APB1ENR1_TIM2EN (1 << 0) /* Bit 0: TIM2 enable */ +#define RCC_APB1ENR1_TIM3EN (1 << 1) /* Bit 1: TIM3 enable */ +#define RCC_APB1ENR1_TIM4EN (1 << 2) /* Bit 2: TIM4 enable */ +#define RCC_APB1ENR1_TIM5EN (1 << 3) /* Bit 3: TIM5 enable */ +#define RCC_APB1ENR1_TIM6EN (1 << 4) /* Bit 4: TIM6 enable */ +#define RCC_APB1ENR1_TIM7EN (1 << 5) /* Bit 5: TIM7 enable */ +#define RCC_APB1ENR1_RTCAPBEN (1 << 10) /* Bit 10: RTC APB clock enable */ +#define RCC_APB1ENR1_WWDGEN (1 << 11) /* Bit 11: Windowed Watchdog enable */ +#define RCC_APB1ENR1_SPI2EN (1 << 14) /* Bit 14: SPI2 enable */ +#define RCC_APB1ENR1_SPI3EN (1 << 15) /* Bit 15: SPI3 enable */ +#define RCC_APB1ENR1_USART2EN (1 << 17) /* Bit 17: USART2 enable */ +#define RCC_APB1ENR1_USART3EN (1 << 18) /* Bit 18: USART3 enable */ +#define RCC_APB1ENR1_UART4EN (1 << 19) /* Bit 19: USART4 enable */ +#define RCC_APB1ENR1_UART5EN (1 << 20) /* Bit 20: USART5 enable */ +#define RCC_APB1ENR1_I2C1EN (1 << 21) /* Bit 21: I2C1 enable */ +#define RCC_APB1ENR1_I2C2EN (1 << 22) /* Bit 22: I2C2 enable */ +#define RCC_APB1ENR1_I2C3EN (1 << 23) /* Bit 23: I2C3 enable */ +#define RCC_APB1ENR1_CRSEN (1 << 24) /* Bit 24: CRSEN enable */ +#define RCC_APB1ENR1_PWREN (1 << 28) /* Bit 28: Power interface enable */ +#define RCC_APB1ENR1_DAC1EN (1 << 29) /* Bit 29: DAC1 enable */ +#define RCC_APB1ENR1_OPAMPEN (1 << 30) /* Bit 30: OPAMP enable */ +#define RCC_APB1ENR1_LPTIM1EN (1 << 31) /* Bit 31: Low-power Timer 1 enable */ + +/* APB1 Peripheral Clock enable register 2 */ + +#define RCC_APB1ENR2_LPUART1EN (1 << 0) /* Bit 0: Low-power UART 1 enable */ +#define RCC_APB1ENR2_I2C4EN (1 << 1) /* Bit 1: I2C4 enable */ +#define RCC_APB1ENR2_LPTIM2EN (1 << 5) /* Bit 5: Low-power Timer 2 enable */ +#define RCC_APB1ENR2_LPTIM3EN (1 << 6) /* Bit 6: Low-power Timer 3 enable */ +#define RCC_APB1ENR2_FDCAN1EN (1 << 9) /* Bit 9: FDCAN1 enable */ +#define RCC_APB1ENR2_USBFSEN (1 << 21) /* Bit 21: USB FS enable */ +#define RCC_APB1ENR2_UCPD1EN (1 << 23) /* Bit 23: UCPD1 enable */ + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_SYSCFGEN (1 << 0) /* Bit 0: SYSCFG + COMP + VREFBUF enable */ +#define RCC_APB2ENR_TIM1EN (1 << 11) /* Bit 11: TIM1 enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI1 enable */ +#define RCC_APB2ENR_TIM8EN (1 << 13) /* Bit 13: TIM8 enable */ +#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 enable */ +#define RCC_APB2ENR_TIM15EN (1 << 16) /* Bit 16: TIM15 enable */ +#define RCC_APB2ENR_TIM16EN (1 << 17) /* Bit 17: TIM16 enable */ +#define RCC_APB2ENR_TIM17EN (1 << 18) /* Bit 18: TIM17 enable */ +#define RCC_APB2ENR_SAI1EN (1 << 21) /* Bit 21: SAI1 enable */ +#define RCC_APB2ENR_SAI2EN (1 << 22) /* Bit 22: SAI2 enable */ +#define RCC_APB2ENR_DFSDM1EN (1 << 24) /* Bit 24: DFSDM1 enable */ + +/* RCC AHB1 Sleep and Stop modes peripheral clock enable register */ + +#define RCC_AHB1SMENR_DMA1SMEN (1 << 0) /* Bit 0: DMA1 enable during Sleep mode */ +#define RCC_AHB1SMENR_DMA2SMEN (1 << 1) /* Bit 1: DMA2 enable during Sleep mode */ +#define RCC_AHB1SMENR_DMAMUX1SMEN (1 << 2) /* Bit 2: DMAMUX1 enable during Sleep mode */ +#define RCC_AHB1SMENR_FLASHSMEN (1 << 8) /* Bit 8: Flash memory interface enable during Sleep mode */ +#define RCC_AHB1SMENR_SRAM1SMEN (1 << 9) /* Bit 9: SRAM1 enable during Sleep mode */ +#define RCC_AHB1SMENR_CRCSMEN (1 << 12) /* Bit 12: CRC enable during Sleep mode */ +#define RCC_AHB1SMENR_TSCSMEN (1 << 16) /* Bit 16: Touch sensing controller enable during Sleep mode */ +#define RCC_AHB1SMENR_GTZCSMEN (1 << 22) /* Bit 22: GTZC enable during Sleep mode */ +#define RCC_AHB1SMENR_ICACHESMEN (1 << 23) /* Bit 23: Instruction cache enable during Sleep mode */ + +/* RCC AHB2 low power mode peripheral clock enable register */ + +#define RCC_AHB2SMENR_GPIOASMEN (1 << 0) /* Bit 0: IO port A enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOBSMEN (1 << 1) /* Bit 1: IO port B enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOCSMEN (1 << 2) /* Bit 2: IO port C enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIODSMEN (1 << 3) /* Bit 3: IO port D enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOESMEN (1 << 4) /* Bit 4: IO port E enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOFSMEN (1 << 5) /* Bit 5: IO port F enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOGSMEN (1 << 6) /* Bit 6: IO port G enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOHSMEN (1 << 7) /* Bit 7: IO port H enable during Sleep mode */ +#define RCC_AHB2SMENR_SRAM2SMEN (1 << 9) /* Bit 9: SRAM2 enable during Sleep mode */ +#define RCC_AHB2SMENR_ADCSMEN (1 << 13) /* Bit 13: ADC interface enable during Sleep mode (common to all ADCs) */ +#define RCC_AHB2SMENR_AESSMEN (1 << 16) /* Bit 16: AES Cryptographic module enable during Sleep mode */ +#define RCC_AHB2SMENR_HASHSMEN (1 << 17) /* Bit 17: HASH module enable during Sleep mode */ +#define RCC_AHB2SMENR_RNGSMEN (1 << 18) /* Bit 18: Random number generator module enable during Sleep mode */ +#define RCC_AHB2SMENR_PKASMEN (1 << 19) /* Bit 19: PKA module enable during Sleep mode */ +#define RCC_AHB2SMENR_OTFDEC1SMEN (1 << 21) /* Bit 21: OTFDEC1 module enable during Sleep mode */ +#define RCC_AHB2SMENR_SDMMC1SMEN (1 << 22) /* Bit 22: SDMMC1 module enable during Sleep mode */ + +/* RCC AHB3 low power mode peripheral clock enable register */ + +#define RCC_AHB3SMENR_FMCSMEN (1 << 0) /* Bit 0: Flexible memory controller module enable during Sleep mode */ +#define RCC_AHB3SMENR_OSPISMEN (1 << 8) /* Bit 8: OCTOSPI1 module enable during Sleep mode */ + +/* RCC APB1 low power mode peripheral clock enable register 1 */ + +#define RCC_APB1SMENR1_TIM2SMEN (1 << 0) /* Bit 0: TIM2 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM3SMEN (1 << 1) /* Bit 1: TIM3 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM4SMEN (1 << 2) /* Bit 2: TIM4 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM5SMEN (1 << 3) /* Bit 3: TIM5 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM6SMEN (1 << 4) /* Bit 4: TIM6 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM7SMEN (1 << 5) /* Bit 5: TIM7 enable during Sleep mode */ +#define RCC_APB1SMENR1_RTCAPBSMEN (1 << 10) /* Bit 10: RTC APB clock enable during Sleep mode */ +#define RCC_APB1SMENR1_WWDGSMEN (1 << 11) /* Bit 11: Windowed Watchdog enable during Sleep mode */ +#define RCC_APB1SMENR1_SPI2SMEN (1 << 14) /* Bit 14: SPI2 enable during Sleep mode */ +#define RCC_APB1SMENR1_SPI3SMEN (1 << 15) /* Bit 15: SPI3 enable during Sleep mode */ +#define RCC_APB1SMENR1_USART2SMEN (1 << 17) /* Bit 17: USART2 enable during Sleep mode */ +#define RCC_APB1SMENR1_USART3SMEN (1 << 18) /* Bit 18: USART3 enable during Sleep mode */ +#define RCC_APB1SMENR1_UART4SMEN (1 << 19) /* Bit 19: USART4 enable during Sleep mode */ +#define RCC_APB1SMENR1_UART5SMEN (1 << 20) /* Bit 20: USART5 enable during Sleep mode */ +#define RCC_APB1SMENR1_I2C1SMEN (1 << 21) /* Bit 21: I2C1 enable during Sleep mode */ +#define RCC_APB1SMENR1_I2C2SMEN (1 << 22) /* Bit 22: I2C2 enable during Sleep mode */ +#define RCC_APB1SMENR1_I2C3SMEN (1 << 23) /* Bit 23: I2C3 enable during Sleep mode */ +#define RCC_APB1SMENR1_CRSSMEN (1 << 24) /* Bit 24: CRS enable during Sleep mode */ +#define RCC_APB1SMENR1_PWRSMEN (1 << 28) /* Bit 28: Power interface enable during Sleep mode */ +#define RCC_APB1SMENR1_DAC1SMEN (1 << 29) /* Bit 29: DAC1 enable during Sleep mode */ +#define RCC_APB1SMENR1_OPAMPSMEN (1 << 30) /* Bit 30: OPAMP enable during Sleep mode */ +#define RCC_APB1SMENR1_LPTIM1SMEN (1 << 31) /* Bit 31: Low-power Timer 1 enable during Sleep mode */ + +/* RCC APB1 low power modeperipheral clock enable register 2 */ + +#define RCC_APB1SMENR2_LPUART1SMEN (1 << 0) /* Bit 0: Low-power UART 1 enable during Sleep mode */ +#define RCC_APB1SMENR2_I2C4SMEN (1 << 1) /* Bit 1: I2C4 enable during Sleep mode */ +#define RCC_APB1SMENR2_LPTIM2SMEN (1 << 5) /* Bit 5: Low-power Timer 2 enable during Sleep mode */ +#define RCC_APB1SMENR2_LPTIM3SMEN (1 << 6) /* Bit 6: Low-power Timer 3 enable during Sleep mode */ +#define RCC_APB1SMENR2_FDCAN1SMEN (1 << 9) /* Bit 9: FDCAN1 enable during Sleep mode */ +#define RCC_APB1SMENR2_USBFSSMEN (1 << 21) /* Bit 21: USB FS enable during Sleep mode */ +#define RCC_APB1SMENR2_UCPD1SMEN (1 << 23) /* Bit 23: UCPDS1 enable during Sleep mode */ + +/* RCC APB2 low power mode peripheral clock enable register */ + +#define RCC_APB2SMENR_SYSCFGSMEN (1 << 0) /* Bit 0: System configuration controller enable during Sleep mode */ +#define RCC_APB2SMENR_TIM1SMEN (1 << 11) /* Bit 11: TIM1 enable during Sleep mode */ +#define RCC_APB2SMENR_SPI1SMEN (1 << 12) /* Bit 12: SPI1 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM8SMEN (1 << 13) /* Bit 13: TIM8 enable during Sleep mode */ +#define RCC_APB2SMENR_USART1SMEN (1 << 14) /* Bit 14: USART1 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM15SMEN (1 << 16) /* Bit 16: TIM15 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM16SMEN (1 << 17) /* Bit 17: TIM16 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM17SMEN (1 << 18) /* Bit 18: TIM17 enable during Sleep mode */ +#define RCC_APB2SMENR_SAI1SMEN (1 << 21) /* Bit 21: SAI1 enable during Sleep mode */ +#define RCC_APB2SMENR_SAI2SMEN (1 << 22) /* Bit 22: SAI2 enable during Sleep mode */ +#define RCC_APB2SMENR_DFSDM1SMEN (1 << 24) /* Bit 24: DFSDM1 enable during Sleep mode */ + +/* Peripheral Independent Clock Configuration register */ + +#define RCC_CCIPR_USART1SEL_SHIFT (0) +#define RCC_CCIPR_USART1SEL_MASK (3 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_PCLK1 (0 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_SYSCLK (1 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_HSI16 (2 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_LSE (3 << RCC_CCIPR_USART1SEL_SHIFT) + +#define RCC_CCIPR_USART2SEL_SHIFT (2) +#define RCC_CCIPR_USART2SEL_MASK (3 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_PCLK1 (0 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_SYSCLK (1 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_HSI16 (2 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_LSE (3 << RCC_CCIPR_USART2SEL_SHIFT) + +#define RCC_CCIPR_USART3SEL_SHIFT (4) +#define RCC_CCIPR_USART3SEL_MASK (3 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_PCLK1 (0 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_SYSCLK (1 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_HSI16 (2 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_LSE (3 << RCC_CCIPR_USART3SEL_SHIFT) + +#define RCC_CCIPR_UART4SEL_SHIFT (6) +#define RCC_CCIPR_UART4SEL_MASK (3 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_PCLK1 (0 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_SYSCLK (1 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_HSI16 (2 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_LSE (3 << RCC_CCIPR_UART4SEL_SHIFT) + +#define RCC_CCIPR_UART5SEL_SHIFT (8) +#define RCC_CCIPR_UART5SEL_MASK (3 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_PCLK1 (0 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_SYSCLK (1 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_HSI16 (2 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_LSE (3 << RCC_CCIPR_UART5SEL_SHIFT) + +#define RCC_CCIPR_LPUART1SEL_SHIFT (10) +#define RCC_CCIPR_LPUART1SEL_MASK (3 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_PCLK1 (0 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_SYSCLK (1 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_HSI16 (2 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_LSE (3 << RCC_CCIPR_LPUART1SEL_SHIFT) + +#define RCC_CCIPR_I2C1SEL_SHIFT (12) +#define RCC_CCIPR_I2C1SEL_MASK (3 << RCC_CCIPR_I2C1SEL_SHIFT) +# define RCC_CCIPR_I2C1SEL_PCLK1 (0 << RCC_CCIPR_I2C1SEL_SHIFT) +# define RCC_CCIPR_I2C1SEL_SYSCLK (1 << RCC_CCIPR_I2C1SEL_SHIFT) +# define RCC_CCIPR_I2C1SEL_HSI16 (2 << RCC_CCIPR_I2C1SEL_SHIFT) + +#define RCC_CCIPR_I2C2SEL_SHIFT (14) +#define RCC_CCIPR_I2C2SEL_MASK (3 << RCC_CCIPR_I2C2SEL_SHIFT) +# define RCC_CCIPR_I2C2SEL_PCLK1 (0 << RCC_CCIPR_I2C2SEL_SHIFT) +# define RCC_CCIPR_I2C2SEL_SYSCLK (1 << RCC_CCIPR_I2C2SEL_SHIFT) +# define RCC_CCIPR_I2C2SEL_HSI16 (2 << RCC_CCIPR_I2C2SEL_SHIFT) + +#define RCC_CCIPR_I2C3SEL_SHIFT (16) +#define RCC_CCIPR_I2C3SEL_MASK (3 << RCC_CCIPR_I2C3SEL_SHIFT) +# define RCC_CCIPR_I2C3SEL_PCLK1 (0 << RCC_CCIPR_I2C3SEL_SHIFT) +# define RCC_CCIPR_I2C3SEL_SYSCLK (1 << RCC_CCIPR_I2C3SEL_SHIFT) +# define RCC_CCIPR_I2C3SEL_HSI16 (2 << RCC_CCIPR_I2C3SEL_SHIFT) + +#define RCC_CCIPR_LPTIM1SEL_SHIFT (18) +#define RCC_CCIPR_LPTIM1SEL_MASK (3 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_PCLK1 (0 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_LSI (1 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_HSI16 (2 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_LSE (3 << RCC_CCIPR_LPTIM1SEL_SHIFT) + +#define RCC_CCIPR_LPTIM2SEL_SHIFT (20) +#define RCC_CCIPR_LPTIM2SEL_MASK (3 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_PCLK1 (0 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_LSI (1 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_HSI16 (2 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_LSE (3 << RCC_CCIPR_LPTIM2SEL_SHIFT) + +#define RCC_CCIPR_LPTIM3SEL_SHIFT (22) +#define RCC_CCIPR_LPTIM3SEL_MASK (3 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_LPTIM3SEL_PCLK1 (0 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_LPTIM3SEL_LSI (1 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_LPTIM3SEL_HSI16 (2 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_LPTIM3SEL_LSE (3 << RCC_CCIPR_SAI1SEL_SHIFT) + +#define RCC_CCIPR_FDCANSEL_SHIFT (24) +#define RCC_CCIPR_FDCANSEL_MASK (3 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_FDCANSEL_HSE (0 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_FDCANSEL_PLL48M1CLK (1 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_FDCANSEL_PLLSAI1CLK (2 << RCC_CCIPR_SAI2SEL_SHIFT) + +#define RCC_CCIPR_CLK48MSEL_SHIFT (26) +#define RCC_CCIPR_CLK48MSEL_MASK (3 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48MSEL_HSI48 (0 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48MSEL_PLL48M2CLK (1 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48MSEL_PLL48M1CLK (2 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48MSEL_MSI (3 << RCC_CCIPR_CLK48SEL_SHIFT) + +#define RCC_CCIPR_ADCSEL_SHIFT (28) +#define RCC_CCIPR_ADCSEL_MASK (3 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_NONE (0 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_PLLADC1CLK (1 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_SYSCLK (3 << RCC_CCIPR_ADCSEL_SHIFT) + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ + +#define RCC_BDCR_LSEDRV_SHIFT (3) /* Bits 3-4: LSE oscillator drive capability */ +#define RCC_BDCR_LSEDRV_MASK (3 << RCC_BDCR_LSEDRV_SHIFT) +# define RCC_BDCR_LSEDRV_LOW (0 << RCC_BDCR_LSEDRV_SHIFT) /* 00: Lower driving capability */ +# define RCC_BDCR_LSEDRV_MEDLO (1 << RCC_BDCR_LSEDRV_SHIFT) /* 01: Medium Low driving capability */ +# define RCC_BDCR_LSEDRV_MEDHI (2 << RCC_BDCR_LSEDRV_SHIFT) /* 10: Medium High driving capability*/ +# define RCC_BDCR_LSEDRV_HIGH (3 << RCC_BDCR_LSEDRV_SHIFT) /* 11: Higher driving capability */ + +#define RCC_BDCR_LSECSSON (1 << 5) /* Bit 5: CSS on LSE enable */ +#define RCC_BDCR_LSECSSD (1 << 6) /* Bit 6: CSS on LSE failure Detection */ +#define RCC_BDCR_LSESYSEN (1 << 7) /* Bit 7: LSE system clock (LSESYS) enable */ + +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 32 used as RTC clock */ + +#define RCC_BDCR_LSESYSRDY (1 << 11) /* Bit 11: LSE system clock (LSESYS) ready */ + +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ +#define RCC_BDCR_LSCOEN (1 << 24) /* Bit 24: Low speed clock output enable */ +#define RCC_BDCR_LSCOSEL (1 << 25) /* Bit 25: Low speed clock output selection */ +# define RCC_BCDR_LSCOSEL_LSI 0 /* LSI selected */ +# define RCC_BDCR_LSCOSEL_LSE RCC_BDCR_LSCOSEL /* LSE selected */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ + +#define RCC_CSR_LSIPRE (1 << 4) /* Bit 4: Internal Low Speed oscillator prescaler (LSI/128) enable */ + +#define RCC_CSR_MSISRANGE_SHIFT 8 +# define RCC_CSR_MSISRANGE_MASK (0x0F << RCC_CSR_MSISRANGE_SHIFT) /* MSI range after Standby mode */ +# define RCC_CSR_MSISRANGE_1M (4 << RCC_CSR_MSISRANGE_SHIFT) /* 0100: around 1 MHz */ +# define RCC_CSR_MSISRANGE_2M (5 << RCC_CSR_MSISRANGE_SHIFT) /* 0101: around 2 MHz */ +# define RCC_CSR_MSISRANGE_4M (6 << RCC_CSR_MSISRANGE_SHIFT) /* 0110: around 4 MHz */ +# define RCC_CSR_MSISRANGE_8M (7 << RCC_CSR_MSISRANGE_SHIFT) /* 0111: around 8 MHz */ + +#define RCC_CSR_RMVF (1 << 23) /* Bit 23: Remove reset flag */ +#define RCC_CSR_OBLRSTF (1 << 25) /* Bit 25: Option byte loader reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_BORRSTF (1 << 27) /* Bit 27: BOR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +/* Clock recovery RC register */ + +#define RCC_CRRCR_HSI48CAL_SHIFT 7 +# define RCC_CRRCR_HSI48CAL_MASK (0x01ff << RCC_CRRCR_HSI48CAL_SHIFT) /* HSI48 clock calibration */ + +#define RCC_CRRCR_HSI48ON (1 << 0) /* Bit 0: HSI48 clock enable */ +#define RCC_CRRCR_HSI48RDY (1 << 1) /* Bit 1: HSI48 clock ready flag */ + +/* Peripheral Independent Clock Configuration 2 register */ + +#define RCC_CCIPR2_I2C4SEL_SHIFT (0) /* Bits 0-1: I2C4 clock source selection */ +#define RCC_CCIPR2_I2C4SEL_MASK (3 << RCC_CCIPR2_I2C4SEL_SHIFT) +# define RCC_CCIPR2_I2C4SEL_PCLK (0 << RCC_CCIPR2_I2C4SEL_SHIFT) +# define RCC_CCIPR2_I2C4SEL_SYSCLK (1 << RCC_CCIPR2_I2C4SEL_SHIFT) +# define RCC_CCIPR2_I2C4SEL_HSI (2 << RCC_CCIPR2_I2C4SEL_SHIFT) + +#define RCC_CCIPR2_DFSDMSEL_SHIFT (2) /* Bit 2: DFSDMSEL kernel clock source selection */ +#define RCC_CCIPR2_DFSDMSEL_MASK (1 << RCC_CCIPR2_DFSDMSEL_SHIFT) +# define RCC_CCIPR2_DFSDMSEL_PCLK2 (0 << RCC_CCIPR2_DFSDMSEL_SHIFT) +# define RCC_CCIPR2_FDSDMSEL_SYSCLK (1 << RCC_CCIPR2_FDSDMSEL_SHIFT) + +#define RCC_CCIPR2_ADFSDMSEL_SHIFT (3) /* Bit 3-4: DFSDMSEL audio clock source selection */ +#define RCC_CCIPR2_ADFSDMSEL_MASK (3 << RCC_CCIPR2_ADFSDMSEL_SHIFT) +# define RCC_CCIPR2_ADFSDMSEL_SAI1 (0 << RCC_CCIPR2_ADFSDMSEL_SHIFT) +# define RCC_CCIPR2_AFDSDMSEL_SYSCLK (1 << RCC_CCIPR2_ADFSDMSEL_SHIFT) +# define RCC_CCIPR2_ADFSDMSEL_HSI16 (2 << RCC_CCIPR2_ADFSDMSEL_SHIFT) + +#define RCC_CCIPR2_SAI1SEL_SHIFT (5) /* Bit 5-7: SAI1 clock source selection */ +#define RCC_CCIPR2_SAI1SEL_MASK (7 << RCC_CCIPR2_SAI1SEL_SHIFT) +# define RCC_CCIPR2_SAI1SEL_PLLSAI1CLK (0 << RCC_CCIPR2_SAI1SEL_SHIFT) +# define RCC_CCIPR2_SAI1SEL_PLLSAI2CLK (1 << RCC_CCIPR2_SAI1SEL_SHIFT) +# define RCC_CCIPR2_SAI1SEL_PLLSAI3CLK (2 << RCC_CCIPR2_SAI1SEL_SHIFT) +# define RCC_CCIPR2_SAI1SEL_EXTCLK (3 << RCC_CCIPR2_SAI1SEL_SHIFT) +# define RCC_CCIPR2_SAI1SEL_HSI (4 << RCC_CCIPR2_SAI1SEL_SHIFT) + +#define RCC_CCIPR2_SAI2SEL_SHIFT (8) /* Bit 8-10: SAI2 clock source selection */ +#define RCC_CCIPR2_SAI2SEL_MASK (7 << RCC_CCIPR2_SAI2SEL_SHIFT) +# define RCC_CCIPR2_SAI2SEL_PLLSAI1CLK (0 << RCC_CCIPR2_SAI2SEL_SHIFT) +# define RCC_CCIPR2_SAI2SEL_PLLSAI2CLK (1 << RCC_CCIPR2_SAI2SEL_SHIFT) +# define RCC_CCIPR2_SAI2SEL_PLLSAI3CLK (2 << RCC_CCIPR2_SAI2SEL_SHIFT) +# define RCC_CCIPR2_SAI2SEL_EXTCLK (3 << RCC_CCIPR2_SAI2SEL_SHIFT) +# define RCC_CCIPR2_SAI2SEL_HSI (4 << RCC_CCIPR2_SAI2SEL_SHIFT) + +#define RCC_CCIPR2_SDMMCSEL_SHIFT (14) /* Bit 14: SDMMC clock source selection */ +#define RCC_CCIPR2_SDMMCSEL_MASK (1 << RCC_CCIPR2_SDMMCSEL_SHIFT) +# define RCC_CCIPR2_SDMMCSEL_PCLK2 (0 << RCC_CCIPR2_SDMMCSEL_SHIFT) +# define RCC_CCIPR2_SDMMCSEL_SYSCLK (1 << RCC_CCIPR2_SDMMCSEL_SHIFT) + +#define RCC_CCIPR2_OSPISEL_SHIFT (20) /* Bit 21-20: OCTOSPI clock source selection */ +#define RCC_CCIPR2_OSPISEL_MASK (3 << RCC_CCIPR2_OSPISEL_SHIFT) +# define RCC_CCIPR2_OSPISEL_SYSCLK (0 << RCC_CCIPR2_OSPISEL_SHIFT) +# define RCC_CCIPR2_OSPISEL_MSI (1 << RCC_CCIPR2_OSPISEL_SHIFT) +# define RCC_CCIPR2_OSPISEL_PLL48M1CLK (2 << RCC_CCIPR2_OSPISEL_SHIFT) +#endif + +#endif /* CONFIG_STM32U5_STM32U585XX */ +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585XX_RCC_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32u585xx_spi.h b/arch/arm/src/stm32u5/hardware/stm32u585xx_spi.h new file mode 100644 index 0000000000..02dbfc2fae --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32u585xx_spi.h @@ -0,0 +1,407 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32u585xx_spi.h + * + * 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_STM32U5_HARDWARE_STM32U585XX_SPI_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585XX_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_STM32U5_STM32U585XX) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Maximum allowed speed as per data sheet for all SPIs */ + +# define STM32_SPI_CLK_MAX 160000000UL + +/* Register Offsets *********************************************************/ + +#define STM32_SPI_CR1_OFFSET 0x0000 /* SPI/I2S Control Register 1 */ +#define STM32_SPI_CR2_OFFSET 0x0004 /* SPI control register 2 */ +#define STM32_SPI_CFG1_OFFSET 0x0008 /* SPI configuration register 1 */ +#define STM32_SPI_CFG2_OFFSET 0x000C /* SPI configuration register 2 */ +#define STM32_SPI_IER_OFFSET 0x0010 /* SPI/I2S interrupt enable register */ +#define STM32_SPI_SR_OFFSET 0x0014 /* SPI/I2S status register */ +#define STM32_SPI_IFCR_OFFSET 0x0018 /* SPI/I2S interrupt/status flags clear register */ +#define STM32_SPI_TXDR_OFFSET 0x0020 /* SPI/I2S transmit data register */ +#define STM32_SPI_RXDR_OFFSET 0x0030 /* SPI/I2S receive data register */ +#define STM32_SPI_CRCPOLY_OFFSET 0x0040 /* SPI/I2S SPI polynominal register */ +#define STM32_SPI_TXCRC_OFFSET 0x0044 /* SPI/I2S SPI transmitter CRC register */ +#define STM32_SPI_RXCRC_OFFSET 0x0048 /* SPI/I2S SPI receiver CRC register */ +#define STM32_SPI_UDRDR_OFFSET 0x004C /* SPI/I2S SPI underrun data register */ + +/* Register Addresses *******************************************************/ + +#if STM32_NSPI > 0 +# define STM32_SPI1_CR1 (STM32_SPI1_BASE+STM32_SPI_CR1_OFFSET) +# define STM32_SPI1_CR2 (STM32_SPI1_BASE+STM32_SPI_CR2_OFFSET) +# define STM32_SPI1_CFG1 (STM32_SPI1_BASE+STM32_SPI_CFG1_OFFSET) +# define STM32_SPI1_CFG2 (STM32_SPI1_BASE+STM32_SPI_CFG2_OFFSET) +# define STM32_SPI1_IER (STM32_SPI1_BASE+STM32_SPI_IER_OFFSET) +# define STM32_SPI1_SR (STM32_SPI1_BASE+STM32_SPI_SR_OFFSET) +# define STM32_SPI1_IFCR (STM32_SPI1_BASE+STM32_SPI_IFCR_OFFSET) +# define STM32_SPI1_TXDR (STM32_SPI1_BASE+STM32_SPI_TXDR_OFFSET) +# define STM32_SPI1_RXDR (STM32_SPI1_BASE+STM32_SPI_RXDR_OFFSET) +# define STM32_SPI1_CRCPOLY (STM32_SPI1_BASE+STM32_SPI_CRCPOLY_OFFSET) +# define STM32_SPI1_TXCRC (STM32_SPI1_BASE+STM32_SPI_TXCRC_OFFSET) +# define STM32_SPI1_RXCRC (STM32_SPI1_BASE+STM32_SPI_RXCRC_OFFSET) +# define STM32_SPI1_UDRDR (STM32_SPI1_BASE+STM32_SPI_UDRDR_OFFSET) +#endif + +#if STM32_NSPI > 1 +# define STM32_SPI2_CR1 (STM32_SPI2_BASE+STM32_SPI_CR1_OFFSET) +# define STM32_SPI2_CR2 (STM32_SPI2_BASE+STM32_SPI_CR2_OFFSET) +# define STM32_SPI2_CFG1 (STM32_SPI2_BASE+STM32_SPI_CFG1_OFFSET) +# define STM32_SPI2_CFG2 (STM32_SPI2_BASE+STM32_SPI_CFG2_OFFSET) +# define STM32_SPI2_IER (STM32_SPI2_BASE+STM32_SPI_IER_OFFSET) +# define STM32_SPI2_SR (STM32_SPI2_BASE+STM32_SPI_SR_OFFSET) +# define STM32_SPI2_IFCR (STM32_SPI2_BASE+STM32_SPI_IFCR_OFFSET) +# define STM32_SPI2_TXDR (STM32_SPI2_BASE+STM32_SPI_TXDR_OFFSET) +# define STM32_SPI2_RXDR (STM32_SPI2_BASE+STM32_SPI_RXDR_OFFSET) +# define STM32_SPI2_CRCPOLY (STM32_SPI2_BASE+STM32_SPI_CRCPOLY_OFFSET) +# define STM32_SPI2_TXCRC (STM32_SPI2_BASE+STM32_SPI_TXCRC_OFFSET) +# define STM32_SPI2_RXCRC (STM32_SPI2_BASE+STM32_SPI_RXCRC_OFFSET) +# define STM32_SPI2_UDRDR (STM32_SPI2_BASE+STM32_SPI_UDRDR_OFFSET) +#endif + +#if STM32_NSPI > 2 +# define STM32_SPI3_CR1 (STM32_SPI3_BASE+STM32_SPI_CR1_OFFSET) +# define STM32_SPI3_CR2 (STM32_SPI3_BASE+STM32_SPI_CR2_OFFSET) +# define STM32_SPI3_CFG1 (STM32_SPI3_BASE+STM32_SPI_CFG1_OFFSET) +# define STM32_SPI3_CFG2 (STM32_SPI3_BASE+STM32_SPI_CFG2_OFFSET) +# define STM32_SPI3_IER (STM32_SPI3_BASE+STM32_SPI_IER_OFFSET) +# define STM32_SPI3_SR (STM32_SPI3_BASE+STM32_SPI_SR_OFFSET) +# define STM32_SPI3_IFCR (STM32_SPI3_BASE+STM32_SPI_IFCR_OFFSET) +# define STM32_SPI3_TXDR (STM32_SPI3_BASE+STM32_SPI_TXDR_OFFSET) +# define STM32_SPI3_RXDR (STM32_SPI3_BASE+STM32_SPI_RXDR_OFFSET) +# define STM32_SPI3_CRCPOLY (STM32_SPI3_BASE+STM32_SPI_CRCPOLY_OFFSET) +# define STM32_SPI3_TXCRC (STM32_SPI3_BASE+STM32_SPI_TXCRC_OFFSET) +# define STM32_SPI3_RXCRC (STM32_SPI3_BASE+STM32_SPI_RXCRC_OFFSET) +# define STM32_SPI3_UDRDR (STM32_SPI3_BASE+STM32_SPI_UDRDR_OFFSET) +#endif + +/* Register Bitfield Definitions ********************************************/ + +/* SPI Control Register 1 */ + +#define SPI_CR1_SPE (1 << 0) /* Bit 0: SPI Enable */ + /* Bits 1-7: Reserved */ +#define SPI_CR1_MASRX (1 << 8) /* Bit 8: */ +#define SPI_CR1_CSTART (1 << 9) /* Bit 9: master transfer start */ +#define SPI_CR1_CSUSP (1 << 10) /* Bit 10: master suspend request */ +#define SPI_CR1_HDDIR (1 << 11) /* Bit 11: RX/TX direction at Half-duplex mode */ +#define SPI_CR1_SSI (1 << 12) /* Bit 12: Internal slave select */ +#define SPI_CR1_CRC33_17 (1 << 13) /* Bit 13: 32-bit CRC polynominal configuration */ +#define SPI_CR1_RCRCINI (1 << 14) /* Bit 14: CRC calculation initialization pattern control for receiver */ +#define SPI_CR1_TCRCINI (1 << 15) /* Bit 15: CRC calculation initialization pattern control for transmitter */ +#define SPI_CR1_IOLOCK (1 << 16) /* Bit 16: locking the AF configuration of associated IOs */ + /* Bits 17-31: Reserved */ + +/* SPI Control Register 2 */ + +#define SPI_CR2_TSIZE_SHIFT (0) /* Bits 0-15 */ +#define SPI_CR2_TSIZE_MASK (0xff << SPI_CR2_TSIZE_SHIFT) +#define SPI_CR2_TSER_SHIFT (16) /* Bits 16-31 */ +#define SPI_CR2_TSER_MASK (0xff << SPI_CR2_TSER_SHIFT) + +/* SPI configuration register 1 */ + +#define SPI_CFG1_DSIZE_SHIFT (0) /* Bits 0-4: number of bits in at single SPI data frame */ +#define SPI_CFG1_DSIZE_VAL(n) ((n-1) << SPI_CFG1_DSIZE_SHIFT) +#define SPI_CFG1_DSIZE_MASK (0x1f << SPI_CFG1_DSIZE_SHIFT) + + /* 00000 - 00010 - not used */ +# define SPI_CFG1_DSIZE_4BIT (3 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_5BIT (4 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_6BIT (5 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_7BIT (6 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_8BIT (7 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_9BIT (8 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_10BIT (9 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_11BIT (10 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_12BIT (11 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_13BIT (12 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_14BIT (13 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_15BIT (14 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_16BIT (15 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_17BIT (16 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_18BIT (17 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_19BIT (18 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_20BIT (19 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_21BIT (20 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_22BIT (21 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_23BIT (22 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_24BIT (23 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_25BIT (24 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_26BIT (25 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_27BIT (26 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_28BIT (27 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_29BIT (28 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_30BIT (29 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_31BIT (30 << SPI_CFG1_DSIZE_SHIFT) +# define SPI_CFG1_DSIZE_32BIT (31 << SPI_CFG1_DSIZE_SHIFT) +#define SPI_CFG1_FTHLV_SHIFT (5) /* Bits 5-8: FIFO threshold level */ +#define SPI_CFG1_FTHLV_MASK (0xf << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_1DATA (0 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_2DATA (1 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_3DATA (2 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_4DATA (3 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_5DATA (4 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_6DATA (5 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_7DATA (6 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_8DATA (7 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_9DATA (8 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_10DATA (9 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_11DATA (10 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_12DATA (11 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_13DATA (12 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_14DATA (13 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_15DATA (14 << SPI_CFG1_FTHLV_SHIFT) +# define SPI_CFG1_FTHLV_16DATA (15 << SPI_CFG1_FTHLV_SHIFT) +#define SPI_CFG1_UDRCFG_SHIFT (9) /* Bits 9-10: behavior of slave transmitter at underrun condition */ +#define SPI_CFG1_UDRCFG_MASK (0x3 << SPI_CFG1_UDRCFG_SHIFT) +# define SPI_CFG1_UDRCFG_CONST (0 << SPI_CFG1_UDRCFG_SHIFT) +# define SPI_CFG1_UDRCFG_LASTRX (1 << SPI_CFG1_UDRCFG_SHIFT) +# define SPI_CFG1_UDRCFG_LASTTX (2 << SPI_CFG1_UDRCFG_SHIFT) + + /* 11: Reserved */ +#define SPI_CFG1_UDRDET_SHIFT (11) /* Bits 11-12: detection of underrun condition at slave transmitter */ +#define SPI_CFG1_UDRDET_MASK (0x3 << SPI_CFG1_UDRDET_SHIFT) +# define SPI_CFG1_UDRDET_BEG (0 << SPI_CFG1_UDRDET_SHIFT) +# define SPI_CFG1_UDRDET_END (1 << SPI_CFG1_UDRDET_SHIFT) +# define SPI_CFG1_UDRDET_SS (2 << SPI_CFG1_UDRDET_SHIFT) + + /* 11: Reserved */ + + /* Bit 13: Reserved */ +#define SPI_CFG1_RXDMAEN (1 << 14) /* Bit 14: RX-DMA stream enable */ +#define SPI_CFG1_TXDMAEN (1 << 15) /* Bit 15: TX-DMA stream enable */ +#define SPI_CFG1_CRCSIZE_SHIFT (16) /* Bits 16-20: length of CRC frame to be transacted and compared */ +#define SPI_CFG1_CRCSIZE_VAL(n) ((n-1) << SPI_CFG1_CRCSIZE_SHIFT) +#define SPI_CFG1_CRCSIZE_MASK (0x1f << SPI_CFG1_CRCSIZE_SHIFT) + + /* 00000-00010: Reserved */ +# define SPI_CFG1_CRCSIZE_4BIT (3 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_5BIT (4 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_6BIT (5 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_7BIT (6 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_8BIT (7 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_9BIT (8 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_10BIT (9 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_11BIT (10 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_12BIT (11 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_13BIT (12 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_14BIT (13 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_15BIT (14 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_16BIT (15 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_17BIT (16 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_18BIT (17 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_19BIT (18 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_20BIT (19 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_21BIT (20 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_22BIT (21 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_23BIT (22 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_24BIT (23 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_25BIT (24 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_26BIT (25 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_27BIT (26 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_28BIT (27 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_29BIT (28 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_30BIT (29 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_31BIT (30 << SPI_CFG1_CRCSIZE_SHIFT) +# define SPI_CFG1_CRCSIZE_32BIT (31 << SPI_CFG1_CRCSIZE_SHIFT) + + /* Bit 21: Reserved */ +#define SPI_CFG1_CRCEN (1 << 22) /* Bit 22: hardware CRC computation enable */ + + /* Bits 23-27: Reserved */ +#define SPI_CFG1_MBR_SHIFT (28) /* Bits 28-30: master baud rate */ +#define SPI_CFG1_MBR_MASK (0x7 << SPI_CFG1_MBR_SHIFT) +# define SPI_CFG1_MBR_FPCLKd2 (0 << SPI_CFG1_MBR_SHIFT) +# define SPI_CFG1_MBR_FPCLKd4 (1 << SPI_CFG1_MBR_SHIFT) +# define SPI_CFG1_MBR_FPCLKd8 (2 << SPI_CFG1_MBR_SHIFT) +# define SPI_CFG1_MBR_FPCLKd16 (3 << SPI_CFG1_MBR_SHIFT) +# define SPI_CFG1_MBR_FPCLKd32 (4 << SPI_CFG1_MBR_SHIFT) +# define SPI_CFG1_MBR_FPCLKd64 (5 << SPI_CFG1_MBR_SHIFT) +# define SPI_CFG1_MBR_FPCLKd128 (6 << SPI_CFG1_MBR_SHIFT) +# define SPI_CFG1_MBR_FPCLKd256 (7 << SPI_CFG1_MBR_SHIFT) + + /* Bit 31: Reserved */ + +/* SPI configuration register 2 */ + +#define SPI_CFG2_MSSI_SHIFT (0) /* Bits 0-3:master SS idleness */ +#define SPI_CFG2_MSSI_MASK (0xf << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_0CLK (0 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_1CLK (1 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_2CLK (2 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_3CLK (3 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_4CLK (4 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_5CLK (5 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_6CLK (6 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_7CLK (7 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_8CLK (8 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_9CLK (9 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_10CLK (10 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_11CLK (11 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_12CLK (12 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_13CLK (13 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_14CLK (14 << SPI_CFG2_MSSI_SHIFT) +# define SPI_CFG2_MSSI_15CLK (15 << SPI_CFG2_MSSI_SHIFT) +#define SPI_CFG2_MIDI_SHIFT (4) /* Bits 4-7: master Inter-Data idleness */ +#define SPI_CFG2_MIDI_MASK (0xf << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_0CLK (0 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_1CLK (1 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_2CLK (2 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_3CLK (3 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_4CLK (4 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_5CLK (5 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_6CLK (6 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_7CLK (7 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_8CLK (8 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_9CLK (9 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_10CLK (10 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_11CLK (11 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_12CLK (12 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_13CLK (13 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_14CLK (14 << SPI_CFG2_MIDI_SHIFT) +# define SPI_CFG2_MIDI_15CLK (15 << SPI_CFG2_MIDI_SHIFT) + + /* Bits 8-14: Reserved */ +#define SPI_CFG2_IOSWP (1 << 15) /* Bit 15: swap functionality of MISO and MOSI pins */ + + /* Bit 16: Reserved */ +#define SPI_CFG2_COMM_SHIFT (17) /* Bits 17-18: SPI communication mode */ +#define SPI_CFG2_COMM_MASK (0x3 << SPI_CFG2_COMM_SHIFT) +# define SPI_CFG2_COMM_FULL (0 << SPI_CFG2_COMM_SHIFT) +# define SPI_CFG2_COMM_STX (1 << SPI_CFG2_COMM_SHIFT) +# define SPI_CFG2_COMM_SRX (2 << SPI_CFG2_COMM_SHIFT) +# define SPI_CFG2_COMM_HALF (3 << SPI_CFG2_COMM_SHIFT) +#define SPI_CFG2_SP_SHIFT (19) /* Bits 19-21: serial protocol */ +#define SPI_CFG2_SP_MASK (0x7 << SPI_CFG2_SP_SHIFT) +# define SPI_CFG2_SP_MOTOROLA (0 << SPI_CFG2_SP_SHIFT) +# define SPI_CFG2_SP_TI (1 << SPI_CFG2_SP_SHIFT) + + /* 010-111: Reserved */ +#define SPI_CFG2_MASTER (1 << 22) /* Bit 22: SPI master */ +#define SPI_CFG2_LSBFRST (1 << 23) /* Bit 23: data frame format */ +#define SPI_CFG2_CPHA (1 << 24) /* Bit 24: clock phase */ +#define SPI_CFG2_CPOL (1 << 25) /* Bit 25: clock polarity */ +#define SPI_CFG2_SSM (1 << 26) /* Bit 26: software management of SS signal input */ + /* Bit 27: Reserved */ +#define SPI_CFG2_SSIOP (1 << 28) /* Bit 28: SS input/output polarity */ +#define SPI_CFG2_SSOE (1 << 29) /* Bit 29: SS output enable */ +#define SPI_CFG2_SSOM (1 << 30) /* Bit 30: SS output management in master mode */ +#define SPI_CFG2_AFCNTR (1 << 31) /* Bit 31: alternate function GPIOs control */ + +/* SPI/I2S status register */ + +#define SPI_SR_RXP (1 << 0) /* Bit 0: Rx-packet available */ +#define SPI_SR_TXP (1 << 1) /* Bit 1: Tx-packet space available */ +#define SPI_SR_DXP (1 << 2) /* Bit 2: duplex packet */ +#define SPI_SR_EOT (1 << 3) /* Bit 3: end of transfer */ +#define SPI_SR_TXTF (1 << 4) /* Bit 4: transmission transfer filled */ +#define SPI_SR_UDR (1 << 5) /* Bit 5: underrun at slave transmission mode */ +#define SPI_SR_OVR (1 << 6) /* Bit 6: overrun */ +#define SPI_SR_CRCE (1 << 7) /* Bit 7: CRC error */ +#define SPI_SR_TIFRE (1 << 8) /* Bit 8: TI frame format error */ +#define SPI_SR_MODF (1 << 9) /* Bit 9: mode fault */ +#define SPI_SR_TSERF (1 << 10) /* Bit 10: additional number of SPI data to be transacted was reload */ +#define SPI_SR_SUSP (1 << 11) /* Bit 11: suspend */ +#define SPI_SR_TXC (1 << 12) /* Bit 12: TxFIFO transmission complete */ +#define SPI_SR_RXPLVL_SHIFT (13) /* Bits 13-14: RxFIFO packing level */ +#define SPI_SR_RXPLVL_MASK (1 << SPI_SR_RXPLVL_SHIFT) +#define SPI_SR_RXWNE (1 << 15) /* Bit 15: RxFIFO word not empty */ +#define SPI_SR_CTSIZE_SHIFT (16) /* Bits 16-31: number of data frames remaining in current TSIZE session */ +#define SPI_SR_CTSIZE_MASK (1 << SPI_SR_CTSIZE_SHIFT) + +/* SPI/I2S interrupt/status flags interrupt enable register */ + +#define SPI_IER_RXPIE (1 << 0) /* Bit 0: RXP Interrupt enable */ +#define SPI_IER_TXPIE (1 << 1) /* Bit 1: TXP interrupt enable */ +#define SPI_IER_DXPIE (1 << 2) /* Bit 2: DXP interrupt enable */ +#define SPI_IER_EOTIE (1 << 3) /* Bit 3: EOT, SUSP and TXC interrupt enable */ +#define SPI_IER_TXTFIE (1 << 4) /* Bit 4: TXTFIE interrupt enable */ +#define SPI_IER_UDRIE (1 << 5) /* Bit 5: UDR interrupt enable */ +#define SPI_IER_OVRIE (1 << 6) /* Bit 6: OVR interrupt enable */ +#define SPI_IER_CRCEIE (1 << 7) /* Bit 7: CRC error interrupt enable */ +#define SPI_IER_TIFREIE (1 << 8) /* Bit 8: TIFRE interrupt enable */ +#define SPI_IER_MODFIE (1 << 9) /* Bit 9: mode fault interrupt enable */ +#define SPI_IER_TSERFIE (1 << 10) /* Bit 10: additional number of transactions + * reload interrupt enable */ + +/* SPI/I2S interrupt/status flags clear register */ + + /* Bits 0-2: Reserved */ +#define SPI_IFCR_EOTC (1 << 3) /* Bit 3: end of transfer flag clear */ +#define SPI_IFCR_TXTFC (1 << 4) /* Bit 4: transmission Transfer Flilled flag clear */ +#define SPI_IFCR_UDRC (1 << 5) /* Bit 5: underrun flag clear */ +#define SPI_IFCR_OVRC (1 << 6) /* Bit 6: overrun flag clear */ +#define SPI_IFCR_CRCEC (1 << 7) /* Bit 7: CRC error flag clear */ +#define SPI_IFCR_TIFREC (1 << 8) /* Bit 8: TI frame format error flag clear */ +#define SPI_IFCR_MODFC (1 << 9) /* Bit 9: mode fault flag clear */ +#define SPI_IFCR_TSERFC (1 << 10) /* Bit 10: TSERF flag clear*/ +#define SPI_IFCR_SUSPC (1 << 11) /* Bit 11: suspend flag clear */ + /* Bits 12-31: Reserved */ + +/* SPI/I2S transmit data register */ + +#define SPI_TXDR_TXDR_SHIFT (0) /* Bits 0-15: transmit data register */ +#define SPI_TXDR_TXDR_MASK (0xffff << SPI_TXDR_TXDR_SHIFT) + /* Bits 16-31: write ignored */ + +/* SPI/I2S receive data register */ + +#define SPI_RXDR_RXDR_SHIFT (0) /* Bits 0-15: receive data register */ +#define SPI_RXDR_RXDR_MASK (0xffff << SPI_RXDR_RXDR_SHIFT) + /* Bits 16-31: read zero */ + +/* SPI/I2S SPI polynominal register */ + +#define SPI_CRCPOLY_CRCPOLY_SHIFT (0) /* Bits 0-15: CRC polynominal register */ +#define SPI_CRCPOLY_CRCPOLY_MASK (0xffff << SPI_CRCPOLY_CRCPOLY_SHIFT) + /* Bits 16-31: write ignored */ + +/* SPI/I2S SPI transmitter CRC register */ + +#define SPI_TXCRC_TXCRC_SHIFT (0) /* Bits 0-15: CRC register for transmitter */ +#define SPI_TXCRC_TXCRC_MASK (0xffff << SPI_TXCRC_TXCRC_SHIFT) + /* Bits 16-31: write ignored */ + +/* SPI/I2S SPI receiver CRC register */ + +#define SPI_RXCRC_RXCRC_SHIFT (0) /* Bits 0-15: CRC register for receiver */ +#define SPI_RXCRC_RXCRC_MASK (0xffff << SPI_RXCRC_RXCRC_SHIFT) + /* Bits 16-31: read zero */ + +/* SPI/I2S SPI underrun data register */ + +#define SPI_UDRDR_UDRDR_SHIFT (0) /* Bits 0-15: data at slave underrun condition*/ +#define SPI_UDRDR_UDRDR_MASK (0xffff << SPI_UDRDR_UDRDR_SHIFT) + /* Bits 16-31: read zero */ + +#endif /* CONFIG_STM32U5_STM32U585XX */ +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585XX_SPI_H */ diff --git a/arch/arm/src/stm32u5/hardware/stm32u585xx_syscfg.h b/arch/arm/src/stm32u5/hardware/stm32u585xx_syscfg.h new file mode 100644 index 0000000000..dec2aa36cc --- /dev/null +++ b/arch/arm/src/stm32u5/hardware/stm32u585xx_syscfg.h @@ -0,0 +1,135 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/hardware/stm32u585xx_syscfg.h + * + * 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_STM32U5_HARDWARE_STM32U585XX_SYSCFG_H +#define __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585XX_SYSCFG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32U5_STM32U585XX) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32U5_SYSCFG_SECCFGR_OFFSET 0x0000 /* SYSCFG secure configuration register */ +#define STM32U5_SYSCFG_CFGR1_OFFSET 0x0004 /* SYSCFG configuration register 1 */ +#define STM32U5_SYSCFG_FPUIMR_OFFSET 0x0008 /* SYSCFG FPU interrupt mask register */ +#define STM32U5_SYSCFG_CNSLCKR_OFFSET 0x000c /* SYSCFG CPU non-secure lock register */ +#define STM32U5_SYSCFG_CSLCKR_OFFSET 0x0010 /* SYSCFG CPU secure lock register */ +#define STM32U5_SYSCFG_CFGR2_OFFSET 0x0014 /* SYSCFG configuration register 2 */ +#define STM32U5_SYSCFG_SCSR_OFFSET 0x0018 /* SYSCFG SRAM2 control and status register */ +#define STM32U5_SYSCFG_SKR_OFFSET 0x001c /* SYSCFG SRAM2 key register */ +#define STM32U5_SYSCFG_SWPR_OFFSET 0x0020 /* SYSCFG SRAM2 write protection register */ +#define STM32U5_SYSCFG_SWPR2_OFFSET 0x0024 /* SYSCFG SRAM2 write protection register 2 */ +#define STM32U5_SYSCFG_RSSCMDR_OFFSET 0x002c /* SYSCFG RSS command register */ + +/* Register Addresses *******************************************************/ + +#define STM32U5_SYSCFG_SECCFGR (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_SECCFGR_OFFSET) +#define STM32U5_SYSCFG_CFGR1 (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_CFGR1_OFFSET) +#define STM32U5_SYSCFG_FPUIMR (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_FPUIMR_OFFSET) +#define STM32U5_SYSCFG_CNSLCKR (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_CNSLCKR_OFFSET) +#define STM32U5_SYSCFG_CSLCKR (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_CSLCKR_OFFSET) +#define STM32U5_SYSCFG_CFGR2 (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_CFGR2_OFFSET) +#define STM32U5_SYSCFG_SCSR (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_SCSR_OFFSET) +#define STM32U5_SYSCFG_SKR (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_SKR_OFFSET) +#define STM32U5_SYSCFG_SWPR (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_SWPR_OFFSET) +#define STM32U5_SYSCFG_SWPR2 (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_SWPR2_OFFSET) +#define STM32U5_SYSCFG_RSSCMDR (STM32U5_SYSCFG_BASE + STM32U5_SYSCFG_RSSCMDR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* SYSCFG secure configuration register */ + +#define SYSCFG_SECCFGR_SYSCFGSEC (1 << 0) /* SYSCFG clock control security */ +#define SYSCFG_SECCFGR_CLASSBSEC (1 << 1) /* ClassB security */ +#define SYSCFG_SECCFGR_SRAM2SEC (1 << 2) /* SRAM2 security */ +#define SYSCFG_SECCFGR_FPUSEC (1 << 3) /* FPU security */ + +/* SYSCFG configuration register 1 */ + +#define SYSCFG_CFGR1_BOOSTEN (1 << 8) /* Bit 8: I/O analog switch voltage booster enable (use when vdd is low) */ +#define SYSCFG_CFGR1_ANASWVDD (1 << 9) /* Bit 9: GPIO analog switch control voltage selection */ +#define SYSCFG_CFGR1_I2C_PB6_FMP (1 << 16) /* Bit 16: Fast-mode Plus (Fm+) driving capability activation on PB6 */ +#define SYSCFG_CFGR1_I2C_PB7_FMP (1 << 17) /* Bit 17: Fast-mode Plus (Fm+) driving capability activation on PB7 */ +#define SYSCFG_CFGR1_I2C_PB8_FMP (1 << 18) /* Bit 18: Fast-mode Plus (Fm+) driving capability activation on PB8 */ +#define SYSCFG_CFGR1_I2C_PB9_FMP (1 << 19) /* Bit 19: Fast-mode Plus (Fm+) driving capability activation on PB9 */ +#define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 Fast-mode Plus (Fm+) driving capability activation */ +#define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C2 Fast-mode Plus (Fm+) driving capability activation */ +#define SYSCFG_CFGR1_I2C3_FMP (1 << 22) /* Bit 22: I2C3 Fast-mode Plus (Fm+) driving capability activation */ +#define SYSCFG_CFGR1_I2C4_FMP (1 << 23) /* Bit 23: I2C4 Fast-mode Plus (Fm+) driving capability activation */ + +/* SYSCFG FPU interrupt mask register */ + +#define SYSCFG_FPUIMR_IE0 (1 << 0) /* Bit 0: FPU Invalid operation interrupt enable */ +#define SYSCFG_FPUIMR_IE1 (1 << 1) /* Bit 1: FPU Divide-by-zero interrupt enable */ +#define SYSCFG_FPUIMR_IE2 (1 << 2) /* Bit 2: FPU Underflow interrupt enable */ +#define SYSCFG_FPUIMR_IE3 (1 << 3) /* Bit 3: FPU Overflow interrupt enable */ +#define SYSCFG_FPUIMR_IE4 (1 << 4) /* Bit 4: FPU Input abnormal interrupt enable */ +#define SYSCFG_FPUIMR_IE5 (1 << 5) /* Bit 5: FPU Inexact interrupt enable */ + +/* SYSCFG CPU non-secure lock register */ + +#define SYSCFG_CNSLCKR_LOCKNSVTOR (1 << 0) /* Bit 0: VTOR_NS register lock */ +#define SYSCFG_CNSLCKR_LOCKNSMPU (1 << 1) /* Bit 1: Non-seucre MPU registers lock */ + +/* SYSCFG CPU secure lock register */ + +#define SYSCFG_CSLCKR_LOCKSVTAIRCR (1 << 0) /* Bit 0: VTOR_S register and AIRCR register bits lock */ +#define SYSCFG_CSLCKR_LOCKSMPU (1 << 1) /* Bit 1: Secure MPU registers lock */ +#define SYSCFG_CSLCKR_LOCKSAU (1 << 2) /* Bit 2: SAU registers lock */ + +/* SYSCFG configuration register 2 */ + +#define SYSCFG_CFGR2_CLL (1 << 0) /* Bit 0: Cortex-M33 LOCKUP (hardfault) output enable */ +#define SYSCFG_CFGR2_SPL (1 << 1) /* Bit 1: SRAM2 parity lock */ +#define SYSCFG_CFGR2_PVDL (1 << 2) /* Bit 2: PVD lock enable */ +#define SYSCFG_CFGR2_ECCL (1 << 3) /* Bit 3: ECC lock */ +#define SYSCFG_CFGR2_SPF (1 << 8) /* Bit 8: SRAM2 parity error flag */ + +/* SYSCFG SRAM2 control and status register */ + +#define SYSCFG_SCSR_SRAM2ER (1 << 0) /* Bit 0: SRAM2 Erase */ +#define SYSCFG_SCSR_SRAM2BSY (1 << 1) /* Bit 1: SRAM2 busy in erase operation */ + +/* SYSCFG SRAM2 key register */ + +#define SYSCFG_SKR_SHIFT 0 +#define SYSCFG_SKR_MASK (0xFF << SYSCFG_SKR_SHIFT) + +/* SYSCFG SRAM2 write protection register 1 and 2: There is one bit per SRAM2 + * page (0 to 31 and 32 to 63, respectively). + */ + +/* SYSCFG RSS command register */ + +#define SYSCFG_RSSCMDR_SHIFT 0 +#define SYSCFG_RSSCMDR_MASK (0xFFFF << SYSCFG_RSSCMDR_SHIFT) + +#endif /* CONFIG_STM32U5_STM32U585XX */ +#endif /* __ARCH_ARM_SRC_STM32U5_HARDWARE_STM32U585XX_SYSCFG_H */ diff --git a/arch/arm/src/stm32u5/stm32.h b/arch/arm/src/stm32u5/stm32.h new file mode 100644 index 0000000000..d3a7002564 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32.h + * + * 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_STM32U5_STM32_H +#define __ARCH_ARM_SRC_STM32U5_STM32_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "arm_internal.h" + +/* Peripherals **************************************************************/ + +#include "chip.h" +#include "stm32_dbgmcu.h" +#include "stm32_flash.h" +#include "stm32_gpio.h" +#include "stm32_pwr.h" +#include "stm32_rcc.h" +#include "stm32_spi.h" +#include "stm32_tim.h" +#include "stm32_uart.h" +#include "stm32_lowputc.h" + +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_H */ diff --git a/arch/arm/src/stm32u5/stm32_allocateheap.c b/arch/arm/src/stm32u5/stm32_allocateheap.c new file mode 100644 index 0000000000..c034965eef --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_allocateheap.c @@ -0,0 +1,372 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_allocateheap.c + * + * 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 "chip.h" +#include "mpu.h" +#include "arm_arch.h" +#include "arm_internal.h" +#include "stm32_mpuinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Internal SRAM is available in all members of the STM32U5 family. The + * following definitions must be provided to specify the size and + * location of internal (system) SRAM1 and SRAM2: + * + * SRAM1_START 0x20000000 + * SRAM1_END + * SRAM2_START 0x10000000 + * SRAM2_END + * + * In addition to internal SRAM, memory may also be available through the + * FSMC. In order to use FSMC SRAM, the following additional things need to + * be present in the NuttX configuration file: + * + * CONFIG_STM32U5_FSMC=y : Enables the FSMC + * CONFIG_STM32U5_FSMC_SRAM=y : Indicates that SRAM is available via the + * FSMC (as opposed to an LCD or FLASH). + * CONFIG_HEAP2_BASE : The base address of the SRAM in the FSMC + * address space + * CONFIG_HEAP2_SIZE : The size of the SRAM in the FSMC + * address space + * CONFIG_MM_REGIONS : Must be set to a large enough value to + * include the additional regions. + */ + +#ifndef CONFIG_STM32U5_FSMC +# undef CONFIG_STM32U5_FSMC_SRAM +#endif + +/* STM32U5[7,8]6xx have 128 Kib in two banks, both accessible to DMA: + * + * 1) 96 KiB of System SRAM beginning at address 0x2000:0000 - 0x2001:8000 + * 2) 32 KiB of System SRAM beginning at address 0x1000:0000 - 0x1000:8000 + * + * STM32U596xx have 320 Kib in two banks, both accessible to DMA: + * + * 1) 256 KiB of System SRAM beginning at address 0x2000:0000 - 0x2004:0000 + * 2) 64 KiB of System SRAM beginning at address 0x1000:0000 - 0x1001:0000 + * + * STM32U5Rxxx have 640 Kib in three banks: + * + * 1) 192 KiB of System SRAM beginning at address 0x2000:0000 - 0x2003:0000 + * 2) 64 KiB of System SRAM beginning at address 0x1000:0000 - 0x1001:0000 + * 3) 384 KiB of System SRAM beginning at address 0x2004:0000 - 0x200A:0000 + * + * In addition, external FSMC SRAM may be available. + */ + +/* Set the range of system SRAM */ + +#define SRAM1_START STM32_SRAM_BASE +#define SRAM1_END (SRAM1_START + STM32_SRAM1_SIZE) + +/* Set the range of SRAM2 as well, requires a second memory region */ + +#define SRAM2_START STM32_SRAM2_BASE +#define SRAM2_END (SRAM2_START + STM32_SRAM2_SIZE) + +/* Set the range of SRAM3, requiring a third memory region */ + +#ifdef STM32_SRAM3_SIZE +# define SRAM3_START STM32_SRAM3_BASE +# define SRAM3_END (SRAM3_START + STM32_SRAM3_SIZE) +#endif + +/* Some sanity checking. If multiple memory regions are defined, verify + * that CONFIG_MM_REGIONS is set to match the number of memory regions + * that we have been asked to add to the heap. + */ + +#if CONFIG_MM_REGIONS < defined(CONFIG_STM32U5_SRAM2_HEAP) + \ + defined(CONFIG_STM32U5_SRAM3_HEAP) + \ + defined(CONFIG_STM32U5_FSMC_SRAM_HEAP) + 1 +# error "You need more memory manager regions to support selected heap components" +#endif + +#if CONFIG_MM_REGIONS > defined(CONFIG_STM32U5_SRAM2_HEAP) + \ + defined(CONFIG_STM32U5_SRAM3_HEAP) + \ + defined(CONFIG_STM32U5_FSMC_SRAM_HEAP) + 1 +# warning "CONFIG_MM_REGIONS large enough but I do not know what some of the region(s) are" +#endif + +/* If FSMC SRAM is going to be used as heap, then verify that the starting + * address and size of the external SRAM region has been provided in the + * configuration (as CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE). + */ + +#ifdef CONFIG_STM32U5_FSMC_SRAM +# if !defined(CONFIG_HEAP2_BASE) || !defined(CONFIG_HEAP2_SIZE) +# error "CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE must be provided" +# undef CONFIG_STM32U5_FSMC_SRAM +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_heap_color + * + * Description: + * Set heap memory to a known, non-zero state to checking heap usage. + * + ****************************************************************************/ + +#ifdef CONFIG_HEAP_COLORATION +static inline void up_heap_color(FAR void *start, size_t size) +{ + memset(start, HEAP_COLOR, size); +} +#else +# define up_heap_color(start,size) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size given by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)ubase, usize); + + /* Allow user-mode access to the user heap memory */ + + stm32_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = SRAM1_END - g_idle_topstack; + + /* Colorize the heap for debug */ + + up_heap_color(*heap_start, *heap_size); +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif + +/**************************************************************************** + * Name: arm_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void arm_addregion(void) +{ +#ifdef CONFIG_STM32U5_SRAM2_HEAP + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the SRAM2 heap */ + + stm32_mpu_uheap((uintptr_t)SRAM2_START, SRAM2_END - SRAM2_START); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)SRAM2_START, SRAM2_END - SRAM2_START); + + /* Add the SRAM2 user heap region. */ + + kumm_addregion((FAR void *)SRAM2_START, SRAM2_END - SRAM2_START); + +#endif /* SRAM2 */ + +#ifdef CONFIG_STM32U5_SRAM3_HEAP + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the SRAM3 heap */ + + stm32_mpu_uheap((uintptr_t)SRAM3_START, SRAM3_END - SRAM3_START); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)SRAM3_START, SRAM3_END - SRAM3_START); + + /* Add the SRAM3 user heap region. */ + + kumm_addregion((FAR void *)SRAM3_START, SRAM3_END - SRAM3_START); + +#endif /* SRAM3 */ + +#ifdef CONFIG_STM32U5_FSMC_SRAM_HEAP +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the FSMC SRAM user heap memory */ + + stm32_mpu_uheap((uintptr_t)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + + /* Add the external FSMC SRAM user heap region. */ + + kumm_addregion((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); +#endif +} +#endif diff --git a/arch/arm/src/stm32u5/stm32_dbgmcu.h b/arch/arm/src/stm32u5/stm32_dbgmcu.h new file mode 100644 index 0000000000..946d6986ef --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_dbgmcu.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_dbgmcu.h + * + * 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_STM32U5_STM32_DBGMCU_H +#define __ARCH_ARM_SRC_STM32U5_STM32_DBGMCU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_STM32U5_STM32U585XX) +# include "hardware/stm32u585xx_dbgmcu.h" +#else +# error "Unsupported STM32U5 chip" +#endif + +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_DBGMCU_H */ diff --git a/arch/arm/src/stm32u5/stm32_dumpgpio.c b/arch/arm/src/stm32u5/stm32_dumpgpio.c new file mode 100644 index 0000000000..ab40be487e --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_dumpgpio.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_dumpgpio.c + * + * 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 + +/* Output debug info even if debug output is not selected. */ + +#undef CONFIG_DEBUG_INFO +#define CONFIG_DEBUG_INFO 1 + +#include +#include +#include + +#include + +#include "arm_arch.h" +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_rcc.h" + +#ifdef CONFIG_DEBUG_FEATURES + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Port letters for prettier debug output */ + +static const char g_portchar[STM32_NPORTS] = +{ +#if STM32_NPORTS > 11 +# error "Additional support required for this number of GPIOs" +#elif STM32_NPORTS > 10 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K' +#elif STM32_NPORTS > 9 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' +#elif STM32_NPORTS > 8 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' +#elif STM32_NPORTS > 7 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' +#elif STM32_NPORTS > 6 + 'A', 'B', 'C', 'D', 'E', 'F', 'G' +#elif STM32_NPORTS > 5 + 'A', 'B', 'C', 'D', 'E', 'F' +#elif STM32_NPORTS > 4 + 'A', 'B', 'C', 'D', 'E' +#elif STM32_NPORTS > 3 + 'A', 'B', 'C', 'D' +#elif STM32_NPORTS > 2 + 'A', 'B', 'C' +#elif STM32_NPORTS > 1 + 'A', 'B' +#elif STM32_NPORTS > 0 + 'A' +#else +# error "Bad number of GPIOs" +#endif +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +int stm32_dumpgpio(uint32_t pinset, const char *msg) +{ + irqstate_t flags; + uint32_t base; + unsigned int port; + + /* Get the base address associated with the GPIO port */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + base = g_gpiobase[port]; + + /* The following requires exclusive access to the GPIO registers */ + + flags = enter_critical_section(); + + DEBUGASSERT(port < STM32_NPORTS); + + _info("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + + if ((getreg32(STM32_RCC_AHB2ENR1) & RCC_AHB2ENR1_GPIOEN(port)) != 0) + { + _info(" MODE: %08x OTYPE: %04x OSPEED: %08x PUPDR: %08x\n", + getreg32(base + STM32_GPIO_MODER_OFFSET), + getreg32(base + STM32_GPIO_OTYPER_OFFSET), + getreg32(base + STM32_GPIO_OSPEED_OFFSET), + getreg32(base + STM32_GPIO_PUPDR_OFFSET)); + _info(" IDR: %04x ODR: %04x BSRR: %08x LCKR: %04x\n", + getreg32(base + STM32_GPIO_IDR_OFFSET), + getreg32(base + STM32_GPIO_ODR_OFFSET), + getreg32(base + STM32_GPIO_BSRR_OFFSET), + getreg32(base + STM32_GPIO_LCKR_OFFSET)); + _info(" AFRH: %08x AFRL: %08x\n", + getreg32(base + STM32_GPIO_AFRH_OFFSET), + getreg32(base + STM32_GPIO_AFRL_OFFSET)); + } + else + { + _info(" GPIO%c not enabled: AHB2ENR: %08x\n", + g_portchar[port], getreg32(STM32_RCC_AHB2ENR1)); + } + + leave_critical_section(flags); + return OK; +} + +#endif /* CONFIG_DEBUG_FEATURES */ diff --git a/arch/arm/src/stm32u5/stm32_exti.h b/arch/arm/src/stm32u5/stm32_exti.h new file mode 100644 index 0000000000..a2126eed3f --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_exti.h @@ -0,0 +1,153 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_exti.h + * + * 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_STM32U5_STM32_EXTI_H +#define __ARCH_ARM_SRC_STM32U5_STM32_EXTI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "hardware/stm32_exti.h" + +/**************************************************************************** + * 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_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Input Parameters: + * pinset - GPIO pin configuration + * risingedge - Enables interrupt on rising edges + * fallingedge - Enables interrupt on falling edges + * event - Generate event when set + * func - When non-NULL, generate interrupt + * arg - Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) is returned on success, otherwise a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func, void *arg); + +/**************************************************************************** + * Name: stm32_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Input Parameters: + * - rising/falling edge: enables interrupt on rising/falling edges + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int stm32_exti_alarm(bool risingedge, bool fallingedge, bool event, + xcpt_t func, void *arg); +#endif + +/**************************************************************************** + * Name: stm32_exti_wakeup + * + * Description: + * Sets/clears EXTI wakeup interrupt. + * + * Input Parameters: + * - rising/falling edge: enables interrupt on rising/falling edges + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_PERIODIC +int stm32_exti_wakeup(bool risingedge, bool fallingedge, bool event, + xcpt_t func, void *arg); +#endif + +/**************************************************************************** + * Name: stm32_exti_comp + * + * Description: + * Sets/clears comparator based events and interrupt triggers. + * + * Input Parameters: + * - cmp: comparator + * - rising/falling edge: enables interrupt on rising/falling edges + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) returned on success; a negated errno value is returned on + * failure. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_COMP +int stm32_exti_comp(int cmp, bool risingedge, bool fallingedge, + bool event, xcpt_t func, void *arg); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_EXTI_H */ diff --git a/arch/arm/src/stm32u5/stm32_exti_gpio.c b/arch/arm/src/stm32u5/stm32_exti_gpio.c new file mode 100644 index 0000000000..2ffe5255d1 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_exti_gpio.c @@ -0,0 +1,173 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_exti_gpio.c + * + * 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_arch.h" +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_exti.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct gpio_callback_s +{ + xcpt_t callback; /* Callback entry point */ + void *arg; /* The argument that accompanies the callback */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to each EXTI */ + +static struct gpio_callback_s g_gpio_handlers[16]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Interrupt Service Routine - Dispatcher + ****************************************************************************/ + +static int stm32_exti0_15_isr(int irq, void *context, FAR void *arg) +{ + int ret = OK; + int exti; + + exti = irq - STM32_IRQ_EXTI0; + DEBUGASSERT((exti >= 0) && (exti <= 15)); + + /* Clear the pending interrupt for both rising and falling edges. */ + + putreg32(0x0001 << exti, STM32_EXTI_RPR1); + putreg32(0x0001 << exti, STM32_EXTI_FPR1); + + /* And dispatch the interrupt to the handler */ + + if (g_gpio_handlers[exti].callback != NULL) + { + xcpt_t callback = g_gpio_handlers[exti].callback; + void *cbarg = g_gpio_handlers[exti].arg; + + ret = callback(irq, context, cbarg); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Input Parameters: + * pinset - GPIO pin configuration + * risingedge - Enables interrupt on rising edges + * fallingedge - Enables interrupt on falling edges + * event - Generate event when set + * func - When non-NULL, generate interrupt + * arg - Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) is returned on success, otherwise a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func, void *arg) +{ + uint32_t pin = pinset & GPIO_PIN_MASK; + uint32_t exti = 1 << pin; + int irq = STM32_IRQ_EXTI0 + pin; + + g_gpio_handlers[pin].callback = func; + g_gpio_handlers[pin].arg = arg; + + /* Install external interrupt handlers */ + + if (func) + { + irq_attach(irq, stm32_exti0_15_isr, NULL); + up_enable_irq(irq); + } + else + { + up_disable_irq(irq); + } + + /* Configure GPIO, enable EXTI line enabled if event or interrupt is + * enabled. + */ + + if (event || func) + { + pinset |= GPIO_EXTI; + } + + stm32_configgpio(pinset); + + /* Configure rising/falling edges */ + + modifyreg32(STM32_EXTI_RTSR1, + risingedge ? 0 : exti, + risingedge ? exti : 0); + modifyreg32(STM32_EXTI_FTSR1, + fallingedge ? 0 : exti, + fallingedge ? exti : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32_EXTI_EMR1, + event ? 0 : exti, + event ? exti : 0); + modifyreg32(STM32_EXTI_IMR1, + func ? 0 : exti, + func ? exti : 0); + + return OK; +} diff --git a/arch/arm/src/stm32u5/stm32_flash.c b/arch/arm/src/stm32u5/stm32_flash.c new file mode 100644 index 0000000000..e29781ec27 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_flash.c @@ -0,0 +1,507 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_flash.c + * + * 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. + * + ****************************************************************************/ + +/* Provides standard flash access functions, to be used by the flash mtd + * driver. The interface is defined in the include/nuttx/progmem.h + * + * Notes about this implementation: + * - HSI16 is automatically turned ON by MCU, if not enabled beforehand + * - Only Standard Programming is supported, no Fast Programming. + * - Low Power Modes are not permitted during write/erase + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "stm32_rcc.h" +#include "stm32_waste.h" +#include "stm32_flash.h" + +#include "arm_arch.h" + +#if !(defined(CONFIG_STM32U5_STM32U585XX)) +# error "Unrecognized STM32 chip" +#endif + +#if !defined(CONFIG_STM32U5_FLASH_OVERRIDE_DEFAULT) +# warning "Flash Configuration has been overridden - make sure it is correct" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FLASH_KEY1 0x45670123 +#define FLASH_KEY2 0xCDEF89AB + +#define OPTBYTES_KEY1 0x08192A3B +#define OPTBYTES_KEY2 0x4C5D6E7F + +#define FLASH_PAGE_SIZE STM32_FLASH_PAGESIZE +#define FLASH_PAGE_WORDS (FLASH_PAGE_SIZE / 4) +#define FLASH_PAGE_MASK (FLASH_PAGE_SIZE - 1) +#if FLASH_PAGE_SIZE == 2048 +# define FLASH_PAGE_SHIFT (11) /* 2**11 = 2048B */ +#elif FLASH_PAGE_SIZE == 4096 +# define FLASH_PAGE_SHIFT (12) /* 2**12 = 4096B */ +#elif FLASH_PAGE_SIZE == 8192 +# define FLASH_PAGE_SHIFT (13) /* 2**13 = 8192B */ +#else +# error Unsupported STM32_FLASH_PAGESIZE +#endif +#define FLASH_BYTE2PAGE(o) ((o) >> FLASH_PAGE_SHIFT) + +#define FLASH_NSCR_PAGE_ERASE FLASH_NSCR_PER +#define FLASH_NSSR_WRITE_PROTECTION_ERROR FLASH_NSSR_WRPERR + +/* All errors for Standard Programming, not for other operations. */ + +#define FLASH_NSSR_ALLERRS (FLASH_NSSR_PGSERR | FLASH_NSSR_SIZERR | \ + FLASH_NSSR_PGAERR | FLASH_NSSR_WRPERR | \ + FLASH_NSSR_PROGERR) + +#ifndef MIN +# define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sem_t g_sem = SEM_INITIALIZER(1); +static uint32_t g_page_buffer[FLASH_PAGE_WORDS]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline void sem_lock(void) +{ + int ret; + + do + { + /* Take the semaphore (perhaps waiting) */ + + ret = nxsem_wait(&g_sem); + + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + DEBUGASSERT(ret == OK || ret == -EINTR); + } + while (ret == -EINTR); +} + +static inline void sem_unlock(void) +{ + nxsem_post(&g_sem); +} + +static void flash_unlock(void) +{ + while (getreg32(STM32_FLASH_NSSR) & FLASH_NSSR_BSY) + { + stm32_waste(); + } + + if (getreg32(STM32_FLASH_NSCR) & FLASH_NSCR_LOCK) + { + /* Unlock sequence */ + + putreg32(FLASH_KEY1, STM32_FLASH_NSKEYR); + putreg32(FLASH_KEY2, STM32_FLASH_NSKEYR); + } +} + +static void flash_lock(void) +{ + modifyreg32(STM32_FLASH_NSCR, 0, FLASH_NSCR_LOCK); +} + +static void flash_optbytes_unlock(void) +{ + flash_unlock(); + + if (getreg32(STM32_FLASH_NSCR) & FLASH_NSCR_OPTLOCK) + { + /* Unlock Option Bytes sequence */ + + putreg32(OPTBYTES_KEY1, STM32_FLASH_OPTKEYR); + putreg32(OPTBYTES_KEY2, STM32_FLASH_OPTKEYR); + } +} + +static inline void flash_optbytes_lock(void) +{ + /* We don't need to set OPTLOCK here as it is automatically + * set by MCU when flash_lock() sets LOCK. + */ + + flash_lock(); +} + +static inline void flash_erase(size_t page) +{ + finfo("erase page %u\n", page); + + modifyreg32(STM32_FLASH_NSCR, 0, FLASH_NSCR_PAGE_ERASE); + modifyreg32(STM32_FLASH_NSCR, FLASH_NSCR_PNB_MASK, FLASH_NSCR_PNB(page)); + modifyreg32(STM32_FLASH_NSCR, 0, FLASH_NSCR_STRT); + + while (getreg32(STM32_FLASH_NSSR) & FLASH_NSSR_BSY) + { + stm32_waste(); + } + + modifyreg32(STM32_FLASH_NSCR, FLASH_NSCR_PAGE_ERASE, 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void stm32_flash_unlock(void) +{ + sem_lock(); + flash_unlock(); + sem_unlock(); +} + +void stm32_flash_lock(void) +{ + sem_lock(); + flash_lock(); + sem_unlock(); +} + +/**************************************************************************** + * Name: stm32_flash_user_optbytes + * + * Description: + * Modify the contents of the user option bytes (USR OPT) on the flash. + * This does not set OBL_LAUNCH so new options take effect only after + * next power reset. + * + * Input Parameters: + * clrbits - Bits in the option bytes to be cleared + * setbits - Bits in the option bytes to be set + * + * Returned Value: + * Option bytes after operation is completed + * + ****************************************************************************/ + +uint32_t stm32_flash_user_optbytes(uint32_t clrbits, uint32_t setbits) +{ + uint32_t regval; + + /* To avoid accidents, do not allow setting RDP via this function. + * Remove these asserts if want to enable changing the protection level. + * WARNING: level 2 protection is permanent! + */ + + DEBUGASSERT((clrbits & FLASH_OPTR_RDP_MASK) == 0); + DEBUGASSERT((setbits & FLASH_OPTR_RDP_MASK) == 0); + + sem_lock(); + flash_optbytes_unlock(); + + /* Modify Option Bytes in register. */ + + regval = getreg32(STM32_FLASH_OPTR); + + finfo("Flash option bytes before: 0x%x\n", (unsigned)regval); + + regval = (regval & ~clrbits) | setbits; + putreg32(regval, STM32_FLASH_OPTR); + + finfo("Flash option bytes after: 0x%x\n", (unsigned)regval); + + /* Start Option Bytes programming and wait for completion. */ + + modifyreg32(STM32_FLASH_NSCR, 0, FLASH_NSCR_OPTSTRT); + + while (getreg32(STM32_FLASH_NSSR) & FLASH_NSSR_BSY) + { + stm32_waste(); + } + + flash_optbytes_lock(); + sem_unlock(); + + return regval; +} + +size_t up_progmem_pagesize(size_t page) +{ + return STM32_FLASH_PAGESIZE; +} + +size_t up_progmem_erasesize(size_t block) +{ + return STM32_FLASH_PAGESIZE; +} + +ssize_t up_progmem_getpage(size_t addr) +{ + if (addr >= STM32_FLASH_BASE) + { + addr -= STM32_FLASH_BASE; + } + + if (addr >= STM32_FLASH_SIZE) + { + return -EFAULT; + } + + return addr / STM32_FLASH_PAGESIZE; +} + +size_t up_progmem_getaddress(size_t page) +{ + if (page >= STM32_FLASH_NPAGES) + { + return SIZE_MAX; + } + + return page * STM32_FLASH_PAGESIZE + STM32_FLASH_BASE; +} + +size_t up_progmem_neraseblocks(void) +{ + return STM32_FLASH_NPAGES; +} + +bool up_progmem_isuniform(void) +{ + return true; +} + +ssize_t up_progmem_eraseblock(size_t block) +{ + if (block >= STM32_FLASH_NPAGES) + { + return -EFAULT; + } + + /* Erase single block */ + + sem_lock(); + flash_unlock(); + + flash_erase(block); + + flash_lock(); + sem_unlock(); + + /* Verify */ + + if (up_progmem_ispageerased(block) == 0) + { + return up_progmem_erasesize(block); + } + else + { + return -EIO; + } +} + +ssize_t up_progmem_ispageerased(size_t page) +{ + size_t addr; + size_t count; + size_t bwritten = 0; + + if (page >= STM32_FLASH_NPAGES) + { + return -EFAULT; + } + + /* Verify */ + + for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page); + count; count--, addr++) + { + if (getreg8(addr) != 0xff) + { + bwritten++; + } + } + + return bwritten; +} + +ssize_t up_progmem_write(size_t addr, const void *buf, size_t buflen) +{ + uint32_t *dest; + const uint32_t *src; + size_t written; + size_t xfrsize; + size_t offset; + size_t page; + int i; + int ret = OK; + + /* Check for valid address range. */ + + offset = addr; + if (addr >= STM32_FLASH_BASE) + { + offset -= STM32_FLASH_BASE; + } + + if (offset + buflen > STM32_FLASH_SIZE) + { + return -EFAULT; + } + + /* Get the page number corresponding to the flash offset and the byte + * offset into the page. Align write destination to page boundary. + */ + + page = FLASH_BYTE2PAGE((uint32_t)offset); + offset &= FLASH_PAGE_MASK; + + dest = (uint32_t *)((uint8_t *)addr - offset); + written = 0; + + sem_lock(); + + /* Get flash ready and begin flashing. */ + + flash_unlock(); + + /* Loop until all of the data has been written */ + + while (buflen > 0) + { + /* How much can we write into this page? */ + + xfrsize = MIN((size_t)FLASH_PAGE_SIZE - offset, buflen); + + /* Do we need to use the intermediate buffer? */ + + if (offset == 0 && xfrsize == FLASH_PAGE_SIZE) + { + /* No, we can take the data directly from the user buffer */ + + src = (const uint32_t *)buf; + } + else + { + /* Yes, copy data into global page buffer */ + + if (offset > 0) + { + memcpy(g_page_buffer, dest, offset); + } + + memcpy((uint8_t *)g_page_buffer + offset, buf, xfrsize); + + if (offset + xfrsize < FLASH_PAGE_SIZE) + { + memcpy((uint8_t *)g_page_buffer + offset + xfrsize, + (const uint8_t *)dest + offset + xfrsize, + FLASH_PAGE_SIZE - offset - xfrsize); + } + + src = g_page_buffer; + } + + /* Erase the page. Unlike most flash chips, STM32 is unable to + * write back existing data read from page without erase. + */ + + flash_erase(page); + + /* Write the page. Must be with double-words. */ + + modifyreg32(STM32_FLASH_NSCR, 0, FLASH_NSCR_PG); + + for (i = 0; i < FLASH_PAGE_WORDS; i += 2) + { + *dest++ = *src++; + *dest++ = *src++; + + while (getreg32(STM32_FLASH_NSSR) & FLASH_NSSR_BSY) + { + stm32_waste(); + } + + /* Verify */ + + if (getreg32(STM32_FLASH_NSSR) & FLASH_NSSR_WRITE_PROTECTION_ERROR) + { + modifyreg32(STM32_FLASH_NSCR, FLASH_NSCR_PG, 0); + ret = -EROFS; + goto out; + } + + if (getreg32(dest - 1) != *(src - 1) || + getreg32(dest - 2) != *(src - 2)) + { + modifyreg32(STM32_FLASH_NSCR, FLASH_NSCR_PG, 0); + ret = -EIO; + goto out; + } + } + + modifyreg32(STM32_FLASH_NSCR, FLASH_NSCR_PG, 0); + + /* Adjust pointers and counts for the next time through the loop */ + + written += xfrsize; + addr += xfrsize; + dest = (uint32_t *)addr; + buf = (void *)((uintptr_t)buf + xfrsize); + buflen -= xfrsize; + page++; + } + +out: + /* If there was an error, clear all error flags in status + * register (rc_w1 register so do this by writing the + * error bits). + */ + + if (ret != OK) + { + ferr("flash write error: %d, status: 0x%x\n", ret, + (unsigned)getreg32(STM32_FLASH_NSSR)); + modifyreg32(STM32_FLASH_NSSR, 0, FLASH_NSSR_ALLERRS); + } + + flash_lock(); + sem_unlock(); + return (ret == OK) ? written : ret; +} diff --git a/arch/arm/src/stm32u5/stm32_flash.h b/arch/arm/src/stm32u5/stm32_flash.h new file mode 100644 index 0000000000..1f7c602f92 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_flash.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_flash.h + * + * 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_STM32U5_STM32_FLASH_H +#define __ARCH_ARM_SRC_STM32U5_STM32_FLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/stm32_flash.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void stm32_flash_lock(void); +void stm32_flash_unlock(void); + +/**************************************************************************** + * Name: stm32_flash_user_optbytes + * + * Description: + * Modify the contents of the user option bytes (USR OPT) on the flash. + * This does not set OBL_LAUNCH so new options take effect only after + * next power reset. + * + * Input Parameters: + * clrbits - Bits in the option bytes to be cleared + * setbits - Bits in the option bytes to be set + * + * Returned Value: + * Option bytes after operation is completed + * + ****************************************************************************/ + +uint32_t stm32_flash_user_optbytes(uint32_t clrbits, uint32_t setbits); + +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_FLASH_H */ diff --git a/arch/arm/src/stm32u5/stm32_gpio.c b/arch/arm/src/stm32u5/stm32_gpio.c new file mode 100644 index 0000000000..2b5fb6a255 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_gpio.c @@ -0,0 +1,403 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_gpio.c + * + * 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 "arm_arch.h" + +#include "chip.h" +#include "stm32_gpio.h" + +#include "hardware/stm32_syscfg.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Base addresses for each GPIO block */ + +const uint32_t g_gpiobase[STM32_NPORTS] = +{ +#if STM32_NPORTS > 0 + STM32_GPIOA_BASE, +#endif +#if STM32_NPORTS > 1 + STM32_GPIOB_BASE, +#endif +#if STM32_NPORTS > 2 + STM32_GPIOC_BASE, +#endif +#if STM32_NPORTS > 3 + STM32_GPIOD_BASE, +#endif +#if STM32_NPORTS > 4 + STM32_GPIOE_BASE, +#endif +#if STM32_NPORTS > 5 + STM32_GPIOF_BASE, +#endif +#if STM32_NPORTS > 6 + STM32_GPIOG_BASE, +#endif +#if STM32_NPORTS > 7 + STM32_GPIOH_BASE, +#endif +#if STM32_NPORTS > 8 + STM32_GPIOI_BASE, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32_start(). + * + * Assumptions: + * This function is called early in the initialization sequence so that + * no mutual exclusion is necessary. + * + ****************************************************************************/ + +void stm32_gpioinit(void) +{ +} + +/**************************************************************************** + * 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. + * + * To-Do: Auto Power Enable + ****************************************************************************/ + +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 >= STM32_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 = enter_critical_section(); + + /* 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); + + leave_critical_section(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 + * + * To-Do: Auto Power Disable + ****************************************************************************/ + +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; + + /* To-Do: Mark its unuse for automatic power saving options */ + + 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 < STM32_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 < STM32_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/stm32u5/stm32_gpio.h b/arch/arm/src/stm32u5/stm32_gpio.h new file mode 100644 index 0000000000..e55640b607 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_gpio.h @@ -0,0 +1,363 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_gpio.h + * + * 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_STM32U5_STM32_GPIO_H +#define __ARCH_ARM_SRC_STM32U5_STM32_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include +#include + +#include "chip.h" + +#if defined(CONFIG_STM32U5_STM32U585XX) +# include "hardware/stm32_gpio.h" +#else +# error "Unsupported STM32U5 chip" +#endif + +/**************************************************************************** + * 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 .... + */ + +#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 */ + +/* 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[STM32_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); + +/**************************************************************************** + * Name: stm32_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Input Parameters: + * pinset - GPIO pin configuration + * risingedge - Enables interrupt on rising edges + * fallingedge - Enables interrupt on falling edges + * event - Generate event when set + * func - When non-NULL, generate interrupt + * arg - Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) is returned on success, otherwise a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func, void *arg); + +/**************************************************************************** + * Function: stm32_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +int stm32_dumpgpio(uint32_t pinset, const char *msg); +#else +# define stm32_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Function: stm32_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32_start(). + * + ****************************************************************************/ + +void stm32_gpioinit(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_GPIO_H */ diff --git a/arch/arm/src/stm32u5/stm32_idle.c b/arch/arm/src/stm32u5/stm32_idle.c new file mode 100644 index 0000000000..4a83f45f3a --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_idle.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_idle.c + * + * 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 "chip.h" +#include "stm32_rcc.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 + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#define up_idlepm() + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their 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 + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power. */ + +#if !(defined(CONFIG_DEBUG_SYMBOLS) && defined(CONFIG_STM32U5_DISABLE_IDLE_SLEEP_DURING_DEBUG)) + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif + +#endif +} diff --git a/arch/arm/src/stm32u5/stm32_irq.c b/arch/arm/src/stm32u5/stm32_irq.c new file mode 100644 index 0000000000..61579bd58c --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_irq.c @@ -0,0 +1,521 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_irq.c + * + * 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_arch.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) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * 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\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_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)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), + getreg32(NVIC_IRQ24_27_PRIORITY), + getreg32(NVIC_IRQ28_31_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), + getreg32(NVIC_IRQ40_43_PRIORITY), + getreg32(NVIC_IRQ44_47_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), + getreg32(NVIC_IRQ56_59_PRIORITY), + getreg32(NVIC_IRQ60_63_PRIORITY)); + irqinfo(" %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY)); + + leave_critical_section(flags); +} +#else +# define stm32_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: stm32_nmi, stm32_busfault, stm32_usagefault, stm32_pendsv, + * stm32_dbgmonitor, 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, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int stm32_busfault(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32_usagefault(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32_pendsv(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int stm32_dbgmonitor(int irq, FAR void *context, FAR void *arg) +{ + (void)up_irq_save(); + _err("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int stm32_reserved(int irq, FAR void *context, FAR void *arg) +{ + (void)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. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV8M_USEBASEPRI +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); +} +#endif + +/**************************************************************************** + * 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. If we are using the STMicro DFU bootloader, + * then the vector table will be offset to a different location in FLASH + * and we will need to set the NVIC vector location to this alternative + * location. + */ + + 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; + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* 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 +#ifdef CONFIG_ARMV8M_USEBASEPRI + stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* 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); + up_enable_irq(STM32_IRQ_MEMFAULT); +#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, stm32_busfault, NULL); + irq_attach(STM32_IRQ_USAGEFAULT, stm32_usagefault, NULL); + irq_attach(STM32_IRQ_PENDSV, stm32_pendsv, NULL); + irq_attach(STM32_IRQ_DBGMONITOR, stm32_dbgmonitor, NULL); + irq_attach(STM32_IRQ_RESERVED, stm32_reserved, NULL); +#endif + + stm32_dumpnvic("initial", NR_IRQS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + 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/stm32u5/stm32_lowputc.c b/arch/arm/src/stm32u5/stm32_lowputc.c new file mode 100644 index 0000000000..bc9278e116 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_lowputc.c @@ -0,0 +1,400 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_lowputc.c + * + * 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 "arm_arch.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 */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_LPUART1_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_LPUART1_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR2 +# define STM32_CONSOLE_APBEN RCC_APB1ENR2_LPUART1EN +# define STM32_CONSOLE_BAUD CONFIG_LPUART1_BAUD +# define STM32_CONSOLE_BITS CONFIG_LPUART1_BITS +# define STM32_CONSOLE_PARITY CONFIG_LPUART1_PARITY +# define STM32_CONSOLE_2STOP CONFIG_LPUART1_2STOP +# define STM32_CONSOLE_TX GPIO_LPUART1_TX +# define STM32_CONSOLE_RX GPIO_LPUART1_RX +# ifdef CONFIG_LPUART1_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_LPUART1_RS485_DIR +# if (CONFIG_LPUART1_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART1_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART1_BASE +# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB2ENR +# define STM32_CONSOLE_APBEN RCC_APB2ENR_USART1EN +# define STM32_CONSOLE_BAUD CONFIG_USART1_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART1_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART1_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART1_2STOP +# define STM32_CONSOLE_TX GPIO_USART1_TX +# define STM32_CONSOLE_RX GPIO_USART1_RX +# ifdef CONFIG_USART1_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART1_RS485_DIR +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART2_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR1 +# define STM32_CONSOLE_APBEN RCC_APB1ENR1_USART2EN +# define STM32_CONSOLE_BAUD CONFIG_USART2_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART2_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART2_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART2_2STOP +# define STM32_CONSOLE_TX GPIO_USART2_TX +# define STM32_CONSOLE_RX GPIO_USART2_RX +# ifdef CONFIG_USART2_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART2_RS485_DIR +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_USART3_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR1 +# define STM32_CONSOLE_APBEN RCC_APB1ENR1_USART3EN +# define STM32_CONSOLE_BAUD CONFIG_USART3_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART3_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART3_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART3_2STOP +# define STM32_CONSOLE_TX GPIO_USART3_TX +# define STM32_CONSOLE_RX GPIO_USART3_RX +# ifdef CONFIG_USART3_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART3_RS485_DIR +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART4_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR1 +# define STM32_CONSOLE_APBEN RCC_APB1ENR1_UART4EN +# define STM32_CONSOLE_BAUD CONFIG_UART4_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART4_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART4_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART4_2STOP +# define STM32_CONSOLE_TX GPIO_UART4_TX +# define STM32_CONSOLE_RX GPIO_UART4_RX +# ifdef CONFIG_UART4_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART4_RS485_DIR +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define STM32_CONSOLE_BASE STM32_UART5_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR1 +# define STM32_CONSOLE_APBEN RCC_APB1ENR1_UART5EN +# define STM32_CONSOLE_BAUD CONFIG_UART5_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART5_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART5_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART5_2STOP +# define STM32_CONSOLE_TX GPIO_UART5_TX +# define STM32_CONSOLE_RX GPIO_UART5_RX +# ifdef CONFIG_UART5_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART5_RS485_DIR +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# endif + + /* CR1 settings */ + +# if STM32_CONSOLE_BITS == 9 +# define USART_CR1_M0_VALUE USART_CR1_M0 +# define USART_CR1_M1_VALUE 0 +# elif STM32_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 STM32_CONSOLE_PARITY == 1 /* odd parity */ +# define USART_CR1_PARITY_VALUE (USART_CR1_PCE|USART_CR1_PS) +# elif STM32_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 STM32_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 STM32_USARTDIV8 \ + (((STM32_APBCLOCK << 1) + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) +# define STM32_USARTDIV16 \ + ((STM32_APBCLOCK + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) + + /* Use oversamply by 8 only if the divisor is small. But what is small? */ + +# if STM32_USARTDIV8 > 2000 +# define STM32_BRR_VALUE STM32_USARTDIV16 +# else +# define USE_OVER8 1 +# define STM32_BRR_VALUE \ + ((STM32_USARTDIV8 & 0xfff0) | ((STM32_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 + /* Wait until the TX data register is empty */ + + while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & + USART_ISR_TXE) == 0); +#ifdef STM32_CONSOLE_RS485_DIR + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, + STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Then send the character */ + + putreg32((uint32_t)ch, STM32_CONSOLE_BASE + STM32_USART_TDR_OFFSET); + +#ifdef STM32_CONSOLE_RS485_DIR + while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & + USART_ISR_TC) == 0); + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, + !STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * 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) + /* Enable USART APB1/2 clock */ + + modifyreg32(STM32_CONSOLE_APBREG, 0, STM32_CONSOLE_APBEN); +#endif + + /* Enable the console USART and configure GPIO pins needed for rx/tx. + * + * NOTE: Clocking for selected U[S]ARTs was already provided in + * stm32_rcc.c + */ + +#ifdef STM32_CONSOLE_TX + stm32_configgpio(STM32_CONSOLE_TX); +#endif +#ifdef STM32_CONSOLE_RX + stm32_configgpio(STM32_CONSOLE_RX); +#endif + +#ifdef STM32_CONSOLE_RS485_DIR + stm32_configgpio(STM32_CONSOLE_RS485_DIR); + stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, + !STM32_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Enable and configure the selected console device */ + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Configure CR2 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + cr &= ~USART_CR2_CLRBITS; + cr |= USART_CR2_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + + /* Configure CR1 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + cr &= ~USART_CR1_CLRBITS; + cr |= USART_CR1_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + + /* Configure CR3 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + cr &= ~USART_CR3_CLRBITS; + cr |= USART_CR3_SETBITS; + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + + /* Configure the USART Baud Rate */ + + putreg32(STM32_BRR_VALUE, + STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); + + /* Select oversampling by 8 or by 16 */ + + cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + +#ifdef USE_OVER8 + cr |= USART_CR1_OVER8; +#else + cr &= ~USART_CR1_OVER8; +#endif + + /* Enable Rx, Tx, and the USART */ + + cr |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + +#endif /* HAVE_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} diff --git a/arch/arm/src/stm32u5/stm32_lowputc.h b/arch/arm/src/stm32u5/stm32_lowputc.h new file mode 100644 index 0000000000..f99b25676f --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_lowputc.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_lowputc.h + * + * 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_STM32U5_STM32_LOWPUTC_H +#define __ARCH_ARM_SRC_STM32U5_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_STM32U5_STM32_LOWPUTC_H */ diff --git a/arch/arm/src/stm32u5/stm32_lse.c b/arch/arm/src/stm32u5/stm32_lse.c new file mode 100644 index 0000000000..8afcebed84 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_lse.c @@ -0,0 +1,187 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_lse.c + * + * 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 "arm_arch.h" + +#include "stm32_pwr.h" +#include "stm32_rcc.h" +#include "stm32_waste.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LSERDY_TIMEOUT (500 * CONFIG_BOARD_LOOPSPERMSEC) + +#ifdef CONFIG_STM32U5_RTC_LSECLOCK_START_DRV_CAPABILITY +# if CONFIG_STM32U5_RTC_LSECLOCK_START_DRV_CAPABILITY < 0 || \ + CONFIG_STM32U5_RTC_LSECLOCK_START_DRV_CAPABILITY > 3 +# error "Invalid LSE drive capability setting" +#endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY +static const uint32_t drives[4] = +{ + RCC_BDCR_LSEDRV_LOW, + RCC_BDCR_LSEDRV_MEDLO, + RCC_BDCR_LSEDRV_MEDHI, + RCC_BDCR_LSEDRV_HIGH +}; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rcc_enablelse + * + * Description: + * Enable the External Low-Speed (LSE) oscillator and the LSE system clock. + * + ****************************************************************************/ + +void stm32_rcc_enablelse(void) +{ + bool writable; + uint32_t regval; + volatile int32_t timeout; +#ifdef CONFIG_STM32U5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + volatile int32_t drive = 0; +#endif + + /* Check if both the External Low-Speed (LSE) oscillator and the LSE system + * clock are already running. + */ + + regval = getreg32(STM32_RCC_BDCR); + + if ((regval & (RCC_BDCR_LSEON | RCC_BDCR_LSERDY | + RCC_BDCR_LSESYSEN | RCC_BDCR_LSESYSEN)) != + (RCC_BDCR_LSEON | RCC_BDCR_LSERDY | + RCC_BDCR_LSESYSEN | RCC_BDCR_LSESYSEN)) + { + /* The LSE is in the RTC domain and write access is denied to this + * domain after reset, you have to enable write access using DBP bit in + * the PWR CR register before to configuring the LSE. + */ + + writable = stm32_pwr_enablebkp(true); + + /* Enable the External Low-Speed (LSE) oscillator by setting the LSEON + * bit the RCC BDCR register. + */ + + regval |= RCC_BDCR_LSEON; + +#ifdef CONFIG_STM32U5_RTC_LSECLOCK_START_DRV_CAPABILITY + /* Set start-up drive capability for LSE oscillator. LSE must be OFF + * to change drive strength. + */ + + regval &= ~(RCC_BDCR_LSEDRV_MASK | RCC_BDCR_LSEON); + regval |= CONFIG_STM32U5_RTC_LSECLOCK_START_DRV_CAPABILITY << + RCC_BDCR_LSEDRV_SHIFT; + putreg32(regval, STM32_RCC_BDCR); + regval |= RCC_BDCR_LSEON; +#endif + +#ifdef CONFIG_STM32U5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + do + { + regval &= ~(RCC_BDCR_LSEDRV_MASK | RCC_BDCR_LSEON); + regval |= drives[drive++]; + putreg32(regval, STM32_RCC_BDCR); + regval |= RCC_BDCR_LSEON; +#endif + + putreg32(regval, STM32_RCC_BDCR); + + /* Wait for the LSE clock to be ready (or until a timeout elapsed) + */ + + for (timeout = LSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the LSERDY flag is the set in the BDCR */ + + regval = getreg32(STM32_RCC_BDCR); + + if (regval & RCC_BDCR_LSERDY) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + +#ifdef CONFIG_STM32U5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + if (timeout != 0) + { + break; + } + } + while (drive < sizeof(drives) / sizeof(drives[0])); +#endif + + if (timeout != 0) + { + /* Enable LSE system clock. The LSE system clock seems to provide + * a means to gate the LSE clock distribution to peripherals. It + * must be enabled for MSI PLL mode (syncing the MSI to the LSE). + */ + + regval |= RCC_BDCR_LSESYSEN; + + putreg32(regval, STM32_RCC_BDCR); + + /* Wait for the LSE system clock to be ready */ + + while (!((regval = getreg32(STM32_RCC_BDCR)) & + RCC_BDCR_LSESYSRDY)) + { + stm32_waste(); + } + } + +#ifdef CONFIG_STM32U5_RTC_LSECLOCK_LOWER_RUN_DRV_CAPABILITY + + /* Set running drive capability for LSE oscillator. */ + + regval &= ~RCC_BDCR_LSEDRV_MASK; + regval |= RCC_BDCR_LSEDRV_LOW << RCC_BDCR_LSEDRV_SHIFT; + putreg32(regval, STM32_RCC_BDCR); +#endif + + /* Disable backup domain access if it was disabled on entry */ + + (void)stm32_pwr_enablebkp(writable); + } +} diff --git a/arch/arm/src/stm32u5/stm32_lsi.c b/arch/arm/src/stm32u5/stm32_lsi.c new file mode 100644 index 0000000000..071f1c283f --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_lsi.c @@ -0,0 +1,71 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_lsi.c + * + * 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 "arm_arch.h" +#include "stm32_rcc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rcc_enablelsi + * + * Description: + * Enable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_enablelsi(void) +{ + /* Enable the Internal Low-Speed (LSI) RC Oscillator by setting the LSION + * bit the RCC BDCR register. + */ + + modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_LSION); + + /* Wait for the internal LSI oscillator to be stable. */ + + while ((getreg32(STM32_RCC_BDCR) & RCC_BDCR_LSIRDY) == 0); +} + +/**************************************************************************** + * Name: stm32_rcc_disablelsi + * + * Description: + * Disable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_disablelsi(void) +{ + /* Disable the Internal Low-Speed (LSI) RC Oscillator by resetting the + * LSION bit the RCC BDCR register. + */ + + modifyreg32(STM32_RCC_BDCR, RCC_BDCR_LSION, 0); + + /* LSIRDY should go low after 3 LSI clock cycles */ +} diff --git a/arch/arm/src/stm32u5/stm32_mpuinit.c b/arch/arm/src/stm32u5/stm32_mpuinit.c new file mode 100644 index 0000000000..8acfd881ab --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_mpuinit.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_mpuinit.c + * + * 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 "mpu.h" +#include "stm32_mpuinit.h" + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_ARM_MPU) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MAX +# define MAX(a,b) a > b ? a : b +#endif + +#ifndef MIN +# define MIN(a,b) a < b ? a : b +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only restricted SAM3U + * resources. + * + ****************************************************************************/ + +void stm32_mpuinitialize(void) +{ + uintptr_t datastart = MIN(USERSPACE->us_datastart, USERSPACE->us_bssstart); + uintptr_t dataend = MAX(USERSPACE->us_dataend, USERSPACE->us_bssend); + + DEBUGASSERT(USERSPACE->us_textend >= USERSPACE->us_textstart && + dataend >= datastart); + + /* Show MPU information */ + + mpu_showtype(); + + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +/**************************************************************************** + * Name: stm32_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void stm32_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} + +#endif /* CONFIG_BUILD_PROTECTED && CONFIG_ARM_MPU */ diff --git a/arch/arm/src/stm32u5/stm32_mpuinit.h b/arch/arm/src/stm32u5/stm32_mpuinit.h new file mode 100644 index 0000000000..16c0868976 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_mpuinit.h @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_mpuinit.h + * + * 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_STM32U5_STM32_MPUINIT_H +#define __ARCH_ARM_SRC_STM32U5_STM32_MPUINIT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_mpuinitialize + * + * Description: + * Configure the MPU to permit user-space access to only unrestricted MCU + * resources. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void stm32_mpuinitialize(void); +#else +# define stm32_mpuinitialize() +#endif + +/**************************************************************************** + * Name: stm32_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void stm32_mpu_uheap(uintptr_t start, size_t size); +#else +# define stm32_mpu_uheap(start,size) +#endif + +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_MPUINIT_H */ diff --git a/arch/arm/src/stm32u5/stm32_pwr.c b/arch/arm/src/stm32u5/stm32_pwr.c new file mode 100644 index 0000000000..4994b89e6a --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_pwr.c @@ -0,0 +1,296 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_pwr.c + * + * 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_arch.h" +#include "stm32_pwr.h" +#include "stm32_rcc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PWR_TIMEOUT (10 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline uint16_t stm32_pwr_getreg(uint8_t offset) +{ + return (uint16_t)getreg32(STM32_PWR_BASE + (uint32_t)offset); +} + +static inline void stm32_pwr_putreg(uint8_t offset, uint16_t value) +{ + putreg32((uint32_t)value, STM32_PWR_BASE + (uint32_t)offset); +} + +static inline void stm32_pwr_modifyreg(uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg32(STM32_PWR_BASE + (uint32_t)offset, (uint32_t)clearbits, + (uint32_t)setbits); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: enableclk + * + * Description: + * Enable/disable the clock to the power control peripheral. Enabling must + * be done after the APB1 clock is validly configured, and prior to using + * any functionality controlled by the PWR block (i.e. much of anything + * else provided by this module). + * + * Input Parameters: + * enable - True: enable the clock to the Power control (PWR) block. + * + * Returned Value: + * True: the PWR block was previously enabled. + * + ****************************************************************************/ + +bool stm32_pwr_enableclk(bool enable) +{ + uint32_t regval; + bool wasenabled; + + regval = getreg32(STM32_RCC_AHB3ENR); + wasenabled = ((regval & RCC_AHB3ENR_PWREN) != 0); + + /* Power interface clock enable. */ + + if (wasenabled && !enable) + { + /* Disable power interface clock */ + + regval &= ~RCC_AHB3ENR_PWREN; + putreg32(regval, STM32_RCC_AHB3ENR); + } + else if (!wasenabled && enable) + { + /* Enable power interface clock */ + + regval |= RCC_AHB3ENR_PWREN; + putreg32(regval, STM32_RCC_AHB3ENR); + } + + return wasenabled; +} + +/**************************************************************************** + * Name: stm32_pwr_enablebkp + * + * Description: + * Enables 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) +{ + uint16_t regval; + bool waswritable; + + /* Get the current state of the PWR disable Backup domain register */ + + regval = stm32_pwr_getreg(STM32_PWR_DBPR_OFFSET); + waswritable = ((regval & PWR_DBPR_DBP) != 0); + + /* Enable or disable the ability to write */ + + if (waswritable && !writable) + { + /* Disable backup domain access */ + + regval &= ~PWR_DBPR_DBP; + stm32_pwr_putreg(STM32_PWR_DBPR_OFFSET, regval); + } + else if (!waswritable && writable) + { + /* Enable backup domain access */ + + regval |= PWR_DBPR_DBP; + stm32_pwr_putreg(STM32_PWR_DBPR_OFFSET, regval); + + /* Enable does not happen right away */ + + up_udelay(4); + } + + return waswritable; +} + +/**************************************************************************** + * Name stm32_pwr_adjustvcore + * + * Description: + * Adjusts the voltage used for digital peripherals (V_CORE) before + * raising or after decreasing the system clock frequency. Compare + * [RM0456], section 10.5.4 Dynamic voltage scaling management. + * + * Input Parameters: + * sysclock - The frequency in Hertz the system clock will or has been set + * to. + * + ****************************************************************************/ + +void stm32_pwr_adjustvcore(unsigned sysclock) +{ + volatile int timeout; + uint32_t vos_range; + + /* Select the applicable V_CORE voltage range depending on the new system + * clock frequency. + */ + + DEBUGASSERT(sysclock <= 160000000); + + if (sysclock > 110000000) + { + vos_range = PWR_VOSR_VOS_RANGE1 | PWR_VOSR_BOOSTEN; + } + else if (sysclock > 55000000) + { + vos_range = PWR_VOSR_VOS_RANGE2 | PWR_VOSR_BOOSTEN; + } + else if (sysclock > 25000000) + { + vos_range = PWR_VOSR_VOS_RANGE3; + } + else + { + vos_range = PWR_VOSR_VOS_RANGE4; + } + + modreg32(vos_range, PWR_VOSR_VOS_MASK | PWR_VOSR_BOOSTEN, STM32_PWR_VOSR); + + /* Wait until the new V_CORE voltage range has been applied. */ + + for (timeout = PWR_TIMEOUT; timeout; timeout--) + { + if (getreg32(STM32_PWR_VOSR) & PWR_VOSR_VOSRDY) + { + break; + } + } + + DEBUGASSERT(timeout > 0); + + /* Wait until the voltage level for the currently used VOS is ready. */ + + for (timeout = PWR_TIMEOUT; timeout; timeout--) + { + if (getreg32(STM32_PWR_SVMSR) & PWR_SVMSR_ACTVOSRDY) + { + break; + } + } + + DEBUGASSERT(timeout > 0); +#if 0 + /* Wait until the embedded power distribution (EPOD) booster has been + * enabled, if applicable. + */ + + DEBUGASSERT(timeout > 0); + + if (vos_range & PWR_VOSR_BOOSTEN) + { + for (timeout = PWR_TIMEOUT; timeout; timeout--) + { + if (getreg32(STM32_PWR_VOSR) & PWR_VOSR_BOOSTRDY) + { + break; + } + } + } +#endif + + DEBUGASSERT(timeout > 0); +} + +/**************************************************************************** + * Name stm32_pwr_enable_smps + * + * Description: + * Select between the Low-Drop Out (LDO) or Switched Mode Power Suppy + * (SMPS) regulator. Compare [RM0456], section 10.5.1 SMPS and LDO + * embedded regulators. + * + * Input Parameters: + * enable - If true, the SMPS regulator will be enabled, otherwise the LDO, + * + ****************************************************************************/ + +void stm32_pwr_enablesmps(bool enable) +{ + volatile int timeout; + uint32_t regsel = enable ? PWR_CR3_REGSEL_SMPS : PWR_CR3_REGSEL_LDO; + + /* Select the respective regulator. */ + + modreg32(regsel, PWR_CR3_REGSEL, STM32_PWR_CR3); + + /* Wait until the respective regulator has been activated. */ + + for (timeout = PWR_TIMEOUT; timeout; timeout--) + { + if (enable) + { + if ((getreg32(STM32_PWR_SVMSR) & PWR_SVMSR_REGS) == + PWR_SVMSR_REGS_SMPS) + { + break; + } + } + else + { + if ((getreg32(STM32_PWR_SVMSR) & PWR_SVMSR_REGS) == + PWR_SVMSR_REGS_LDO) + { + break; + } + } + } + + DEBUGASSERT(timeout > 0); +} diff --git a/arch/arm/src/stm32u5/stm32_pwr.h b/arch/arm/src/stm32u5/stm32_pwr.h new file mode 100644 index 0000000000..3b7ea55673 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_pwr.h @@ -0,0 +1,127 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_pwr.h + * + * 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_STM32U5_STM32_PWR_H +#define __ARCH_ARM_SRC_STM32U5_STM32_PWR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "hardware/stm32_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: enableclk + * + * Description: + * Enable/disable the clock to the power control peripheral. Enabling must + * be done after the APB1 clock is validly configured, and prior to using + * any functionality controlled by the PWR block (i.e. much of anything + * else provided by this module). + * + * Input Parameters: + * enable - True: enable the clock to the Power control (PWR) block. + * + * Returned Value: + * True: the PWR block was previously enabled. + * + ****************************************************************************/ + +bool stm32_pwr_enableclk(bool enable); + +/**************************************************************************** + * Name: stm32_pwr_enablebkp + * + * Description: + * Enables write access to the backup domain (RTC registers, RTC backup + * data registers and backup SRAM). Compare [RM0456], section 10.4.7 + * Battery Backup domain, Backup domain access. + * + * 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_adjustvcore + * + * Description: + * Adjusts the voltage used for digital peripherals (V_CORE) before + * raising or after decreasing the system clock frequency. Compare + * [RM0456], section 10.5.4 Dynamic voltage scaling management. + * + * Input Parameters: + * sysclock - The frequency in Hertz the system clock will be raised to. + * + ****************************************************************************/ + +void stm32_pwr_adjustvcore(unsigned sysclock); + +/**************************************************************************** + * Name stm32_pwr_enable_smps + * + * Description: + * Select between the Low-Drop Out (LDO) or Switched Mode Power Suppy + * (SMPS) regulator. Compare [RM0456], section 10.5.1 SMPS and LDO + * embedded regulators. + * + * Input Parameters: + * enable - If true, the SMPS regulator will be enabled, otherwise the LDO, + * + ****************************************************************************/ + +void stm32_pwr_enablesmps(bool enable); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_PWR_H */ diff --git a/arch/arm/src/stm32u5/stm32_rcc.c b/arch/arm/src/stm32u5/stm32_rcc.c new file mode 100644 index 0000000000..184e68577d --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_rcc.c @@ -0,0 +1,236 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_rcc.c + * + * 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 "arm_arch.h" + +#include "chip.h" +#include "stm32_rcc.h" +#include "stm32_flash.h" +#include "stm32.h" +#include "stm32_waste.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 HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name + * + * Description + * The RTC needs to reset the Backup Domain to change RTCSEL and resetting + * the Backup Domain renders to disabling the LSE as consequence. In + * order to avoid resetting the Backup Domain when we already configured + * LSE we will reset the Backup Domain early (here). + * + * Input Parameters + * None + * + * Returned Value + * None + * + ****************************************************************************/ + +#if defined(CONFIG_STM32U5_PWR) && defined(CONFIG_STM32U5_RTC) +static inline void rcc_resetbkp(void) +{ + bool init_stat; + + /* Check if the RTC is already configured */ + + init_stat = stm32_rtc_is_initialized(); + if (!init_stat) + { + uint32_t bkregs[STM32U5_RTC_BKCOUNT]; + int i; + + /* Backup backup-registers before RTC reset. */ + + for (i = 0; i < STM32U5_RTC_BKCOUNT; i++) + { + bkregs[i] = getreg32(STM32U5_RTC_BKR(i)); + } + + /* Enable write access to the backup domain (RTC registers, RTC + * backup data registers and backup SRAM). + */ + + (void)stm32_pwr_enablebkp(true); + + /* We might be changing RTCSEL - to ensure such changes work, we must + * reset the backup domain (having backed up the RTC_MAGIC token) + */ + + modifyreg32(STM32U5_RCC_BDCR, 0, RCC_BDCR_BDRST); + modifyreg32(STM32U5_RCC_BDCR, RCC_BDCR_BDRST, 0); + + /* Restore backup-registers, except RTC related. */ + + for (i = 0; i < STM32U5_RTC_BKCOUNT; i++) + { + if (RTC_MAGIC_REG == STM32U5_RTC_BKR(i)) + { + continue; + } + + putreg32(bkregs[i], STM32U5_RTC_BKR(i)); + } + + (void)stm32_pwr_enablebkp(false); + } +} +#else +# define rcc_resetbkp() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name + * + * Description + * Called to establish the clock settings based on the values in board.h. + * This function (by default) will reset most everything, enable the PLL, + * and enable peripheral clocking for all peripherals enabled in the NuttX + * configuration file. + * + * If CONFIG_ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG is defined, then + * clocking will be enabled by an externally provided, board-specific + * function called stm32_board_clockconfig(). + * + * Input Parameters + * None + * + * Returned Value + * None + * + ****************************************************************************/ + +void stm32_clockconfig(void) +{ +#if 0 + /* Make sure that we are starting in the reset state */ + + rcc_reset(); + + /* Reset backup domain if appropriate */ + + rcc_resetbkp(); +#endif +#if defined(CONFIG_ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in + * board.h + */ + + stm32_stdclockconfig(); + +#endif + + /* Enable peripheral clocking */ + + stm32_rcc_enableperipherals(); +} + +/**************************************************************************** + * Name + * + * 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 + * re-enable/re-start the PLL + * + * This function performs a subset of the operations performed by + * stm32_clockconfig() + * reset the currently enabled peripheral clocks. + * + * If CONFIG_ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG is defined, then + * clocking will be enabled by an externally provided, board-specific + * function called stm32_board_clockconfig(). + * + * Input Parameters + * None + * + * Returned Value + * None + * + ****************************************************************************/ + +#ifdef CONFIG_PM +void stm32_clockenable(void) +{ +#if defined(CONFIG_ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in + * board.h + */ + + stm32_stdclockconfig(); + +#endif +} +#endif diff --git a/arch/arm/src/stm32u5/stm32_rcc.h b/arch/arm/src/stm32u5/stm32_rcc.h new file mode 100644 index 0000000000..0967817c02 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_rcc.h @@ -0,0 +1,236 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_rcc.h + * + * 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_STM32U5_STM32_RCC_H +#define __ARCH_ARM_SRC_STM32U5_STM32_RCC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm_arch.h" +#include "chip.h" + +#if defined(CONFIG_STM32U5_STM32U585XX) +# include "hardware/stm32u585xx_rcc.h" +#else +# error "Unsupported STM32U5 chip" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#elseO +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This symbol references the Cortex-M33 vector table (as positioned by the + * linker script, ld.script or ld.script.dfu. The standard location for the + * vector table is at the beginning of FLASH at address 0x0800:0000. If we + * are using the STMicro DFU bootloader, then the vector table will be offset + * to a different location in FLASH and we will need to set the NVIC vector + * location to this alternative location. + */ + +extern uint32_t _vectors[]; /* See stm32_vectors.S */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_mcoconfig + * + * Description: + * Selects the clock source to output on MCO pin (PA8) for stm32u585xx. + * PA8 should be configured in alternate function mode. + * + * Input Parameters: + * source - One of the RCC_CFGR_MCO definitions from chip/stm32u585xx_rcc.h + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void stm32_mcoconfig(uint32_t source) +{ + uint32_t regval; + + /* Set MCO source */ + + regval = getreg32(STM32_RCC_CFGR1); + regval &= ~(RCC_CFGR1_MCOSEL_MASK); + regval |= (source & RCC_CFGR1_MCOSEL_MASK); + putreg32(regval, STM32_RCC_CFGR1); +} + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * This function (by default) will reset most everything, enable the PLL, + * and enable peripheral clocking for all periperipherals enabled in the + * NuttX configuration file. + * + * If CONFIG_ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG is defined, then + * clocking will be enabled by an externally provided, board-specific + * function called stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void stm32_clockconfig(void); + +/**************************************************************************** + * Name: stm32_board_clockconfig + * + * Description: + * Any STM32U5 board may replace the "standard" board clock configuration + * logic with its own, custom clock configuration logic. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG +void stm32_board_clockconfig(void); +#endif + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * The standard logic to configure the clocks based on settings in board.h. + * Applicable if no custom clock config is provided. This function is + * chip type specific and implemented in corresponding modules such as e.g. + * stm3262xx_rcc.c + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG +void stm32_stdclockconfig(void); +#endif + +/**************************************************************************** + * 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. + * + * If CONFIG_ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG is defined, then + * clocking will be enabled by an externally provided, board-specific + * function called stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_PM +void stm32_clockenable(void); +#endif + +/**************************************************************************** + * Name: stm32_rcc_enablelse + * + * Description: + * Enable the External Low-Speed (LSE) Oscillator. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void stm32_rcc_enablelse(void); + +/**************************************************************************** + * Name: stm32_rcc_enablelsi + * + * Description: + * Enable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_enablelsi(void); + +/**************************************************************************** + * Name: stm32_rcc_disablelsi + * + * Description: + * Disable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32_rcc_disablelsi(void); + +/**************************************************************************** + * Name: stm32_rcc_enableperipherals + * + * Description: + * Enable all the chip peripherals according to configuration. This is + * chip type specific and thus implemented in corresponding modules such as + * e.g. stm3262xx_rcc.c + * + ****************************************************************************/ + +void stm32_rcc_enableperipherals(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_RCC_H */ diff --git a/arch/arm/src/stm32u5/stm32_serial.c b/arch/arm/src/stm32u5/stm32_serial.c new file mode 100644 index 0000000000..91576fb393 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_serial.c @@ -0,0 +1,3249 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_serial.c + * + * 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 + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_uart.h" +#ifdef SERIAL_HAVE_DMA +# include "stm32_dma.h" +#endif +#include "stm32_rcc.h" +#include "arm_arch.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Some sanity checks *******************************************************/ + +/* DMA configuration */ + +/* If DMA is enabled on any USART, then very that other pre-requisites + * have also been selected. + * UART DMA1 DMA2 + * 1 X X + * 2 X + * 3 X + * 4 X + * 5 X + */ + +#ifdef SERIAL_HAVE_DMA + +/* Verify that DMA has been enabled and the DMA channel has been defined. + */ + +# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) +# if !defined(CONFIG_STM32U5_DMA1) && !defined(CONFIG_STM32U5_DMAMUX) +# error STM32U5 USART2/3 receive DMA requires CONFIG_STM32U5_DMA1 +# endif +# endif + +# if defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) +# if !defined(CONFIG_STM32U5_DMA2) && !defined(CONFIG_STM32U5_DMAMUX) +# error STM32U5 UART4/5 receive DMA requires CONFIG_STM32U5_DMA2 +# endif +# endif + +/* Currently RS-485 support cannot be enabled when RXDMA is in use due to + * lack of testing - RS-485 support was developed on STM32F1x + */ + +# if (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ + (defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_RS485)) || \ + (defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_RS485)) || \ + (defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_RS485)) || \ + (defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_RS485)) +# error "RXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART" +# endif + +/* For the L4, there are alternate DMA channels for USART1. + * Logic in the board.h file make the DMA channel selection by defining + * the following in the board.h file. + */ + +# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX) +# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)" +# endif + +/* UART2-5 have no alternate channels without DMAMUX */ + +# ifndef CONFIG_STM32U5_HAVE_DMAMUX +# define DMAMAP_USART2_RX DMACHAN_USART2_RX +# define DMAMAP_USART3_RX DMACHAN_USART3_RX +# define DMAMAP_UART4_RX DMACHAN_UART4_RX +# define DMAMAP_UART5_RX DMACHAN_UART5_RX +# endif + +# if defined(CONFIG_USART2_RXDMA) && !defined(DMAMAP_USART2_RX) +# error "USART2 DMA channel not defined (DMAMAP_USART2_RX)" +# endif + +# if defined(CONFIG_USART3_RXDMA) && !defined(DMAMAP_USART3_RX) +# error "USART3 DMA channel not defined (DMAMAP_USART3_RX)" +# endif + +# if defined(CONFIG_UART4_RXDMA) && !defined(DMAMAP_UART4_RX) +# error "UART4 DMA channel not defined (DMAMAP_UART4_RX)" +# endif + +# if defined(CONFIG_UART5_RXDMA) && !defined(DMAMAP_UART5_RX) +# error "UART5 DMA channel not defined (DMAMAP_UART5_RX)" +# endif + +/* The DMA buffer size when using RX DMA to emulate a FIFO. + * + * When streaming data, the generic serial layer will be called + * every time the FIFO receives half this number of bytes. + * + * If there ever is a STM32U5 with D-cache, the buffer size + * should be an even multiple of ARMV7M_DCACHE_LINESIZE, so that it + * can be individually invalidated. + */ + +# if !defined(CONFIG_STM32U5_SERIAL_RXDMA_BUFFER_SIZE) || \ + CONFIG_STM32U5_SERIAL_RXDMA_BUFFER_SIZE == 0 +# define RXDMA_BUFFER_SIZE 32 +# else +# define RXDMA_BUFFER_SIZE ((CONFIG_STM32U5_SERIAL_RXDMA_BUFFER_SIZE + 31) & ~31) +# endif + +/* DMA priority */ + +# ifndef CONFIG_USART_DMAPRIO +# define CONFIG_USART_DMAPRIO DMA_CCR_PRIMED +# endif +# if (CONFIG_USART_DMAPRIO & ~DMA_CCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_USART_DMAPRIO" +# endif + +/* DMA control words */ + +# define SERIAL_DMA_CONTROL_WORD \ + (DMA_CCR_CIRC | \ + DMA_CCR_MINC | \ + DMA_CCR_PSIZE_8BITS | \ + DMA_CCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO) +# ifdef CONFIG_SERIAL_IFLOWCONTROL +# define SERIAL_DMA_IFLOW_CONTROL_WORD \ + (DMA_CCR_MINC | \ + DMA_CCR_PSIZE_8BITS | \ + DMA_CCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO) +# endif + +#endif + +/* Power management definitions */ + +#if defined(CONFIG_PM) && !defined(CONFIG_STM32U5_PM_SERIAL_ACTIVITY) +# define CONFIG_STM32U5_PM_SERIAL_ACTIVITY 10 +#endif +#if defined(CONFIG_PM) +# define PM_IDLE_DOMAIN 0 /* Revisit */ +#endif + +/* 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_STM32U5_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_IFLOWCONTROL + bool iflow; /* input flow control (RTS) enabled */ +#endif +#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_IFLOWCONTROL + const bool iflow; /* input flow control (RTS) enabled */ +#endif +#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 + +#ifdef SERIAL_HAVE_DMA + const unsigned int rxdma_channel; /* DMA channel assigned */ +#endif + + /* RX DMA state */ + +#ifdef SERIAL_HAVE_DMA + DMA_HANDLE rxdma; /* currently-open receive DMA stream */ + bool rxenable; /* DMA-based reception en/disable */ +#ifdef CONFIG_PM + bool rxdmasusp; /* Rx DMA suspended */ +#endif + uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */ + char *const rxfifo; /* Receive DMA buffer */ +#endif + +#ifdef HAVE_RS485 + const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ + const bool rs485_dir_polarity; /* U[S]ART RS-485 DIR pin state for TX enabled */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_UART_CONFIG +static void stm32serial_setformat(FAR struct uart_dev_s *dev); +#endif +static int stm32serial_setup(FAR struct uart_dev_s *dev); +static void stm32serial_shutdown(FAR struct uart_dev_s *dev); +static int stm32serial_attach(FAR struct uart_dev_s *dev); +static void stm32serial_detach(FAR struct uart_dev_s *dev); +static int stm32serial_interrupt(int irq, FAR void *context, + FAR void *arg); +static int stm32serial_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +#ifndef SERIAL_HAVE_ONLY_DMA +static int stm32serial_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status); +static void stm32serial_rxint(FAR struct uart_dev_s *dev, bool enable); +static bool stm32serial_rxavailable(FAR struct uart_dev_s *dev); +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool stm32serial_rxflowcontrol(FAR struct uart_dev_s *dev, + unsigned int nbuffered, bool upper); +#endif +static void stm32serial_send(FAR struct uart_dev_s *dev, int ch); +static void stm32serial_txint(FAR struct uart_dev_s *dev, bool enable); +static bool stm32serial_txready(FAR struct uart_dev_s *dev); + +#ifdef SERIAL_HAVE_DMA +static int stm32serial_dmasetup(FAR struct uart_dev_s *dev); +static void stm32serial_dmashutdown(FAR struct uart_dev_s *dev); +static int stm32serial_dmareceive(FAR struct uart_dev_s *dev, + FAR unsigned int *status); +static void stm32serial_dmareenable(struct stm32_serial_s *priv); +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool stm32serial_dmaiflowrestart(struct stm32_serial_s *priv); +#endif +static void stm32serial_dmarxint(FAR struct uart_dev_s *dev, bool enable); +static bool stm32serial_dmarxavailable(struct uart_dev_s *dev); + +static void stm32serial_dmarxcallback(DMA_HANDLE handle, uint8_t status, + FAR void *arg); +#endif + +#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(FAR struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +static int stm32serial_pmprepare(FAR struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +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, +}; +#endif + +#ifdef SERIAL_HAVE_DMA +static const struct uart_ops_s g_uart_dma_ops = +{ + .setup = stm32serial_dmasetup, + .shutdown = stm32serial_dmashutdown, + .attach = stm32serial_attach, + .detach = stm32serial_detach, + .ioctl = stm32serial_ioctl, + .receive = stm32serial_dmareceive, + .rxint = stm32serial_dmarxint, + .rxavailable = stm32serial_dmarxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = stm32serial_rxflowcontrol, +#endif + .send = stm32serial_send, + .txint = stm32serial_txint, + .txready = stm32serial_txready, + .txempty = stm32serial_txready, +}; +#endif + +/* I/O buffers */ + +#ifdef CONFIG_STM32U5_LPUART1_SERIALDRIVER +static char g_lpuart1rxbuffer[CONFIG_LPUART1_RXBUFSIZE]; +static char g_lpuart1txbuffer[CONFIG_LPUART1_TXBUFSIZE]; +# ifdef CONFIG_LPUART1_RXDMA +static char g_lpuart1rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32U5_USART1_SERIALDRIVER +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +# ifdef CONFIG_USART1_RXDMA +static char g_usart1rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32U5_USART2_SERIALDRIVER +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +# ifdef CONFIG_USART2_RXDMA +static char g_usart2rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32U5_USART3_SERIALDRIVER +static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; +# ifdef CONFIG_USART3_RXDMA +static char g_usart3rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32U5_UART4_SERIALDRIVER +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +# ifdef CONFIG_UART4_RXDMA +static char g_uart4rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32U5_UART5_SERIALDRIVER +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +# ifdef CONFIG_UART5_RXDMA +static char g_uart5rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +/* This describes the state of the STM32 USART1 ports. */ + +#ifdef CONFIG_STM32U5_LPUART1_SERIALDRIVER +static struct stm32_serial_s g_lpuart1priv = +{ + .dev = + { +#if CONSOLE_UART == 1 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_LPUART1_RXBUFSIZE, + .buffer = g_lpuart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_LPUART1_TXBUFSIZE, + .buffer = g_lpuart1txbuffer, + }, +#ifdef CONFIG_LPUART1_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_lpuart1priv, + }, + + .irq = STM32_IRQ_LPUART1, + .parity = CONFIG_LPUART1_PARITY, + .bits = CONFIG_LPUART1_BITS, + .stopbits2 = CONFIG_LPUART1_2STOP, + .baud = CONFIG_LPUART1_BAUD, + .apbclock = STM32_PCLK2_FREQUENCY, + .usartbase = STM32_LPUART1_BASE, + .tx_gpio = GPIO_LPUART1_TX, + .rx_gpio = GPIO_LPUART1_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART1_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_LPUART1_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART1_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_LPUART1_RTS, +#endif +#ifdef CONFIG_LPUART1_RXDMA + .rxdma_channel = DMAMAP_LPUSART_RX, + .rxfifo = g_lpuart1rxfifo, +#endif + +#ifdef CONFIG_USART1_RS485 + .rs485_dir_gpio = GPIO_LPUART1_RS485_DIR, +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +#ifdef CONFIG_STM32U5_USART1_SERIALDRIVER +static struct stm32_serial_s g_usart1priv = +{ + .dev = + { +#if CONSOLE_UART == 2 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, +#ifdef CONFIG_USART1_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .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_PCLK2_FREQUENCY, + .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 +#ifdef CONFIG_USART1_RXDMA + .rxdma_channel = DMAMAP_USART1_RX, + .rxfifo = g_usart1rxfifo, +#endif + +#ifdef CONFIG_USART1_RS485 + .rs485_dir_gpio = GPIO_USART1_RS485_DIR, +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART2 port. */ + +#ifdef CONFIG_STM32U5_USART2_SERIALDRIVER +static struct stm32_serial_s g_usart2priv = +{ + .dev = + { +#if CONSOLE_UART == 3 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, +#ifdef CONFIG_USART2_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart2priv, + }, + + .irq = STM32_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, + .baud = CONFIG_USART2_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_USART2_BASE, + .tx_gpio = GPIO_USART2_TX, + .rx_gpio = GPIO_USART2_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART2_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART2_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART2_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART2_RTS, +#endif +#ifdef CONFIG_USART2_RXDMA + .rxdma_channel = DMAMAP_USART2_RX, + .rxfifo = g_usart2rxfifo, +#endif + +#ifdef CONFIG_USART2_RS485 + .rs485_dir_gpio = GPIO_USART2_RS485_DIR, +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART3 port. */ + +#ifdef CONFIG_STM32U5_USART3_SERIALDRIVER +static struct stm32_serial_s g_usart3priv = +{ + .dev = + { +#if CONSOLE_UART == 4 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_usart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_usart3txbuffer, + }, +#ifdef CONFIG_USART3_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart3priv, + }, + + .irq = STM32_IRQ_USART3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, + .baud = CONFIG_USART3_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_USART3_BASE, + .tx_gpio = GPIO_USART3_TX, + .rx_gpio = GPIO_USART3_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART3_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART3_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART3_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART3_RTS, +#endif +#ifdef CONFIG_USART3_RXDMA + .rxdma_channel = DMAMAP_USART3_RX, + .rxfifo = g_usart3rxfifo, +#endif + +#ifdef CONFIG_USART3_RS485 + .rs485_dir_gpio = GPIO_USART3_RS485_DIR, +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART4 port. */ + +#ifdef CONFIG_STM32U5_UART4_SERIALDRIVER +static struct stm32_serial_s g_uart4priv = +{ + .dev = + { +#if CONSOLE_UART == 5 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, +#ifdef CONFIG_UART4_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart4priv, + }, + + .irq = STM32_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART4_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART4_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART4_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART4_RTS, +#endif + .baud = CONFIG_UART4_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART4_BASE, + .tx_gpio = GPIO_UART4_TX, + .rx_gpio = GPIO_UART4_RX, +#ifdef CONFIG_UART4_RXDMA + .rxdma_channel = DMAMAP_UART4_RX, + .rxfifo = g_uart4rxfifo, +#endif + +#ifdef CONFIG_UART4_RS485 + .rs485_dir_gpio = GPIO_UART4_RS485_DIR, +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART5 port. */ + +#ifdef CONFIG_STM32U5_UART5_SERIALDRIVER +static struct stm32_serial_s g_uart5priv = +{ + .dev = + { +#if CONSOLE_UART == 6 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, +#ifdef CONFIG_UART5_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart5priv, + }, + + .irq = STM32_IRQ_UART5, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stopbits2 = CONFIG_UART5_2STOP, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART5_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART5_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART5_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART5_RTS, +#endif + .baud = CONFIG_UART5_BAUD, + .apbclock = STM32_PCLK1_FREQUENCY, + .usartbase = STM32_UART5_BASE, + .tx_gpio = GPIO_UART5_TX, + .rx_gpio = GPIO_UART5_RX, +#ifdef CONFIG_UART5_RXDMA + .rxdma_channel = DMAMAP_UART5_RX, + .rxfifo = g_uart5rxfifo, +#endif + +#ifdef CONFIG_UART5_RS485 + .rs485_dir_gpio = GPIO_UART5_RS485_DIR, +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This table lets us iterate over the configured USARTs */ + +FAR static struct stm32_serial_s * const + g_uart_devs[STM32_NLPUART + STM32_NUSART + STM32_NUART] = +{ +#ifdef CONFIG_STM32U5_LPUART1_SERIALDRIVER + [0] = &g_lpuart1priv, +#endif +#ifdef CONFIG_STM32U5_USART1_SERIALDRIVER + [1] = &g_usart1priv, +#endif +#ifdef CONFIG_STM32U5_USART2_SERIALDRIVER + [2] = &g_usart2priv, +#endif +#ifdef CONFIG_STM32U5_USART3_SERIALDRIVER + [3] = &g_usart3priv, +#endif +#ifdef CONFIG_STM32U5_UART4_SERIALDRIVER + [4] = &g_uart4priv, +#endif +#ifdef CONFIG_STM32U5_UART5_SERIALDRIVER + [5] = &g_uart5priv, +#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(FAR struct stm32_serial_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: stm32serial_putreg + ****************************************************************************/ + +static inline +void stm32serial_putreg(FAR struct stm32_serial_s *priv, + int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: stm32serial_setusartint + ****************************************************************************/ + +static inline +void stm32serial_setusartint(FAR 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: up_restoreusartint + ****************************************************************************/ + +static void stm32serial_restoreusartint(FAR struct stm32_serial_s *priv, + uint16_t ie) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + stm32serial_setusartint(priv, ie); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32serial_disableusartint + ****************************************************************************/ + +static void stm32serial_disableusartint(FAR struct stm32_serial_s *priv, + FAR uint16_t *ie) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + 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 (only 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); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32serial_dmanextrx + * + * Description: + * Returns the index into the RX FIFO where the DMA will place the next + * byte that it receives. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int stm32serial_dmanextrx(FAR struct stm32_serial_s *priv) +{ + size_t dmaresidual; + + dmaresidual = stm32_dmaresidual(priv->rxdma); + + return (RXDMA_BUFFER_SIZE - (int)dmaresidual); +} +#endif + +/**************************************************************************** + * Name: stm32serial_setformat + * + * Description: + * Set the serial line format and speed. + * + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_UART_CONFIG +static void stm32serial_setformat(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + uint32_t regval; + + /* This first implementation is for U[S]ARTs that support oversampling + * by 8 in additional to the standard oversampling by 16. + */ + + uint32_t usartdiv8; + uint32_t cr1; + uint32_t brr; + + /* 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 oversamply by 8 only if the 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, OR + */ + + 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_STM32U5_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) +{ + FAR struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; +#ifdef SERIAL_HAVE_DMA + bool dmarestored = false; +#endif + + 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); + +#ifdef SERIAL_HAVE_DMA + if (priv->dev.ops == &g_uart_dma_ops && !priv->rxdmasusp) + { +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && priv->rxdmanext == RXDMA_BUFFER_SIZE) + { + /* Rx DMA in non-circular iflow mode and already stopped + * at end of DMA buffer. No need to suspend. + */ + } + else +#endif + { + /* Suspend Rx DMA. */ + + stm32_dmastop(priv->rxdma); + priv->rxdmasusp = true; + } + } +#endif + } + else + { +#ifdef SERIAL_HAVE_DMA + if (priv->dev.ops == &g_uart_dma_ops && priv->rxdmasusp) + { +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + (void)stm32serial_dmaiflowrestart(priv); + } + else +#endif + { + /* This USART does not have HW flow-control. Unconditionally + * re-enable DMA (might loss unprocessed bytes received + * to DMA buffer before suspending). + */ + + stm32serial_dmareenable(priv); + priv->rxdmasusp = false; + } + + dmarestored = true; + } +#endif + + /* 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 + } + +#ifdef SERIAL_HAVE_DMA + if (dmarestored) + { + irqstate_t flags; + + flags = enter_critical_section(); + + /* Perform initial Rx DMA buffer fetch to wake-up serial device + * activity. + */ + + if (priv->rxdma != NULL) + { + stm32serial_dmarxcallback(priv->rxdma, 0, priv); + } + + leave_critical_section(flags); + } +#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 < STM32_NLPUART + STM32_NUSART + STM32_NUART; 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(FAR struct uart_dev_s *dev, bool on) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + uint32_t rcc_en; + uint32_t regaddr; + + /* Determine which USART to configure */ + + switch (priv->usartbase) + { + default: + return; +#ifdef CONFIG_STM32U5_LPUART1_SERIALDRIVER + case STM32_LPUART1_BASE: + rcc_en = RCC_APB1ENR2_LPUART1EN; + regaddr = STM32_RCC_APB1ENR2; + break; +#endif +#ifdef CONFIG_STM32U5_USART1_SERIALDRIVER + case STM32_USART1_BASE: + rcc_en = RCC_APB2ENR_USART1EN; + regaddr = STM32_RCC_APB2ENR; + break; +#endif +#ifdef CONFIG_STM32U5_USART2_SERIALDRIVER + case STM32_USART2_BASE: + rcc_en = RCC_APB1ENR1_USART2EN; + regaddr = STM32_RCC_APB1ENR1; + break; +#endif +#ifdef CONFIG_STM32U5_USART3_SERIALDRIVER + case STM32_USART3_BASE: + rcc_en = RCC_APB1ENR1_USART3EN; + regaddr = STM32_RCC_APB1ENR1; + break; +#endif +#ifdef CONFIG_STM32U5_UART4_SERIALDRIVER + case STM32_UART4_BASE: + rcc_en = RCC_APB1ENR1_UART4EN; + regaddr = STM32_RCC_APB1ENR1; + break; +#endif +#ifdef CONFIG_STM32U5_UART5_SERIALDRIVER + case STM32_UART5_BASE: + rcc_en = RCC_APB1ENR1_UART5EN; + regaddr = STM32_RCC_APB1ENR1; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for USART */ + + if (on) + { + modifyreg32(regaddr, 0, rcc_en); + } + else + { + modifyreg32(regaddr, rcc_en, 0); + } +} + +/**************************************************************************** + * 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(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR 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_STM32U5_FLOWCONTROL_BROKEN + /* Instead of letting hw manage this pin, we will bitbang */ + + config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; +#endif + stm32_configgpio(config); + } +#endif + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32_configgpio(priv->rs485_dir_gpio); + stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + } +#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 TE, REm and all interrupt enable bits */ + + regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + regval &= ~(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); + 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_dmasetup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int stm32serial_dmasetup(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + int result; + uint32_t regval; + + /* Do the basic UART setup first, unless we are the console */ + + if (!dev->isconsole) + { + result = stm32serial_setup(dev); + if (result != OK) + { + return result; + } + } + + /* Acquire the DMA channel. This should always succeed. */ + + priv->rxdma = stm32_dmachannel(priv->rxdma_channel); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Configure for non-circular DMA reception into the RX FIFO */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + } + else +#endif + { + /* Configure for circular DMA reception into the RX FIFO */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_CONTROL_WORD); + } + + /* Reset our DMA shadow pointer to match the address just + * programmed above. + */ + + priv->rxdmanext = 0; + + /* Enable receive DMA for the UART */ + + regval = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); + regval |= USART_CR3_DMAR; + stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Start the DMA channel, and arrange for callbacks at the full point + * in the FIFO. After buffer gets full, hardware flow-control kicks + * in and DMA transfer is stopped. + */ + + stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, + (void *)priv, false); + } + else +#endif + { + /* Start the DMA channel, and arrange for callbacks at the half and + * full points in the FIFO. This ensures that we have half a FIFO + * worth of time to claim bytes before they are overwritten. + */ + + stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, + (void *)priv, true); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32serial_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void stm32serial_shutdown(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR 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 device? If not, + * then this may need to be a configuration option. + */ + + stm32_unconfiggpio(priv->tx_gpio); + 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 + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32_unconfiggpio(priv->rs485_dir_gpio); + } +#endif +} + +/**************************************************************************** + * Name: stm32serial_dmashutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void stm32serial_dmashutdown(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + + /* Perform the normal UART shutdown */ + + stm32serial_shutdown(dev); + + /* Stop the DMA channel */ + + stm32_dmastop(priv->rxdma); + + /* Release the DMA channel */ + + stm32_dmafree(priv->rxdma); + priv->rxdma = NULL; +} +#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(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR 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(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR 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 received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int stm32serial_interrupt(int irq, FAR void *context, FAR void *arg) +{ + FAR struct stm32_serial_s *priv = (FAR 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_STM32U5_PM_SERIAL_ACTIVITY > 0 + pm_activity(PM_IDLE_DOMAIN, CONFIG_STM32U5_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 (only 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. + */ + +#ifdef HAVE_RS485 + /* Transmission of whole buffer is over - TC is set, TXEIE is cleared. + * Note - this should be first, to have the most recent TC bit value + * from SR register - sending data affects TC, but without refresh we + * will not know that... + */ + + if ((priv->sr & USART_ISR_TC) != 0 && + (priv->ie & USART_CR1_TCIE) != 0 && + (priv->ie & USART_CR1_TXEIE) == 0) + { + stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + stm32serial_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); + } +#endif + + /* 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_recvchards of 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(FAR struct file *filep, int cmd, + unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + FAR struct inode *inode = filep->f_inode; + FAR struct uart_dev_s *dev = inode->i_private; +#endif +#if defined(CONFIG_SERIAL_TERMIOS) + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + FAR struct stm32_serial_s *user; + + user = (FAR struct stm32_serial_s *)arg; + + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct stm32_serial_s)); + } + } + break; +#endif + +#ifdef CONFIG_STM32U5_USART_SINGLEWIRE + case TIOCSSINGLEWIRE: + { + uint32_t cr1; + uint32_t cr1_ue; + irqstate_t flags; + + flags = enter_critical_section(); + + /* Get the original state of UE */ + + cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + cr1_ue = cr1 & USART_CR1_UE; + cr1 &= ~USART_CR1_UE; + + /* Disable UE, HDSEL can only be written when UE=0 */ + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); + + /* Change the TX port to be open-drain/push-pull and enable/disable + * half-duplex mode. + */ + + uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); + + if ((arg & SER_SINGLEWIRE_ENABLED) != 0) + { + uint32_t gpio_val = GPIO_OPENDRAIN; + + if ((arg & SER_SINGLEWIRE_PULL_MASK) == SER_SINGLEWIRE_PULLUP) + { + gpio_val |= GPIO_PULLUP; + } + else + { + gpio_val |= GPIO_FLOAT; + } + + if ((arg & SER_SINGLEWIRE_PULL_MASK) == SER_SINGLEWIRE_PULLDOWN) + { + gpio_val |= GPIO_PULLDOWN; + } + else + { + gpio_val |= GPIO_FLOAT; + } + + stm32_configgpio((priv->tx_gpio & + ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | + gpio_val); + + cr |= USART_CR3_HDSEL; + } + else + { + stm32_configgpio((priv->tx_gpio & + ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | + GPIO_PUSHPULL); + cr &= ~USART_CR3_HDSEL; + } + + stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, cr); + + /* Re-enable UE if appropriate */ + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); + leave_critical_section(flags); + } + break; +#endif + +#ifdef CONFIG_STM32U5_USART_INVERT + case TIOCSINVERT: + { + uint32_t cr1; + uint32_t cr1_ue; + irqstate_t flags; + + flags = enter_critical_section(); + + /* Get the original state of UE */ + + cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + cr1_ue = cr1 & USART_CR1_UE; + cr1 &= ~USART_CR1_UE; + + /* Disable UE, {R,T}XINV can only be written when UE=0 */ + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); + + /* Enable/disable signal inversion. */ + + uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); + + if (arg & SER_INVERT_ENABLED_RX) + { + cr |= USART_CR2_RXINV; + } + else + { + cr &= ~USART_CR2_RXINV; + } + + if (arg & SER_INVERT_ENABLED_TX) + { + cr |= USART_CR2_TXINV; + } + else + { + cr &= ~USART_CR2_TXINV; + } + + stm32serial_putreg(priv, STM32_USART_CR2_OFFSET, cr); + + /* Re-enable UE if appropriate */ + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); + leave_critical_section(flags); + } + break; +#endif + +#ifdef CONFIG_STM32U5_USART_SWAP + case TIOCSSWAP: + { + uint32_t cr1; + uint32_t cr1_ue; + irqstate_t flags; + + flags = enter_critical_section(); + + /* Get the original state of UE */ + + cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + cr1_ue = cr1 & USART_CR1_UE; + cr1 &= ~USART_CR1_UE; + + /* Disable UE, SWAP can only be written when UE=0 */ + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); + + /* Enable/disable Swap mode. */ + + uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); + + if (arg == SER_SWAP_ENABLED) + { + cr |= USART_CR2_SWAP; + } + else + { + cr &= ~USART_CR2_SWAP; + } + + stm32serial_putreg(priv, STM32_USART_CR2_OFFSET, cr); + + /* Re-enable UE if appropriate */ + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); + leave_critical_section(flags); + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + FAR struct termios *termiosp = (FAR 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; + + /* TODO: CCTS_IFLOW, CCTS_OFLOW */ + } + break; + + case TCSETS: + { + FAR struct termios *termiosp = (FAR 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 */ + +#ifdef CONFIG_STM32U5_USART_BREAKS +# ifdef CONFIG_STM32U5_SERIALBRK_BSDCOMPAT + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags; + uint32_t tx_break; + + flags = enter_critical_section(); + + /* Disable any further tx activity */ + + priv->ie |= USART_CR1_IE_BREAK_INPROGRESS; + + stm32serial_txint(dev, false); + + /* Configure TX as a GPIO output pin and Send a break signal */ + + tx_break = GPIO_OUTPUT | + (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio); + stm32_configgpio(tx_break); + + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + + flags = enter_critical_section(); + + /* Configure TX back to U(S)ART */ + + stm32_configgpio(priv->tx_gpio); + + priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS; + + /* Enable further tx activity */ + + stm32serial_txint(dev, true); + + leave_critical_section(flags); + } + break; +# else + case TIOCSBRK: /* No BSD compatibility: Turn break on for M bit times */ + { + uint32_t cr1; + irqstate_t flags; + + flags = enter_critical_section(); + cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, + cr1 | USART_CR1_SBK); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* No BSD compatibility: May turn off break too soon */ + { + uint32_t cr1; + irqstate_t flags; + + flags = enter_critical_section(); + cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, + cr1 & ~USART_CR1_SBK); + leave_critical_section(flags); + } + break; +# endif +#endif + + 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'. + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static int stm32serial_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status) +{ + FAR struct stm32_serial_s *priv = + (FAR 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 plux error information. Return those in status */ + + *status = priv->sr << 16 | rdr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return rdr & 0xff; +} +#endif + +/**************************************************************************** + * Name: stm32serial_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static void stm32serial_rxint(FAR struct uart_dev_s *dev, bool enable) +{ + FAR struct stm32_serial_s *priv = + (FAR 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); +} +#endif + +/**************************************************************************** + * Name: stm32serial_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static bool stm32serial_rxavailable(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + + return ((stm32serial_getreg(priv, STM32_USART_ISR_OFFSET) & + USART_ISR_RXNE) != 0); +} +#endif + +/**************************************************************************** + * 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 + * + * Input Parameters: + * dev - UART device instance + * nbuffered - the number of characters currently buffered + * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is + * not defined the value will be 0 for an empty buffer or the + * defined buffer size for a full buffer) + * upper - true indicates the upper watermark was crossed where + * false indicates the lower watermark has been crossed + * + * Returned Value: + * true if RX flow control activated. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool stm32serial_rxflowcontrol(FAR struct uart_dev_s *dev, + unsigned int nbuffered, bool upper) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + +#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && \ + defined(CONFIG_STM32U5_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_dmareceive + * + * 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'. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int stm32serial_dmareceive(FAR struct uart_dev_s *dev, + FAR unsigned int *status) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + int c = 0; + + if (stm32serial_dmanextrx(priv) != priv->rxdmanext) + { + c = priv->rxfifo[priv->rxdmanext]; + + priv->rxdmanext++; + if (priv->rxdmanext == RXDMA_BUFFER_SIZE) + { +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* RX DMA buffer full. RX paused, RTS line pulled up to prevent + * more input data from other end. + */ + } + else +#endif + { + priv->rxdmanext = 0; + } + } + } + + return c; +} +#endif + +/**************************************************************************** + * Name: stm32serial_dmareenable + * + * Description: + * Call to re-enable RX DMA. + * + ****************************************************************************/ + +#if defined(SERIAL_HAVE_DMA) +static void stm32serial_dmareenable(FAR struct stm32_serial_s *priv) +{ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Configure for non-circular DMA reception into the RX FIFO */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + } + else +#endif + { + /* Configure for circular DMA reception into the RX FIFO */ + + stm32_dmasetup(priv->rxdma, + priv->usartbase + STM32_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_CONTROL_WORD); + } + + /* Reset our DMA shadow pointer to match the address just + * programmed above. + */ + + priv->rxdmanext = 0; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Start the DMA channel, and arrange for callbacks at the full point + * in the FIFO. After buffer gets full, hardware flow-control kicks + * in and DMA transfer is stopped. + */ + + stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, + (void *)priv, false); + } + else +#endif + { + /* Start the DMA channel, and arrange for callbacks at the half and + * full points in the FIFO. This ensures that we have half a FIFO + * worth of time to claim bytes before they are overwritten. + */ + + stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, + (void *)priv, true); + } + +#ifdef CONFIG_PM + /* Clear DMA suspended flag. */ + + priv->rxdmasusp = false; +#endif +} +#endif + +/**************************************************************************** + * Name: stm32serial_dmaiflowrestart + * + * Description: + * Call to restart RX DMA for input flow-controlled USART + * + ****************************************************************************/ + +#if defined(SERIAL_HAVE_DMA) && defined(CONFIG_SERIAL_IFLOWCONTROL) +static bool stm32serial_dmaiflowrestart(struct stm32_serial_s *priv) +{ + if (!priv->rxenable) + { + /* Rx not enabled by upper layer. */ + + return false; + } + + if (priv->rxdmanext != RXDMA_BUFFER_SIZE) + { +#ifdef CONFIG_PM + if (priv->rxdmasusp) + { + /* Rx DMA in suspended state. */ + + if (stm32serial_dmarxavailable(&priv->dev)) + { + /* DMA buffer has unprocessed data, do not re-enable yet. */ + + return false; + } + } + else +#endif + { + return false; + } + } + + /* DMA is stopped or suspended and DMA buffer does not have pending data, + * re-enabling without data loss is now safe. + */ + + stm32serial_dmareenable(priv); + + return true; +} +#endif + +/**************************************************************************** + * Name: stm32serial_dmarxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void stm32serial_dmarxint(FAR struct uart_dev_s *dev, bool enable) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + + /* En/disable DMA reception. + * + * Note that it is not safe to check for available bytes and immediately + * pass them to uart_recvchars as that could potentially recurse back + * to us again. Instead, bytes must wait until the next up_dma_poll or + * DMA event. + */ + + priv->rxenable = enable; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Re-enable RX DMA. */ + + (void)stm32serial_dmaiflowrestart(priv); + } +#endif +} +#endif + +/**************************************************************************** + * Name: stm32serial_dmarxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static bool stm32serial_dmarxavailable(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + + /* Compare our receive pointer to the current DMA pointer, if they + * do not match, then there are bytes to be received. + */ + + return (stm32serial_dmanextrx(priv) != priv->rxdmanext); +} +#endif + +/**************************************************************************** + * Name: stm32serial_send + * + * Description: + * This method will send one byte on the USART + * + ****************************************************************************/ + +static void stm32serial_send(FAR struct uart_dev_s *dev, int ch) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); + } +#endif + + 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(FAR struct uart_dev_s *dev, bool enable) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + irqstate_t flags; + + /* USART transmit interrupts: + * + * Enable Status Meaning Usage + * --------------- ------------- ---------------------------- ------------- + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (only 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; + + /* If RS-485 is supported on this U[S]ART, then also enable the + * transmission complete interrupt. + */ + +# ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + ie |= USART_CR1_TCIE; + } +# endif + +# ifdef CONFIG_STM32U5_SERIALBRK_BSDCOMPAT + if (priv->ie & USART_CR1_IE_BREAK_INPROGRESS) + { + 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(FAR struct uart_dev_s *dev) +{ + FAR struct stm32_serial_s *priv = + (FAR struct stm32_serial_s *)dev->priv; + + return ((stm32serial_getreg(priv, STM32_USART_ISR_OFFSET) & + USART_ISR_TXE) != 0); +} + +/**************************************************************************** + * Name: stm32serial_dmarxcallback + * + * Description: + * This function checks the current DMA state and calls the generic + * serial stack when bytes appear to be available. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void stm32serial_dmarxcallback(DMA_HANDLE handle, uint8_t status, + FAR void *arg) +{ + FAR struct stm32_serial_s *priv = (FAR struct stm32_serial_s *)arg; + + if (priv->rxenable && stm32serial_dmarxavailable(&priv->dev)) + { + uart_recvchars(&priv->dev); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Re-enable RX DMA. */ + + (void)stm32serial_dmaiflowrestart(priv); + } +#endif + } + + /* Get the masked USART status word to check and clear error flags. + * + * When wake-up from low power mode was not fast enough, UART is resumed + * too late and sometimes exactly when character was coming over UART, + * resulting to frame error. + * If error flag is not cleared, Rx DMA will be stuck. Clearing errors + * will release Rx DMA. + */ + + priv->sr = stm32serial_getreg(priv, STM32_USART_ISR_OFFSET); + + if ((priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) != 0) + { + stm32serial_putreg(priv, STM32_USART_ICR_OFFSET, + (USART_ICR_NCF | USART_ICR_ORECF | + USART_ICR_FECF)); + } +} +#endif + +/**************************************************************************** + * 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. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * None - The driver already agreed to transition to the low power + * consumption state when when it returned OK to the prepare() call. + * + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void stm32serial_pmnotify(FAR 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: + { + /* TODO: Alternative configuration and logic for enabling serial in + * Stop 1 mode with HSI16 missing. Current logic allows + * suspending serial peripherals for Stop 0/1/2 when serial + * Rx/Tx buffers are empty (checked in pmprepare). + */ + + 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. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * Zero - (OK) means the event was successfully processed and that the + * driver is prepared for the PM state change. + * + * Non-zero - means that the driver is not prepared to perform the tasks + * needed achieve this power setting and will cause the state + * change to be aborted. NOTE: The prepare() method will also + * be called when reverting from lower back to higher power + * consumption modes (say because another driver refused a + * lower power state change). Drivers are not permitted to + * return non-zero values when reverting back to higher power + * consumption modes! + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static int stm32serial_pmprepare(FAR 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: + +#ifdef SERIAL_HAVE_DMA + /* Flush Rx DMA buffers before checking state of serial device + * buffers. + */ + + stm32_serial_dma_poll(); +#endif + + /* Check if any of the active ports have data pending on Tx/Rx + * buffers. + */ + + for (n = 0; n < STM32_NLPUART + STM32_NUSART + STM32_NUART; 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 bootup. 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 < STM32_NLPUART + STM32_NUSART + STM32_NUART; 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 + (void)uart_register("/dev/console", &g_uart_devs[CONSOLE_UART - 1]->dev); + +#ifndef CONFIG_STM32U5_SERIAL_DISABLE_REORDERING + /* If not disabled, register the console UART to ttyS0 and exclude + * it from initializing it further down + */ + + (void)uart_register("/dev/ttyS0", &g_uart_devs[CONSOLE_UART - 1]->dev); + minor = 1; +#endif + +#ifdef SERIAL_HAVE_CONSOLE_DMA + /* If we need to re-initialise the console to enable DMA do that here. */ + + stm32serial_dmasetup(&g_uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif /* CONSOLE_UART > 0 */ + + /* Register all remaining USARTs */ + + strcpy(devname, "/dev/ttySx"); + + for (i = 0; i < STM32_NLPUART + STM32_NUSART + STM32_NUART; i++) + { + /* Don't create a device for non-configured ports. */ + + if (g_uart_devs[i] == 0) + { + continue; + } + +#ifndef CONFIG_STM32U5_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++; + (void)uart_register(devname, &g_uart_devs[i]->dev); + } +#endif /* HAVE UART */ +} + +/**************************************************************************** + * Name: stm32_serial_dma_poll + * + * Description: + * Checks receive DMA buffers for received bytes that have not accumulated + * to the point where the DMA half/full interrupt has triggered. + * + * This function should be called from a timer or other periodic context. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32_serial_dma_poll(void) +{ + irqstate_t flags; + + flags = enter_critical_section(); + +#ifdef CONFIG_LPUART1_RXDMA + if (g_lpuart1priv.rxdma != NULL) + { + stm32serial_dmarxcallback(g_lpuart1priv.rxdma, 0, &g_lpuart1priv); + } +#endif + +#ifdef CONFIG_USART1_RXDMA + if (g_usart1priv.rxdma != NULL) + { + stm32serial_dmarxcallback(g_usart1priv.rxdma, 0, &g_usart1priv); + } +#endif + +#ifdef CONFIG_USART2_RXDMA + if (g_usart2priv.rxdma != NULL) + { + stm32serial_dmarxcallback(g_usart2priv.rxdma, 0, &g_usart2priv); + } +#endif + +#ifdef CONFIG_USART3_RXDMA + if (g_usart3priv.rxdma != NULL) + { + stm32serial_dmarxcallback(g_usart3priv.rxdma, 0, &g_usart3priv); + } +#endif + +#ifdef CONFIG_UART4_RXDMA + if (g_uart4priv.rxdma != NULL) + { + stm32serial_dmarxcallback(g_uart4priv.rxdma, 0, &g_uart4priv); + } +#endif + +#ifdef CONFIG_UART5_RXDMA + if (g_uart5priv.rxdma != NULL) + { + stm32serial_dmarxcallback(g_uart5priv.rxdma, 0, &g_uart5priv); + } +#endif + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int 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 + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if CONSOLE_UART > 0 + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + arm_lowputc('\r'); + } + + arm_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/stm32u5/stm32_spi.c b/arch/arm/src/stm32u5/stm32_spi.c new file mode 100644 index 0000000000..353df2c0a2 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_spi.c @@ -0,0 +1,2432 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_spi.c + * + * 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 external functions, stm32_spi1/2/3/4/5/6select and + * stm32_spi1/2/3/4/5/6status must be provided by board-specific logic. They + * are implementations of the select and status methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other + * methods (including stm32_spibus_initialize()) are provided by common STM32 + * logic. To use this common SPI logic on your board: + * + * 1. Provide logic in stm32_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32_spi1/2/3/4/5/6select() and stm32_spi1/2/3/4/5/6status() + * functions in your board-specific logic. These functions will perform + * chip selection and status operations using GPIOs in the way your + * board is configured. + * 3. Add a calls to stm32_spibus_initialize() in your low level + * application initialization logic + * 4. The handle returned by stm32_spibus_initialize() may then be used to + * bind the SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "arm_internal.h" +#include "arm_arch.h" + +#include "chip.h" +#include "stm32_rcc.h" +#include "stm32_gpio.h" +#include "stm32_spi.h" + +#if defined(CONFIG_STM32U5_SPI1) || defined(CONFIG_STM32U5_SPI2) || \ + defined(CONFIG_STM32U5_SPI3) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* SPI interrupts */ + +#ifdef CONFIG_STM32U5_SPI_INTERRUPTS +# error "Interrupt driven SPI not yet supported" +#endif + +/* Can't have both interrupt driven SPI and SPI DMA */ + +#if defined(CONFIG_STM32U5_SPI_INTERRUPTS) && defined(CONFIG_STM32U5_SPI_DMA) +# error "Cannot enable both interrupt mode and DMA mode for SPI" +#endif + +/* SPI DMA priority */ + +#ifdef CONFIG_STM32U5_SPI_DMA + +# if defined(CONFIG_SPI_DMAPRIO) +# define SPI_DMA_PRIO CONFIG_SPI_DMAPRIO +# elif defined(DMA_SCR_PRIMED) +# define SPI_DMA_PRIO DMA_SCR_PRILO +# else +# error "Unknown STM32 DMA" +# endif + +# if (SPI_DMA_PRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SPI_DMAPRIO" +# endif + +/* DMA channel configuration */ + +# define SPI_RXDMA16_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_16BITS|DMA_SCR_PSIZE_16BITS|DMA_SCR_MINC|DMA_SCR_DIR_P2M) +# define SPI_RXDMA8_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_P2M) +# define SPI_RXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_16BITS |DMA_SCR_DIR_P2M) +# define SPI_RXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_DIR_P2M) +# define SPI_TXDMA16_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_16BITS|DMA_SCR_PSIZE_16BITS|DMA_SCR_MINC|DMA_SCR_DIR_M2P) +# define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_M2P) +# define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_16BITS |DMA_SCR_DIR_M2P) +# define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_DIR_M2P) + +/* If built with CONFIG_ARMV7M_DCACHE Buffers need to be aligned and + * multiples of ARMV7M_DCACHE_LINESIZE + */ + +# if defined(CONFIG_ARMV7M_DCACHE) +# define SPIDMA_BUFFER_MASK (ARMV7M_DCACHE_LINESIZE - 1) +# define SPIDMA_SIZE(b) (((b) + SPIDMA_BUFFER_MASK) & ~SPIDMA_BUFFER_MASK) +# define SPIDMA_BUF_ALIGN aligned_data(ARMV7M_DCACHE_LINESIZE) +# else +# define SPIDMA_SIZE(b) (b) +# define SPIDMA_BUF_ALIGN +# endif + +# if defined(CONFIG_STM32U5_SPI1_DMA_BUFFER) && \ + CONFIG_STM32U5_SPI1_DMA_BUFFER > 0 +# define SPI1_DMABUFSIZE_ADJUSTED SPIDMA_SIZE(CONFIG_STM32U5_SPI1_DMA_BUFFER) +# define SPI1_DMABUFSIZE_ALGN SPIDMA_BUF_ALIGN +# endif + +# if defined(CONFIG_STM32U5_SPI2_DMA_BUFFER) && \ + CONFIG_STM32U5_SPI2_DMA_BUFFER > 0 +# define SPI2_DMABUFSIZE_ADJUSTED SPIDMA_SIZE(CONFIG_STM32U5_SPI2_DMA_BUFFER) +# define SPI2_DMABUFSIZE_ALGN SPIDMA_BUF_ALIGN +# endif + +# if defined(CONFIG_STM32U5_SPI3_DMA_BUFFER) && \ + CONFIG_STM32U5_SPI3_DMA_BUFFER > 0 +# define SPI3_DMABUFSIZE_ADJUSTED SPIDMA_SIZE(CONFIG_STM32U5_SPI3_DMA_BUFFER) +# define SPI3_DMABUFSIZE_ALGN SPIDMA_BUF_ALIGN +# endif + +#endif + +/* Kernel clock configuration + * TODO: + * - support for all kernel clock configuration + */ + +#if defined(CONFIG_STM32U5_SPI1) +# define SPI1_KERNEL_CLOCK_FREQ STM32_PCLK2_FREQUENCY +#endif + +#if defined(CONFIG_STM32U5_SPI2) +# define SPI2_KERNEL_CLOCK_FREQ STM32_PCLK1_FREQUENCY +#endif + +#if defined(CONFIG_STM32U5_SPI3) +# define SPI3_KERNEL_CLOCK_FREQ STM32_PCLK3_FREQUENCY +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum spi_config_e +{ + FULL_DUPLEX = 0, + SIMPLEX_TX, + SIMPLEX_RX, + HALF_DUPLEX +}; + +struct stm32_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t spibase; /* SPIn base address */ + uint32_t spiclock; /* Clocking for the SPI module */ + uint8_t spiirq; /* SPI IRQ number */ +#ifdef CONFIG_STM32U5_SPI_DMA + volatile uint8_t rxresult; /* Result of the RX DMA */ + volatile uint8_t txresult; /* Result of the RX DMA */ +#ifdef CONFIG_SPI_TRIGGER + bool defertrig; /* Flag indicating that trigger should be deferred */ + bool trigarmed; /* Flag indicating that the trigger is armed */ +#endif + uint32_t rxch; /* The RX DMA channel number */ + uint32_t txch; /* The TX DMA channel number */ + uint8_t *rxbuf; /* The RX DMA buffer */ + uint8_t *txbuf; /* The TX DMA buffer */ + size_t buflen; /* The DMA buffer length */ + DMA_HANDLE rxdma; /* DMA channel handle for RX transfers */ + DMA_HANDLE txdma; /* DMA channel handle for TX transfers */ + sem_t rxsem; /* Wait for RX DMA to complete */ + sem_t txsem; /* Wait for TX DMA to complete */ + uint32_t txccr; /* DMA control register for TX transfers */ + uint32_t rxccr; /* DMA control register for RX transfers */ +#endif + bool initialized; /* Has SPI interface been initialized */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + int8_t nbits; /* Width of word in bits */ + uint8_t mode; /* Mode 0,1,2,3 */ +#ifdef CONFIG_PM + struct pm_callback_s pm_cb; /* PM callbacks */ +#endif + enum spi_config_e config; /* full/half duplex, simplex transmit/read only */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +static inline uint32_t spi_getreg(FAR struct stm32_spidev_s *priv, + uint32_t offset); +static inline void spi_putreg(FAR struct stm32_spidev_s *priv, + uint32_t offset, uint32_t value); +static inline uint32_t spi_readword(FAR struct stm32_spidev_s *priv); +static inline void spi_writeword(FAR struct stm32_spidev_s *priv, + uint32_t byte); +#ifdef CONFIG_DEBUG_SPI_INFO +static inline void spi_dumpregs(FAR struct stm32_spidev_s *priv); +#endif + +/* DMA support */ + +#ifdef CONFIG_STM32U5_SPI_DMA +static int spi_dmarxwait(FAR struct stm32_spidev_s *priv); +static int spi_dmatxwait(FAR struct stm32_spidev_s *priv); +static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv); +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, + void *arg); +static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, + FAR void *rxbuffer, + FAR void *rxdummy, + size_t nwords, + stm32_dmacfg_t *dmacfg); +static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, + FAR const void *txbuffer, + FAR const void *txdummy, + size_t nwords, + stm32_dmacfg_t *dmacfg); +static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv); +static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv); +#endif + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency); +#ifdef CONFIG_SPI_DELAY_CONTROL +static int spi_setdelay(struct spi_dev_s *dev, uint32_t startdelay, + uint32_t stopdelay, uint32_t csdelay, + uint32_t ifdelay); +#endif +static void spi_setmode(FAR struct spi_dev_s *dev, + enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +#ifdef CONFIG_SPI_HWFEATURES +static int spi_hwfeatures(FAR struct spi_dev_s *dev, + spi_hwfeatures_t features); +#endif +static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd); +static void spi_exchange(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, FAR void *rxbuffer, + size_t nwords); +#ifdef CONFIG_SPI_TRIGGER +static int spi_trigger(FAR struct spi_dev_s *dev); +#endif +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, + FAR void *rxbuffer, size_t nwords); +#endif + +/* Initialization */ + +static void spi_bus_initialize(FAR struct stm32_spidev_s *priv); + +/* PM interface */ + +#ifdef CONFIG_PM +static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI1 +static const struct spi_ops_s g_sp1iops = +{ + .lock = spi_lock, + .select = stm32_spi1select, + .setfrequency = spi_setfrequency, +#ifdef CONFIG_SPI_DELAY_CONTROL + .setdelay = spi_setdelay, +#endif + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = spi_hwfeatures, +#endif + .status = stm32_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_TRIGGER + .trigger = spi_trigger, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32_spi1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +#if defined(SPI1_DMABUFSIZE_ADJUSTED) +static uint8_t g_spi1_txbuf[SPI1_DMABUFSIZE_ADJUSTED] SPI1_DMABUFSIZE_ALGN; +static uint8_t g_spi1_rxbuf[SPI1_DMABUFSIZE_ADJUSTED] SPI1_DMABUFSIZE_ALGN; +#endif + +static struct stm32_spidev_s g_spi1dev = +{ + .spidev = + { + &g_sp1iops + }, + .spibase = STM32_SPI1_BASE, + .spiclock = SPI1_KERNEL_CLOCK_FREQ, + .spiirq = STM32_IRQ_SPI1, +#ifdef CONFIG_STM32U5_SPI1_DMA + .rxch = DMAMAP_SPI1_RX, + .txch = DMAMAP_SPI1_TX, +# if defined(SPI1_DMABUFSIZE_ADJUSTED) + .rxbuf = g_spi1_rxbuf, + .txbuf = g_spi1_txbuf, + .buflen = SPI1_DMABUFSIZE_ADJUSTED, +# endif +#endif +#ifdef CONFIG_PM + .pm_cb.prepare = spi_pm_prepare, +#endif +#ifdef CONFIG_STM32U5_SPI1_COMMTYPE + .config = CONFIG_STM32U5_SPI1_COMMTYPE, +#else + .config = FULL_DUPLEX, +#endif +}; +#endif /* CONFIG_STM32U5_SPI1 */ + +#ifdef CONFIG_STM32U5_SPI2 +static const struct spi_ops_s g_sp2iops = +{ + .lock = spi_lock, + .select = stm32_spi2select, + .setfrequency = spi_setfrequency, +#ifdef CONFIG_SPI_DELAY_CONTROL + .setdelay = spi_setdelay, +#endif + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = spi_hwfeatures, +#endif + .status = stm32_spi2status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32_spi2cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_TRIGGER + .trigger = spi_trigger, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32_spi2register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +#if defined(SPI2_DMABUFSIZE_ADJUSTED) +static uint8_t g_spi2_txbuf[SPI2_DMABUFSIZE_ADJUSTED] SPI2_DMABUFSIZE_ALGN; +static uint8_t g_spi2_rxbuf[SPI2_DMABUFSIZE_ADJUSTED] SPI2_DMABUFSIZE_ALGN; +#endif + +static struct stm32_spidev_s g_spi2dev = +{ + .spidev = + { + &g_sp2iops + }, + .spibase = STM32_SPI2_BASE, + .spiclock = SPI2_KERNEL_CLOCK_FREQ, + .spiirq = STM32_IRQ_SPI2, +#ifdef CONFIG_STM32U5_SPI2_DMA + .rxch = DMAMAP_SPI2_RX, + .txch = DMAMAP_SPI2_TX, +# if defined(SPI2_DMABUFSIZE_ADJUSTED) + .rxbuf = g_spi2_rxbuf, + .txbuf = g_spi2_txbuf, + .buflen = SPI2_DMABUFSIZE_ADJUSTED, +# endif +#endif +#ifdef CONFIG_PM + .pm_cb.prepare = spi_pm_prepare, +#endif +#ifdef CONFIG_STM32U5_SPI2_COMMTYPE + .config = CONFIG_STM32U5_SPI2_COMMTYPE, +#else + .config = FULL_DUPLEX, +#endif +}; +#endif /* CONFIG_STM32U5_SPI2 */ + +#ifdef CONFIG_STM32U5_SPI3 +static const struct spi_ops_s g_sp3iops = +{ + .lock = spi_lock, + .select = stm32_spi3select, + .setfrequency = spi_setfrequency, +#ifdef CONFIG_SPI_DELAY_CONTROL + .setdelay = spi_setdelay, +#endif + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = spi_hwfeatures, +#endif + .status = stm32_spi3status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32_spi3cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_TRIGGER + .trigger = spi_trigger, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32_spi3register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +#if defined(SPI3_DMABUFSIZE_ADJUSTED) +static uint8_t g_spi3_txbuf[SPI3_DMABUFSIZE_ADJUSTED] SPI3_DMABUFSIZE_ALGN; +static uint8_t g_spi3_rxbuf[SPI3_DMABUFSIZE_ADJUSTED] SPI3_DMABUFSIZE_ALGN; +#endif + +static struct stm32_spidev_s g_spi3dev = +{ + .spidev = + { + &g_sp3iops + }, + .spibase = STM32_SPI3_BASE, + .spiclock = SPI3_KERNEL_CLOCK_FREQ, + .spiirq = STM32_IRQ_SPI3, +#ifdef CONFIG_STM32U5_SPI3_DMA + .rxch = DMAMAP_SPI3_RX, + .txch = DMAMAP_SPI3_TX, +# if defined(SPI3_DMABUFSIZE_ADJUSTED) + .rxbuf = g_spi3_rxbuf, + .txbuf = g_spi3_txbuf, + .buflen = SPI3_DMABUFSIZE_ADJUSTED, +# endif +#endif +#ifdef CONFIG_PM + .pm_cb.prepare = spi_pm_prepare, +#endif +#ifdef CONFIG_STM32U5_SPI3_COMMTYPE + .config = CONFIG_STM32U5_SPI3_COMMTYPE, +#else + .config = FULL_DUPLEX, +#endif +}; +#endif /* CONFIG_STM32U5_SPI3 */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_getreg8 + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 8-bit register + * + ****************************************************************************/ + +static inline uint8_t spi_getreg8(FAR struct stm32_spidev_s *priv, + uint32_t offset) +{ + return getreg8(priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_putreg8 + * + * Description: + * Write a 8-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 8-bit value to be written + * + ****************************************************************************/ + +static inline void spi_putreg8(FAR struct stm32_spidev_s *priv, + uint32_t offset, uint8_t value) +{ + putreg8(value, priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_getreg16 + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 16-bit register + * + ****************************************************************************/ + +static inline uint16_t spi_getreg16(FAR struct stm32_spidev_s *priv, + uint32_t offset) +{ + return getreg16(priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_putreg16 + * + * Description: + * Write a 16-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + ****************************************************************************/ + +static inline void spi_putreg16(FAR struct stm32_spidev_s *priv, + uint32_t offset, uint16_t value) +{ + putreg16(value, priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 16-bit register + * + ****************************************************************************/ + +static inline uint32_t spi_getreg(FAR struct stm32_spidev_s *priv, + uint32_t offset) +{ + return getreg32(priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a 16-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + * Returned Value: + * The contents of the 16-bit register + * + ****************************************************************************/ + +static inline void spi_putreg(FAR struct stm32_spidev_s *priv, + uint32_t offset, uint32_t value) +{ + putreg32(value, priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_modifyreg + * + * Description: + * Modify an SPI register + * + ****************************************************************************/ + +static void spi_modifyreg(FAR struct stm32_spidev_s *priv, uint32_t offset, + uint32_t clrbits, uint32_t setbits) +{ + /* Only 32-bit registers */ + + modifyreg32(priv->spibase + offset, clrbits, setbits); +} + +/**************************************************************************** + * Name: spi_readword + * + * Description: + * Read one byte from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Byte as read + * + ****************************************************************************/ + +static inline uint32_t spi_readword(FAR struct stm32_spidev_s *priv) +{ + /* Can't receive in tx only mode */ + + if (priv->config == SIMPLEX_TX) + { + return 0; + } + + /* Wait until the receive buffer is not empty */ + + while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_RXP) == 0); + + /* Then return the received 16 bit word */ + + return spi_getreg16(priv, STM32_SPI_RXDR_OFFSET); +} + +/**************************************************************************** + * Name: spi_writeword + * + * Description: + * Write one byte to SPI + * + * Input Parameters: + * priv - Device-specific state data + * byte - Byte to send + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_writeword(FAR struct stm32_spidev_s *priv, + uint32_t word) +{ + /* Can't transmit in rx only mode */ + + if (priv->config == SIMPLEX_RX) + { + return; + } + + /* Wait until the transmit buffer is empty */ + + while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_TXP) == 0); + + /* Then send the 16 bit word */ + + spi_putreg16(priv, STM32_SPI_TXDR_OFFSET, word); +} + +/**************************************************************************** + * Name: spi_readbyte + * + * Description: + * Read one byte from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Byte as read + * + ****************************************************************************/ + +static inline uint8_t spi_readbyte(FAR struct stm32_spidev_s *priv) +{ + /* Can't receive in tx only mode */ + + if (priv->config == SIMPLEX_TX) + { + return 0; + } + + /* Wait until the receive buffer is not empty */ + + while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_RXP) == 0); + + /* Then return the received byte */ + + return spi_getreg8(priv, STM32_SPI_RXDR_OFFSET); +} + +/**************************************************************************** + * Name: spi_writebyte + * + * Description: + * Write one 8-bit frame to the SPI FIFO + * + * Input Parameters: + * priv - Device-specific state data + * byte - Byte to send + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_writebyte(FAR struct stm32_spidev_s *priv, + uint8_t byte) +{ + /* Can't transmit in rx only mode */ + + if (priv->config == SIMPLEX_RX) + { + return; + } + + /* Wait until the transmit buffer is empty */ + + while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_TXP) == 0); + + /* Then send the byte */ + + spi_putreg8(priv, STM32_SPI_TXDR_OFFSET, byte); +} + +/**************************************************************************** + * Name: spi_dumpregs + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SPI_INFO +static void spi_dumpregs(FAR struct stm32_spidev_s *priv) +{ + spiinfo("CR1: 0x%08" PRIx32 " CFG1: 0x%08" PRIx32 + " CFG2: 0x%08" PRIx32 "\n", + spi_getreg(priv, STM32_SPI_CR1_OFFSET), + spi_getreg(priv, STM32_SPI_CFG1_OFFSET), + spi_getreg(priv, STM32_SPI_CFG2_OFFSET)); + spiinfo("IER: 0x%08" PRIx32 " SR: 0x%08" PRIx32 "\n", + spi_getreg(priv, STM32_SPI_IER_OFFSET), + spi_getreg(priv, STM32_SPI_SR_OFFSET)); +} +#endif + +/**************************************************************************** + * Name: spi_interrupt + * + * Description: + * In DMA transfer mode, handle the transmission complete interrupt + * + ****************************************************************************/ + +static int spi_interrupt(int irq, void *context, void *arg) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)arg; + uint32_t sr = spi_getreg(priv, STM32_SPI_SR_OFFSET); + + if (sr & SPI_SR_TXC) + { + /* Disable interrupt. This needs to be done + * before disabling SPI to avoid spurious TXC interrupt + * (ERRATA: Q2.14.4 TXP interrupt occurring while SPI/I2Sdisabled") + * There is no need to clear the interrupt since it is disabled and + * SPI will be disabled after transmit as well. + */ + + spi_modifyreg(priv, STM32_SPI_IER_OFFSET, SPI_IER_EOTIE, 0); + + /* Set result and release wait semaphore */ +#ifdef CONFIG_STM32U5_SPI_DMA + priv->txresult = 0x80; + nxsem_post(&priv->txsem); +#endif + } + + return 0; +} + +/**************************************************************************** + * Name: spi_dmarxwait + * + * Description: + * Wait for DMA to complete. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI_DMA +static int spi_dmarxwait(FAR struct stm32_spidev_s *priv) +{ + int ret; + + /* Don't wait in tx only mode */ + + if (priv->config == SIMPLEX_TX) + { + return OK; + } + + /* Take the semaphore (perhaps waiting). If the result is zero, then the + * DMA must not really have completed??? + */ + + do + { + ret = nxsem_wait_uninterruptible(&priv->rxsem); + + /* The only expected error is ECANCELED which would occur if the + * calling thread were canceled. + */ + + DEBUGASSERT(ret == OK || ret == -ECANCELED); + } + while (priv->rxresult == 0 && ret == OK); + + return ret; +} +#endif + +/**************************************************************************** + * Name: spi_dmatxwait + * + * Description: + * Wait for DMA to complete. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI_DMA +static int spi_dmatxwait(FAR struct stm32_spidev_s *priv) +{ + int ret; + + /* Don't wait in rx only mode */ + + if (priv->config == SIMPLEX_RX) + { + return OK; + } + + /* Enable TXC interrupt. This needs to be done after starting TX-dma AND + * when spi is enabled to avoid spurious TXC interrupt (ERRATA: + * "2.14.4 TXP interrupt occurring while SPI/I2Sdisabled") + * It is fine to enable this interrupt even if the transfer already did + * complete; in this case the irq will just fire right away + */ + + spi_modifyreg(priv, STM32_SPI_IER_OFFSET, 0, SPI_IER_EOTIE); + + /* Take the semaphore (perhaps waiting). If the result is zero, then the + * DMA must not really have completed??? + */ + + do + { + ret = nxsem_wait_uninterruptible(&priv->txsem); + + /* The only expected error is ECANCELED which would occur if the + * calling thread were canceled. + */ + + DEBUGASSERT(ret == OK || ret == -ECANCELED); + } + while (priv->txresult == 0 && ret == OK); + + return ret; +} +#endif + +/**************************************************************************** + * Name: spi_dmarxwakeup + * + * Description: + * Signal that DMA is complete + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI_DMA +static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv) +{ + nxsem_post(&priv->rxsem); +} +#endif + +/**************************************************************************** + * Name: spi_dmarxcallback + * + * Description: + * Called when the RX DMA completes + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI_DMA +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)arg; + + /* Wake-up the SPI driver */ + + priv->rxresult = isr | 0x080; /* OR'ed with 0x80 to assure non-zero */ + spi_dmarxwakeup(priv); +} +#endif + +/**************************************************************************** + * Name: spi_dmarxsetup + * + * Description: + * Setup to perform RX DMA + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI_DMA +static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, + FAR void *rxbuffer, FAR void *rxdummy, + size_t nwords, stm32_dmacfg_t *dmacfg) +{ + /* Can't receive in tx only mode */ + + if (priv->config == SIMPLEX_TX) + { + priv->rxccr = 0; + return; + } + + /* 8- or 16-bit mode? */ + + if (priv->nbits > 8) + { + /* 16-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + priv->rxccr = SPI_RXDMA16_CONFIG; + } + else + { + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA16NULL_CONFIG; + } + } + else + { + /* 8-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + priv->rxccr = SPI_RXDMA8_CONFIG; + } + else + { + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA8NULL_CONFIG; + } + } + + /* Configure the RX DMA */ + + dmacfg->paddr = priv->spibase + STM32_SPI_RXDR_OFFSET; + dmacfg->maddr = (uint32_t)rxbuffer; + dmacfg->ndata = nwords; + dmacfg->cfg1 = priv->rxccr; + dmacfg->cfg2 = 0; +} +#endif + +/**************************************************************************** + * Name: spi_dmatxsetup + * + * Description: + * Setup to perform TX DMA + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI_DMA +static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, + FAR const void *txbuffer, FAR const void *txdummy, + size_t nwords, stm32_dmacfg_t *dmacfg) +{ + /* Can't transmit in rx only mode */ + + if (priv->config == SIMPLEX_RX) + { + priv->txccr = 0; + return; + } + + /* 8- or 16-bit mode? */ + + if (priv->nbits > 8) + { + /* 16-bit mode -- is there a buffer to transfer data from? */ + + if (txbuffer) + { + priv->txccr = SPI_TXDMA16_CONFIG; + } + else + { + txbuffer = txdummy; + priv->txccr = SPI_TXDMA16NULL_CONFIG; + } + } + else + { + /* 8-bit mode -- is there a buffer to transfer data from? */ + + if (txbuffer) + { + priv->txccr = SPI_TXDMA8_CONFIG; + } + else + { + txbuffer = txdummy; + priv->txccr = SPI_TXDMA8NULL_CONFIG; + } + } + + dmacfg->paddr = priv->spibase + STM32_SPI_TXDR_OFFSET; + dmacfg->maddr = (uint32_t)txbuffer; + dmacfg->ndata = nwords; + dmacfg->cfg1 = priv->txccr; + dmacfg->cfg2 = 0; +} +#endif + +/**************************************************************************** + * Name: spi_dmarxstart + * + * Description: + * Start RX DMA + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI_DMA +static void spi_dmarxstart(FAR struct stm32_spidev_s *priv) +{ + /* Can't receive in tx only mode */ + + if (priv->config == SIMPLEX_TX) + { + return; + } + + priv->rxresult = 0; + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_RXDMAEN); + stm32_dmastart(priv->rxdma, spi_dmarxcallback, priv, false); +} +#endif + +/**************************************************************************** + * Name: spi_dmatxstart + * + * Description: + * Start TX DMA + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI_DMA +static void spi_dmatxstart(FAR struct stm32_spidev_s *priv) +{ + /* Can't transmit in rx only mode */ + + if (priv->config == SIMPLEX_RX) + { + return; + } + + priv->txresult = 0; + stm32_dmastart(priv->txdma, NULL, priv, false); + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_TXDMAEN); +} +#endif + +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI bus is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + int ret; + + if (lock) + { + ret = nxsem_wait_uninterruptible(&priv->exclsem); + } + else + { + ret = nxsem_post(&priv->exclsem); + } + + return ret; +} + +/**************************************************************************** + * Name: spi_enable + ****************************************************************************/ + +static inline int spi_enable(FAR struct stm32_spidev_s *priv, bool state) +{ + int ret = OK; + + if (state == true) + { + /* Enable SPI */ + + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_SPE); + } + else + { + /* Disable SPI */ + + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, SPI_CR1_SPE, 0); + } + + return ret; +} + +/**************************************************************************** + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + uint32_t setbits = 0; + uint32_t actual = 0; + + /* Limit to max possible (if STM32_SPI_CLK_MAX is defined in board.h) */ + + if (frequency > STM32_SPI_CLK_MAX) + { + frequency = STM32_SPI_CLK_MAX; + } + + /* Has the frequency changed? */ + + if (frequency != priv->frequency) + { + /* Choices are limited by PCLK frequency with a set of divisors */ + + if (frequency >= priv->spiclock >> 1) + { + /* More than fPCLK/2. This is as fast as we can go */ + + setbits = SPI_CFG1_MBR_FPCLKd2; /* 000: fPCLK/2 */ + actual = priv->spiclock >> 1; + } + else if (frequency >= priv->spiclock >> 2) + { + /* Between fPCLCK/2 and fPCLCK/4, pick the slower */ + + setbits = SPI_CFG1_MBR_FPCLKd4; /* 001: fPCLK/4 */ + actual = priv->spiclock >> 2; + } + else if (frequency >= priv->spiclock >> 3) + { + /* Between fPCLCK/4 and fPCLCK/8, pick the slower */ + + setbits = SPI_CFG1_MBR_FPCLKd8; /* 010: fPCLK/8 */ + actual = priv->spiclock >> 3; + } + else if (frequency >= priv->spiclock >> 4) + { + /* Between fPCLCK/8 and fPCLCK/16, pick the slower */ + + setbits = SPI_CFG1_MBR_FPCLKd16; /* 011: fPCLK/16 */ + actual = priv->spiclock >> 4; + } + else if (frequency >= priv->spiclock >> 5) + { + /* Between fPCLCK/16 and fPCLCK/32, pick the slower */ + + setbits = SPI_CFG1_MBR_FPCLKd32; /* 100: fPCLK/32 */ + actual = priv->spiclock >> 5; + } + else if (frequency >= priv->spiclock >> 6) + { + /* Between fPCLCK/32 and fPCLCK/64, pick the slower */ + + setbits = SPI_CFG1_MBR_FPCLKd64; /* 101: fPCLK/64 */ + actual = priv->spiclock >> 6; + } + else if (frequency >= priv->spiclock >> 7) + { + /* Between fPCLCK/64 and fPCLCK/128, pick the slower */ + + setbits = SPI_CFG1_MBR_FPCLKd128; /* 110: fPCLK/128 */ + actual = priv->spiclock >> 7; + } + else + { + /* Less than fPCLK/128. This is as slow as we can go */ + + setbits = SPI_CFG1_MBR_FPCLKd256; /* 111: fPCLK/256 */ + actual = priv->spiclock >> 8; + } + + spi_enable(priv, false); + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, SPI_CFG1_MBR_MASK, setbits); + spi_enable(priv, true); + + /* Save the frequency selection so that subsequent reconfigurations + * will be faster. + */ + + spiinfo("Frequency %" PRId32 "->%" PRId32 "\n", frequency, actual); + + priv->frequency = frequency; + priv->actual = actual; + } + + return priv->actual; +} + +/**************************************************************************** + * Name: spi_setdelay + * + * Description: + * Set the SPI Delays in nanoseconds. Optional. + * + * Input Parameters: + * dev - Device-specific state data + * startdelay - The delay between CS active and first CLK + * stopdelay - The delay between last CLK and CS inactive + * csdelay - The delay between CS inactive and CS active again + * ifdelay - The delay between frames + * + * Returned Value: + * Returns zero (OK) on success; a negated errno value is return on any + * failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_DELAY_CONTROL +static int spi_setdelay(struct spi_dev_s *dev, uint32_t startdelay, + uint32_t stopdelay, uint32_t csdelay, + uint32_t ifdelay) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + uint32_t setbits = 0; + uint32_t clrbits = SPI_CFG2_MSSI_MASK | SPI_CFG2_MIDI_MASK; + uint32_t nsperclk = NSEC_PER_SEC / priv->actual; + + startdelay /= nsperclk; + ifdelay /= nsperclk; + + setbits = ((ifdelay << SPI_CFG2_MIDI_SHIFT) & SPI_CFG2_MIDI_MASK) | + ((startdelay << SPI_CFG2_MSSI_SHIFT) & SPI_CFG2_MSSI_MASK); + + spi_enable(priv, false); + + /* Change SPI mode */ + + spi_modifyreg(priv, STM32_SPI_CFG2_OFFSET, clrbits, setbits); + + /* Re-enable SPI */ + + spi_enable(priv, true); + return OK; +} +#endif + +/**************************************************************************** + * Name: spi_setmode + * + * Description: + * Set the SPI mode. see enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + uint32_t setbits = 0; + uint32_t clrbits = 0; + + spiinfo("mode=%" PRIx32 "\n", (uint32_t) mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR1 appropriately */ + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + setbits = 0; + clrbits = SPI_CFG2_CPOL | SPI_CFG2_CPHA; + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + setbits = SPI_CFG2_CPHA; + clrbits = SPI_CFG2_CPOL; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + setbits = SPI_CFG2_CPOL; + clrbits = SPI_CFG2_CPHA; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + setbits = SPI_CFG2_CPOL | SPI_CFG2_CPHA; + clrbits = 0; + break; + + default: + return; + } + + spi_enable(priv, false); + + /* Change SPI mode */ + + spi_modifyreg(priv, STM32_SPI_CFG2_OFFSET, clrbits, setbits); + + /* Re-enable SPI */ + + spi_enable(priv, true); + while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & + SPI_SR_RXPLVL_MASK) != 0) + { + /* Flush SPI read FIFO */ + + spi_getreg(priv, STM32_SPI_RXDR_OFFSET); + } + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/**************************************************************************** + * Name: spi_setbits + * + * Description: + * Set the number of bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requested + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + uint32_t setbits = 0; + uint32_t clrbits = 0; + + spiinfo("nbits=%d\n", nbits); + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + /* Yes... Set CFG1 appropriately */ + + /* Set the number of bits (valid range 4-32) */ + + if (nbits < 4 || nbits > 32) + { + return; + } + + clrbits = SPI_CFG1_DSIZE_MASK; + setbits = SPI_CFG1_DSIZE_VAL(nbits); + + /* RX FIFO Threshold 1 Frame either 8 or 16 bits */ + + setbits |= SPI_CFG1_FTHLV_1DATA; + + spi_enable(priv, false); + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, clrbits, setbits); + spi_enable(priv, true); + + /* Save the selection so that subsequent re-configurations will be + * faster. + */ + + priv->nbits = nbits; + } +} + +/**************************************************************************** + * Name: spi_hwfeatures + * + * Description: + * Set hardware-specific feature flags. + * + * Input Parameters: + * dev - Device-specific state data + * features - H/W feature flags + * + * Returned Value: + * Zero (OK) if the selected H/W features are enabled; A negated errno + * value if any H/W feature is not supportable. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_HWFEATURES +static int spi_hwfeatures(FAR struct spi_dev_s *dev, + spi_hwfeatures_t features) +{ +#if defined(CONFIG_SPI_BITORDER) || defined(CONFIG_SPI_TRIGGER) + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; +#endif + +#ifdef CONFIG_SPI_BITORDER + uint32_t setbits = 0; + uint32_t clrbits = 0; + + spiinfo("features=%08" PRIx8 "\n", features); + + /* Transfer data LSB first? */ + + if ((features & HWFEAT_LSBFIRST) != 0) + { + setbits = SPI_CFG2_LSBFRST; + clrbits = 0; + } + else + { + setbits = 0; + clrbits = SPI_CFG2_LSBFRST; + } + + spi_enable(priv, false); + spi_modifyreg(priv, STM32_SPI_CFG2_OFFSET, clrbits, setbits); + spi_enable(priv, true); + + features &= ~HWFEAT_LSBFIRST; +#endif + +#ifdef CONFIG_SPI_TRIGGER +/* Turn deferred trigger mode on or off. Only applicable for DMA mode. If a + * transfer is deferred then the DMA will not actually be triggered until a + * subsequent call to SPI_TRIGGER to set it off. The thread will be waiting + * on the transfer completing as normal. + */ + + priv->defertrig = ((features & HWFEAT_TRIGGER) != 0); + features &= ~HWFEAT_TRIGGER; +#endif + + /* Other H/W features are not supported */ + + return (features == 0) ? OK : -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + uint32_t regval = 0; + uint32_t ret = 0; + + DEBUGASSERT(priv && priv->spibase); + + /* Clear suspend flag */ + + spi_modifyreg(priv, STM32_SPI_IFCR_OFFSET, 0, SPI_IFCR_SUSPC); + + /* Master transfer start */ + + if (priv->config != SIMPLEX_RX) + { + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSTART); + } + + /* According to the number of bits, access data register as word or byte + * This is absolutely required because of packing. With nbits <=8 bit + * frames, two bytes are received by a 16-bit read of the data register! + */ + + if (priv->nbits > 8) + { + spi_writeword(priv, (uint16_t)(wd & 0xffff)); + ret = spi_readword(priv); + } + else + { + spi_writebyte(priv, (uint8_t)(wd & 0xff)); + ret = (uint32_t)spi_readbyte(priv); + } + + /* Check and clear any error flags (Reading from the SR clears the error + * flags). + */ + + regval = spi_getreg(priv, STM32_SPI_SR_OFFSET); + + /* Suspend */ + + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSUSP); + while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_SUSP) == 0); + + /* Dump some info */ + + if (priv->nbits > 8) + { + spiinfo("Sent: %04" PRIx32 " Return: %04" PRIx32 " Status: %02" PRIx32 + "\n", wd, ret, regval); + } + else + { + spiinfo("Sent: %02" PRIx32 " Return: %02" PRIx32 " Status: %02" PRIx32 + "\n", wd, ret, regval); + } + + UNUSED(regval); + return ret; +} + +/**************************************************************************** + * Name: spi_exchange (no DMA). aka spi_exchange_nodma + * + * Description: + * Exchange a block of data on SPI without using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if !defined(CONFIG_STM32U5_SPI_DMA) || defined(CONFIG_STM32U5_DMACAPABLE) || \ + defined(CONFIG_STM32U5_SPI_DMATHRESHOLD) +#if !defined(CONFIG_STM32U5_SPI_DMA) +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +#else +static void spi_exchange_nodma(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, FAR void *rxbuffer, + size_t nwords) +#endif +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + DEBUGASSERT(priv && priv->spibase); + + spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* Disable the DMA Requests */ + + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, SPI_CFG1_RXDMAEN | + SPI_CFG1_TXDMAEN, 0); + + /* 8- or 16-bit mode? */ + + if (priv->nbits > 8) + { + /* 16-bit mode */ + + const uint16_t *src = (const uint16_t *)txbuffer; + uint16_t *dest = (uint16_t *)rxbuffer; + uint16_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xffff; + } + + /* Exchange one word */ + + word = (uint16_t)spi_send(dev, (uint32_t)word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } + else + { + /* 8-bit mode */ + + const uint8_t *src = (const uint8_t *)txbuffer; + uint8_t *dest = (uint8_t *)rxbuffer; + uint8_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xff; + } + + /* Exchange one word */ + + word = (uint8_t)spi_send(dev, (uint32_t)word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } +} + +#endif /* !CONFIG_STM32U5_SPI_DMA || CONFIG_STM32U5_DMACAPABLE || + * CONFIG_STM32U5_SPI_DMATHRESHOLD + */ + +/**************************************************************************** + * Name: spi_exchange (with DMA capability) + * + * Description: + * Exchange a block of data on SPI using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI_DMA +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + stm32_dmacfg_t rxdmacfg; + stm32_dmacfg_t txdmacfg; + static uint8_t rxdummy[ARMV7M_DCACHE_LINESIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + static const uint16_t txdummy = 0xffff; + FAR void * orig_rxbuffer = rxbuffer; + + DEBUGASSERT(priv != NULL); + + /* Convert the number of word to a number of bytes */ + + size_t nbytes = (priv->nbits > 8) ? nwords << 1 : nwords; + +#ifdef CONFIG_STM32U5_SPI_DMATHRESHOLD + /* If this is a small SPI transfer, then let spi_exchange_nodma() do the + * work. + */ + + if (nbytes <= CONFIG_STM32U5_SPI_DMATHRESHOLD) + { + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } +#endif + + if ((priv->config != SIMPLEX_TX && priv->rxdma == NULL) || + (priv->config != SIMPLEX_RX && priv->txdma == NULL) || + up_interrupt_context()) + { + /* Invalid DMA channels, or interrupt context, fall + * back to non-DMA method. + */ + + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } + + /* If this bus uses the driver's DMA aligned buffers (priv->txbuf != NULL) + * we will incur 2 copies. However the copy cost is much less the non + * DMA transfer time. Having the buffer in the driver ensures DMA can be + * used. This is needed because the stm32_dmacapable API does not support + * passing the buffer extent. So the only extent calculated is buffer + * plus the transfer size. The sizes can be less than a cache line size, + * and not aligned and are typically greater then 4 bytes, which is + * about the break even point for the DMA IO overhead. + */ + + /* Does bus support in driver DMA buffering? */ + + if (priv->txbuf) + { + if (nbytes > priv->buflen) + { + /* Buffer is too big for internal DMA buffer so fall back. */ + + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } + + /* First copy: If provided, copy caller's buffer to the internal DMA + * txbuf + */ + + if (txbuffer) + { + memcpy(priv->txbuf, txbuffer, nbytes); + + /* Adjust pointers to internal DMA buffers */ + + txbuffer = priv->txbuf; + } + + /* orig_rxbuffer holds the callers return buffer */ + + rxbuffer = rxbuffer ? priv->rxbuf : rxbuffer; + } + + /* Setup the DMA configs using the internal or external set of buffers */ + + spi_dmatxsetup(priv, txbuffer, &txdummy, nwords, &txdmacfg); + spi_dmarxsetup(priv, rxbuffer, (uint16_t *)rxdummy, nwords, &rxdmacfg); + +#ifdef CONFIG_STM32U5_DMACAPABLE + + /* Test for DMA capability of only callers buffers, internal buffers are + * guaranteed capable. + */ + + if ((priv->config != SIMPLEX_RX && priv->txbuf == 0 && + !stm32_dmacapable(priv->txdma, &txdmacfg)) || + (priv->config != SIMPLEX_TX && priv->rxbuf == 0 && + !stm32_dmacapable(priv->rxdma, &rxdmacfg))) + { + /* Unsupported memory region fall back to non-DMA method. */ + + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + } + else +#endif + { + /* When starting communication using DMA, to prevent DMA channel + * management raising error events, these steps must be followed in + * order: + * 1. Enable DMA Rx buffer in the RXDMAEN bit in the SPI_CFG1 register, + * if DMA Rx is used. + * 2. Enable DMA requests for Tx and Rx in DMA registers, if the DMA is + * used. + * 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CFG1 register, + * if DMA Tx is used. + * 4. Enable the SPI by setting the SPE bit. + */ + + /* Flush cache to physical memory */ + + if (txbuffer) + { + up_clean_dcache((uintptr_t)txbuffer, (uintptr_t)txbuffer + nbytes); + } + + if (rxbuffer) + { + up_invalidate_dcache((uintptr_t)rxbuffer, + (uintptr_t)rxbuffer + nbytes); + } + + /* N.B. the H7 tri-states the clock output on SPI disable and + * unfortunately the Chip Select (CS) is active. So we keep + * the device disabled for the minimum time, that meets the + * setup sequence criteria. + */ + + spi_enable(priv, false); + + spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n", + txbuffer, rxbuffer, nwords); + DEBUGASSERT(priv->spibase != 0); + + /* Setup the DMA */ + + if (priv->config != SIMPLEX_TX) + { + stm32_dmasetup(priv->rxdma, &rxdmacfg); + } + + if (priv->config != SIMPLEX_RX) + { + stm32_dmasetup(priv->txdma, &txdmacfg); + } + +#ifdef CONFIG_SPI_TRIGGER + /* Is deferred triggering in effect? */ + + if (!priv->defertrig) + { + /* No.. Start the DMAs then the SPI */ + + spi_dmarxstart(priv); + spi_dmatxstart(priv); + spi_enable(priv, true); + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSTART); + } + else + { + /* Yes.. indicated that we are ready to be started */ + + priv->trigarmed = true; + } +#else + /* Start the DMAs then the SPI */ + + spi_dmarxstart(priv); + spi_dmatxstart(priv); + spi_enable(priv, true); + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSTART); +#endif + + /* Then wait for each to complete */ + + spi_dmarxwait(priv); + spi_dmatxwait(priv); + + /* To close communication it is mandatory to follow these steps in + * this order: + * 1. Disable DMA request for Tx and Rx in the DMA registers, if the + * DMA issued. + * 2. Disable the SPI by following the SPI disable procedure. + * 3. Disable DMA Tx and Rx buffers by clearing the TXDMAEN and RXDMAEN + * bits in the SPI_CFG1 register, if DMA Tx and/or DMA Rx are used. + */ + + /* TX transmission must be completed before shutting down the SPI */ + + DEBUGASSERT(priv->config != SIMPLEX_RX ? + (spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_TXC) : 1); + + spi_enable(priv, false); + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, SPI_CFG1_TXDMAEN | + SPI_CFG1_RXDMAEN, 0); + spi_enable(priv, true); + + /* Second copy: Copy the DMA internal buffer to caller's buffer */ + + if (orig_rxbuffer && priv->rxbuf) + { + memcpy(orig_rxbuffer, priv->rxbuf, nbytes); + } + } + +#ifdef CONFIG_SPI_TRIGGER + priv->trigarmed = false; +#endif +} +#endif /* CONFIG_STM32U5_SPI_DMA */ + +/**************************************************************************** + * Name: spi_trigger + * + * Description: + * Trigger a previously configured DMA transfer. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * OK - Trigger was fired + * ENOTSUP - Trigger not fired due to lack of DMA support + * EIO - Trigger not fired because not previously primed + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_TRIGGER +static int spi_trigger(FAR struct spi_dev_s *dev) +{ +#ifdef CONFIG_STM32U5_SPI_DMA + FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + + if (!priv->trigarmed) + { + return -EIO; + } + + spi_dmarxstart(priv); + spi_dmatxstart(priv); + spi_enable(priv, true); + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSTART); + return OK; +#else + return -ENOSYS; +#endif +} +#endif + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of + * words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, + size_t nwords) +{ + spiinfo("txbuffer=%p nwords=%d\n", txbuffer, nwords); + return spi_exchange(dev, txbuffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_recvblock + * + * Description: + * Receive a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - the length of data that can be received in the buffer in + * number of words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, + FAR void *rxbuffer, + size_t nwords) +{ + spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + return spi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/**************************************************************************** + * Name: spi_pm_prepare + * + * 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. + * + * Input Parameters: + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state + * data at the end of the structure. + * domain - Identifies the activity domain of the state change + * pmstate - Identifies the new PM state + * + * Returned Value: + * 0 (OK) means the event was successfully processed and that the driver + * is prepared for the PM state change. Non-zero means that the driver + * is not prepared to perform the tasks needed achieve this power setting + * and will cause the state change to be aborted. NOTE: The prepare + * method will also be recalled when reverting from lower back to higher + * power consumption modes (say because another driver refused a lower + * power state change). Drivers are not permitted to return non-zero + * values when reverting back to higher power consumption modes! + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + struct stm32_spidev_s *priv = + (struct stm32_spidev_s *)((char *)cb - + offsetof(struct stm32_spidev_s, pm_cb)); + int sval; + + /* 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 exclusive lock for SPI bus is held. */ + + if (nxsem_get_value(&priv->exclsem, &sval) < 0) + { + DEBUGASSERT(false); + return -EINVAL; + } + + if (sval <= 0) + { + /* Exclusive lock is held, do not allow entry to deeper PM + * states. + */ + + return -EBUSY; + } + + break; + + default: + + /* Should not get here */ + + break; + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: spi_bus_initialize + * + * Description: + * Initialize the selected SPI bus in its default state (Master, 8-bit, + * mode 0, etc.) + * + * Input Parameters: + * priv - private SPI device structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void spi_bus_initialize(struct stm32_spidev_s *priv) +{ + uint32_t setbits = 0; + uint32_t clrbits = 0; +#ifdef CONFIG_PM + int ret; +#endif + + /* Configure CR1, CFG1 and CFG2. Default configuration: + * Mode 0: CFG2.CPHA=0 and CFG2.CPOL=0 + * Master: CFG2.MSTR=1 + * 8-bit: CFG1.DSIZE=7 + * MSB transmitted first: CFG2.LSBFRST=0 + * Replace NSS with SSI & SSI=1: CR1.SSI=1 CFG2.SSM=1 (prevents MODF + * error) + * Two lines full duplex: CFG2.COMM=0 + */ + + /* CR1 */ + + clrbits = SPI_CR1_SPE; + setbits = SPI_CR1_SSI; + + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, clrbits, setbits); + + /* CFG1 */ + + clrbits = SPI_CFG1_DSIZE_MASK; + setbits = SPI_CFG1_DSIZE_8BIT | SPI_CFG1_FTHLV_1DATA; /* REVISIT: FTHLV */ + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, clrbits, setbits); + + /* CFG2 */ + + clrbits = SPI_CFG2_CPHA | SPI_CFG2_CPOL | SPI_CFG2_LSBFRST | + SPI_CFG2_COMM_MASK; + setbits = SPI_CFG2_AFCNTR | SPI_CFG2_MASTER | SPI_CFG2_SSM; + + switch (priv->config) + { + default: + case FULL_DUPLEX: + setbits |= SPI_CFG2_COMM_FULL; + break; + case SIMPLEX_TX: + setbits |= SPI_CFG2_COMM_STX; + break; + case SIMPLEX_RX: + setbits |= SPI_CFG2_COMM_SRX; + break; + case HALF_DUPLEX: + setbits |= SPI_CFG2_COMM_HALF; + break; + } + + spi_modifyreg(priv, STM32_SPI_CFG2_OFFSET, clrbits, setbits); + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* CRCPOLY configuration */ + + spi_putreg(priv, STM32_SPI_CRCPOLY_OFFSET, 7); + + /* Initialize the SPI semaphore that enforces mutually exclusive access. */ + + nxsem_init(&priv->exclsem, 0, 1); + +#ifdef CONFIG_STM32U5_SPI_DMA + /* Initialize the SPI semaphores that is used to wait for DMA completion. + * This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + nxsem_init(&priv->rxsem, 0, 0); + nxsem_init(&priv->txsem, 0, 0); + + nxsem_set_protocol(&priv->rxsem, SEM_PRIO_NONE); + nxsem_set_protocol(&priv->txsem, SEM_PRIO_NONE); + + /* Get DMA channels. NOTE: stm32_dmachannel() will always assign the DMA + * channel. If the channel is not available, then stm32_dmachannel() will + * block and wait until the channel becomes available. WARNING: If you + * have another device sharing a DMA channel with SPI and the code never + * releases that channel, then the call to stm32_dmachannel() will hang + * forever in this function! Don't let your design do that! + */ + + priv->rxdma = NULL; + priv->txdma = NULL; + if (priv->config != SIMPLEX_TX) + { + priv->rxdma = stm32_dmachannel(priv->rxch); + DEBUGASSERT(priv->rxdma); + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_RXDMAEN); + } + + if (priv->config != SIMPLEX_RX) + { + priv->txdma = stm32_dmachannel(priv->txch); + DEBUGASSERT(priv->txdma); + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_TXDMAEN); + } +#endif + + /* Attach the IRQ to the driver */ + + if (irq_attach(priv->spiirq, spi_interrupt, priv)) + { + /* We could not attach the ISR to the interrupt */ + + spierr("ERROR: Can't initialize spi irq\n"); + return; + } + + /* Enable SPI interrupts */ + + up_enable_irq(priv->spiirq); + + /* Enable SPI */ + + spi_enable(priv, true); + +#ifdef CONFIG_PM + /* Register to receive power management callbacks */ + + ret = pm_register(&priv->pm_cb); + DEBUGASSERT(ret == OK); + UNUSED(ret); +#endif + +#ifdef CONFIG_DEBUG_SPI_INFO + /* Dump registers after initialization */ + + spi_dumpregs(priv); +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_spibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameters: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *stm32_spibus_initialize(int bus) +{ + FAR struct stm32_spidev_s *priv = NULL; + + irqstate_t flags = enter_critical_section(); +#ifdef CONFIG_STM32U5_SPI1 + if (bus == 1) + { + /* Select SPI1 */ + + priv = &g_spi1dev; + + /* Only configure if the bus is not already configured */ + + if (!priv->initialized) + { + /* Configure SPI1 pins: SCK, MISO, and MOSI */ + + stm32_configgpio(GPIO_SPI1_SCK); + stm32_configgpio(GPIO_SPI1_MISO); + stm32_configgpio(GPIO_SPI1_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + priv->initialized = true; + } + } + else +#endif +#ifdef CONFIG_STM32U5_SPI2 + if (bus == 2) + { + /* Select SPI2 */ + + priv = &g_spi2dev; + + /* Only configure if the bus is not already configured */ + + if (!priv->initialized) + { + /* Configure SPI2 pins: SCK, MISO, and MOSI */ + + stm32_configgpio(GPIO_SPI2_SCK); + stm32_configgpio(GPIO_SPI2_MISO); + stm32_configgpio(GPIO_SPI2_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + priv->initialized = true; + } + } + else +#endif +#ifdef CONFIG_STM32U5_SPI3 + if (bus == 3) + { + /* Select SPI3 */ + + priv = &g_spi3dev; + + /* Only configure if the bus is not already configured */ + + if (!priv->initialized) + { + /* Configure SPI3 pins: SCK, MISO, and MOSI */ + + stm32_configgpio(GPIO_SPI3_SCK); + stm32_configgpio(GPIO_SPI3_MISO); + stm32_configgpio(GPIO_SPI3_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + priv->initialized = true; + } + } + else +#endif + { + spierr("ERROR: Unsupported SPI bus: %d\n", bus); + } + + leave_critical_section(flags); + return (FAR struct spi_dev_s *)priv; +} + +#endif /* CONFIG_STM32U5_SPI1 || CONFIG_STM32U5_SPI2 || CONFIG_STM32U5_SPI3 + */ diff --git a/arch/arm/src/stm32u5/stm32_spi.h b/arch/arm/src/stm32u5/stm32_spi.h new file mode 100644 index 0000000000..4f121ffc55 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_spi.h @@ -0,0 +1,179 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_spi.h + * + * 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_STM32U5_STM32_SPI_H +#define __ARCH_ARM_SRC_STM32U5_STM32_SPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "hardware/stm32_spi.h" + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +struct spi_dev_s; /* Forward reference */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_spibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameters: + * bus number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *stm32_spibus_initialize(int bus); + +/**************************************************************************** + * Name: stm32_spi_slave_initialize + * + * Description: + * Initialize the selected SPI bus for slave operation + * + * Input Parameters: + * bus number + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_slave_ctrlr_s *stm32_spi_slave_initialize(int bus); + +/**************************************************************************** + * Name: stm32_spi1/2/...select and stm32_spi1/2/...status + * + * Description: + * The external functions, stm32_spi1/2/...select, stm32_spi1/2/...status, + * and stm32_spi1/2/...cmddata must be provided by board-specific logic. + * These are implementations of the select, status, and cmddata methods of + * the SPI interface defined by struct spi_ops_s (see + * include/nuttx/spi/spi.h). + * All other methods (including stm32_spibus_initialize()) are provided by + * common STM32 logic. To use this common SPI logic on your board: + * + * 1. Provide logic in stm32_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32_spi1/2/...select() and stm32_spi1/2/...status() + * functions in your board-specific logic. These functions will perform + * chip selection and status operations using GPIOs in the way your + * board is configured. + * 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file, + * then provide stm32_spi1/2/...cmddata() functions in your board- + * specific logic. These functions will perform cmd/data selection + * operations using GPIOs in the way your board is configured. + * 4. Add a calls to stm32_spibus_initialize() in your low level + * application initialization logic + * 5. The handle returned by stm32_spibus_initialize() may then be used to + * bind the SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +#ifdef CONFIG_STM32U5_SPI1 +void stm32_spi1select(FAR struct spi_dev_s *dev, uint32_t devid, + bool selected); +uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, uint32_t devid); +int stm32_spi1cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd); +#endif + +#ifdef CONFIG_STM32U5_SPI2 +void stm32_spi2select(FAR struct spi_dev_s *dev, uint32_t devid, + bool selected); +uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, uint32_t devid); +int stm32_spi2cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd); +#endif + +#ifdef CONFIG_STM32U5_SPI3 +void stm32_spi3select(FAR struct spi_dev_s *dev, uint32_t devid, + bool selected); +uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, uint32_t devid); +int stm32_spi3cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd); +#endif + +/**************************************************************************** + * Name: stm32_spi1/2/...register + * + * Description: + * If the board supports a card detect callback to inform the SPI-based + * MMC/SD driver when an SD card is inserted or removed, then + * CONFIG_SPI_CALLBACK should be defined and the following function(s) must + * be implemented. These functions implements the registercallback method + * of the SPI interface (see include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The function to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +#ifdef CONFIG_STM32U5_SPI1 +int stm32_spi1register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32U5_SPI2 +int stm32_spi2register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32U5_SPI3 +int stm32_spi3register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_SPI_H */ diff --git a/arch/arm/src/stm32u5/stm32_start.c b/arch/arm/src/stm32u5/stm32_start.c new file mode 100644 index 0000000000..67420ec9e1 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_start.c @@ -0,0 +1,315 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_start.c + * + * 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_arch.h" +#include "arm_internal.h" +#include "nvic.h" + +#include "stm32.h" +#include "stm32_gpio.h" +#include "stm32_userspace.h" +#include "stm32_start.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Memory Map ***************************************************************/ + +/* 0x0800:0000 - Beginning of the internal FLASH. Address of vectors. + * Mapped as boot memory address 0x0000:0000 at reset. + * 0x080f:ffff - End of flash region (assuming the max of 2MiB of FLASH). + * 0x2000:0000 - Start of internal SRAM1 and start of .data (_sdata) + * - End of .data (_edata) and start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, + * start of heap. NOTE that the ARM uses a decrement before + * store stack so that the correct initial value is the end of + * the stack + 4; + * 0x2002:ffff - End of internal SRAM1 + * 0x2003:0000 - Start of internal SRAM2 + * 0x2003:ffff - End of internal SRAM2 + */ + +#define SRAM2_START STM32U5_SRAM2_BASE +#define SRAM2_END (SRAM2_START + STM32U5_SRAM2_SIZE) + +#define HEAP_BASE ((uintptr_t)&_ebss + CONFIG_IDLETHREAD_STACKSIZE) + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ + +const uintptr_t g_idle_topstack = HEAP_BASE; + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +static inline void stm32_fpuconfig(void); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) arm_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_ARMV8M_STACKCHECK +/* we need to get r10 set before we can allow instrumentation calls */ + +void __start(void) noinstrument_function; +#endif + +/**************************************************************************** + * Name: stm32_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while + * either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#ifndef CONFIG_ARMV8M_LAZYFPU + +static inline void stm32_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= CONTROL_FPCA; + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~(NVIC_FPCCR_ASPEN | NVIC_FPCCR_LSPEN); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= NVIC_CPACR_CP_FULL(10) | NVIC_CPACR_CP_FULL(11); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void stm32_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~CONTROL_FPCA; + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~(NVIC_FPCCR_ASPEN | NVIC_FPCCR_LSPEN); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= NVIC_CPACR_CP_FULL(10) | NVIC_CPACR_CP_FULL(11); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define stm32_fpuconfig() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(void) +{ + const uint32_t *src; + uint32_t *dest; + +#ifdef CONFIG_ARMV8M_STACKCHECK + /* Set the stack limit before we attempt to call any functions */ + + __asm__ volatile + ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) :); +#endif + +#ifdef CONFIG_STM32U5_SRAM2_INIT + /* The SRAM2 region is parity checked, but upon power up, it will be in + * a random state and probably invalid with respect to parity, potentially + * generating faults if accessed. If elected, we will write zeros to the + * memory, forcing the parity to be set to a valid state. + * NOTE: this is optional because this may be inappropriate, especially + * if the memory is being used for it's battery backed purpose. In that + * case, the first-time initialization needs to be performed by the board + * under application-specific circumstances. On the other hand, if we're + * using this memory for, say, additional heap space, then this is handy. + */ + + for (dest = (uint32_t *)SRAM2_START; dest < (uint32_t *)SRAM2_END; ) + { + *dest++ = 0; + } +#endif + + /* Configure the UART so that we can get debug output as soon as possible */ + + stm32_clockconfig(); + stm32_fpuconfig(); + stm32_lowsetup(); + stm32_gpioinit(); + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + showprogress('C'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + arm_earlyserialinit(); +#endif + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + stm32_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + stm32_board_initialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + + nx_start(); + + /* Shoulnd't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/stm32u5/stm32_start.h b/arch/arm/src/stm32u5/stm32_start.h new file mode 100644 index 0000000000..de91866107 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_start.h @@ -0,0 +1,45 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_start.h + * + * 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_STM32U5_STM32_START_H +#define __ARCH_ARM_SRC_STM32U5_STM32_START_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_board_initialize + * + * Description: + * All STM32U5 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_STM32U5_STM32_START_H */ diff --git a/arch/arm/src/stm32u5/stm32_tim.c b/arch/arm/src/stm32u5/stm32_tim.c new file mode 100644 index 0000000000..74965410eb --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_tim.c @@ -0,0 +1,1693 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_tim.c + * + * 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 "chip.h" +#include "arm_internal.h" +#include "arm_arch.h" + +#include "stm32.h" +#include "stm32_gpio.h" +#include "stm32_tim.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Timer devices may be used for different purposes. Such special purposes + * include: + * + * - To generate modulated outputs for such things as motor control. If + * CONFIG_STM32U5_TIMn is defined then the CONFIG_STM32U5_TIMn_PWM may also + * be defined to indicate that the timer is intended to be used for pulsed + * output modulation. + * + * - To control periodic ADC input sampling. If CONFIG_STM32U5_TIMn is + * defined then CONFIG_STM32U5_TIMn_ADC may also be defined to indicate + * that timer "n" is intended to be used for that purpose. + * + * - To control periodic DAC outputs. If CONFIG_STM32U5_TIMn is defined then + * CONFIG_STM32U5_TIMn_DAC may also be defined to indicate that timer "n" + * is intended to be used for that purpose. + * + * - To use a Quadrature Encoder. If CONFIG_STM32U5_TIMn is defined then + * CONFIG_STM32U5_TIMn_QE may also be defined to indicate that timer "n" + * is intended to be used for that purpose. + * + * In any of these cases, the timer will not be used by this timer module. + */ + +#if defined(CONFIG_STM32U5_TIM1_PWM) || defined (CONFIG_STM32U5_TIM1_ADC) || \ + defined(CONFIG_STM32U5_TIM1_DAC) || defined(CONFIG_STM32U5_TIM1_QE) +# undef CONFIG_STM32U5_TIM1 +#endif + +#if defined(CONFIG_STM32U5_TIM2_PWM) || defined (CONFIG_STM32U5_TIM2_ADC) || \ + defined(CONFIG_STM32U5_TIM2_DAC) || defined(CONFIG_STM32U5_TIM2_QE) +# undef CONFIG_STM32U5_TIM2 +#endif + +#if defined(CONFIG_STM32U5_TIM3_PWM) || defined (CONFIG_STM32U5_TIM3_ADC) || \ + defined(CONFIG_STM32U5_TIM3_DAC) || defined(CONFIG_STM32U5_TIM3_QE) +# undef CONFIG_STM32U5_TIM3 +#endif + +#if defined(CONFIG_STM32U5_TIM4_PWM) || defined (CONFIG_STM32U5_TIM4_ADC) || \ + defined(CONFIG_STM32U5_TIM4_DAC) || defined(CONFIG_STM32U5_TIM4_QE) +# undef CONFIG_STM32U5_TIM4 +#endif + +#if defined(CONFIG_STM32U5_TIM5_PWM) || defined (CONFIG_STM32U5_TIM5_ADC) || \ + defined(CONFIG_STM32U5_TIM5_DAC) || defined(CONFIG_STM32U5_TIM5_QE) +# undef CONFIG_STM32U5_TIM5 +#endif + +#if defined(CONFIG_STM32U5_TIM6_PWM) || defined (CONFIG_STM32U5_TIM6_ADC) || \ + defined(CONFIG_STM32U5_TIM6_DAC) || defined(CONFIG_STM32U5_TIM6_QE) +# undef CONFIG_STM32U5_TIM6 +#endif + +#if defined(CONFIG_STM32U5_TIM7_PWM) || defined (CONFIG_STM32U5_TIM7_ADC) || \ + defined(CONFIG_STM32U5_TIM7_DAC) || defined(CONFIG_STM32U5_TIM7_QE) +# undef CONFIG_STM32U5_TIM7 +#endif + +#if defined(CONFIG_STM32U5_TIM8_PWM) || defined (CONFIG_STM32U5_TIM8_ADC) || \ + defined(CONFIG_STM32U5_TIM8_DAC) || defined(CONFIG_STM32U5_TIM8_QE) +# undef CONFIG_STM32U5_TIM8 +#endif + +#if defined(CONFIG_STM32U5_TIM15_PWM) || defined (CONFIG_STM32U5_TIM15_ADC) || \ + defined(CONFIG_STM32U5_TIM15_DAC) || defined(CONFIG_STM32U5_TIM15_QE) +# undef CONFIG_STM32U5_TIM15 +#endif + +#if defined(CONFIG_STM32U5_TIM16_PWM) || defined (CONFIG_STM32U5_TIM16_ADC) || \ + defined(CONFIG_STM32U5_TIM16_DAC) || defined(CONFIG_STM32U5_TIM16_QE) +# undef CONFIG_STM32U5_TIM16 +#endif + +#if defined(CONFIG_STM32U5_TIM17_PWM) || defined (CONFIG_STM32U5_TIM17_ADC) || \ + defined(CONFIG_STM32U5_TIM17_DAC) || defined(CONFIG_STM32U5_TIM17_QE) +# undef CONFIG_STM32U5_TIM17 +#endif + +#if defined(CONFIG_STM32U5_TIM1) +# if defined(GPIO_TIM1_CH1OUT) ||defined(GPIO_TIM1_CH2OUT)||\ + defined(GPIO_TIM1_CH3OUT) ||defined(GPIO_TIM1_CH4OUT) +# define HAVE_TIM1_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32U5_TIM2) +# if defined(GPIO_TIM2_CH1OUT) ||defined(GPIO_TIM2_CH2OUT)||\ + defined(GPIO_TIM2_CH3OUT) ||defined(GPIO_TIM2_CH4OUT) +# define HAVE_TIM2_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32U5_TIM3) +# if defined(GPIO_TIM3_CH1OUT) ||defined(GPIO_TIM3_CH2OUT)||\ + defined(GPIO_TIM3_CH3OUT) ||defined(GPIO_TIM3_CH4OUT) +# define HAVE_TIM3_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32U5_TIM4) +# if defined(GPIO_TIM4_CH1OUT) ||defined(GPIO_TIM4_CH2OUT)||\ + defined(GPIO_TIM4_CH3OUT) ||defined(GPIO_TIM4_CH4OUT) +# define HAVE_TIM4_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32U5_TIM5) +# if defined(GPIO_TIM5_CH1OUT) ||defined(GPIO_TIM5_CH2OUT)||\ + defined(GPIO_TIM5_CH3OUT) ||defined(GPIO_TIM5_CH4OUT) +# define HAVE_TIM5_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32U5_TIM8) +# if defined(GPIO_TIM8_CH1OUT) ||defined(GPIO_TIM8_CH2OUT)||\ + defined(GPIO_TIM8_CH3OUT) ||defined(GPIO_TIM8_CH4OUT) +# define HAVE_TIM8_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32U5_TIM15) +# if defined(GPIO_TIM15_CH1OUT) ||defined(GPIO_TIM15_CH2OUT)||\ + defined(GPIO_TIM15_CH3OUT) ||defined(GPIO_TIM15_CH4OUT) +# define HAVE_TIM15_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32U5_TIM16) +# if defined(GPIO_TIM16_CH1OUT) ||defined(GPIO_TIM16_CH2OUT)||\ + defined(GPIO_TIM16_CH3OUT) ||defined(GPIO_TIM16_CH4OUT) +# define HAVE_TIM16_GPIOCONFIG 1 +#endif +#endif + +#if defined(CONFIG_STM32U5_TIM17) +# if defined(GPIO_TIM17_CH1OUT) ||defined(GPIO_TIM17_CH2OUT)||\ + defined(GPIO_TIM17_CH3OUT) ||defined(GPIO_TIM17_CH4OUT) +# define HAVE_TIM17_GPIOCONFIG 1 +#endif +#endif + +/* This module then only compiles if there are enabled timers that are not + * intended for some other purpose. + */ + +#if defined(CONFIG_STM32U5_TIM1) || defined(CONFIG_STM32U5_TIM2) || \ + defined(CONFIG_STM32U5_TIM3) || defined(CONFIG_STM32U5_TIM4) || \ + defined(CONFIG_STM32U5_TIM5) || defined(CONFIG_STM32U5_TIM6) || \ + defined(CONFIG_STM32U5_TIM7) || defined(CONFIG_STM32U5_TIM8) || \ + defined(CONFIG_STM32U5_TIM15) || defined(CONFIG_STM32U5_TIM16) || \ + defined(CONFIG_STM32U5_TIM17) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* TIM Device Structure */ + +struct stm32_tim_priv_s +{ + FAR const struct stm32_tim_ops_s *ops; + enum stm32_tim_mode_e mode; + uint32_t base; /* TIMn base address */ +}; + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +/* Register helpers */ + +static inline uint16_t stm32_getreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset); +static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint16_t value); +static inline void stm32_modifyreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint16_t clearbits, + uint16_t setbits); +static inline uint32_t stm32_getreg32(FAR struct stm32_tim_dev_s *dev, + uint8_t offset); +static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint32_t value); + +/* Timer helpers */ + +static void stm32_tim_reload_counter(FAR struct stm32_tim_dev_s *dev); +static void stm32_tim_enable(FAR struct stm32_tim_dev_s *dev); +static void stm32_tim_disable(FAR struct stm32_tim_dev_s *dev); +static void stm32_tim_reset(FAR struct stm32_tim_dev_s *dev); +#if defined(HAVE_TIM1_GPIOCONFIG) || defined(HAVE_TIM2_GPIOCONFIG) || \ + defined(HAVE_TIM3_GPIOCONFIG) || defined(HAVE_TIM4_GPIOCONFIG) || \ + defined(HAVE_TIM5_GPIOCONFIG) || defined(HAVE_TIM8_GPIOCONFIG) || \ + defined(HAVE_TIM15_GPIOCONFIG) || defined(HAVE_TIM16_GPIOCONFIG) || \ + defined(HAVE_TIM17_GPIOCONFIG) +static void stm32_tim_gpioconfig(uint32_t cfg, + enum stm32_tim_channel_e mode); +#endif + +/* Timer methods */ + +static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, + enum stm32_tim_mode_e mode); +static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, + uint32_t freq); +static uint32_t stm32_tim_getclock(FAR struct stm32_tim_dev_s *dev); +static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev, + uint32_t period); +static uint32_t stm32_tim_getperiod(FAR struct stm32_tim_dev_s *dev); +static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev); +static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, + uint8_t channel, + enum stm32_tim_channel_e mode); +static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, + uint8_t channel, uint32_t compare); +static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, + uint8_t channel); +static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, + xcpt_t handler, void *arg, int source); +static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, + int source); +static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, + int source); +static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, + int source); +static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, + int source); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct stm32_tim_ops_s stm32_tim_ops = +{ + .setmode = stm32_tim_setmode, + .setclock = stm32_tim_setclock, + .getclock = stm32_tim_getclock, + .setperiod = stm32_tim_setperiod, + .getperiod = stm32_tim_getperiod, + .getcounter = stm32_tim_getcounter, + .setchannel = stm32_tim_setchannel, + .setcompare = stm32_tim_setcompare, + .getcapture = stm32_tim_getcapture, + .setisr = stm32_tim_setisr, + .enableint = stm32_tim_enableint, + .disableint = stm32_tim_disableint, + .ackint = stm32_tim_ackint, + .checkint = stm32_tim_checkint, +}; + +#ifdef CONFIG_STM32U5_TIM1 +struct stm32_tim_priv_s stm32_tim1_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM1_BASE, +}; +#endif +#ifdef CONFIG_STM32U5_TIM2 +struct stm32_tim_priv_s stm32_tim2_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM2_BASE, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM3 +struct stm32_tim_priv_s stm32_tim3_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM3_BASE, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM4 +struct stm32_tim_priv_s stm32_tim4_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM4_BASE, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM5 +struct stm32_tim_priv_s stm32_tim5_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM5_BASE, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM6 +struct stm32_tim_priv_s stm32_tim6_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM6_BASE, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM7 +struct stm32_tim_priv_s stm32_tim7_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM7_BASE, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM8 +struct stm32_tim_priv_s stm32_tim8_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM8_BASE, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM15 +struct stm32_tim_priv_s stm32_tim15_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM15_BASE, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM16 +struct stm32_tim_priv_s stm32_tim16_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM16_BASE, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM17 +struct stm32_tim_priv_s stm32_tim17_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32U5_TIM_MODE_UNUSED, + .base = STM32U5_TIM17_BASE, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_getreg16 + * + * Description: + * Get a 16-bit register value by offset + * + ****************************************************************************/ + +static inline uint16_t stm32_getreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset) +{ + return getreg16(((struct stm32_tim_priv_s *)dev)->base + offset); +} + +/**************************************************************************** + * Name: stm32_putreg16 + * + * Description: + * Put a 16-bit register value by offset + * + ****************************************************************************/ + +static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint16_t value) +{ + putreg16(value, ((struct stm32_tim_priv_s *)dev)->base + offset); +} + +/**************************************************************************** + * Name: stm32_modifyreg16 + * + * Description: + * Modify a 16-bit register value by offset + * + ****************************************************************************/ + +static inline void stm32_modifyreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg16(((struct stm32_tim_priv_s *)dev)->base + offset, clearbits, + setbits); +} + +/**************************************************************************** + * Name: stm32_getreg32 + * + * Description: + * Get a 32-bit register value by offset. This applies only for the + * STM32U5 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. + * + ****************************************************************************/ + +static inline uint32_t stm32_getreg32(FAR struct stm32_tim_dev_s *dev, + uint8_t offset) +{ + return getreg32(((struct stm32_tim_priv_s *)dev)->base + offset); +} + +/**************************************************************************** + * Name: stm32_putreg32 + * + * Description: + * Put a 32-bit register value by offset. This applies only for the + * STM32U5 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. + * + ****************************************************************************/ + +static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint32_t value) +{ + putreg32(value, ((struct stm32_tim_priv_s *)dev)->base + offset); +} + +/**************************************************************************** + * Name: stm32_tim_reload_counter + ****************************************************************************/ + +static void stm32_tim_reload_counter(FAR struct stm32_tim_dev_s *dev) +{ + uint16_t val = stm32_getreg16(dev, STM32U5_GTIM_EGR_OFFSET); + val |= GTIM_EGR_UG; + stm32_putreg16(dev, STM32U5_GTIM_EGR_OFFSET, val); +} + +/**************************************************************************** + * Name: stm32_tim_enable + ****************************************************************************/ + +static void stm32_tim_enable(FAR struct stm32_tim_dev_s *dev) +{ + uint16_t val = stm32_getreg16(dev, STM32U5_GTIM_CR1_OFFSET); + val |= GTIM_CR1_CEN; + stm32_tim_reload_counter(dev); + stm32_putreg16(dev, STM32U5_GTIM_CR1_OFFSET, val); +} + +/**************************************************************************** + * Name: stm32_tim_disable + ****************************************************************************/ + +static void stm32_tim_disable(FAR struct stm32_tim_dev_s *dev) +{ + uint16_t val = stm32_getreg16(dev, STM32U5_GTIM_CR1_OFFSET); + val &= ~GTIM_CR1_CEN; + stm32_putreg16(dev, STM32U5_GTIM_CR1_OFFSET, val); +} + +/**************************************************************************** + * Name: stm32_tim_reset + * + * Description: + * Reset timer into system default state, but do not affect output/input + * pins + * + ****************************************************************************/ + +static void stm32_tim_reset(FAR struct stm32_tim_dev_s *dev) +{ + ((struct stm32_tim_priv_s *)dev)->mode = STM32U5_TIM_MODE_DISABLED; + stm32_tim_disable(dev); +} + +/**************************************************************************** + * Name: stm32_tim_gpioconfig + ****************************************************************************/ + +#if defined(HAVE_TIM1_GPIOCONFIG) || defined(HAVE_TIM2_GPIOCONFIG) || \ + defined(HAVE_TIM3_GPIOCONFIG) || defined(HAVE_TIM4_GPIOCONFIG) || \ + defined(HAVE_TIM5_GPIOCONFIG) || defined(HAVE_TIM8_GPIOCONFIG) || \ + defined(HAVE_TIM15_GPIOCONFIG) || defined(HAVE_TIM16_GPIOCONFIG) || \ + defined(HAVE_TIM17_GPIOCONFIG) +static void stm32_tim_gpioconfig(uint32_t cfg, + enum stm32_tim_channel_e mode) +{ + /* TODO: Add support for input capture and bipolar dual outputs for TIM8 */ + + if (mode & STM32U5_TIM_CH_MODE_MASK) + { + stm32_configgpio(cfg); + } + else + { + stm32_unconfiggpio(cfg); + } +} +#endif + +/**************************************************************************** + * Name: stm32_tim_setmode + ****************************************************************************/ + +static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, + enum stm32_tim_mode_e mode) +{ + uint16_t val = GTIM_CR1_CEN | GTIM_CR1_ARPE; + + DEBUGASSERT(dev != NULL); + + /* This function is not supported on basic timers. To enable or + * disable it, simply set its clock to valid frequency or zero. + */ + +#if STM32U5_NBTIM > 0 + if (((struct stm32_tim_priv_s *)dev)->base == STM32U5_TIM6_BASE +#endif +#if STM32U5_NBTIM > 1 + || ((struct stm32_tim_priv_s *)dev)->base == STM32U5_TIM7_BASE +#endif +#if STM32U5_NBTIM > 0 + ) + { + return -EINVAL; + } +#endif + + /* Decode operational modes */ + + switch (mode & STM32U5_TIM_MODE_MASK) + { + case STM32U5_TIM_MODE_DISABLED: + val = 0; + break; + + case STM32U5_TIM_MODE_DOWN: + val |= GTIM_CR1_DIR; + + case STM32U5_TIM_MODE_UP: + break; + + case STM32U5_TIM_MODE_UPDOWN: + val |= GTIM_CR1_CENTER1; + + /* Our default: Interrupts are generated on compare, when counting + * down + */ + + break; + + case STM32U5_TIM_MODE_PULSE: + val |= GTIM_CR1_OPM; + break; + + default: + return -EINVAL; + } + + stm32_tim_reload_counter(dev); + stm32_putreg16(dev, STM32U5_GTIM_CR1_OFFSET, val); + +#if STM32U5_NATIM > 0 + /* Advanced registers require Main Output Enable */ + + if (((struct stm32_tim_priv_s *)dev)->base == STM32U5_TIM1_BASE || + ((struct stm32_tim_priv_s *)dev)->base == STM32U5_TIM8_BASE) + { + stm32_modifyreg16(dev, STM32U5_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE); + } +#endif + + return OK; +} + +/**************************************************************************** + * Name: stm32_tim_setclock + ****************************************************************************/ + +static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, + uint32_t freq) +{ + uint32_t freqin; + int prescaler; + + DEBUGASSERT(dev != NULL); + + /* Disable Timer? */ + + if (freq == 0) + { + stm32_tim_disable(dev); + return 0; + } + + /* Get the input clock frequency for this timer. These vary with + * different timer clock sources, MCU-specific timer configuration, and + * board-specific clock configuration. The correct input clock frequency + * must be defined in the board.h header file. + */ + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32U5_TIM1 + case STM32U5_TIM1_BASE: + freqin = BOARD_TIM1_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM2 + case STM32U5_TIM2_BASE: + freqin = BOARD_TIM2_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM3 + case STM32U5_TIM3_BASE: + freqin = BOARD_TIM3_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM4 + case STM32U5_TIM4_BASE: + freqin = BOARD_TIM4_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM5 + case STM32U5_TIM5_BASE: + freqin = BOARD_TIM5_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM6 + case STM32U5_TIM6_BASE: + freqin = BOARD_TIM6_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM7 + case STM32U5_TIM7_BASE: + freqin = BOARD_TIM7_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM8 + case STM32U5_TIM8_BASE: + freqin = BOARD_TIM8_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM15 + case STM32U5_TIM15_BASE: + freqin = BOARD_TIM15_FREQUENCY; + break; +#endif +#ifdef CONFIG_STM32U5_TIM16 + case STM32U5_TIM16_BASE: + freqin = BOARD_TIM16_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM17 + case STM32U5_TIM17_BASE: + freqin = BOARD_TIM17_FREQUENCY; + break; +#endif + + default: + return -EINVAL; + } + + /* Select a pre-scaler value for this timer using the input clock + * frequency. + */ + + prescaler = freqin / freq; + + /* We need to decrement value for '1', but only, if that will not to + * cause underflow. + */ + + if (prescaler > 0) + { + prescaler--; + } + + /* Check for overflow as well. */ + + if (prescaler > 0xffff) + { + prescaler = 0xffff; + } + + stm32_putreg16(dev, STM32U5_GTIM_PSC_OFFSET, prescaler); + stm32_tim_enable(dev); + + return prescaler; +} + +/**************************************************************************** + * Name: stm32_tim_getclock + ****************************************************************************/ + +static uint32_t stm32_tim_getclock(FAR struct stm32_tim_dev_s *dev) +{ + uint32_t freqin; + uint32_t clock; + DEBUGASSERT(dev != NULL); + + /* Get the input clock frequency for this timer. These vary with + * different timer clock sources, MCU-specific timer configuration, and + * board-specific clock configuration. The correct input clock frequency + * must be defined in the board.h header file. + */ + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32U5_TIM1 + case STM32U5_TIM1_BASE: + freqin = BOARD_TIM1_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM2 + case STM32U5_TIM2_BASE: + freqin = BOARD_TIM2_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM3 + case STM32U5_TIM3_BASE: + freqin = BOARD_TIM3_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM4 + case STM32U5_TIM4_BASE: + freqin = BOARD_TIM4_FREQUENCY; + break; +#endif +#ifdef CONFIG_STM32U5_TIM5 + case STM32U5_TIM5_BASE: + freqin = BOARD_TIM5_FREQUENCY; + break; +#endif +#ifdef CONFIG_STM32U5_TIM6 + case STM32U5_TIM6_BASE: + freqin = BOARD_TIM6_FREQUENCY; + break; +#endif +#ifdef CONFIG_STM32U5_TIM7 + case STM32U5_TIM7_BASE: + freqin = BOARD_TIM7_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM8 + case STM32U5_TIM8_BASE: + freqin = BOARD_TIM8_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM15 + case STM32U5_TIM15_BASE: + freqin = BOARD_TIM15_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM16 + case STM32U5_TIM16_BASE: + freqin = BOARD_TIM16_FREQUENCY; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM17 + case STM32U5_TIM17_BASE: + freqin = BOARD_TIM17_FREQUENCY; + break; +#endif + default: + return -EINVAL; + } + + /* From chip datasheet, at page 1179. */ + + clock = freqin / (stm32_getreg16(dev, STM32U5_GTIM_PSC_OFFSET) + 1); + return clock; +} + +/**************************************************************************** + * Name: stm32_tim_setperiod + ****************************************************************************/ + +static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev, + uint32_t period) +{ + DEBUGASSERT(dev != NULL); + stm32_putreg32(dev, STM32U5_GTIM_ARR_OFFSET, period); +} + +/**************************************************************************** + * Name: stm32_tim_getperiod + ****************************************************************************/ + +static uint32_t stm32_tim_getperiod (FAR struct stm32_tim_dev_s *dev) +{ + DEBUGASSERT(dev != NULL); + return stm32_getreg32 (dev, STM32U5_GTIM_ARR_OFFSET); +} + +/**************************************************************************** + * Name: stm32_tim_getcounter + ****************************************************************************/ + +static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev) +{ + DEBUGASSERT(dev != NULL); + uint32_t counter = stm32_getreg32(dev, STM32U5_GTIM_CNT_OFFSET); + + /* In datasheet page 988, there is a useless bit named UIFCPY in TIMx_CNT. + * reset it it result when not TIM2 or TIM5. + */ + +#if defined(CONFIG_STM32U5_TIM2) || defined(CONFIG_STM32U5_TIM5) + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32U5_TIM2 + case STM32U5_TIM2_BASE: +#endif +#ifdef CONFIG_STM32U5_TIM5 + case STM32U5_TIM5_BASE: +#endif + return counter; + + default: + return counter & 0x0000ffff; + } +#else + return counter & 0x0000ffff; +#endif +} + +/**************************************************************************** + * Name: stm32_tim_setchannel + ****************************************************************************/ + +static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, + uint8_t channel, + enum stm32_tim_channel_e mode) +{ + uint16_t ccmr_orig = 0; + uint16_t ccmr_val = 0; + uint16_t ccmr_mask = 0xff; + uint16_t ccer_val; + uint8_t ccmr_offset = STM32U5_GTIM_CCMR1_OFFSET; + + DEBUGASSERT(dev != NULL); + + /* Further we use range as 0..3; if channel=0 it will also overflow here */ + + if (--channel > 4) + { + return -EINVAL; + } + + /* Assume that channel is disabled and polarity is active high */ + + ccer_val = stm32_getreg16(dev, STM32U5_GTIM_CCER_OFFSET); + ccer_val &= ~((GTIM_CCER_CC1P | GTIM_CCER_CC1E) << + GTIM_CCER_CCXBASE(channel)); + + /* This function is not supported on basic timers. To enable or + * disable it, simply set its clock to valid frequency or zero. + */ + +#if STM32U5_NBTIM > 0 + if (((struct stm32_tim_priv_s *)dev)->base == STM32U5_TIM6_BASE +#endif +#if STM32U5_NBTIM > 1 + || ((struct stm32_tim_priv_s *)dev)->base == STM32U5_TIM7_BASE +#endif +#if STM32U5_NBTIM > 0 + ) + { + return -EINVAL; + } +#endif + + /* Decode configuration */ + + switch (mode & STM32U5_TIM_CH_MODE_MASK) + { + case STM32U5_TIM_CH_DISABLED: + break; + + case STM32U5_TIM_CH_OUTPWM: + ccmr_val = (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC1M_SHIFT) + + GTIM_CCMR1_OC1PE; + ccer_val |= GTIM_CCER_CC1E << GTIM_CCER_CCXBASE(channel); + break; + + default: + return -EINVAL; + } + + /* Set polarity */ + + if (mode & STM32U5_TIM_CH_POLARITY_NEG) + { + ccer_val |= GTIM_CCER_CC1P << GTIM_CCER_CCXBASE(channel); + } + + /* Define its position (shift) and get register offset */ + + if (channel & 1) + { + ccmr_val <<= 8; + ccmr_mask <<= 8; + } + + if (channel > 1) + { + ccmr_offset = STM32U5_GTIM_CCMR2_OFFSET; + } + + ccmr_orig = stm32_getreg16(dev, ccmr_offset); + ccmr_orig &= ~ccmr_mask; + ccmr_orig |= ccmr_val; + stm32_putreg16(dev, ccmr_offset, ccmr_orig); + stm32_putreg16(dev, STM32U5_GTIM_CCER_OFFSET, ccer_val); + + /* set GPIO */ + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32U5_TIM1 + case STM32U5_TIM1_BASE: + switch (channel) + { +#if defined(GPIO_TIM1_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM1_CH1OUT, mode); + break; +#endif + +#if defined(GPIO_TIM1_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM1_CH2OUT, mode); + break; +#endif + +#if defined(GPIO_TIM1_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM1_CH3OUT, mode); + break; +#endif + +#if defined(GPIO_TIM1_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM1_CH4OUT, mode); + break; +#endif + + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32U5_TIM2 + case STM32U5_TIM2_BASE: + switch (channel) + { +#if defined(GPIO_TIM2_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM2_CH1OUT, mode); + break; +#endif + +#if defined(GPIO_TIM2_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM2_CH2OUT, mode); + break; +#endif + +#if defined(GPIO_TIM2_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM2_CH3OUT, mode); + break; +#endif + +#if defined(GPIO_TIM2_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM2_CH4OUT, mode); + break; +#endif + + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32U5_TIM3 + case STM32U5_TIM3_BASE: + switch (channel) + { +#if defined(GPIO_TIM3_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM3_CH1OUT, mode); + break; +#endif + +#if defined(GPIO_TIM3_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM3_CH2OUT, mode); + break; +#endif + +#if defined(GPIO_TIM3_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM3_CH3OUT, mode); + break; +#endif + +#if defined(GPIO_TIM3_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM3_CH4OUT, mode); + break; +#endif + + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32U5_TIM4 + case STM32U5_TIM4_BASE: + switch (channel) + { +#if defined(GPIO_TIM4_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM4_CH1OUT, mode); + break; +#endif + +#if defined(GPIO_TIM4_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM4_CH2OUT, mode); + break; +#endif +#if defined(GPIO_TIM4_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM4_CH3OUT, mode); + break; +#endif + +#if defined(GPIO_TIM4_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM4_CH4OUT, mode); + break; +#endif + + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32U5_TIM5 + case STM32U5_TIM5_BASE: + switch (channel) + { +#if defined(GPIO_TIM5_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM5_CH1OUT, mode); + break; +#endif + +#if defined(GPIO_TIM5_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM5_CH2OUT, mode); + break; +#endif + +#if defined(GPIO_TIM5_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM5_CH3OUT, mode); + break; +#endif + +#if defined(GPIO_TIM5_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM5_CH4OUT, mode); + break; +#endif + + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32U5_TIM8 + case STM32U5_TIM8_BASE: + switch (channel) + { +#if defined(GPIO_TIM8_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM8_CH1OUT, mode); + break; +#endif + +#if defined(GPIO_TIM8_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM8_CH2OUT, mode); + break; +#endif + +#if defined(GPIO_TIM8_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM8_CH3OUT, mode); + break; +#endif + +#if defined(GPIO_TIM8_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM8_CH4OUT, mode); + break; +#endif + + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32U5_TIM15 + case STM32U5_TIM15_BASE: + switch (channel) + { +#if defined(GPIO_TIM15_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM15_CH1OUT, mode); + break; +#endif + +#if defined(GPIO_TIM15_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM15_CH2OUT, mode); + break; +#endif + +#if defined(GPIO_TIM15_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM15_CH3OUT, mode); + break; +#endif + +#if defined(GPIO_TIM15_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM15_CH4OUT, mode); + break; +#endif + + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32U5_TIM16 + case STM32U5_TIM16_BASE: + switch (channel) + { +#if defined(GPIO_TIM16_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM16_CH1OUT, mode); + break; +#endif + +#if defined(GPIO_TIM16_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM16_CH2OUT, mode); + break; +#endif + +#if defined(GPIO_TIM16_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM16_CH3OUT, mode); + break; +#endif + +#if defined(GPIO_TIM16_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM16_CH4OUT, mode); + break; +#endif + + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32U5_TIM17 + case STM32U5_TIM17_BASE: + switch (channel) + { +#if defined(GPIO_TIM17_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM17_CH1OUT, mode); + break; +#endif + +#if defined(GPIO_TIM17_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM17_CH2OUT, mode); + break; +#endif + +#if defined(GPIO_TIM17_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM17_CH3OUT, mode); + break; +#endif + +#if defined(GPIO_TIM17_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM17_CH4OUT, mode); + break; +#endif + + default: + return -EINVAL; + } + break; +#endif + + default: + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_tim_setcompare + ****************************************************************************/ + +static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, + uint8_t channel, uint32_t compare) +{ + DEBUGASSERT(dev != NULL); + + switch (channel) + { + case 1: + stm32_putreg32(dev, STM32U5_GTIM_CCR1_OFFSET, compare); + break; + + case 2: + stm32_putreg32(dev, STM32U5_GTIM_CCR2_OFFSET, compare); + break; + + case 3: + stm32_putreg32(dev, STM32U5_GTIM_CCR3_OFFSET, compare); + break; + + case 4: + stm32_putreg32(dev, STM32U5_GTIM_CCR4_OFFSET, compare); + break; + + default: + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_tim_getcapture + ****************************************************************************/ + +static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, + uint8_t channel) +{ + DEBUGASSERT(dev != NULL); + + switch (channel) + { + case 1: + return stm32_getreg32(dev, STM32U5_GTIM_CCR1_OFFSET); + + case 2: + return stm32_getreg32(dev, STM32U5_GTIM_CCR2_OFFSET); + + case 3: + return stm32_getreg32(dev, STM32U5_GTIM_CCR3_OFFSET); + + case 4: + return stm32_getreg32(dev, STM32U5_GTIM_CCR4_OFFSET); + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: stm32_tim_setisr + ****************************************************************************/ + +static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, + xcpt_t handler, void *arg, int source) +{ + int vectorno; + + DEBUGASSERT(dev != NULL); + DEBUGASSERT(source == 0); + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32U5_TIM1 + case STM32U5_TIM1_BASE: + vectorno = STM32U5_IRQ_TIM1UP; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM2 + case STM32U5_TIM2_BASE: + vectorno = STM32U5_IRQ_TIM2; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM3 + case STM32U5_TIM3_BASE: + vectorno = STM32U5_IRQ_TIM3; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM4 + case STM32U5_TIM4_BASE: + vectorno = STM32U5_IRQ_TIM4; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM5 + case STM32U5_TIM5_BASE: + vectorno = STM32U5_IRQ_TIM5; + break; +#endif +#ifdef CONFIG_STM32U5_TIM6 + case STM32U5_TIM6_BASE: + vectorno = STM32U5_IRQ_TIM6; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM7 + case STM32U5_TIM7_BASE: + vectorno = STM32U5_IRQ_TIM7; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM8 + case STM32U5_TIM8_BASE: + vectorno = STM32U5_IRQ_TIM8UP; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM15 + case STM32U5_TIM15_BASE: + vectorno = STM32U5_IRQ_TIM15; + break; +#endif +#ifdef CONFIG_STM32U5_TIM16 + case STM32U5_TIM16_BASE: + vectorno = STM32U5_IRQ_TIM16; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM17 + case STM32U5_TIM17_BASE: + vectorno = STM32U5_IRQ_TIM17; + break; +#endif + + default: + return -EINVAL; + } + + /* Disable interrupt when callback is removed */ + + if (!handler) + { + up_disable_irq(vectorno); + irq_detach(vectorno); + return OK; + } + + /* Otherwise set callback and enable interrupt */ + + irq_attach(vectorno, handler, arg); + up_enable_irq(vectorno); + + return OK; +} + +/**************************************************************************** + * Name: stm32_tim_enableint + ****************************************************************************/ + +static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, + int source) +{ + DEBUGASSERT(dev != NULL); + stm32_modifyreg16(dev, STM32U5_GTIM_DIER_OFFSET, 0, GTIM_DIER_UIE); +} + +/**************************************************************************** + * Name: stm32_tim_disableint + ****************************************************************************/ + +static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, + int source) +{ + DEBUGASSERT(dev != NULL); + stm32_modifyreg16(dev, STM32U5_GTIM_DIER_OFFSET, GTIM_DIER_UIE, 0); +} + +/**************************************************************************** + * Name: stm32_tim_ackint + ****************************************************************************/ + +static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source) +{ + stm32_putreg16(dev, STM32U5_GTIM_SR_OFFSET, ~GTIM_SR_UIF); +} + +/**************************************************************************** + * Name: stm32_tim_checkint + ****************************************************************************/ + +static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, + int source) +{ + uint16_t regval = stm32_getreg16(dev, STM32U5_GTIM_SR_OFFSET); + return (regval & GTIM_SR_UIF) ? 1 : 0; +} + +/**************************************************************************** + * Pubic Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_tim_init + ****************************************************************************/ + +FAR struct stm32_tim_dev_s *stm32_tim_init(int timer) +{ + struct stm32_tim_dev_s *dev = NULL; + + /* Get structure and enable power */ + + switch (timer) + { +#ifdef CONFIG_STM32U5_TIM1 + case 1: + dev = (struct stm32_tim_dev_s *)&stm32_tim1_priv; + modifyreg32(STM32U5_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM2 + case 2: + dev = (struct stm32_tim_dev_s *)&stm32_tim2_priv; + modifyreg32(STM32U5_RCC_APB1ENR1, 0, RCC_APB1ENR1_TIM2EN); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM3 + case 3: + dev = (struct stm32_tim_dev_s *)&stm32_tim3_priv; + modifyreg32(STM32U5_RCC_APB1ENR1, 0, RCC_APB1ENR1_TIM3EN); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM4 + case 4: + dev = (struct stm32_tim_dev_s *)&stm32_tim4_priv; + modifyreg32(STM32U5_RCC_APB1ENR1, 0, RCC_APB1ENR1_TIM4EN); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM5 + case 5: + dev = (struct stm32_tim_dev_s *)&stm32_tim5_priv; + modifyreg32(STM32U5_RCC_APB1ENR1, 0, RCC_APB1ENR1_TIM5EN); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM6 + case 6: + dev = (struct stm32_tim_dev_s *)&stm32_tim6_priv; + modifyreg32(STM32U5_RCC_APB1ENR1, 0, RCC_APB1ENR1_TIM6EN); + break; +#endif +#ifdef CONFIG_STM32U5_TIM7 + case 7: + dev = (struct stm32_tim_dev_s *)&stm32_tim7_priv; + modifyreg32(STM32U5_RCC_APB1ENR1, 0, RCC_APB1ENR1_TIM7EN); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM8 + case 8: + dev = (struct stm32_tim_dev_s *)&stm32_tim8_priv; + modifyreg32(STM32U5_RCC_APB2ENR, 0, RCC_APB2ENR_TIM8EN); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM15 + case 15: + dev = (struct stm32_tim_dev_s *)&stm32_tim15_priv; + modifyreg32(STM32U5_RCC_APB2ENR, 0, RCC_APB2ENR_TIM15EN); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM16 + case 16: + dev = (struct stm32_tim_dev_s *)&stm32_tim16_priv; + modifyreg32(STM32U5_RCC_APB2ENR, 0, RCC_APB2ENR_TIM16EN); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM17 + case 17: + dev = (struct stm32_tim_dev_s *)&stm32_tim17_priv; + modifyreg32(STM32U5_RCC_APB2ENR, 0, RCC_APB2ENR_TIM17EN); + break; +#endif + + default: + return NULL; + } + + /* Is device already allocated */ + + if (((struct stm32_tim_priv_s *)dev)->mode != STM32U5_TIM_MODE_UNUSED) + { + return NULL; + } + + stm32_tim_reset(dev); + + return dev; +} + +/**************************************************************************** + * Name: stm32_tim_deinit + * + * TODO: Detach interrupts, and close down all TIM Channels + * + ****************************************************************************/ + +int stm32_tim_deinit(FAR struct stm32_tim_dev_s *dev) +{ + DEBUGASSERT(dev != NULL); + + /* Disable power */ + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32U5_TIM1 + case STM32U5_TIM1_BASE: + modifyreg32(STM32U5_RCC_APB2ENR, RCC_APB2ENR_TIM1EN, 0); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM2 + case STM32U5_TIM2_BASE: + modifyreg32(STM32U5_RCC_APB1ENR1, RCC_APB1ENR1_TIM2EN, 0); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM3 + case STM32U5_TIM3_BASE: + modifyreg32(STM32U5_RCC_APB1ENR1, RCC_APB1ENR1_TIM3EN, 0); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM4 + case STM32U5_TIM4_BASE: + modifyreg32(STM32U5_RCC_APB1ENR1, RCC_APB1ENR1_TIM4EN, 0); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM5 + case STM32U5_TIM5_BASE: + modifyreg32(STM32U5_RCC_APB1ENR1, RCC_APB1ENR1_TIM5EN, 0); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM6 + case STM32U5_TIM6_BASE: + modifyreg32(STM32U5_RCC_APB1ENR1, RCC_APB1ENR1_TIM6EN, 0); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM7 + case STM32U5_TIM7_BASE: + modifyreg32(STM32U5_RCC_APB1ENR1, RCC_APB1ENR1_TIM7EN, 0); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM8 + case STM32U5_TIM8_BASE: + modifyreg32(STM32U5_RCC_APB2ENR, RCC_APB2ENR_TIM8EN, 0); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM15 + case STM32U5_TIM15_BASE: + modifyreg32(STM32U5_RCC_APB2ENR, RCC_APB2ENR_TIM15EN, 0); + break; +#endif +#ifdef CONFIG_STM32U5_TIM16 + case STM32U5_TIM16_BASE: + modifyreg32(STM32U5_RCC_APB2ENR, RCC_APB2ENR_TIM16EN, 0); + break; +#endif + +#ifdef CONFIG_STM32U5_TIM17 + case STM32U5_TIM17_BASE: + modifyreg32(STM32U5_RCC_APB2ENR, RCC_APB2ENR_TIM17EN, 0); + break; +#endif + + default: + return -EINVAL; + } + + /* Mark it as free */ + + ((struct stm32_tim_priv_s *)dev)->mode = STM32U5_TIM_MODE_UNUSED; + + return OK; +} + +#endif /* defined(CONFIG_STM32U5_TIM1 || ... || TIM17) */ diff --git a/arch/arm/src/stm32u5/stm32_tim.h b/arch/arm/src/stm32u5/stm32_tim.h new file mode 100644 index 0000000000..87b99ca147 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_tim.h @@ -0,0 +1,210 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_tim.h + * + * 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_STM32U5_STM32_TIM_H +#define __ARCH_ARM_SRC_STM32U5_STM32_TIM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "hardware/stm32_tim.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Helpers ******************************************************************/ + +#define STM32U5_TIM_SETMODE(d,mode) ((d)->ops->setmode(d,mode)) +#define STM32U5_TIM_SETCLOCK(d,freq) ((d)->ops->setclock(d,freq)) +#define STM32U5_TIM_GETCLOCK(d) ((d)->ops->getclock(d)) +#define STM32U5_TIM_SETPERIOD(d,period) ((d)->ops->setperiod(d,period)) +#define STM32U5_TIM_GETPERIOD(d) ((d)->ops->getperiod(d)) +#define STM32U5_TIM_GETCOUNTER(d) ((d)->ops->getcounter(d)) +#define STM32U5_TIM_SETCHANNEL(d,ch,mode) ((d)->ops->setchannel(d,ch,mode)) +#define STM32U5_TIM_SETCOMPARE(d,ch,comp) ((d)->ops->setcompare(d,ch,comp)) +#define STM32U5_TIM_GETCAPTURE(d,ch) ((d)->ops->getcapture(d,ch)) +#define STM32U5_TIM_SETISR(d,hnd,arg,s) ((d)->ops->setisr(d,hnd,arg,s)) +#define STM32U5_TIM_ENABLEINT(d,s) ((d)->ops->enableint(d,s)) +#define STM32U5_TIM_DISABLEINT(d,s) ((d)->ops->disableint(d,s)) +#define STM32U5_TIM_ACKINT(d,s) ((d)->ops->ackint(d,s)) +#define STM32U5_TIM_CHECKINT(d,s) ((d)->ops->checkint(d,s)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* TIM Device Structure */ + +struct stm32_tim_dev_s +{ + struct stm32_tim_ops_s *ops; +}; + +/* TIM Modes of Operation */ + +enum stm32_tim_mode_e +{ + STM32U5_TIM_MODE_UNUSED = -1, + + /* One of the following */ + + STM32U5_TIM_MODE_MASK = 0x0310, + STM32U5_TIM_MODE_DISABLED = 0x0000, + STM32U5_TIM_MODE_UP = 0x0100, + STM32U5_TIM_MODE_DOWN = 0x0110, + STM32U5_TIM_MODE_UPDOWN = 0x0200, + STM32U5_TIM_MODE_PULSE = 0x0300, + + /* One of the following */ + + STM32U5_TIM_MODE_CK_INT = 0x0000, +#if 0 + STM32U5_TIM_MODE_CK_INT_TRIG = 0x0400, + STM32U5_TIM_MODE_CK_EXT = 0x0800, + STM32U5_TIM_MODE_CK_EXT_TRIG = 0x0c00, +#endif + + /* Clock sources, OR'ed with CK_EXT */ + +#if 0 + STM32U5_TIM_MODE_CK_CHINVALID = 0x0000, + STM32U5_TIM_MODE_CK_CH1 = 0x0001, + STM32U5_TIM_MODE_CK_CH2 = 0x0002, + STM32U5_TIM_MODE_CK_CH3 = 0x0003, + STM32U5_TIM_MODE_CK_CH4 = 0x0004 +#endif + + /* Todo: external trigger block */ +}; + +/* TIM Channel Modes */ + +enum stm32_tim_channel_e +{ + STM32U5_TIM_CH_DISABLED = 0x00, + + /* Common configuration */ + + STM32U5_TIM_CH_POLARITY_POS = 0x00, + STM32U5_TIM_CH_POLARITY_NEG = 0x01, + + /* MODES: */ + + STM32U5_TIM_CH_MODE_MASK = 0x06, + + /* Output Compare Modes */ + + STM32U5_TIM_CH_OUTPWM = 0x04, /* Enable standard PWM mode, active high when counter < compare */ +#if 0 + STM32U5_TIM_CH_OUTCOMPARE = 0x06, +#endif + + /* TODO other modes ... as PWM capture, ENCODER and Hall Sensor */ +}; + +/* TIM Operations */ + +struct stm32_tim_ops_s +{ + /* Basic Timers */ + + int (*setmode)(FAR struct stm32_tim_dev_s *dev, + enum stm32_tim_mode_e mode); + int (*setclock)(FAR struct stm32_tim_dev_s *dev, uint32_t freq); + uint32_t (*getclock)(FAR struct stm32_tim_dev_s *dev); + void (*setperiod)(FAR struct stm32_tim_dev_s *dev, uint32_t period); + uint32_t (*getperiod)(FAR struct stm32_tim_dev_s *dev); + uint32_t (*getcounter)(FAR struct stm32_tim_dev_s *dev); + + /* General and Advanced Timers Adds */ + + int (*setchannel)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, + enum stm32_tim_channel_e mode); + int (*setcompare)(FAR struct stm32_tim_dev_s *dev, uint8_t channel, + uint32_t compare); + int (*getcapture)(FAR struct stm32_tim_dev_s *dev, uint8_t channel); + + /* Timer interrupts */ + + int (*setisr)(FAR struct stm32_tim_dev_s *dev, + xcpt_t handler, void *arg, int source); + void (*enableint)(FAR struct stm32_tim_dev_s *dev, int source); + void (*disableint)(FAR struct stm32_tim_dev_s *dev, int source); + void (*ackint)(FAR struct stm32_tim_dev_s *dev, int source); + int (*checkint)(FAR struct stm32_tim_dev_s *dev, int source); +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Power-up timer and get its structure */ + +FAR struct stm32_tim_dev_s *stm32_tim_init(int timer); + +/* Power-down timer, mark it as unused */ + +int stm32_tim_deinit(FAR struct stm32_tim_dev_s *dev); + +/**************************************************************************** + * Name: stm32_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the form + * /dev/timer0 + * timer - the timer number. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_TIMER +int stm32_timer_initialize(FAR const char *devpath, int timer); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_TIM_H */ diff --git a/arch/arm/src/stm32u5/stm32_tim_lowerhalf.c b/arch/arm/src/stm32u5/stm32_tim_lowerhalf.c new file mode 100644 index 0000000000..d3abed4b83 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_tim_lowerhalf.c @@ -0,0 +1,605 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_tim_lowerhalf.c + * + * 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 "stm32_tim.h" + +#if defined(CONFIG_TIMER) && \ + (defined(CONFIG_STM32U5_TIM1) || defined(CONFIG_STM32U5_TIM2) || \ + defined(CONFIG_STM32U5_TIM3) || defined(CONFIG_STM32U5_TIM4) || \ + defined(CONFIG_STM32U5_TIM5) || defined(CONFIG_STM32U5_TIM6) || \ + defined(CONFIG_STM32U5_TIM7) || defined(CONFIG_STM32U5_TIM8) || \ + defined(CONFIG_STM32U5_TIM15) || defined(CONFIG_STM32U5_TIM16) || \ + defined(CONFIG_STM32U5_TIM17)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define STM32U5_TIM1_RES 16 +#define STM32U5_TIM2_RES 32 +#define STM32U5_TIM3_RES 16 +#define STM32U5_TIM4_RES 16 +#define STM32U5_TIM5_RES 32 +#define STM32U5_TIM6_RES 16 +#define STM32U5_TIM7_RES 16 +#define STM32U5_TIM8_RES 16 +#define STM32U5_TIM15_RES 16 +#define STM32U5_TIM16_RES 16 +#define STM32U5_TIM17_RES 16 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * timer_lowerhalf_s structure. + */ + +struct stm32_lowerhalf_s +{ + FAR const struct timer_ops_s *ops; /* Lower half operations */ + FAR struct stm32_tim_dev_s *tim; /* stm32 timer driver */ + tccb_t callback; /* Current upper half interrupt callback */ + FAR void *arg; /* Argument passed to upper half callback */ + bool started; /* True: Timer has been started */ + const uint8_t resolution; /* Number of bits in the timer (16 or 32 bits) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Interrupt handling *******************************************************/ + +static int stm32_timer_handler(int irq, void *context, void *arg); + +/* "Lower half" driver methods **********************************************/ + +static int stm32_start(FAR struct timer_lowerhalf_s *lower); +static int stm32_stop(FAR struct timer_lowerhalf_s *lower); +static int stm32_getstatus(FAR struct timer_lowerhalf_s *lower, + FAR struct timer_status_s *status); +static int stm32_settimeout(FAR struct timer_lowerhalf_s *lower, + uint32_t timeout); +static void stm32_setcallback(FAR struct timer_lowerhalf_s *lower, + tccb_t callback, FAR void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* "Lower half" driver methods */ + +static const struct timer_ops_s g_timer_ops = +{ + .start = stm32_start, + .stop = stm32_stop, + .getstatus = stm32_getstatus, + .settimeout = stm32_settimeout, + .setcallback = stm32_setcallback, + .ioctl = NULL, +}; + +#ifdef CONFIG_STM32U5_TIM1 +static struct stm32_lowerhalf_s g_tim1_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM1_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM2 +static struct stm32_lowerhalf_s g_tim2_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM2_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM3 +static struct stm32_lowerhalf_s g_tim3_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM3_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM4 +static struct stm32_lowerhalf_s g_tim4_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM4_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM5 +static struct stm32_lowerhalf_s g_tim5_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM5_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM6 +static struct stm32_lowerhalf_s g_tim6_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM6_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM7 +static struct stm32_lowerhalf_s g_tim7_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM7_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM8 +static struct stm32_lowerhalf_s g_tim8_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM8_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM15 +static struct stm32_lowerhalf_s g_tim15_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM15_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM16 +static struct stm32_lowerhalf_s g_tim16_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM16_RES, +}; +#endif + +#ifdef CONFIG_STM32U5_TIM17 +static struct stm32_lowerhalf_s g_tim17_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32U5_TIM17_RES, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_timer_handler + * + * Description: + * timer interrupt handler + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static int stm32_timer_handler(int irq, void *context, void *arg) +{ + FAR struct stm32_lowerhalf_s *lower = + (FAR struct stm32_lowerhalf_s *)arg; + uint32_t next_interval_us = 0; + + STM32U5_TIM_ACKINT(lower->tim, 0); + + if (lower->callback(&next_interval_us, lower->arg)) + { + if (next_interval_us > 0) + { + STM32U5_TIM_SETPERIOD(lower->tim, next_interval_us); + } + } + else + { + stm32_stop((struct timer_lowerhalf_s *)lower); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_start + * + * Description: + * Start the timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_start(FAR struct timer_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = + (FAR struct stm32_lowerhalf_s *)lower; + + if (!priv->started) + { + STM32U5_TIM_SETMODE(priv->tim, STM32U5_TIM_MODE_UP); + + if (priv->callback != NULL) + { + STM32U5_TIM_SETISR(priv->tim, stm32_timer_handler, priv, 0); + STM32U5_TIM_ENABLEINT(priv->tim, 0); + } + + priv->started = true; + return OK; + } + + /* Return EBUSY to indicate that the timer was already running */ + + return -EBUSY; +} + +/**************************************************************************** + * Name: stm32_stop + * + * Description: + * Stop the timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_stop(FAR struct timer_lowerhalf_s *lower) +{ + FAR struct stm32_lowerhalf_s *priv = + (FAR struct stm32_lowerhalf_s *)lower; + + if (priv->started) + { + STM32U5_TIM_SETMODE(priv->tim, STM32U5_TIM_MODE_DISABLED); + STM32U5_TIM_DISABLEINT(priv->tim, 0); + STM32U5_TIM_SETISR(priv->tim, NULL, NULL, 0); + priv->started = false; + return OK; + } + + /* Return ENODEV to indicate that the timer was not running */ + + return -ENODEV; +} + +/**************************************************************************** + * Name: stm32_getstatus + * + * Description: + * get timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower- + * half" driver state structure. + * status - The location to return the status information. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_getstatus(FAR struct timer_lowerhalf_s *lower, + FAR struct timer_status_s *status) +{ + FAR struct stm32_lowerhalf_s *priv = + (FAR struct stm32_lowerhalf_s *)lower; + uint64_t maxtimeout; + uint32_t timeout; + uint32_t clock; + uint32_t period; + uint32_t clock_factor; + + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = 0; + if (priv->started) + { + status->flags |= TCFLAGS_ACTIVE; + } + + if (priv->callback) + { + status->flags |= TCFLAGS_HANDLER; + } + + /* Get timeout */ + + maxtimeout = (1 << priv->resolution) - 1; + clock = STM32U5_TIM_GETCLOCK(priv->tim); + period = STM32U5_TIM_GETPERIOD(priv->tim); + + if (clock == 1000000) + { + timeout = period; + } + else + { + timeout = (maxtimeout * 1000000) / clock; + } + + status->timeout = timeout; + + /* Get the time remaining until the timer expires (in microseconds) */ + + clock_factor = (clock == 1000000)? 1: (clock / 1000000); + status->timeleft = (timeout - STM32U5_TIM_GETCOUNTER(priv->tim)) * + clock_factor; + return OK; +} + +/**************************************************************************** + * Name: stm32_settimeout + * + * Description: + * Set a new timeout value (and reset the timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * timeout - The new timeout value in microseconds. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_settimeout(FAR struct timer_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct stm32_lowerhalf_s *priv = + (FAR struct stm32_lowerhalf_s *)lower; + uint64_t maxtimeout; + + if (priv->started) + { + return -EPERM; + } + + maxtimeout = (1 << priv->resolution) - 1; + if (timeout > maxtimeout) + { + uint64_t freq = (maxtimeout * 1000000) / timeout; + STM32U5_TIM_SETCLOCK(priv->tim, freq); + STM32U5_TIM_SETPERIOD(priv->tim, maxtimeout); + } + else + { + STM32U5_TIM_SETCLOCK(priv->tim, 1000000); + STM32U5_TIM_SETPERIOD(priv->tim, timeout); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_sethandler + * + * Description: + * Call this user provided timeout handler. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * callback - The new timer expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * arg - Argument that will be provided in the callback + * + * Returned Value: + * The previous timer expiration function pointer or NULL is there was + * no previous function pointer. + * + ****************************************************************************/ + +static void stm32_setcallback(FAR struct timer_lowerhalf_s *lower, + tccb_t callback, FAR void *arg) +{ + FAR struct stm32_lowerhalf_s *priv = + (FAR struct stm32_lowerhalf_s *)lower; + irqstate_t flags = enter_critical_section(); + + /* Save the new callback */ + + priv->callback = callback; + priv->arg = arg; + + if (callback != NULL && priv->started) + { + STM32U5_TIM_SETISR(priv->tim, stm32_timer_handler, priv, 0); + STM32U5_TIM_ENABLEINT(priv->tim, 0); + } + else + { + STM32U5_TIM_DISABLEINT(priv->tim, 0); + STM32U5_TIM_SETISR(priv->tim, NULL, NULL, 0); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the + * form /dev/timer0 + * timer - the timer's number. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int stm32_timer_initialize(FAR const char *devpath, int timer) +{ + FAR struct stm32_lowerhalf_s *lower; + + switch (timer) + { +#ifdef CONFIG_STM32U5_TIM1 + case 1: + lower = &g_tim1_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM2 + case 2: + lower = &g_tim2_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM3 + case 3: + lower = &g_tim3_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM4 + case 4: + lower = &g_tim4_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM5 + case 5: + lower = &g_tim5_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32U5_TIM6 + case 6: + lower = &g_tim6_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM7 + case 7: + lower = &g_tim7_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM8 + case 8: + lower = &g_tim8_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM15 + case 15: + lower = &g_tim15_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM16 + case 16: + lower = &g_tim16_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32U5_TIM17 + case 17: + lower = &g_tim17_lowerhalf; + break; +#endif + + default: + return -ENODEV; + } + + /* Initialize the elements of lower half state structure */ + + lower->started = false; + lower->callback = NULL; + lower->tim = stm32_tim_init(timer); + + if (lower->tim == NULL) + { + return -EINVAL; + } + + /* Register the timer driver as /dev/timerX. The returned value from + * timer_register is a handle that could be used with timer_unregister(). + * REVISIT: The returned handle is discard here. + */ + + FAR void *drvr = timer_register(devpath, + (FAR struct timer_lowerhalf_s *)lower); + if (drvr == NULL) + { + /* The actual cause of the failure may have been a failure to allocate + * perhaps a failure to register the timer driver (such as if the + * 'depath' were not unique). We know here but we return EEXIST to + * indicate the failure (implying the non-unique devpath). + */ + + return -EEXIST; + } + + return OK; +} + +#endif /* CONFIG_TIMER */ diff --git a/arch/arm/src/stm32u5/stm32_timerisr.c b/arch/arm/src/stm32u5/stm32_timerisr.c new file mode 100644 index 0000000000..a13f392053 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_timerisr.c @@ -0,0 +1,149 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_timerisr.c + * + * 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 "nvic.h" +#include "clock/clock.h" +#include "arm_internal.h" +#include "arm_arch.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). + * + * The RCC feeds the Cortex System Timer (SysTick) with the AHB clock (HCLK) + * divided by 8. The SysTick can work either with this clock or with the + * Cortex clock (HCLK), configurable in the SysTick Control and Status + * register. + */ + +/* Power up default is HCLK, not HCLK/8. + * And I don't know now to re-configure it yet + */ + +#undef CONFIG_STM32U5_SYSTICK_HCLKd8 + +#ifdef CONFIG_STM32U5_SYSTICK_HCLKd8 +# define SYSTICK_RELOAD ((STM32_HCLK_FREQUENCY / 8 / CLK_TCK) - 1) +#else +# define SYSTICK_RELOAD ((STM32_HCLK_FREQUENCY / CLK_TCK) - 1) +#endif + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +static int stm32_timerisr(int irq, uint32_t *regs, void *arg) +{ + /* Process timer interrupt */ + + nxsched_process_timer(); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +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); + + /* Make sure that the SYSTICK clock source is set correctly */ + +#if 0 /* Does not work. Comes up with HCLK source and I can't change it */ + regval = getreg32(NVIC_SYSTICK_CTRL); +#ifdef CONFIG_STM32U5_SYSTICK_HCLKd8 + regval &= ~NVIC_SYSTICK_CTRL_CLKSOURCE; +#else + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; +#endif + putreg32(regval, NVIC_SYSTICK_CTRL); +#endif + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(STM32_IRQ_SYSTICK, (xcpt_t)stm32_timerisr, NULL); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(STM32_IRQ_SYSTICK); +} diff --git a/arch/arm/src/stm32u5/stm32_uart.h b/arch/arm/src/stm32u5/stm32_uart.h new file mode 100644 index 0000000000..45fe35607c --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_uart.h @@ -0,0 +1,298 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_uart.h + * + * 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_STC_STM32U5_STM32_UART_H +#define __ARCH_ARM_STC_STM32U5_STM32_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" + +#if defined(CONFIG_STM32U5_STM32U585XX) +# include "hardware/stm32_uart.h" +#else +# error "Unsupported STM32U5 chip" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Make sure that we have not enabled more U[S]ARTs than are supported by the + * device. + */ + +#if !defined(CONFIG_STM32U5_HAVE_UART5) +# undef CONFIG_STM32U5_UART5 +#endif +#if !defined(CONFIG_STM32U5_HAVE_UART4) +# undef CONFIG_STM32U5_UART4 +#endif +#if !defined(CONFIG_STM32U5_HAVE_USART3) +# undef CONFIG_STM32U5_USART3 +#endif +#if !defined(CONFIG_STM32U5_HAVE_USART2) +# undef CONFIG_STM32U5_USART2 +#endif +#if !defined(CONFIG_STM32U5_HAVE_USART1) +# undef CONFIG_STM32U5_USART1 +#endif +#if !defined(CONFIG_STM32U5_HAVE_LPUART1) +# undef CONFIG_STM32U5_LPUART1 +#endif + +/* Sanity checks */ + +#if !defined(CONFIG_STM32U5_LPUART1) +# undef CONFIG_STM32U5_LPUART1_SERIALDRIVER +# undef CONFIG_STM32U5_LPUART1_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32U5_USART1) +# undef CONFIG_STM32U5_USART1_SERIALDRIVER +# undef CONFIG_STM32U5_USART1_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32U5_USART2) +# undef CONFIG_STM32U5_USART2_SERIALDRIVER +# undef CONFIG_STM32U5_USART2_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32U5_USART3) +# undef CONFIG_STM32U5_USART3_SERIALDRIVER +# undef CONFIG_STM32U5_USART3_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32U5_UART4) +# undef CONFIG_STM32U5_UART4_SERIALDRIVER +# undef CONFIG_STM32U5_UART4_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32U5_UART5) +# undef CONFIG_STM32U5_UART5_SERIALDRIVER +# undef CONFIG_STM32U5_UART5_1WIREDRIVER +#endif + +/* Is there a USART enabled? */ + +#if defined(CONFIG_STM32U5_LPUART1) || defined(CONFIG_STM32U5_USART1) || \ + defined(CONFIG_STM32U5_USART2) || defined(CONFIG_STM32U5_USART3) || \ + defined(CONFIG_STM32U5_UART4) || defined(CONFIG_STM32U5_UART5) +# define HAVE_UART 1 +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_LPUART1_SERIAL_CONSOLE) && defined(CONFIG_STM32U5_LPUART1_SERIALDRIVER) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 1 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32U5_USART1_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 2 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32U5_USART2_SERIALDRIVER) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 3 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32U5_USART3_SERIALDRIVER) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 4 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32U5_UART4_SERIALDRIVER) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 5 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32U5_UART5_SERIALDRIVER) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# define CONSOLE_UART 6 +# define HAVE_CONSOLE 1 +#else +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 0 +# undef HAVE_CONSOLE +#endif + +/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX + * configuration + */ + +#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) +# undef CONFIG_USART1_RXDMA +# undef CONFIG_USART2_RXDMA +# undef CONFIG_USART3_RXDMA +# undef CONFIG_UART4_RXDMA +# undef CONFIG_UART5_RXDMA +#endif + +/* Disable the DMA configuration on all unused USARTs */ + +#ifndef CONFIG_STM32U5_LPUART1_SERIALDRIVER +# undef CONFIG_LPUART1_RXDMA +#endif + +#ifndef CONFIG_STM32U5_USART1_SERIALDRIVER +# undef CONFIG_USART1_RXDMA +#endif + +#ifndef CONFIG_STM32U5_USART2_SERIALDRIVER +# undef CONFIG_USART2_RXDMA +#endif + +#ifndef CONFIG_STM32U5_USART3_SERIALDRIVER +# undef CONFIG_USART3_RXDMA +#endif + +#ifndef CONFIG_STM32U5_UART4_SERIALDRIVER +# undef CONFIG_UART4_RXDMA +#endif + +#ifndef CONFIG_STM32U5_UART5_SERIALDRIVER +# undef CONFIG_UART5_RXDMA +#endif + +/* Is DMA available on any (enabled) USART? */ + +#undef SERIAL_HAVE_DMA +#if defined(CONFIG_LPUART1_RXDMA) || defined(CONFIG_USART1_RXDMA) || \ + defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \ + defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) +# define SERIAL_HAVE_DMA 1 +#endif + +/* Is DMA used on the console UART? */ + +#undef SERIAL_HAVE_CONSOLE_DMA +#if defined(CONFIG_LPUART1_SERIAL_CONSOLE) && defined(CONFIG_LPUART1_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#endif + +/* Is DMA used on all (enabled) USARTs */ + +#define SERIAL_HAVE_ONLY_DMA 1 +#if defined(CONFIG_STM32U5_LPUART1_SERIALDRIVER) && !defined(CONFIG_LPUART1_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32U5_USART1_SERIALDRIVER) && !defined(CONFIG_USART1_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32U5_USART2_SERIALDRIVER) && !defined(CONFIG_USART2_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32U5_USART3_SERIALDRIVER) && !defined(CONFIG_USART3_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32U5_UART4_SERIALDRIVER) && !defined(CONFIG_UART4_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32U5_UART5_SERIALDRIVER) && !defined(CONFIG_UART5_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#endif + +/* Is RS-485 used? */ + +#if defined(CONFIG_LPUART1_RS485) || defined(CONFIG_USART1_RS485) || \ + defined(CONFIG_USART2_RS485) || defined(CONFIG_USART3_RS485) || \ + defined(CONFIG_UART4_RS485) || defined(CONFIG_UART5_RS485) +# define HAVE_RS485 1 +#endif + +#ifdef HAVE_RS485 +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE | USART_CR1_TCIE) +#else +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE) +#endif + +/**************************************************************************** + * 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 + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_serial_dma_poll + * + * Description: + * Must be called periodically if any STM32 UART is configured for DMA. + * The DMA callback is triggered for each fifo size/2 bytes, but this can + * result in some bytes being transferred but not collected if the incoming + * data is not a whole multiple of half the FIFO size. + * + * May be safely called from either interrupt or thread context. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32_serial_dma_poll(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_STC_STM32U5_STM32_UART_H */ diff --git a/arch/arm/src/stm32u5/stm32_uid.c b/arch/arm/src/stm32u5/stm32_uid.c new file mode 100644 index 0000000000..0ce9a80527 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_uid.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_uid.c + * + * 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 "hardware/stm32_memorymap.h" +#include "stm32_uid.h" + +#ifdef STM32U5_SYSMEM_UID + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void stm32_get_uniqueid(uint8_t uniqueid[12]) +{ + int i; + + for (i = 0; i < 12; i++) + { + uniqueid[i] = *((uint8_t *)(STM32U5_SYSMEM_UID) + i); + } +} + +#endif /* STM32U5_SYSMEM_UID */ diff --git a/arch/arm/src/stm32u5/stm32_uid.h b/arch/arm/src/stm32u5/stm32_uid.h new file mode 100644 index 0000000000..0f3e9993a3 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_uid.h @@ -0,0 +1,36 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_uid.h + * + * 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_STM32U5_STM32_UID_H +#define __ARCH_ARM_SRC_STM32U5_STM32_UID_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void stm32_get_uniqueid(uint8_t uniqueid[12]); + +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_UID_H */ diff --git a/arch/arm/src/stm32u5/stm32_userspace.c b/arch/arm/src/stm32u5/stm32_userspace.c new file mode 100644 index 0000000000..1720befbc7 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_userspace.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_userspace.c + * + * 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_mpuinit.h" +#include "stm32_userspace.h" + +#ifdef CONFIG_BUILD_PROTECTED + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +void stm32_userspace(void) +{ + uint8_t *src; + uint8_t *dest; + uint8_t *end; + + /* Clear all of user-space .bss */ + + DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 && + USERSPACE->us_bssstart <= USERSPACE->us_bssend); + + dest = (uint8_t *)USERSPACE->us_bssstart; + end = (uint8_t *)USERSPACE->us_bssend; + + while (dest != end) + { + *dest++ = 0; + } + + /* Initialize all of user-space .data */ + + DEBUGASSERT(USERSPACE->us_datasource != 0 && + USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 && + USERSPACE->us_datastart <= USERSPACE->us_dataend); + + src = (uint8_t *)USERSPACE->us_datasource; + dest = (uint8_t *)USERSPACE->us_datastart; + end = (uint8_t *)USERSPACE->us_dataend; + + while (dest != end) + { + *dest++ = *src++; + } + + /* Configure the MPU to permit user-space access to its FLASH and RAM */ + + stm32_mpuinitialize(); +} + +#endif /* CONFIG_BUILD_PROTECTED */ diff --git a/arch/arm/src/stm32u5/stm32_userspace.h b/arch/arm/src/stm32u5/stm32_userspace.h new file mode 100644 index 0000000000..f7e89e51c1 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_userspace.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_userspace.h + * + * 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_STM32U5_STM32_USERSPACE_H +#define __ARCH_ARM_SRC_STM32U5_STM32_USERSPACE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_userspace + * + * Description: + * For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void stm32_userspace(void); +#endif + +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_USERSPACE_H */ diff --git a/arch/arm/src/stm32u5/stm32_waste.c b/arch/arm/src/stm32u5/stm32_waste.c new file mode 100644 index 0000000000..1baf90282e --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_waste.c @@ -0,0 +1,42 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_waste.c + * + * 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 "stm32_waste.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +uint32_t idle_wastecounter = 0; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void stm32_waste(void) +{ + idle_wastecounter++; +} diff --git a/arch/arm/src/stm32u5/stm32_waste.h b/arch/arm/src/stm32u5/stm32_waste.h new file mode 100644 index 0000000000..2cc78dbd11 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32_waste.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32_waste.h + * + * 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_STM32U5_STM32_WASTE_H +#define __ARCH_ARM_SRC_STM32U5_STM32_WASTE_H + +/* Waste CPU Time */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Waste CPU Time + * + * stm32_waste() is the logic that will be executed when portions of kernel + * or user-app is polling some register or similar, waiting for desired + * status. This time is wasted away. This function offers a measure of badly + * written piece of software or some undesired behavior. + * + * At the same time this function adds to some IDLE time which portion + * cannot be used for other purposes (yet). + */ + +void stm32_waste(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32U5_STM32_WASTE_H */ diff --git a/arch/arm/src/stm32u5/stm32u585xx_rcc.c b/arch/arm/src/stm32u5/stm32u585xx_rcc.c new file mode 100644 index 0000000000..68a25ceec2 --- /dev/null +++ b/arch/arm/src/stm32u5/stm32u585xx_rcc.c @@ -0,0 +1,935 @@ +/**************************************************************************** + * arch/arm/src/stm32u5/stm32u585xx_rcc.c + * + * 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 "stm32_pwr.h" +#include "stm32_flash.h" +#include "stm32_rcc.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. Normally this is very fast, but I have seen at least one + * board that required this long, long timeout for the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/* Same for HSI and MSI */ + +#define HSIRDY_TIMEOUT HSERDY_TIMEOUT +#define MSIRDY_TIMEOUT HSERDY_TIMEOUT + +/* HSE divisor to yield ~1MHz RTC clock */ + +#define HSE_DIVISOR (STM32_HSE_FREQUENCY + 500000) / 1000000 + +/* Determine if board wants to use HSI48 as 48 MHz oscillator. */ + +#if defined(CONFIG_STM32U5_HAVE_HSI48) && defined(STM32_USE_CLK48) +# if STM32_CLK48_SEL == RCC_CCIPR_CLK48SEL_HSI48 +# define STM32_USE_HSI48 +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_enableahb1 + * + * Description: + * Enable selected AHB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB1ENR register to enabled the clocks + * of selected AHB1 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB1ENR); + +#ifdef CONFIG_STM32U5_GPDMA1 + regval |= RCC_AHB1ENR_GPDMA1EN; +#endif + +#ifdef CONFIG_STM32U5_CORDIC + regval |= RCC_AHB1ENR_CORDIC; +#endif + +#ifdef CONFIG_STM32U5_FMAC + regval |= RCC_AHB1ENR_FMACEN; +#endif + +#ifdef CONFIG_STM32U5_MDF1 + regval |= RCC_AHB1ENR_MDF1EN; +#endif + +#ifdef CONFIG_STM32U5_FLASH + regval |= RCC_AHB1ENR_FLASHEN; +#endif + +#ifdef CONFIG_STM32U5_CRC + regval |= RCC_AHB1ENR_CRCEN; +#endif + +#ifdef CONFIG_STM32U5_TSC + regval |= RCC_AHB1ENR_TSCEN; +#endif + +#ifdef CONFIG_STM32U5_RAMCFG + regval |= RCC_AHB1ENR_RAMCFGEN; +#endif + +#ifdef CONFIG_STM32U5_DMA2D + regval |= RCC_AHB1ENR_DMA2DEN; +#endif + +#ifdef CONFIG_STM32U5_GTZC1 + regval |= RCC_AHB1ENR_GTZC1EN; +#endif + +#ifdef CONFIG_STM32U5_BKPSRAM + regval |= RCC_AHB1ENR_BKPSRAMEN; +#endif + +#ifdef CONFIG_STM32U5_DCACHE1 + regval |= RCC_AHB1ENR_DCACHE1EN; +#endif + +#ifdef CONFIG_STM32U5_SRAM1 + regval |= RCC_AHB1ENR_SRAM1EN; +#endif + + putreg32(regval, STM32_RCC_AHB1ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb2 + * + * Description: + * Enable selected AHB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB2ENR1 and AHB2ENR2 registers to + * enable the clocks of selected AHB2 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB2ENR1); + +#if STM32_NPORTS > 0 + regval |= (RCC_AHB2ENR1_GPIOAEN +#if STM32_NPORTS > 1 + | RCC_AHB2ENR1_GPIOBEN +#endif +#if STM32_NPORTS > 2 + | RCC_AHB2ENR1_GPIOCEN +#endif +#if STM32_NPORTS > 3 + | RCC_AHB2ENR1_GPIODEN +#endif +#if STM32_NPORTS > 4 + | RCC_AHB2ENR1_GPIOEEN +#endif +#if STM32_NPORTS > 5 + | RCC_AHB2ENR1_GPIOFEN +#endif +#if STM32_NPORTS > 6 + | RCC_AHB2ENR1_GPIOGEN +#endif +#if STM32_NPORTS > 7 + | RCC_AHB2ENR1_GPIOHEN +#endif +#if STM32_NPORTS > 8 + | RCC_AHB2ENR1_GPIOIEN +#endif + ); +#endif + +#if defined(CONFIG_STM32U5_ADC1) + regval |= RCC_AHB2ENR1_ADC1EN; +#endif + +#if defined(CONFIG_STM32U5_DCMI_PSSI) + regval |= RCC_AHB2ENR1_DCMI_PSSIEN; +#endif + +#ifdef CONFIG_STM32U5_OTG + regval |= RCC_AHB2ENR1_OTGEN; +#endif + +#ifdef CONFIG_STM32U5_AES + regval |= RCC_AHB2ENR1_AESEN; +#endif + +#ifdef CONFIG_STM32U5_HASH + regval |= RCC_AHB2ENR1_HASHEN +#endif + +#ifdef CONFIG_STM32U5_RNG + regval |= RCC_AHB2ENR1_RNGEN; +#endif + +#ifdef CONFIG_STM32U5_PKA + regval |= RCC_AHB2ENR_PKAEN; +#endif + +#ifdef CONFIG_STM32U5_SAES + regval |= RCC_AHB2ENR1_SAES; +#endif + +#ifdef CONFIG_STM32U5_OCTOSPIM + regval |= RCC_AHB2ENR1_OCTOSPIM; +#endif + +#ifdef CONFIG_STM32U5_OTFDEC1 + regval |= RCC_AHB2ENR1_OTFDEC1; +#endif + +#ifdef CONFIG_STM32U5_OTFDEC2 + regval |= RCC_AHB2ENR1_OTFDEC2; +#endif + +#ifdef CONFIG_STM32U5_SDMMC1EN + regval |= RCC_AHB2ENR1_SDMMC1EN; +#endif + +#ifdef CONFIG_STM32U5_SDMMC2EN + regval |= RCC_AHB2ENR1_SDMMC2EN; +#endif + +#ifdef CONFIG_STM32U5_SRAM2 + regval |= RCC_AHB2ENR1_SRAM2EN; +#endif + +#ifdef CONFIG_STM32U5_SRAM3 + regval |= RCC_AHB2ENR1_SRAM3EN; +#endif + + putreg32(regval, STM32_RCC_AHB2ENR1); + + regval = getreg32(STM32_RCC_AHB2ENR2); + +#ifdef CONFIG_STM32U5_FSMC + regval |= RCC_AHB2ENR2_FSMCEN; +#endif + +#ifdef CONFIG_STM32U5_OCTOSPI1 + regval |= RCC_AHB2ENR2_OCTOSPI1EN; +#endif + +#ifdef CONFIG_STM32U5_OCTOSPI2 + regval |= RCC_AHB2ENR2_OCTOSPI2EN; +#endif + + putreg32(regval, STM32_RCC_AHB2ENR2); +} + +/**************************************************************************** + * Name: rcc_enableahb3 + * + * Description: + * Enable selected AHB3 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb3(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB3ENR register to enabled the clocks + * of selected AHB3 peripherals. + */ + + regval = getreg32(STM32_RCC_AHB3ENR); + +#ifdef CONFIG_STM32U5_LPGPIO1 + regval |= RCC_AHB3ENR_LPGPIO1EN; +#endif + +#ifdef CONFIG_STM32U5_PWR + regval |= RCC_AHB3ENR_PWREN; +#endif + +#ifdef CONFIG_STM32U5_ADC4 + regval |= RCC_AHB3ENR_ADC4EN; +#endif + +#ifdef CONFIG_STM32U5_DAC1 + regval |= RCC_AHB3ENR_DAC1EN; +#endif + +#ifdef CONFIG_STM32U5_LPDMA1 + regval |= RCC_AHB3ENR_LPDMA1EN; +#endif + +#ifdef CONFIG_STM32U5_ADF1 + regval |= RCC_AHB3ENR_ADF1EN; +#endif + +#ifdef CONFIG_STM32U5_GTZC2 + regval |= RCC_AHB3ENR_GTZC2EN; +#endif + +#ifdef CONFIG_STM32U5_SRAM4 + regval |= RCC_AHB3ENR_SRAM4EN; +#endif + + putreg32(regval, STM32_RCC_AHB3ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB1ENR register to enabled the clocks + * of selected APB1 peripherals. + */ + + regval = getreg32(STM32_RCC_APB1ENR1); + +#ifdef CONFIG_STM32U5_TIM2 + regval |= RCC_APB1ENR1_TIM2EN; +#endif + +#ifdef CONFIG_STM32U5_TIM3 + regval |= RCC_APB1ENR1_TIM3EN; +#endif + +#ifdef CONFIG_STM32U5_TIM4 + regval |= RCC_APB1ENR1_TIM4EN; +#endif + +#ifdef CONFIG_STM32U5_TIM5 + regval |= RCC_APB1ENR1_TIM5EN; +#endif + +#ifdef CONFIG_STM32U5_TIM6 + regval |= RCC_APB1ENR1_TIM6EN; +#endif + +#ifdef CONFIG_STM32U5_TIM7 + regval |= RCC_APB1ENR1_TIM7EN; +#endif + +#ifdef CONFIG_STM32U5_WWDG + regval |= RCC_APB1ENR1_WWDGEN; +#endif + +#ifdef CONFIG_STM32U5_SPI2 + regval |= RCC_APB1ENR1_SPI2EN; +#endif + +#ifdef CONFIG_STM32U5_USART2 + regval |= RCC_APB1ENR1_USART2EN; +#endif + +#ifdef CONFIG_STM32U5_USART3 + regval |= RCC_APB1ENR1_USART3EN; +#endif + +#ifdef CONFIG_STM32U5_UART4 + regval |= RCC_APB1ENR1_UART4EN; +#endif + +#ifdef CONFIG_STM32U5_UART5 + regval |= RCC_APB1ENR1_UART5EN; +#endif + +#ifdef CONFIG_STM32U5_I2C1 + regval |= RCC_APB1ENR1_I2C1EN; +#endif + +#ifdef CONFIG_STM32U5_I2C2 + regval |= RCC_APB1ENR1_I2C2EN; +#endif + +#ifdef CONFIG_STM32U5_CRS + regval |= RCC_APB1ENR1_CRSEN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR1); /* Enable peripherals */ + + /* Second APB1 register */ + + regval = getreg32(STM32_RCC_APB1ENR2); + +#ifdef CONFIG_STM32U5_I2C4 + regval |= RCC_APB1ENR2_I2C4EN; +#endif + +#ifdef CONFIG_STM32U5_LPTIM2 + regval |= RCC_APB1ENR2_LPTIM2EN; +#endif + +#ifdef CONFIG_STM32U5_FDCAN1 + regval |= RCC_APB1ENR2_FDCAN1EN; +#endif + +#ifdef CONFIG_STM32U5_UCPD1 + regval |= RCC_APB1ENR2_UCPD1EN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR2); +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the clocks + * of selected APB2 peripherals. + */ + + regval = getreg32(STM32_RCC_APB2ENR); + +#ifdef CONFIG_STM32U5_TIM1 + regval |= RCC_APB2ENR_TIM1EN; +#endif + +#ifdef CONFIG_STM32U5_SPI1 + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32U5_TIM8 + regval |= RCC_APB2ENR_TIM8EN; +#endif + +#ifdef CONFIG_STM32U5_USART1 + regval |= RCC_APB2ENR_USART1EN; +#endif + +#ifdef CONFIG_STM32U5_TIM15 + regval |= RCC_APB2ENR_TIM15EN; +#endif + +#ifdef CONFIG_STM32U5_TIM16 + regval |= RCC_APB2ENR_TIM16EN; +#endif + +#ifdef CONFIG_STM32U5_TIM17 + regval |= RCC_APB2ENR_TIM17EN; +#endif + +#ifdef CONFIG_STM32U5_SAI1 + regval |= RCC_APB2ENR_SAI1EN; +#endif + +#ifdef CONFIG_STM32U5_SAI2 + regval |= RCC_APB2ENR_SAI2EN; +#endif + + putreg32(regval, STM32_RCC_APB2ENR); +} + +/**************************************************************************** + * Name: rcc_enableapb3 + * + * Description: + * Enable selected APB3 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb3(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB3ENR register to enabled the clocks + * of selected APB3 peripherals. + */ + + regval = getreg32(STM32_RCC_APB3ENR); + +#ifdef CONFIG_STM32U5_SYSCFG + regval |= RCC_APB3ENR_SYSCFGEN; +#endif + +#ifdef CONFIG_STM32U5_SPI3 + regval |= RCC_APB3ENR_SPI3EN; +#endif + +#ifdef CONFIG_STM32U5_LPUART1 + regval |= RCC_APB3ENR_LPUART1EN; +#endif + +#ifdef CONFIG_STM32U5_I2C3EN + regval |= RCC_APB3ENR_I2C3EN; +#endif + +#ifdef CONFIG_STM32U5_LPTIM1 + regval |= RCC_APB3ENR_LPTIM1EN; +#endif + +#ifdef CONFIG_STM32U5_LPTIM3 + regval |= RCC_APB3ENR_LPTIM3EN; +#endif + +#ifdef CONFIG_STM32U5_LPTIM4 + regval |= RCC_APB3ENR_LPTIM4EN; +#endif + +#ifdef CONFIG_STM32U5_OPAMP + regval |= RCC_APB3ENR_OPAMPEN; +#endif + +#ifdef CONFIG_STM32U5_COMP + regval |= RCC_APB3ENR_COMPEN; +#endif + +#ifdef CONFIG_STM32U5_VREF + regval |= RCC_APB3ENR_VREFEN; +#endif + +#ifdef CONFIG_STM32U5_RTCAPB + regval |= RCC_APB3ENR_RTCAPBEN; +#endif + + putreg32(regval, STM32_RCC_APB3ENR); +} + +/**************************************************************************** + * Name: rcc_enableccip + * + * Description: + * Set peripherals independent clock configuration. + * + ****************************************************************************/ + +static inline void rcc_enableccip(void) +{ + /* Certain peripherals have no clock selected even when their enable bit is + * set. Set some defaults in the CCIPR register so those peripherals + * will at least have a clock. + */ +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rcc_enableperipherals + ****************************************************************************/ + +void stm32_rcc_enableperipherals(void) +{ + rcc_enableccip(); + rcc_enableahb1(); + rcc_enableahb2(); + rcc_enableahb3(); + rcc_enableapb1(); + rcc_enableapb2(); + rcc_enableapb3(); +} + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#ifndef CONFIG_ARCH_BOARD_STM32U5_CUSTOM_CLOCKCONFIG +void stm32_stdclockconfig(void) +{ + uint32_t regval; + volatile int32_t timeout; + + /* Enable Internal Multi-Speed System (MSIS) and Kernel (MSIK) Clock */ + +#if defined(STM32_BOARD_USEHSI) || defined(STM32_I2C_USE_HSI16) + /* Enable Internal High-Speed Clock (HSI) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSION; /* Enable HSI */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSI is ready (or until a timeout elapsed) */ + + for (timeout = HSIRDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSIRDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } +#endif + +#if defined(STM32_BOARD_USEHSI) + /* Already set above */ + +#elif defined(STM32_BOARD_USEMSI) + /* Enable Internal Multi-Speed Clock (MSI) */ + + /* Wait until the MSI is either off or ready (or until a timeout elapsed) */ + + for (timeout = MSIRDY_TIMEOUT; timeout > 0; timeout--) + { + if ((regval = getreg32(STM32_RCC_CR)), + (regval & RCC_CR_MSIRDY) || ~(regval & RCC_CR_MSION)) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + + /* setting MSIRANGE */ + + regval = getreg32(STM32_RCC_CR); + regval |= (STM32_BOARD_MSIRANGE | RCC_CR_MSION); /* Enable MSI and frequency */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the MSI is ready (or until a timeout elapsed) */ + + for (timeout = MSIRDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the MSIRDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_MSIRDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + +#elif defined(STM32_BOARD_USEHSE) + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is the set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } +#else + +# error stm32_stdclockconfig(), must have one of STM32_BOARD_USEHSI, STM32_BOARD_USEMSI, STM32_BOARD_USEHSE defined + +#endif + + /* Check for a timeout. If this timeout occurs, then we are hosed. We + * have no real back-up plan, although the following logic makes it look + * as though we do. + */ + + if (timeout > 0) + { + /* Select main regulator voltage range according to system clock + * frequency. + */ + + /* Ensure Power control is enabled before modifying it. */ + + stm32_pwr_enableclk(true); + + /* Select correct main regulator range */ + + regval = getreg32(STM32_PWR_CR1); + regval &= ~PWR_CR1_VOS_MASK; + + if (STM32_SYSCLK_FREQUENCY > 80000000) + { + regval |= PWR_CR1_VOS_RANGE0; + } + else if (STM32_SYSCLK_FREQUENCY > 26000000) + { + regval |= PWR_CR1_VOS_RANGE1; + } + else + { + regval |= PWR_CR1_VOS_RANGE0; + } + + putreg32(regval, STM32_PWR_CR1); + + /* Wait for voltage regulator to stabilize */ + + while (getreg32(STM32_PWR_SR2) & PWR_SR2_VOSF) + { + } + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32_RCC_CFGR_HPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32_RCC_CFGR_PPRE2; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32_RCC_CFGR_PPRE1; + putreg32(regval, STM32_RCC_CFGR); + +#ifdef CONFIG_STM32U5_RTC_HSECLOCK + /* Set the RTC clock divisor */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_RTCPRE_MASK; + regval |= RCC_CFGR_RTCPRE(HSE_DIVISOR); + putreg32(regval, STM32_RCC_CFGR); +#endif + + /* Set the PLL source and main divider */ + + regval = getreg32(STM32_RCC_PLLCFG); + + /* Configure Main PLL */ + + /* Set the PLL dividers and multipliers to configure the main PLL */ + + regval = (STM32_PLLCFG_PLLM | STM32_PLLCFG_PLLN | + STM32_PLLCFG_PLLP | STM32_PLLCFG_PLLQ | + STM32_PLLCFG_PLLR); + +#ifdef STM32_PLLCFG_PLLP_ENABLED + regval |= RCC_PLLCFG_PLLPEN; +#endif +#ifdef STM32_PLLCFG_PLLQ_ENABLED + regval |= RCC_PLLCFG_PLLQEN; +#endif +#ifdef STM32_PLLCFG_PLLR_ENABLED + regval |= RCC_PLLCFG_PLLREN; +#endif + + /* XXX The choice of clock source to PLL (all three) is independent + * of the sys clock source choice, review the STM32_BOARD_USEHSI + * name; probably split it into two, one for PLL source and one + * for sys clock source. + */ + +#ifdef STM32_BOARD_USEHSI + regval |= RCC_PLLCFG_PLLSRC_HSI16; +#elif defined(STM32_BOARD_USEMSI) + regval |= RCC_PLLCFG_PLLSRC_MSI; +#else /* if STM32_BOARD_USEHSE */ + regval |= RCC_PLLCFG_PLLSRC_HSE; +#endif + + putreg32(regval, STM32_RCC_PLLCFG); + + /* Enable the main PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0) + { + } + +#ifdef CONFIG_STM32U5_SAI1PLL + /* Configure SAI1 PLL */ + + regval = getreg32(STM32_RCC_PLLSAI1CFG); + + /* Set the PLL dividers and multipliers to configure the SAI1 PLL */ + + regval = (STM32_PLLSAI1CFG_PLLN | STM32_PLLSAI1CFG_PLLP + | STM32_PLLSAI1CFG_PLLQ | STM32_PLLSAI1CFG_PLLR); + +#ifdef STM32_PLLSAI1CFG_PLLP_ENABLED + regval |= RCC_PLLSAI1CFG_PLLPEN; +#endif +#ifdef STM32_PLLSAI1CFG_PLLQ_ENABLED + regval |= RCC_PLLSAI1CFG_PLLQEN; +#endif +#ifdef STM32_PLLSAI1CFG_PLLR_ENABLED + regval |= RCC_PLLSAI1CFG_PLLREN; +#endif + + putreg32(regval, STM32_RCC_PLLSAI1CFG); + + /* Enable the SAI1 PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLSAI1ON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLSAI1RDY) == 0) + { + } +#endif + +#ifdef CONFIG_STM32U5_SAI2PLL + /* Configure SAI2 PLL */ + + regval = getreg32(STM32_RCC_PLLSAI2CFG); + + /* Set the PLL dividers and multipliers to configure the SAI2 PLL */ + + regval = (STM32_PLLSAI2CFG_PLLN | STM32_PLLSAI2CFG_PLLP | + STM32_PLLSAI2CFG_PLLR); + +#ifdef STM32_PLLSAI2CFG_PLLP_ENABLED + regval |= RCC_PLLSAI2CFG_PLLPEN; +#endif +#ifdef STM32_PLLSAI2CFG_PLLR_ENABLED + regval |= RCC_PLLSAI2CFG_PLLREN; +#endif + + putreg32(regval, STM32_RCC_PLLSAI2CFG); + + /* Enable the SAI2 PLL */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_PLLSAI2ON; + putreg32(regval, STM32_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLSAI2RDY) == 0) + { + } +#endif + + /* Enable FLASH 5 wait states */ + + regval = FLASH_ACR_LATENCY_5; + putreg32(regval, STM32_FLASH_ACR); + + /* Select the main PLL as system clock source */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= RCC_CFGR_SW_PLL; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until the PLL source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_PLL) + { + } + +#if defined(CONFIG_STM32U5_IWDG) || defined(CONFIG_STM32U5_RTC_LSICLOCK) + /* Low speed internal clock source LSI */ + + stm32_rcc_enablelsi(); +#endif + +#if defined(STM32_USE_LSE) + /* Low speed external clock source LSE + * + * TODO: There is another case where the LSE needs to + * be enabled: if the MCO1 pin selects LSE as source. + * XXX and other cases, like automatic trimming of MSI for USB use + */ + + /* ensure Power control is enabled since it is indirectly required + * to alter the LSE parameters. + */ + + stm32_pwr_enableclk(true); + + /* XXX other LSE settings must be made before turning on the oscillator + * and we need to ensure it is first off before doing so. + */ + + /* Turn on the LSE oscillator + * XXX this will almost surely get moved since we also want to use + * this for automatically trimming MSI, etc. + */ + + stm32_rcc_enablelse(); + +# if defined(STM32_BOARD_USEMSI) + /* Now that LSE is up, auto trim the MSI */ + + regval = getreg32(STM32_RCC_CR); + regval |= RCC_CR_MSIPLLEN; + putreg32(regval, STM32_RCC_CR); +# endif +#endif /* STM32_USE_LSE */ + } +} +#endif