diff --git a/.gitignore b/.gitignore index 1a330bdd34e01..02cfe592aab07 100644 --- a/.gitignore +++ b/.gitignore @@ -95,3 +95,4 @@ SAVEconfig .aider* imx9-norimage.img config.txt +CMakeUserPresets.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 16f2720b99180..198923472894f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,42 @@ if(EXISTS "${NUTTX_DIR}/.config") FATAL_ERROR "Please distclean previous make build with `make distclean`") endif() +# Check if board presets already exist +set(GENERATED_PRESET_FILE "${CMAKE_SOURCE_DIR}/CMakeUserPresets.json") + +if(NOT EXISTS "${GENERATED_PRESET_FILE}") + message(STATUS "CMake board presets not found. Generating them now...") + message( + STATUS + " This will create 'CMakeUserPresets.json' with all available board configs." + ) + + execute_process( + COMMAND python3 "${CMAKE_SOURCE_DIR}/tools/generate_cmake_presets.py" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE GEN_RESULT + OUTPUT_VARIABLE GEN_OUTPUT + ERROR_VARIABLE GEN_ERROR) + + if(GEN_RESULT EQUAL 0) + message(STATUS " Board presets generated successfully.") + message( + STATUS + " Please reload CMake configuration (e.g., re-run 'cmake -B build')") + message(STATUS " to see the presets in your IDE.") + else() + message( + WARNING + "Failed to generate board presets (python3 not found or script error).") + message(WARNING " To enable preset selection, run manually:") + message( + WARNING " python3 ${CMAKE_SOURCE_DIR}/tools/generate_cmake_presets.py") + if(GEN_ERROR) + message(STATUS " Error output: ${GEN_ERROR}") + endif() + endif() +endif() + if(NOT DEFINED BOARD_CONFIG) message(FATAL_ERROR "Please define configuration with BOARD_CONFIG") endif() diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000000000..9734de9d564b7 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,19 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "default", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "cacheVariables": {} + }, + { + "name": "Default", + "inherits": "default", + "cacheVariables": { + "BOARD_CONFIG": "n32h762iil7:nsh" + } + } + ] +} diff --git a/Documentation/platforms/arm/n32h7/boards/n32h762iil7/index.rst b/Documentation/platforms/arm/n32h7/boards/n32h762iil7/index.rst new file mode 100644 index 0000000000000..f4dd3ca30bcea --- /dev/null +++ b/Documentation/platforms/arm/n32h7/boards/n32h762iil7/index.rst @@ -0,0 +1,187 @@ +============================= +N32H762IIL7 Development Board +============================= + +.. tags:: chip:n32h762, arch:armv7e-m, vendor:nations + +.. figure:: n32h762iil7.png + :scale: 30 % + :align: center + :alt: N32H762IIL7 development board + + N32H762IIL7 development board from Nations Technologies. + +The N32H762IIL7 is a high-performance Cortex-M7 development board from Nations +Technologies, featuring a 600 MHz ARM Cortex-M7 core, 1.5 MB SRAM, and 2 MB +on-chip SIP Flash. It is designed for industrial control, IoT gateways, and +other compute-intensive applications. + +Features +======== + +OsTest LogFile: + +https://github.com/apache/nuttx/blob/17b96027359785bcb455342bfcaa900b46637540/arch/arm/src/n32h7/nuttx_test.log + +The current NuttX BSP supports the following features: + +- MCU: N32H762IIL7 (ARM Cortex-M7 @ 600 MHz) +- 1.5 MB SRAM (configurable as ITCM/DTCM/AXI SRAM) +- 2 MB SIP Flash (with cache limitations, see note) +- GPIO, EXTI, RCC, UART (console) +- TIM: timer, PWM, oneshot, tickless +- DMA (chained transfers) +- USBHS (Device and Host modes, external ULPI PHY required for HS) +- SDMMC (ADMA2 support) +- CORDIC hardware accelerator +- FLASH (MTD driver) +- UID + +**Not yet supported:** ADC, DAC, I2C, SPI, ETH, CAN/FDCAN, RTC, WDT. + +.. note:: + The SIP Flash on this chip does not work well with cache. For maximum + performance, critical code should be placed in ITCM (zero-wait memory). + +Buttons and LEDs +================ + +The board provides three user-controllable LEDs (Green, Blue, Red) and several +buttons. + +- **LEDs**: + - Green (LD1) - GPIO PA1 + - Blue (LD2) - GPIO PA2 + - Red (LD3) - GPIO PA3 + (All active high) + +- **Buttons**: + - Wakeup (B1) - GPIO PA0 + - Key1 - GPIO PC0 + - Key2 - GPIO PC1 + - Key3 - GPIO PC4 + (A high value when pressed) + +Pin Mapping +=========== + +The following table lists the default pin assignments for the N32H762IIL7 board. +For a complete list, refer to `boards/arm/n32h7/n32h762iil7/include/board.h`. + +===== ============ =================================================== +Pin Signal Function +===== ============ =================================================== +PA9 USART1_TX Console output (default) +PA10 USART1_RX Console input (default) +PA11 USBHS1_DM USBHS1 data- +PA12 USBHS1_DP USBHS1 data+ +PB14 USBHS2_DM USBHS2 data- +PB15 USBHS2_DP USBHS2 data+ +PD2 SDMMC1_CMD SD card command +PC8 SDMMC1_D0 SD card data 0 +PC9 SDMMC1_D1 SD card data 1 +PC10 SDMMC1_D2 SD card data 2 +PC11 SDMMC1_D3 SD card data 3 +PC12 SDMMC1_CK SD card clock +PC13 SDIO_NCD Card detect (input, pull-up) +PC6 USBHS1_PWRON Power control for USBHS1 (output) +PD12 USBHS2_PWRON Power control for USBHS2 (output) +PE9 ATIM1_CH1 PWM channel 1 (TIM1) +PE11 ATIM1_CH2 PWM channel 2 +PE13 ATIM1_CH3 PWM channel 3 +PE14 ATIM1_CH4 PWM channel 4 +PE5 GTIMB1_CH1 PWM channel 1 (TIMB1) +PE6 GTIMB1_CH2 PWM channel 2 +PE0 GTIMB1_CH3 PWM channel 3 +PE1 GTIMB1_CH4 PWM channel 4 +PA6 GTIMA2_CH1 Capture input 1 (TIM2) +... ... ... +===== ============ =================================================== + +Power Supply +============ + +The board can be powered via USB (5V) or an external DC supply. It includes an +on-board voltage regulator to generate 3.3V for the MCU and peripherals. + +Installation +============ + +To build NuttX for this board, you will need the standard ARM GCC toolchain +(version 10.2 or later) or Clang (14+). Installation instructions are the same +as for other Cortex-M boards. For details, see the +:doc:`/quickstart/install` guide. + +Building NuttX +============== + +This board supports both the traditional Makefile build system and the newer +CMake/Ninja build system. + +Makefile (GCC): + .. code:: console + + $ cd nuttx + $ ./tools/configure.sh n32h762iil7:nsh + $ make -j$(nproc) + +Makefile (Clang): + .. code:: console + + $ ./tools/configure.sh n32h762iil7:nsh + $ make menuconfig # select Clang toolchain + $ make -j$(nproc) + +CMake/Ninja (GCC only): + .. code:: console + + $ cd nuttx + $ cmake -B build -DBOARD_CONFIG=n32h762iil7:nsh -G Ninja + $ ninja -C build + +The resulting image (`nuttx.bin` or `nuttx.elf`) can be found in the build +directory. + +Flashing and Debugging +====================== + +The N32H762IIL7 can be programmed via JTAG/SWD using a debug probe. + +**Supported debugger**: J-Link + Ozone (the J-Link patch must be obtained from +Nations Technologies or extracted from the vendor’s .pack file). Other probes +(e.g., ST-Link, CMSIS-DAP) are not currently supported. + +The exact procedure depends on your J-Link configuration. Typically, you would +use Ozone to load the ELF file and flash it. + +.. todo:: + Provide exact Ozone project settings if possible. + +Configurations +============== + +The board identifier for `tools/configure.sh` is `n32h762iil7`. Currently, only +one configuration is provided: + +nsh +--- + +This configuration provides the NuttShell (NSH) over the USART1 console at +115200 baud. It includes **all currently supported drivers** and a selection of +example applications (CoreMark, ostest, sdbench, osperf, ramspeed, etc.). It is +the recommended starting point for evaluation. + + .. code:: console + + $ ./tools/configure.sh n32h762iil7:nsh + $ make + +.. note:: + Additional configurations (e.g., ``usb``, ``sdmmc``) may be added in the + future as more peripherals are ported. + +License Exceptions +================== + +The N32H7 port is entirely original work and is licensed under the Apache 2.0 +license, with no third-party proprietary code included. diff --git a/Documentation/platforms/arm/n32h7/boards/n32h762iil7/n32h762iil7.png b/Documentation/platforms/arm/n32h7/boards/n32h762iil7/n32h762iil7.png new file mode 100644 index 0000000000000..8a756f97eae87 Binary files /dev/null and b/Documentation/platforms/arm/n32h7/boards/n32h762iil7/n32h762iil7.png differ diff --git a/Documentation/platforms/arm/n32h7/index.rst b/Documentation/platforms/arm/n32h7/index.rst new file mode 100644 index 0000000000000..09d07ef1408ab --- /dev/null +++ b/Documentation/platforms/arm/n32h7/index.rst @@ -0,0 +1,62 @@ +============= +Nations N32H7 +============= + +Supported MCUs +============== + +The following N32H7 series MCUs are supported in NuttX: + +============ ======= ================ +MCU Support Note +============ ======= ================ +N32H762IIL7 Yes Cortex-M7 @ 600MHz, 1.5MB SRAM, 2MB Flash +N32H76x Yes Currently supported via the N32H762IIL7 BSP +N32H78x No (No plan yet) +============ ======= ================ + +Peripheral Support +================== + +The following list indicates peripherals supported in NuttX for N32H7 family: + +========== ======= ====================== +Peripheral Support Notes +========== ======= ====================== +GPIO Yes +EXTI Yes +RCC Yes +UART Yes +TIM Yes +PWM Yes +ONESHOT Yes +TICKLESS Yes +DMA Yes +USBHS Yes Device and Host modes +SDMMC Yes ADMA2 supported +CORDIC Yes +FLASH Yes MTD driver +UID Yes +WDT No Not yet ported +RTC No Not yet ported +I2C No Not yet ported +SPI No Not yet ported +ADC No Not yet ported +DAC No Not yet ported +CAN/FDCAN No Not yet ported +ETH No Not yet ported +========== ======= ====================== + +.. note:: + The SIP Flash on N32H76x has a limitation that prevents effective cache usage. + Therefore, code running from Flash may have lower performance than expected. + It is recommended to place critical code in ITCM for better performance. + +Supported Boards +================ + +.. toctree:: + :glob: + :maxdepth: 1 + + boards/*/* diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9bbf8540d5d54..8c67fd0240687 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -303,6 +303,22 @@ config ARCH_CHIP_MOXART ---help--- MoxART family +config ARCH_CHIP_N32H7 + bool "N32 H7" + select ARCH_CORTEXM7 + select ARCH_HAVE_MPU + select ARCH_HAVE_I2CRESET + select ARCH_HAVE_PROGMEM +# select ARCH_HAVE_HEAPCHECK + select ARCH_HAVE_SPI_BITORDER + select ARM_HAVE_MPU_UNIFIED + select ARMV7M_HAVE_STACKCHECK + select ARCH_HAVE_TICKLESS + select ARCH_HAVE_TIMEKEEPING + ---help--- + Nation Tech N32H7 architectures (ARM Cortex-M7 or + dual ARM Cortex-M7 Cortex-M4). + config ARCH_CHIP_NRF52 bool "Nordic nRF52" select ARCH_CORTEXM4 @@ -1317,6 +1333,7 @@ config ARCH_CHIP default "lpc54xx" if ARCH_CHIP_LPC54XX default "max326xx" if ARCH_CHIP_MAX326XX default "moxart" if ARCH_CHIP_MOXART + default "n32h7" if ARCH_CHIP_N32H7 default "nrf52" if ARCH_CHIP_NRF52 default "nrf53" if ARCH_CHIP_NRF53 default "nrf91" if ARCH_CHIP_NRF91 @@ -1811,6 +1828,9 @@ endif if ARCH_CHIP_MOXART source "arch/arm/src/moxart/Kconfig" endif +if ARCH_CHIP_N32H7 +source "arch/arm/src/n32h7/Kconfig" +endif if ARCH_CHIP_NRF52 source "arch/arm/src/nrf52/Kconfig" endif diff --git a/arch/arm/include/n32h7/chip.h b/arch/arm/include/n32h7/chip.h new file mode 100644 index 0000000000000..65a39c47c4c43 --- /dev/null +++ b/arch/arm/include/n32h7/chip.h @@ -0,0 +1,112 @@ +/**************************************************************************** + * arch/arm/include/n32h7/chip.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_N32H7_CHIP_H +#define __ARCH_ARM_INCLUDE_N32H7_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* N32H7x3xx Differences between family members: + * + * ----------- ---------------- ----- ---- + * SPI + * PART PACKAGE GPIOs I2S + * ----------- ---------------- ----- ---- + * N32H762Ix LQFP176 138 7/4 + * ----------- ---------------- ----- ---- + * + * Parts N32H7xxxI have 2048Kb of FLASH + * + * The correct FLASH size will be set CONFIG_N32H7_FLASH_CONFIG_x or + * overridden with CONFIG_N32H7_FLASH_OVERRIDE_x + */ + +#if defined (CONFIG_ARCH_CHIP_N32H762II) + +/* Memory */ +# define N32H7_AXI_RAM_SIZE (128*1024) /* Placeholder, actual value to be determined */ +# define N32H7_AHB_RAM_SIZE (352*1024) /* Placeholder, actual value to be determined */ +# if defined(CONFIG_ARMV7M_HAVE_DTCM) +# define N32H7_DTCM_SRAM_SIZE (1024*1024) /* Assume same as N32H7, adjust as needed */ +# else +# define N32H7_DTCM_SRAM_SIZE (0) /* No DTCM SRAM on TCM interface */ +# endif +# if defined(CONFIG_ARMV7M_HAVE_ITCM) +# define N32H7_ITCM_SRAM_SIZE (0) /* Assume same as N32H7, adjust as needed */ +# else +# define N32H7_ITCM_SRAM_SIZE (0) /* No ITCM SRAM on TCM interface */ +# endif + +/* Peripherals */ +# if defined(CONFIG_N32H7_IO_CONFIG_V) +# define N32H7_NGPIO (5) /* Placeholder, actual value to be determined */ +# elif defined(CONFIG_N32H7_IO_CONFIG_Z) +# define N32H7_NGPIO (7) /* Placeholder, actual value to be determined */ +# elif defined(CONFIG_N32H7_IO_CONFIG_I) +# define N32H7_NGPIO (9) /* Placeholder, actual value to be determined */ +# elif defined(CONFIG_N32H7_IO_CONFIG_X) +# define N32H7_NGPIO (11) /* Placeholder, actual value to be determined */ +# else +# error CONFIG_N32H7_IO_CONFIG_x Not Set +# endif + +# define N32H7_NDMA (3) /* Placeholder, actual value to be determined */ +# define N32H7_NADC (3) /* Placeholder, actual value to be determined */ +# define N32H7_NDAC (2) /* Placeholder, actual value to be determined */ +# define N32H7_NCMP (4) /* Placeholder, actual value to be determined */ +# define N32H7_NFMAC (1) /* Placeholder, actual value to be determined */ +# define N32H7_NUSART (7) /* Placeholder, actual value to be determined */ +# define N32H7_NSPI (7) /* Placeholder, actual value to be determined */ +# define N32H7_NI2S (4) /* Placeholder, actual value to be determined */ +# define N32H7_NUART (7) /* Placeholder, actual value to be determined */ +# define N32H7_NI2C (10) /* Placeholder, actual value to be determined */ +# define N32H7_NCAN (4) /* Placeholder, actual value to be determined */ +# define N32H7_NSDMMC (2) /* Placeholder, actual value to be determined */ +#else +# error N32 H7 chip not identified +#endif + +/** + * @brief Compute TCM configuration value from ITCM/DTCM/AXI sizes (KB). + * All sizes must be multiples of 128 and sum to 1024 KB. + * Result matches N32H7 TRM encoding 0x00..0x2C. + */ +#define N32H7_TCM_CFG(itcm_kb, dtcm_kb, axi_kb) \ + ( ( ( (axi_kb) / 128 ) * (19 - (axi_kb) / 128 ) / 2 ) + \ + ( (8 - (axi_kb) / 128) - (itcm_kb) / 128 ) ) + +/* 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_N32H7_CHIP_H */ diff --git a/arch/arm/include/n32h7/irq.h b/arch/arm/include/n32h7/irq.h new file mode 100644 index 0000000000000..816681783ca1e --- /dev/null +++ b/arch/arm/include/n32h7/irq.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/arm/include/n32h7/irq.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + + #ifndef __ARCH_ARM_INCLUDE_N32H7_IRQ_H + #define __ARCH_ARM_INCLUDE_N32H7_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* N32H7x3xx Differences between family members: + * + * ----------- ---------------- ----- ---- + * SPI + * PART PACKAGE GPIOs I2S + * ----------- ---------------- ----- ---- + * N32H762Ix LQFP176 138 7/4 + * ----------- ---------------- ----- ---- + * + * Parts N32H7xxxI have 2048Kb of FLASH + * + * The correct FLASH size will be set CONFIG_N32H7_FLASH_CONFIG_x or + * overridden with CONFIG_N32H7_FLASH_OVERRIDE_x + */ + +#if defined (CONFIG_ARCH_CHIP_N32H762II) +#else +# error N32 H7 chip not identified +#endif + +/* Processor Exceptions (vectors 0-15) */ + +#define N32_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 N32_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define N32_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define N32_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define N32_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define N32_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ + +/* Vectors 7-10: Reserved */ +#define N32_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define N32_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + +/* Vector 13: Reserved */ +#define N32_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define N32_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are chip-specific + */ + +#define N32_IRQ_FIRST (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_N32H7_N32H76X) +# include +#else +# error "Unsupported N32H7 chip" +#endif + +#endif /* __ARCH_ARM_INCLUDE_N32H7_IRQ_H */ diff --git a/arch/arm/include/n32h7/n32h76x_irq.h b/arch/arm/include/n32h7/n32h76x_irq.h new file mode 100644 index 0000000000000..2962a6cfc275b --- /dev/null +++ b/arch/arm/include/n32h7/n32h76x_irq.h @@ -0,0 +1,301 @@ +/**************************************************************************** + * arch/arm/include/n32h7/n32h76x_irq.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, + * only indirectly through arch/irq.h + */ + + #ifndef __ARCH_ARM_INCLUDE_N32H7_N32H76X_IRQ_H + #define __ARCH_ARM_INCLUDE_N32H7_N32H76X_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* IRQ numbers. + * The IRQ number corresponds vector number and hence map directly to bits + * in the NVIC. + * This does, however, waste several words of memory in the IRQ to handle + * mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be + * found in the file nuttx/arch/arm/include/n32h7/irq.h which includes + * this file + * + * External interrupts (vectors >= 16) + */ + +/* IRQ numbers for N32H76x CM7 (NVIC1) + * The IRQ number corresponds to vector number (offset from 0) + * External interrupts (vectors 16-249) + */ + +#define N32_IRQ_WWDG1 (N32_IRQ_FIRST + 0) +#define N32_IRQ_PVD (N32_IRQ_FIRST + 1) +#define N32_IRQ_RTC_TAMPER (N32_IRQ_FIRST + 2) +#define N32_IRQ_RTC_WKUP (N32_IRQ_FIRST + 3) +#define N32_IRQ_RCC (N32_IRQ_FIRST + 4) +#define N32_IRQ_EXTI0 (N32_IRQ_FIRST + 5) +#define N32_IRQ_EXTI1 (N32_IRQ_FIRST + 6) +#define N32_IRQ_EXTI2 (N32_IRQ_FIRST + 7) +#define N32_IRQ_EXTI3 (N32_IRQ_FIRST + 8) +#define N32_IRQ_EXTI4 (N32_IRQ_FIRST + 9) +#define N32_IRQ_EXTI9_5 (N32_IRQ_FIRST + 10) +#define N32_IRQ_EXTI15_10 (N32_IRQ_FIRST + 11) +#define N32_IRQ_DMA1_CHANNEL0 (N32_IRQ_FIRST + 12) +#define N32_IRQ_DMA1_CHANNEL1 (N32_IRQ_FIRST + 13) +#define N32_IRQ_DMA1_CHANNEL2 (N32_IRQ_FIRST + 14) +#define N32_IRQ_DMA1_CHANNEL3 (N32_IRQ_FIRST + 15) +#define N32_IRQ_DMA1_CHANNEL4 (N32_IRQ_FIRST + 16) +#define N32_IRQ_DMA1_CHANNEL5 (N32_IRQ_FIRST + 17) +#define N32_IRQ_DMA1_CHANNEL6 (N32_IRQ_FIRST + 18) +#define N32_IRQ_DMA1_CHANNEL7 (N32_IRQ_FIRST + 19) +#define N32_IRQ_DMA2_CHANNEL0 (N32_IRQ_FIRST + 20) +#define N32_IRQ_DMA2_CHANNEL1 (N32_IRQ_FIRST + 21) +#define N32_IRQ_DMA2_CHANNEL2 (N32_IRQ_FIRST + 22) +#define N32_IRQ_DMA2_CHANNEL3 (N32_IRQ_FIRST + 23) +#define N32_IRQ_DMA2_CHANNEL4 (N32_IRQ_FIRST + 24) +#define N32_IRQ_DMA2_CHANNEL5 (N32_IRQ_FIRST + 25) +#define N32_IRQ_DMA2_CHANNEL6 (N32_IRQ_FIRST + 26) +#define N32_IRQ_DMA2_CHANNEL7 (N32_IRQ_FIRST + 27) +#define N32_IRQ_DMA3_CHANNEL0 (N32_IRQ_FIRST + 28) +#define N32_IRQ_DMA3_CHANNEL1 (N32_IRQ_FIRST + 29) +#define N32_IRQ_DMA3_CHANNEL2 (N32_IRQ_FIRST + 30) +#define N32_IRQ_DMA3_CHANNEL3 (N32_IRQ_FIRST + 31) +#define N32_IRQ_DMA3_CHANNEL4 (N32_IRQ_FIRST + 32) +#define N32_IRQ_DMA3_CHANNEL5 (N32_IRQ_FIRST + 33) +#define N32_IRQ_DMA3_CHANNEL6 (N32_IRQ_FIRST + 34) +#define N32_IRQ_DMA3_CHANNEL7 (N32_IRQ_FIRST + 35) +#define N32_IRQ_MDMA_CHANNEL0 (N32_IRQ_FIRST + 36) +#define N32_IRQ_MDMA_CHANNEL1 (N32_IRQ_FIRST + 37) +#define N32_IRQ_MDMA_CHANNEL2 (N32_IRQ_FIRST + 38) +#define N32_IRQ_MDMA_CHANNEL3 (N32_IRQ_FIRST + 39) +#define N32_IRQ_MDMA_CHANNEL4 (N32_IRQ_FIRST + 40) +#define N32_IRQ_MDMA_CHANNEL5 (N32_IRQ_FIRST + 41) +#define N32_IRQ_MDMA_CHANNEL6 (N32_IRQ_FIRST + 42) +#define N32_IRQ_MDMA_CHANNEL7 (N32_IRQ_FIRST + 43) +#define N32_IRQ_MDMA_CHANNEL8 (N32_IRQ_FIRST + 44) +#define N32_IRQ_MDMA_CHANNEL9 (N32_IRQ_FIRST + 45) +#define N32_IRQ_MDMA_CHANNEL10 (N32_IRQ_FIRST + 46) +#define N32_IRQ_MDMA_CHANNEL11 (N32_IRQ_FIRST + 47) +#define N32_IRQ_MDMA_CHANNEL12 (N32_IRQ_FIRST + 48) +#define N32_IRQ_MDMA_CHANNEL13 (N32_IRQ_FIRST + 49) +#define N32_IRQ_MDMA_CHANNEL14 (N32_IRQ_FIRST + 50) +#define N32_IRQ_MDMA_CHANNEL15 (N32_IRQ_FIRST + 51) +#define N32_IRQ_SDPU (N32_IRQ_FIRST + 52) + +/* Reserved (53) */ + +/* Reserved (54) */ +#define N32_IRQ_FPU_CPU1 (N32_IRQ_FIRST + 55) +#define N32_IRQ_ECCMON (N32_IRQ_FIRST + 56) +#define N32_IRQ_RTC_ALARM (N32_IRQ_FIRST + 57) +#define N32_IRQ_I2C1_EVENT (N32_IRQ_FIRST + 58) +#define N32_IRQ_I2C1_ERR (N32_IRQ_FIRST + 59) +#define N32_IRQ_I2C2_EVENT (N32_IRQ_FIRST + 60) +#define N32_IRQ_I2C2_ERR (N32_IRQ_FIRST + 61) +#define N32_IRQ_I2C3_EVENT (N32_IRQ_FIRST + 62) +#define N32_IRQ_I2C3_ERR (N32_IRQ_FIRST + 63) +#define N32_IRQ_I2C4_EVENT (N32_IRQ_FIRST + 64) +#define N32_IRQ_I2C4_ERR (N32_IRQ_FIRST + 65) +#define N32_IRQ_I2C5_EVENT (N32_IRQ_FIRST + 66) +#define N32_IRQ_I2C5_ERR (N32_IRQ_FIRST + 67) +#define N32_IRQ_I2C6_EVENT (N32_IRQ_FIRST + 68) +#define N32_IRQ_I2C6_ERR (N32_IRQ_FIRST + 69) +#define N32_IRQ_I2C7_EVENT (N32_IRQ_FIRST + 70) +#define N32_IRQ_I2C7_ERR (N32_IRQ_FIRST + 71) +#define N32_IRQ_I2C8_EVENT (N32_IRQ_FIRST + 72) +#define N32_IRQ_I2C8_ERR (N32_IRQ_FIRST + 73) +#define N32_IRQ_I2C9_EVENT (N32_IRQ_FIRST + 74) +#define N32_IRQ_I2C9_ERR (N32_IRQ_FIRST + 75) +#define N32_IRQ_I2C10_EVENT (N32_IRQ_FIRST + 76) +#define N32_IRQ_I2C10_ERR (N32_IRQ_FIRST + 77) +#define N32_IRQ_I2S1 (N32_IRQ_FIRST + 78) +#define N32_IRQ_I2S2 (N32_IRQ_FIRST + 79) +#define N32_IRQ_I2S3 (N32_IRQ_FIRST + 80) +#define N32_IRQ_I2S4 (N32_IRQ_FIRST + 81) +#define N32_IRQ_xSPI1_IRQ (N32_IRQ_FIRST + 82) +#define N32_IRQ_xSPI2_IRQ (N32_IRQ_FIRST + 83) +#define N32_IRQ_SPI1 (N32_IRQ_FIRST + 84) +#define N32_IRQ_SPI2 (N32_IRQ_FIRST + 85) +#define N32_IRQ_SPI3 (N32_IRQ_FIRST + 86) +#define N32_IRQ_SPI4 (N32_IRQ_FIRST + 87) +#define N32_IRQ_SPI5 (N32_IRQ_FIRST + 88) +#define N32_IRQ_SPI6 (N32_IRQ_FIRST + 89) +#define N32_IRQ_SPI7 (N32_IRQ_FIRST + 90) +#define N32_IRQ_LCD_EVENT (N32_IRQ_FIRST + 91) +#define N32_IRQ_LCD_ERR (N32_IRQ_FIRST + 92) +#define N32_IRQ_DVP1 (N32_IRQ_FIRST + 93) +#define N32_IRQ_DVP2 (N32_IRQ_FIRST + 94) +#define N32_IRQ_DMAMUX2 (N32_IRQ_FIRST + 95) +#define N32_IRQ_USBHS1_HS_EPx_OUT (N32_IRQ_FIRST + 96) +#define N32_IRQ_USBHS1_HS_EPx_IN (N32_IRQ_FIRST + 97) +#define N32_IRQ_USBHS1_HS_WKUP (N32_IRQ_FIRST + 98) +#define N32_IRQ_USBHS1_HS (N32_IRQ_FIRST + 99) +#define N32_IRQ_USBHS2_HS_EPx_OUT (N32_IRQ_FIRST + 100) +#define N32_IRQ_USBHS2_HS_EPx_IN (N32_IRQ_FIRST + 101) +#define N32_IRQ_USBHS2_HS_WKUP (N32_IRQ_FIRST + 102) +#define N32_IRQ_USBHS2_HS (N32_IRQ_FIRST + 103) +#define N32_IRQ_ETH1 (N32_IRQ_FIRST + 104) +#define N32_IRQ_ETH1_PMT_LPI (N32_IRQ_FIRST + 105) +#define N32_IRQ_ETH2 (N32_IRQ_FIRST + 106) +#define N32_IRQ_ETH2_PMT_LPI (N32_IRQ_FIRST + 107) +#define N32_IRQ_FDCAN1_INT0 (N32_IRQ_FIRST + 108) +#define N32_IRQ_FDCAN2_INT0 (N32_IRQ_FIRST + 109) +#define N32_IRQ_FDCAN3_INT0 (N32_IRQ_FIRST + 110) +#define N32_IRQ_FDCAN4_INT0 (N32_IRQ_FIRST + 111) +#define N32_IRQ_FDCAN1_INT1 (N32_IRQ_FIRST + 112) +#define N32_IRQ_FDCAN2_INT1 (N32_IRQ_FIRST + 113) +#define N32_IRQ_FDCAN3_INT1 (N32_IRQ_FIRST + 114) +#define N32_IRQ_FDCAN4_INT1 (N32_IRQ_FIRST + 115) +#define N32_IRQ_USART1 (N32_IRQ_FIRST + 116) +#define N32_IRQ_USART2 (N32_IRQ_FIRST + 117) +#define N32_IRQ_USART3 (N32_IRQ_FIRST + 118) +#define N32_IRQ_USART4 (N32_IRQ_FIRST + 119) +#define N32_IRQ_USART5 (N32_IRQ_FIRST + 120) +#define N32_IRQ_USART6 (N32_IRQ_FIRST + 121) +#define N32_IRQ_USART7 (N32_IRQ_FIRST + 122) +#define N32_IRQ_USART8 (N32_IRQ_FIRST + 123) +#define N32_IRQ_UART9 (N32_IRQ_FIRST + 124) +#define N32_IRQ_UART10 (N32_IRQ_FIRST + 125) +#define N32_IRQ_UART11 (N32_IRQ_FIRST + 126) +#define N32_IRQ_UART12 (N32_IRQ_FIRST + 127) +#define N32_IRQ_UART13 (N32_IRQ_FIRST + 128) +#define N32_IRQ_UART14 (N32_IRQ_FIRST + 129) +#define N32_IRQ_UART15 (N32_IRQ_FIRST + 130) +#define N32_IRQ_LPUART1 (N32_IRQ_FIRST + 131) +#define N32_IRQ_LPUART2 (N32_IRQ_FIRST + 132) +#define N32_IRQ_GPU (N32_IRQ_FIRST + 133) + +/* Reserved (134) */ +#define N32_IRQ_SDMMC1 (N32_IRQ_FIRST + 135) +#define N32_IRQ_SDMMC2 (N32_IRQ_FIRST + 136) +#define N32_IRQ_ADC1 (N32_IRQ_FIRST + 137) +#define N32_IRQ_ADC2 (N32_IRQ_FIRST + 138) +#define N32_IRQ_ADC3 (N32_IRQ_FIRST + 139) +#define N32_IRQ_COMP12 (N32_IRQ_FIRST + 140) +#define N32_IRQ_COMP34 (N32_IRQ_FIRST + 141) +#define N32_IRQ_SHRTIM1_INT1 (N32_IRQ_FIRST + 142) +#define N32_IRQ_SHRTIM1_INT2 (N32_IRQ_FIRST + 143) +#define N32_IRQ_SHRTIM1_INT3 (N32_IRQ_FIRST + 144) +#define N32_IRQ_SHRTIM1_INT4 (N32_IRQ_FIRST + 145) +#define N32_IRQ_SHRTIM1_INT5 (N32_IRQ_FIRST + 146) +#define N32_IRQ_SHRTIM1_INT6 (N32_IRQ_FIRST + 147) +#define N32_IRQ_SHRTIM1_INT7 (N32_IRQ_FIRST + 148) +#define N32_IRQ_SHRTIM1_INT8 (N32_IRQ_FIRST + 149) +#define N32_IRQ_SHRTIM2_INT1 (N32_IRQ_FIRST + 150) +#define N32_IRQ_SHRTIM2_INT2 (N32_IRQ_FIRST + 151) +#define N32_IRQ_SHRTIM2_INT3 (N32_IRQ_FIRST + 152) +#define N32_IRQ_SHRTIM2_INT4 (N32_IRQ_FIRST + 153) +#define N32_IRQ_SHRTIM2_INT5 (N32_IRQ_FIRST + 154) +#define N32_IRQ_SHRTIM2_INT6 (N32_IRQ_FIRST + 155) +#define N32_IRQ_SHRTIM2_INT7 (N32_IRQ_FIRST + 156) +#define N32_IRQ_SHRTIM2_INT8 (N32_IRQ_FIRST + 157) +#define N32_IRQ_FDCAN5_INT0 (N32_IRQ_FIRST + 158) +#define N32_IRQ_FDCAN6_INT0 (N32_IRQ_FIRST + 159) +#define N32_IRQ_FDCAN7_INT0 (N32_IRQ_FIRST + 160) +#define N32_IRQ_FDCAN8_INT0 (N32_IRQ_FIRST + 161) +#define N32_IRQ_FDCAN5_INT1 (N32_IRQ_FIRST + 162) +#define N32_IRQ_FDCAN6_INT1 (N32_IRQ_FIRST + 163) +#define N32_IRQ_FDCAN7_INT1 (N32_IRQ_FIRST + 164) +#define N32_IRQ_FDCAN8_INT1 (N32_IRQ_FIRST + 165) +#define N32_IRQ_DSI (N32_IRQ_FIRST + 166) + +/* Reserved (167) */ +#define N32_IRQ_AHB_CACHE_PARMON (N32_IRQ_FIRST + 168) +#define N32_IRQ_LPTIM5_WKUP (N32_IRQ_FIRST + 169) +#define N32_IRQ_JPEG_SGDMA_H2P (N32_IRQ_FIRST + 170) +#define N32_IRQ_JPEG_SGDMA_P2H (N32_IRQ_FIRST + 171) +#define N32_IRQ_WAKEUP_IO (N32_IRQ_FIRST + 172) +#define N32_IRQ_SEMA4_INT1 (N32_IRQ_FIRST + 173) +#define N32_IRQ_WWDG1_RST (N32_IRQ_FIRST + 174) +#define N32_IRQ_OTPC (N32_IRQ_FIRST + 175) +#define N32_IRQ_FEMC (N32_IRQ_FIRST + 176) +#define N32_IRQ_DCMUA (N32_IRQ_FIRST + 177) +#define N32_IRQ_DAC1 (N32_IRQ_FIRST + 178) +#define N32_IRQ_DAC2 (N32_IRQ_FIRST + 179) +#define N32_IRQ_MDMA_AHBS_ER (N32_IRQ_FIRST + 180) +#define N32_IRQ_CM7_CACHE_READ_ER (N32_IRQ_FIRST + 181) +#define N32_IRQ_DAC3 (N32_IRQ_FIRST + 182) +#define N32_IRQ_DAC4 (N32_IRQ_FIRST + 183) +#define N32_IRQ_EMC (N32_IRQ_FIRST + 184) +#define N32_IRQ_DAC5 (N32_IRQ_FIRST + 185) +#define N32_IRQ_DAC6 (N32_IRQ_FIRST + 186) +#define N32_IRQ_ESC_OPB (N32_IRQ_FIRST + 187) +#define N32_IRQ_ESC_SYNC0 (N32_IRQ_FIRST + 188) +#define N32_IRQ_ESC_SYNC1 (N32_IRQ_FIRST + 189) +#define N32_IRQ_ESC_WRP (N32_IRQ_FIRST + 190) + +/* Reserved (191) */ +#define N32_IRQ_ATIM1_BRK (N32_IRQ_FIRST + 192) +#define N32_IRQ_ATIM1_TRG_COM (N32_IRQ_FIRST + 193) +#define N32_IRQ_ATIM1_CC (N32_IRQ_FIRST + 194) +#define N32_IRQ_ATIM1_UP (N32_IRQ_FIRST + 195) +#define N32_IRQ_ATIM2_BRK (N32_IRQ_FIRST + 196) +#define N32_IRQ_ATIM2_TRG_COM (N32_IRQ_FIRST + 197) +#define N32_IRQ_ATIM2_CC (N32_IRQ_FIRST + 198) +#define N32_IRQ_ATIM2_UP (N32_IRQ_FIRST + 199) +#define N32_IRQ_ATIM3_BRK (N32_IRQ_FIRST + 200) +#define N32_IRQ_ATIM3_TRG_COM (N32_IRQ_FIRST + 201) +#define N32_IRQ_ATIM3_CC (N32_IRQ_FIRST + 202) +#define N32_IRQ_ATIM3_UP (N32_IRQ_FIRST + 203) +#define N32_IRQ_ATIM4_BRK (N32_IRQ_FIRST + 204) +#define N32_IRQ_ATIM4_TRG_COM (N32_IRQ_FIRST + 205) +#define N32_IRQ_ATIM4_CC (N32_IRQ_FIRST + 206) +#define N32_IRQ_ATIM4_UP (N32_IRQ_FIRST + 207) +#define N32_IRQ_GTIMA1 (N32_IRQ_FIRST + 208) +#define N32_IRQ_GTIMA2 (N32_IRQ_FIRST + 209) +#define N32_IRQ_GIIMA3 (N32_IRQ_FIRST + 210) +#define N32_IRQ_GTIMA4 (N32_IRQ_FIRST + 211) +#define N32_IRQ_GTIMA5 (N32_IRQ_FIRST + 212) +#define N32_IRQ_GTIMA6 (N32_IRQ_FIRST + 213) +#define N32_IRQ_GTIMA7 (N32_IRQ_FIRST + 214) +#define N32_IRQ_GTIMB1 (N32_IRQ_FIRST + 215) +#define N32_IRQ_GTIMB2 (N32_IRQ_FIRST + 216) +#define N32_IRQ_GTIMB3 (N32_IRQ_FIRST + 217) +#define N32_IRQ_BTIM1 (N32_IRQ_FIRST + 218) +#define N32_IRQ_BTIM2 (N32_IRQ_FIRST + 219) +#define N32_IRQ_BTIM3 (N32_IRQ_FIRST + 220) +#define N32_IRQ_BTIM4 (N32_IRQ_FIRST + 221) +#define N32_IRQ_LPTIM1_WKUP (N32_IRQ_FIRST + 222) +#define N32_IRQ_LPTIM2_WKUP (N32_IRQ_FIRST + 223) +#define N32_IRQ_LPTIM3_WKUP (N32_IRQ_FIRST + 224) +#define N32_IRQ_LPTIM4_WKUP (N32_IRQ_FIRST + 225) +#define N32_IRQ_DSMU_FLT0 (N32_IRQ_FIRST + 226) +#define N32_IRQ_DSMU_FLT1 (N32_IRQ_FIRST + 227) +#define N32_IRQ_DSMU_FLT2 (N32_IRQ_FIRST + 228) +#define N32_IRQ_DSMU_FLT3 (N32_IRQ_FIRST + 229) +#define N32_IRQ_FMAC (N32_IRQ_FIRST + 230) +#define N32_IRQ_CORDIC (N32_IRQ_FIRST + 231) +#define N32_IRQ_DMAMUX1 (N32_IRQ_FIRST + 232) +#define N32_IRQ_MMU (N32_IRQ_FIRST + 233) + +#define N32H7_IRQ_NEXTINTS 234 +#define NR_IRQS (N32_IRQ_FIRST + N32H7_IRQ_NEXTINTS) + +#endif /* __ARCH_ARM_INCLUDE_N32H7_N32H76X_IRQ_H */ diff --git a/arch/arm/src/n32h7/CMakeLists.txt b/arch/arm/src/n32h7/CMakeLists.txt new file mode 100644 index 0000000000000..f6fdfa1713f2f --- /dev/null +++ b/arch/arm/src/n32h7/CMakeLists.txt @@ -0,0 +1,202 @@ +# ############################################################################## +# arch/arm/src/n32h7/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +set(SRCS) + +list( + APPEND + SRCS + n32_allocateheap.c + n32_exti_gpio.c + n32_gpio.c + n32_irq.c + n32_rcc.c + n32_lowputc.c + n32_serial.c + n32_cordic.c + n32_uid.c + n32_systemreset.c + n32_start.c) + +if(CONFIG_N32H7_PROGMEM) + list(APPEND SRCS n32_flash.c) +endif() + +if(CONFIG_ARCH_N32H7_DUALCORE) + list(APPEND SRCS n32_dualcore.c) +endif() + +if(CONFIG_N32H7_HSEM) + list(APPEND SRCS n32_hsem.c) +endif() + +if(CONFIG_RPTUN) + list(APPEND SRCS n32_rptun.c) +endif() + +if(CONFIG_SCHED_TICKLESS) + list(APPEND SRCS n32_tickless.c) +else() + list(APPEND SRCS n32_timerisr.c) +endif() + +if(CONFIG_N32H7_ONESHOT) + list(APPEND SRCS n32_oneshot.c) +endif() + +if(CONFIG_ONESHOT) + list(APPEND SRCS n32_oneshot_lowerhalf.c) +endif() + +if(CONFIG_ARM_MPU) + list(APPEND SRCS n32_mpuinit.c) +endif() + +if(CONFIG_BUILD_PROTECTED) + list(APPEND SRCS n32_userspace.c) +endif() + +if(CONFIG_N32H7_ADC) + list(APPEND SRCS n32_adc.c) +endif() + +if(CONFIG_N32H7_FDCAN) + list(APPEND SRCS n32_fdcan_sock.c) +endif() + +if(CONFIG_N32H7_BBSRAM) + list(APPEND SRCS n32_bbsram.c) +endif() + +if(CONFIG_N32H7_DMA) + list(APPEND SRCS n32_dma.c) +endif() + +if(CONFIG_N32H7_FMC) + list(APPEND SRCS n32_fmc.c) +endif() + +if(CONFIG_N32H7_IWDG OR CONFIG_N32H7_RTC_LSICLOCK) + list(APPEND SRCS n32_lsi.c) +endif() + +if(CONFIG_N32H7_RTC_LSECLOCK) + list(APPEND SRCS n32_lse.c) +endif() + +if(CONFIG_N32H7_I2C) + list(APPEND SRCS n32_i2c.c) +endif() + +if(CONFIG_N32H7_PWR) + list(APPEND SRCS n32_pwr.c) +endif() + +if(CONFIG_ARCH_IDLE_CUSTOM) + list(APPEND SRCS n32_idle.c) +endif() + +if(CONFIG_N32H7_QUADSPI) + list(APPEND SRCS n32_qspi.c) +endif() + +if(CONFIG_N32H7_RTC) + list(APPEND SRCS n32_rtc.c) + if(CONFIG_RTC_ALARM) + list(APPEND SRCS n32_exti_alarm.c) + endif() + if(CONFIG_RTC_PERIODIC) + list(APPEND SRCS n32_exti_wakeup.c) + endif() + if(CONFIG_RTC_DRIVER) + list(APPEND SRCS n32_rtc_lowerhalf.c) + endif() +endif() + +if(CONFIG_N32H7_SPI) + list(APPEND SRCS n32_spi.c) +endif() + +if(CONFIG_SPI_SLAVE) + list(APPEND SRCS n32_spi_slave.c) +endif() + +if(CONFIG_N32H7_SDMMC) + list(APPEND SRCS n32_sdmmc.c) +endif() + +if(CONFIG_TIMER) + list(APPEND SRCS n32_tim_lowerhalf.c) +endif() + +if(CONFIG_N32H7_CAPTURE) + list(APPEND SRCS n32_capture.c) +endif() + +if(CONFIG_CAPTURE) + list(APPEND SRCS n32_capture_lowerhalf.c) +endif() + +if(CONFIG_USBDEV) + list(APPEND SRCS n32_usbhsdev.c) +endif() + +if(CONFIG_USBHOST) + list(APPEND SRCS n32_usbhshost.c) +endif() + +if(CONFIG_N32H7_TIM) + list(APPEND SRCS n32_tim.c) +endif() + +if(CONFIG_N32H7_LPTIM) + list(APPEND SRCS n32_lptim.c) +endif() + +if(CONFIG_N32H7_PWM) + list(APPEND SRCS n32_pwm.c) +endif() + +if(CONFIG_N32H7_ETHMAC) + list(APPEND SRCS n32_ethernet.c) +endif() + +if(CONFIG_SENSORS_QENCODER) + list(APPEND SRCS n32_qencoder.c) +endif() + +if(CONFIG_PM) + list(APPEND SRCS n32_pmsleep.c n32_pmstandby.c n32_pmstop.c) + if(NOT CONFIG_ARCH_CUSTOM_PMINIT) + list(APPEND SRCS n32_pminitialize.c) + endif() +endif() + +if(CONFIG_N32H7_IWDG) + list(APPEND SRCS n32_iwdg.c) +endif() + +if(CONFIG_N32H7_WWDG) + list(APPEND SRCS n32_wwdg.c) +endif() + +target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/arm/src/n32h7/Kconfig b/arch/arm/src/n32h7/Kconfig new file mode 100644 index 0000000000000..864caa2034307 --- /dev/null +++ b/arch/arm/src/n32h7/Kconfig @@ -0,0 +1,5302 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_N32H7 + +# "N32 H7 Configuration Options" + +choice + prompt "N32 H7 Chip Selection" + default ARCH_CHIP_N32H762II + depends on ARCH_CHIP_N32H7 + +config ARCH_CHIP_N32H762II + bool "N32H762IIL7" + select N32H7_N32H76X + select N32H7_FLASH_CONFIG_I + select N32H7_IO_CONFIG_I + ---help--- + N32 H7 Cortex M7, 2048 Kb FLASH, 15K Kb SRAM, + with cryptographic accelerator, LQFP176 +endchoice # N32 H7 Chip Selection + +config N32H7_N32H76X + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU + select N32H7_HAVE_ETHERNET + select N32H7_HAVE_FMC + select ARCH_HAVE_SERIAL_TERMIOS + +config N32H7_HAVE_USART8 + bool + default n + +config N32H7_HAVE_FMC + bool + default n + +config N32H7_HAVE_ETHERNET + bool + default n + +choice + prompt "N32 H7 Core selection" + default ARCH_CHIP_N32H7_CORTEXM7 + +config ARCH_CHIP_N32H7_CORTEXM7 + bool "N32H7 Cortex-M7 core" + select ARCH_CORTEXM7 + select ARMV7M_HAVE_ICACHE + select ARMV7M_HAVE_DCACHE + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + +config ARCH_CHIP_N32H7_CORTEXM4 + bool "N32H7 Cortex-M4 core" + depends on ARCH_N32H7_DUALCORE + select ARCH_CORTEXM4 + +endchoice # N32 H7 Core selection + +config N32H7_FLASH_CONFIG_I + bool + default n + +config N32H7_FLASH_CONFIG_K + bool + default n + +choice + prompt "Override Flash Size Designator" + depends on ARCH_CHIP_N32H7 + default N32H7_FLASH_OVERRIDE_DEFAULT + ---help--- + N32H7 series parts numbering (sans the package type) ends with a + letter that designates the FLASH size. + + Designator Size in KiB + I 2048 + K 4096 + + 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 N32 Chip Selection. + +config N32H7_FLASH_OVERRIDE_DEFAULT + bool "Default" + +config N32H7_FLASH_OVERRIDE_I + bool "I 2048KiB" + +config N32H7_FLASH_OVERRIDE_K + bool "K 4096KiB" + +endchoice # "Override Flash Size Designator" + +config N32H7_BSRAMEXCLUDE + bool + default y + +config N32H7_IO_CONFIG_V + bool + default n + +config N32H7_IO_CONFIG_Z + bool + default n + +config N32H7_IO_CONFIG_I + bool + default n + +config N32H7_IO_CONFIG_X + bool + default n + +config N32H7_CORDIC + bool "CORDIC" + select MATH_CORDIC + default n + +config N32H7_PWR + bool "PWR" + default n + +config N32H7_DMA + bool "DMA" + select ARCH_DMA + default n + +config N32H7_MDMA + bool "MDMA" + default n + +config N32H7_DMA1 + bool "DMA1" + default n + +config N32H7_DMA2 + bool "DMA2" + default n + +config N32H7_DMA3 + bool "DMA3" + default n + +config N32H7_TIM + bool "TIM" + default n + +config N32H7_PWM + bool "PWM" + default n + +config N32H7_SDMMC + bool "SDMMC" + select MMCSD + select ARCH_HAVE_SDIO + select SDIO_BLOCKSETUP + default n + +if N32H7_SDMMC +config N32H7_SDMMC_ADMA + bool "SDMMC ADMA" + select SDIO_DMA + default n +if N32H7_SDMMC_ADMA +config N32H7_SDMMC_MAX_DESCS + int + default 4 + ---help--- + Maximum number of SDMMC ADMA descriptors. +endif +endif # N32H7_SDMMC + +config N32H7_SDMMC1 + bool "SDMMC1" + default n + select N32H7_SDMMC + +config N32H7_SDMMC2 + bool "SDMMC2" + default n + select N32H7_SDMMC + +config N32H7_PROGMEM + bool "Progmem MTD configuration" + default n + select MTD + select MTD_PROGMEM + +config N32H7_USBHS + bool "USBHS" + default n + +config N32H7_USBHS_FS + bool "USBHS FS" + default n + +if N32H7_USBHS +config N32H7_USBHS_ID_DISABLE + bool "Disable USBHS ID GPIO" + default y + +config N32H7_USBHS_SOFOUTPUT + bool "USBHS SOF Output" + default n +endif # N32H7_USBHS + +config N32H7_USBHS1_DEV + bool "USBHS1 Device" + default n + select USBDEV + select N32H7_USBHS + +config N32H7_USBHS2_DEV + bool "USBHS2 Device" + default n + select USBDEV + select N32H7_USBHS + +config N32H7_USBHS1_HOST + bool "USBHS1 Host" + default n + select USBHOST + select USBHOST_INT_DISABLE + select N32H7_USBHS + +config N32H7_USBHS2_HOST + bool "USBHS2 Host" + default n + select USBHOST + select USBHOST_INT_DISABLE + select N32H7_USBHS + +menuconfig N32H7_SERIAL + bool "Serial Driver Support" + default n + ---help--- + Enable N32H7 serial driver. + +if N32H7_SERIAL +config N32H7_USART1 + bool "USART1" + default n + select USART1_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_USART2 + bool "USART2" + default n + select USART2_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_USART3 + bool "USART3" + default n + select USART3_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_USART4 + bool "USART4" + default n + select USART4_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_USART5 + bool "USART5" + default n + select USART5_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_USART6 + bool "USART6" + default n + select USART6_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_USART7 + bool "USART7" + default n + select USART7_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_USART8 + bool "USART8" + default n + select USART8_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_UART9 + bool "UART9" + default n + select UART9_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_UART10 + bool "UART10" + default n + select UART10_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_UART11 + bool "UART11" + default n + select UART11_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_UART12 + bool "UART12" + default n + select UART12_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_UART13 + bool "UART13" + default n + select UART13_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_UART14 + bool "UART14" + default n + select UART14_SERIALDRIVER + +endif # N32H7_SERIAL +if N32H7_SERIAL +config N32H7_UART15 + bool "UART15" + default n + select UART15_SERIALDRIVER + +endif # N32H7_SERIAL + +# +# Timer Configuration for N32H7 - AUTO GENERATED +# Do not edit manually. +# + +menu "Timer Configuration" + +if SCHED_TICKLESS + +config N32H7_TICKLESS_TIMER + int "Tickless hardware timer" + default 15 + range 1 18 + ---help--- + If the Tickless OS feature is enabled, then one timer must be + assigned to provide the timer needed by the OS. + + N32H7 Timer Number Mapping: + 1 = ATIM1 10 = GTIMA6 + 2 = ATIM2 11 = GTIMA7 + 3 = GTIMA1 12 = GTIMB1 + 4 = GTIMA2 13 = GTIMB2 + 5 = GTIMA3 14 = GTIMB3 + 6 = ATIM3 15 = BTIM1 + 7 = ATIM4 16 = BTIM2 + 8 = GTIMA4 17 = BTIM3 + 9 = GTIMA5 18 = BTIM4 + +config N32H7_TICKLESS_CHANNEL + int "Tickless timer channel" + default 1 + range 1 4 + ---help--- + If the Tickless OS feature is enabled, the timer needs one channel + on that timer to handle intervals. + +endif # SCHED_TICKLESS + +config N32H7_ONESHOT + bool "TIM one-shot wrapper" + default n + select ONESHOT + ---help--- + Enable a wrapper around the low level timer/counter functions to + support one-shot timer. + +config N32H7_ONESHOT_MAXCHANNELS + int "Maximum number of oneshot channels" + default 1 + range 1 8 + depends on N32H7_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 N32H7_TIMER + bool "N32H7 timer driver support" + default n + select TIMER + ---help--- + Enable support for the N32H7 timer driver (n32_tim.c and + n32_tim_lowerhalf.c). + +config N32H7_TIMER_ADVANCED + bool "Advanced Timers (ATIM1-4)" + select N32H7_TIM + ---help--- + Enable support for Advanced Timers (ATIM1, ATIM2, ATIM3, ATIM4). + These timers support complementary outputs, dead-time, break, + repetition counter, and encoder modes. + +config N32H7_TIMER_GTIMA + bool "General-purpose Timers A (GTIMA1-7)" + select N32H7_TIM + ---help--- + Enable support for General-purpose Timers A (GTIMA1-7). + These timers support PWM, input capture, output compare, + and encoder modes. No complementary outputs. + +config N32H7_TIMER_GTIMB + bool "General-purpose Timers B (GTIMB1-3)" + select N32H7_TIM + ---help--- + Enable support for General-purpose Timers B (GTIMB1-3). + These timers support PWM, input capture, output compare, + complementary outputs (CH1 only), break, and encoder modes. + +config N32H7_TIMER_BASIC + bool "Basic Timers (BTIM1-4)" + select N32H7_TIM + ---help--- + Enable support for Basic Timers (BTIM1, BTIM2, BTIM3, BTIM4). + These timers have a 32-bit counter and only support update events. + No PWM, capture, or encoder modes. + +if N32H7_TIMER_ADVANCED + +config N32H7_ATIM1 + bool "ATIM1" + default n + ---help--- + Enable Advanced Timer ATIM1. + +if N32H7_ATIM1 + +config N32H7_ATIM1_PWM + bool "ATIM1 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve ATIM1 for use by PWM. + +if N32H7_ATIM1_PWM + +config N32H7_ATIM1_MODE + int "ATIM1 Mode" + default 0 + range 0 4 + ---help--- + Specifies the ATIM1 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +config N32H7_ATIM1_LOCK + int "ATIM1 Lock Level" + default 0 + range 0 3 + ---help--- + ATIM1 BDTR lock level configuration. + +config N32H7_ATIM1_TDTS + int "ATIM1 t_DTS Division" + default 0 + range 0 2 + ---help--- + ATIM1 dead-time and sampling clock division: 0=tCK_INT, 1=2*tCK_INT, 2=4*tCK_INT. + +config N32H7_ATIM1_DEADTIME + int "ATIM1 Initial Dead-time" + default 0 + range 0 255 + ---help--- + ATIM1 initial dead-time value (0-255). + +config N32H7_ATIM1_BREAK1 + bool "ATIM1 Break1 Enable" + default n + ---help--- + Enable Break1 input for ATIM1. + +config N32H7_ATIM1_BRK1POL + int "ATIM1 Break1 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_BREAK1 + ---help--- + ATIM1 Break1 polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_BREAK2 + bool "ATIM1 Break2 Enable" + default n + ---help--- + Enable Break2 input for ATIM1 (ATIM only). + +config N32H7_ATIM1_BRK2POL + int "ATIM1 Break2 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_BREAK2 + ---help--- + ATIM1 Break2 polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_BRK2FLT + int "ATIM1 Break2 Filter" + default 0 + range 0 15 + depends on N32H7_ATIM1_BREAK2 + ---help--- + ATIM1 Break2 filter value (0-15). + +if N32H7_PWM_MULTICHAN + +config N32H7_ATIM1_CHANNEL1 + bool "ATIM1 Channel 1" + default n + +if N32H7_ATIM1_CHANNEL1 + +config N32H7_ATIM1_CH1OUT + bool "ATIM1 Channel 1 Output Enable" + default N32H7_ATIM1_CHANNEL1 + ---help--- + Enable output for ATIM1 Channel 1. If disabled, the channel will not be used. + +config N32H7_ATIM1_CH1MODE + int "ATIM1 Channel 1 Mode" + default 6 + depends on N32H7_ATIM1_CH1OUT + range 0 11 + ---help--- + ATIM1 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM1_CH1POL + int "ATIM1 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH1OUT + ---help--- + ATIM1 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_CH1IDLE + int "ATIM1 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH1OUT + ---help--- + ATIM1 Channel 1 idle state: 0=inactive, 1=active. + +config N32H7_ATIM1_CH1NOUT + bool "ATIM1 Channel 1 Complementary Output Enable" + default n + depends on N32H7_ATIM1_CH1OUT + ---help--- + Enable complementary output for ATIM1 Channel 1. + +config N32H7_ATIM1_CH1NPOL + int "ATIM1 Channel 1 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH1NOUT + ---help--- + ATIM1 Channel 1 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_CH1NIDLE + int "ATIM1 Channel 1 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH1NOUT + ---help--- + ATIM1 Channel 1 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM1_CHANNEL1 + +config N32H7_ATIM1_CHANNEL2 + bool "ATIM1 Channel 2" + default n + +if N32H7_ATIM1_CHANNEL2 + +config N32H7_ATIM1_CH2OUT + bool "ATIM1 Channel 2 Output Enable" + default N32H7_ATIM1_CHANNEL2 + ---help--- + Enable output for ATIM1 Channel 2. If disabled, the channel will not be used. + +config N32H7_ATIM1_CH2MODE + int "ATIM1 Channel 2 Mode" + default 6 + depends on N32H7_ATIM1_CH2OUT + range 0 11 + ---help--- + ATIM1 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM1_CH2POL + int "ATIM1 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH2OUT + ---help--- + ATIM1 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_CH2IDLE + int "ATIM1 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH2OUT + ---help--- + ATIM1 Channel 2 idle state: 0=inactive, 1=active. + +config N32H7_ATIM1_CH2NOUT + bool "ATIM1 Channel 2 Complementary Output Enable" + default n + depends on N32H7_ATIM1_CH2OUT + ---help--- + Enable complementary output for ATIM1 Channel 2. + +config N32H7_ATIM1_CH2NPOL + int "ATIM1 Channel 2 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH2NOUT + ---help--- + ATIM1 Channel 2 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_CH2NIDLE + int "ATIM1 Channel 2 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH2NOUT + ---help--- + ATIM1 Channel 2 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM1_CHANNEL2 + +config N32H7_ATIM1_CHANNEL3 + bool "ATIM1 Channel 3" + default n + +if N32H7_ATIM1_CHANNEL3 + +config N32H7_ATIM1_CH3OUT + bool "ATIM1 Channel 3 Output Enable" + default N32H7_ATIM1_CHANNEL3 + ---help--- + Enable output for ATIM1 Channel 3. If disabled, the channel will not be used. + +config N32H7_ATIM1_CH3MODE + int "ATIM1 Channel 3 Mode" + default 6 + depends on N32H7_ATIM1_CH3OUT + range 0 11 + ---help--- + ATIM1 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM1_CH3POL + int "ATIM1 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH3OUT + ---help--- + ATIM1 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_CH3IDLE + int "ATIM1 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH3OUT + ---help--- + ATIM1 Channel 3 idle state: 0=inactive, 1=active. + +config N32H7_ATIM1_CH3NOUT + bool "ATIM1 Channel 3 Complementary Output Enable" + default n + depends on N32H7_ATIM1_CH3OUT + ---help--- + Enable complementary output for ATIM1 Channel 3. + +config N32H7_ATIM1_CH3NPOL + int "ATIM1 Channel 3 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH3NOUT + ---help--- + ATIM1 Channel 3 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_CH3NIDLE + int "ATIM1 Channel 3 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH3NOUT + ---help--- + ATIM1 Channel 3 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM1_CHANNEL3 + +config N32H7_ATIM1_CHANNEL4 + bool "ATIM1 Channel 4" + default n + +if N32H7_ATIM1_CHANNEL4 + +config N32H7_ATIM1_CH4OUT + bool "ATIM1 Channel 4 Output Enable" + default N32H7_ATIM1_CHANNEL4 + ---help--- + Enable output for ATIM1 Channel 4. If disabled, the channel will not be used. + +config N32H7_ATIM1_CH4MODE + int "ATIM1 Channel 4 Mode" + default 6 + depends on N32H7_ATIM1_CH4OUT + range 0 11 + ---help--- + ATIM1 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM1_CH4POL + int "ATIM1 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH4OUT + ---help--- + ATIM1 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_CH4IDLE + int "ATIM1 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH4OUT + ---help--- + ATIM1 Channel 4 idle state: 0=inactive, 1=active. + +config N32H7_ATIM1_CH4NOUT + bool "ATIM1 Channel 4 Complementary Output Enable" + default n + depends on N32H7_ATIM1_CH4OUT + ---help--- + Enable complementary output for ATIM1 Channel 4. + +config N32H7_ATIM1_CH4NPOL + int "ATIM1 Channel 4 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH4NOUT + ---help--- + ATIM1 Channel 4 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM1_CH4NIDLE + int "ATIM1 Channel 4 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH4NOUT + ---help--- + ATIM1 Channel 4 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM1_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_ATIM1_CHANNEL + int "ATIM1 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If ATIM1 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_ATIM1_CHMODE + int "ATIM1 Channel Mode" + default 6 + range 0 11 + ---help--- + ATIM1 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_ATIM1_PWM + +config N32H7_ATIM1_QE + bool "ATIM1 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve ATIM1 for use as a quadrature encoder interface. + +endif # N32H7_ATIM1 + +config N32H7_ATIM2 + bool "ATIM2" + default n + ---help--- + Enable Advanced Timer ATIM2. + +if N32H7_ATIM2 + +config N32H7_ATIM2_PWM + bool "ATIM2 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve ATIM2 for use by PWM. + +if N32H7_ATIM2_PWM + +config N32H7_ATIM2_MODE + int "ATIM2 Mode" + default 0 + range 0 4 + ---help--- + Specifies the ATIM2 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +config N32H7_ATIM2_LOCK + int "ATIM2 Lock Level" + default 0 + range 0 3 + ---help--- + ATIM2 BDTR lock level configuration. + +config N32H7_ATIM2_TDTS + int "ATIM2 t_DTS Division" + default 0 + range 0 2 + ---help--- + ATIM2 dead-time and sampling clock division: 0=tCK_INT, 1=2*tCK_INT, 2=4*tCK_INT. + +config N32H7_ATIM2_DEADTIME + int "ATIM2 Initial Dead-time" + default 0 + range 0 255 + ---help--- + ATIM2 initial dead-time value (0-255). + +config N32H7_ATIM2_BREAK1 + bool "ATIM2 Break1 Enable" + default n + ---help--- + Enable Break1 input for ATIM2. + +config N32H7_ATIM2_BRK1POL + int "ATIM2 Break1 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_BREAK1 + ---help--- + ATIM2 Break1 polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_BREAK2 + bool "ATIM2 Break2 Enable" + default n + ---help--- + Enable Break2 input for ATIM2 (ATIM only). + +config N32H7_ATIM2_BRK2POL + int "ATIM2 Break2 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_BREAK2 + ---help--- + ATIM2 Break2 polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_BRK2FLT + int "ATIM2 Break2 Filter" + default 0 + range 0 15 + depends on N32H7_ATIM2_BREAK2 + ---help--- + ATIM2 Break2 filter value (0-15). + +if N32H7_PWM_MULTICHAN + +config N32H7_ATIM2_CHANNEL1 + bool "ATIM2 Channel 1" + default n + +if N32H7_ATIM2_CHANNEL1 + +config N32H7_ATIM2_CH1OUT + bool "ATIM2 Channel 1 Output Enable" + default N32H7_ATIM2_CHANNEL1 + ---help--- + Enable output for ATIM2 Channel 1. If disabled, the channel will not be used. + +config N32H7_ATIM2_CH1MODE + int "ATIM2 Channel 1 Mode" + default 6 + depends on N32H7_ATIM2_CH1OUT + range 0 11 + ---help--- + ATIM2 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM2_CH1POL + int "ATIM2 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH1OUT + ---help--- + ATIM2 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_CH1IDLE + int "ATIM2 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH1OUT + ---help--- + ATIM2 Channel 1 idle state: 0=inactive, 1=active. + +config N32H7_ATIM2_CH1NOUT + bool "ATIM2 Channel 1 Complementary Output Enable" + default n + depends on N32H7_ATIM2_CH1OUT + ---help--- + Enable complementary output for ATIM2 Channel 1. + +config N32H7_ATIM2_CH1NPOL + int "ATIM2 Channel 1 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH1NOUT + ---help--- + ATIM2 Channel 1 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_CH1NIDLE + int "ATIM2 Channel 1 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH1NOUT + ---help--- + ATIM2 Channel 1 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM2_CHANNEL1 + +config N32H7_ATIM2_CHANNEL2 + bool "ATIM2 Channel 2" + default n + +if N32H7_ATIM2_CHANNEL2 + +config N32H7_ATIM2_CH2OUT + bool "ATIM2 Channel 2 Output Enable" + default N32H7_ATIM2_CHANNEL2 + ---help--- + Enable output for ATIM2 Channel 2. If disabled, the channel will not be used. + +config N32H7_ATIM2_CH2MODE + int "ATIM2 Channel 2 Mode" + default 6 + depends on N32H7_ATIM2_CH2OUT + range 0 11 + ---help--- + ATIM2 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM2_CH2POL + int "ATIM2 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH2OUT + ---help--- + ATIM2 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_CH2IDLE + int "ATIM2 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH2OUT + ---help--- + ATIM2 Channel 2 idle state: 0=inactive, 1=active. + +config N32H7_ATIM2_CH2NOUT + bool "ATIM2 Channel 2 Complementary Output Enable" + default n + depends on N32H7_ATIM2_CH2OUT + ---help--- + Enable complementary output for ATIM2 Channel 2. + +config N32H7_ATIM2_CH2NPOL + int "ATIM2 Channel 2 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH2NOUT + ---help--- + ATIM2 Channel 2 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_CH2NIDLE + int "ATIM2 Channel 2 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH2NOUT + ---help--- + ATIM2 Channel 2 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM2_CHANNEL2 + +config N32H7_ATIM2_CHANNEL3 + bool "ATIM2 Channel 3" + default n + +if N32H7_ATIM2_CHANNEL3 + +config N32H7_ATIM2_CH3OUT + bool "ATIM2 Channel 3 Output Enable" + default N32H7_ATIM2_CHANNEL3 + ---help--- + Enable output for ATIM2 Channel 3. If disabled, the channel will not be used. + +config N32H7_ATIM2_CH3MODE + int "ATIM2 Channel 3 Mode" + default 6 + depends on N32H7_ATIM2_CH3OUT + range 0 11 + ---help--- + ATIM2 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM2_CH3POL + int "ATIM2 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH3OUT + ---help--- + ATIM2 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_CH3IDLE + int "ATIM2 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH3OUT + ---help--- + ATIM2 Channel 3 idle state: 0=inactive, 1=active. + +config N32H7_ATIM2_CH3NOUT + bool "ATIM2 Channel 3 Complementary Output Enable" + default n + depends on N32H7_ATIM2_CH3OUT + ---help--- + Enable complementary output for ATIM2 Channel 3. + +config N32H7_ATIM2_CH3NPOL + int "ATIM2 Channel 3 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH3NOUT + ---help--- + ATIM2 Channel 3 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_CH3NIDLE + int "ATIM2 Channel 3 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH3NOUT + ---help--- + ATIM2 Channel 3 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM2_CHANNEL3 + +config N32H7_ATIM2_CHANNEL4 + bool "ATIM2 Channel 4" + default n + +if N32H7_ATIM2_CHANNEL4 + +config N32H7_ATIM2_CH4OUT + bool "ATIM2 Channel 4 Output Enable" + default N32H7_ATIM2_CHANNEL4 + ---help--- + Enable output for ATIM2 Channel 4. If disabled, the channel will not be used. + +config N32H7_ATIM2_CH4MODE + int "ATIM2 Channel 4 Mode" + default 6 + depends on N32H7_ATIM2_CH4OUT + range 0 11 + ---help--- + ATIM2 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM2_CH4POL + int "ATIM2 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH4OUT + ---help--- + ATIM2 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_CH4IDLE + int "ATIM2 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH4OUT + ---help--- + ATIM2 Channel 4 idle state: 0=inactive, 1=active. + +config N32H7_ATIM2_CH4NOUT + bool "ATIM2 Channel 4 Complementary Output Enable" + default n + depends on N32H7_ATIM2_CH4OUT + ---help--- + Enable complementary output for ATIM2 Channel 4. + +config N32H7_ATIM2_CH4NPOL + int "ATIM2 Channel 4 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH4NOUT + ---help--- + ATIM2 Channel 4 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM2_CH4NIDLE + int "ATIM2 Channel 4 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH4NOUT + ---help--- + ATIM2 Channel 4 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM2_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_ATIM2_CHANNEL + int "ATIM2 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If ATIM2 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_ATIM2_CHMODE + int "ATIM2 Channel Mode" + default 6 + range 0 11 + ---help--- + ATIM2 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_ATIM2_PWM + +config N32H7_ATIM2_QE + bool "ATIM2 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve ATIM2 for use as a quadrature encoder interface. + +endif # N32H7_ATIM2 + +config N32H7_ATIM3 + bool "ATIM3" + default n + ---help--- + Enable Advanced Timer ATIM3. + +if N32H7_ATIM3 + +config N32H7_ATIM3_PWM + bool "ATIM3 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve ATIM3 for use by PWM. + +if N32H7_ATIM3_PWM + +config N32H7_ATIM3_MODE + int "ATIM3 Mode" + default 0 + range 0 4 + ---help--- + Specifies the ATIM3 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +config N32H7_ATIM3_LOCK + int "ATIM3 Lock Level" + default 0 + range 0 3 + ---help--- + ATIM3 BDTR lock level configuration. + +config N32H7_ATIM3_TDTS + int "ATIM3 t_DTS Division" + default 0 + range 0 2 + ---help--- + ATIM3 dead-time and sampling clock division: 0=tCK_INT, 1=2*tCK_INT, 2=4*tCK_INT. + +config N32H7_ATIM3_DEADTIME + int "ATIM3 Initial Dead-time" + default 0 + range 0 255 + ---help--- + ATIM3 initial dead-time value (0-255). + +config N32H7_ATIM3_BREAK1 + bool "ATIM3 Break1 Enable" + default n + ---help--- + Enable Break1 input for ATIM3. + +config N32H7_ATIM3_BRK1POL + int "ATIM3 Break1 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_BREAK1 + ---help--- + ATIM3 Break1 polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_BREAK2 + bool "ATIM3 Break2 Enable" + default n + ---help--- + Enable Break2 input for ATIM3 (ATIM only). + +config N32H7_ATIM3_BRK2POL + int "ATIM3 Break2 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_BREAK2 + ---help--- + ATIM3 Break2 polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_BRK2FLT + int "ATIM3 Break2 Filter" + default 0 + range 0 15 + depends on N32H7_ATIM3_BREAK2 + ---help--- + ATIM3 Break2 filter value (0-15). + +if N32H7_PWM_MULTICHAN + +config N32H7_ATIM3_CHANNEL1 + bool "ATIM3 Channel 1" + default n + +if N32H7_ATIM3_CHANNEL1 + +config N32H7_ATIM3_CH1OUT + bool "ATIM3 Channel 1 Output Enable" + default N32H7_ATIM3_CHANNEL1 + ---help--- + Enable output for ATIM3 Channel 1. If disabled, the channel will not be used. + +config N32H7_ATIM3_CH1MODE + int "ATIM3 Channel 1 Mode" + default 6 + depends on N32H7_ATIM3_CH1OUT + range 0 11 + ---help--- + ATIM3 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM3_CH1POL + int "ATIM3 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH1OUT + ---help--- + ATIM3 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_CH1IDLE + int "ATIM3 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH1OUT + ---help--- + ATIM3 Channel 1 idle state: 0=inactive, 1=active. + +config N32H7_ATIM3_CH1NOUT + bool "ATIM3 Channel 1 Complementary Output Enable" + default n + depends on N32H7_ATIM3_CH1OUT + ---help--- + Enable complementary output for ATIM3 Channel 1. + +config N32H7_ATIM3_CH1NPOL + int "ATIM3 Channel 1 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH1NOUT + ---help--- + ATIM3 Channel 1 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_CH1NIDLE + int "ATIM3 Channel 1 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH1NOUT + ---help--- + ATIM3 Channel 1 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM3_CHANNEL1 + +config N32H7_ATIM3_CHANNEL2 + bool "ATIM3 Channel 2" + default n + +if N32H7_ATIM3_CHANNEL2 + +config N32H7_ATIM3_CH2OUT + bool "ATIM3 Channel 2 Output Enable" + default N32H7_ATIM3_CHANNEL2 + ---help--- + Enable output for ATIM3 Channel 2. If disabled, the channel will not be used. + +config N32H7_ATIM3_CH2MODE + int "ATIM3 Channel 2 Mode" + default 6 + depends on N32H7_ATIM3_CH2OUT + range 0 11 + ---help--- + ATIM3 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM3_CH2POL + int "ATIM3 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH2OUT + ---help--- + ATIM3 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_CH2IDLE + int "ATIM3 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH2OUT + ---help--- + ATIM3 Channel 2 idle state: 0=inactive, 1=active. + +config N32H7_ATIM3_CH2NOUT + bool "ATIM3 Channel 2 Complementary Output Enable" + default n + depends on N32H7_ATIM3_CH2OUT + ---help--- + Enable complementary output for ATIM3 Channel 2. + +config N32H7_ATIM3_CH2NPOL + int "ATIM3 Channel 2 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH2NOUT + ---help--- + ATIM3 Channel 2 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_CH2NIDLE + int "ATIM3 Channel 2 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH2NOUT + ---help--- + ATIM3 Channel 2 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM3_CHANNEL2 + +config N32H7_ATIM3_CHANNEL3 + bool "ATIM3 Channel 3" + default n + +if N32H7_ATIM3_CHANNEL3 + +config N32H7_ATIM3_CH3OUT + bool "ATIM3 Channel 3 Output Enable" + default N32H7_ATIM3_CHANNEL3 + ---help--- + Enable output for ATIM3 Channel 3. If disabled, the channel will not be used. + +config N32H7_ATIM3_CH3MODE + int "ATIM3 Channel 3 Mode" + default 6 + depends on N32H7_ATIM3_CH3OUT + range 0 11 + ---help--- + ATIM3 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM3_CH3POL + int "ATIM3 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH3OUT + ---help--- + ATIM3 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_CH3IDLE + int "ATIM3 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH3OUT + ---help--- + ATIM3 Channel 3 idle state: 0=inactive, 1=active. + +config N32H7_ATIM3_CH3NOUT + bool "ATIM3 Channel 3 Complementary Output Enable" + default n + depends on N32H7_ATIM3_CH3OUT + ---help--- + Enable complementary output for ATIM3 Channel 3. + +config N32H7_ATIM3_CH3NPOL + int "ATIM3 Channel 3 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH3NOUT + ---help--- + ATIM3 Channel 3 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_CH3NIDLE + int "ATIM3 Channel 3 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH3NOUT + ---help--- + ATIM3 Channel 3 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM3_CHANNEL3 + +config N32H7_ATIM3_CHANNEL4 + bool "ATIM3 Channel 4" + default n + +if N32H7_ATIM3_CHANNEL4 + +config N32H7_ATIM3_CH4OUT + bool "ATIM3 Channel 4 Output Enable" + default N32H7_ATIM3_CHANNEL4 + ---help--- + Enable output for ATIM3 Channel 4. If disabled, the channel will not be used. + +config N32H7_ATIM3_CH4MODE + int "ATIM3 Channel 4 Mode" + default 6 + depends on N32H7_ATIM3_CH4OUT + range 0 11 + ---help--- + ATIM3 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM3_CH4POL + int "ATIM3 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH4OUT + ---help--- + ATIM3 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_CH4IDLE + int "ATIM3 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH4OUT + ---help--- + ATIM3 Channel 4 idle state: 0=inactive, 1=active. + +config N32H7_ATIM3_CH4NOUT + bool "ATIM3 Channel 4 Complementary Output Enable" + default n + depends on N32H7_ATIM3_CH4OUT + ---help--- + Enable complementary output for ATIM3 Channel 4. + +config N32H7_ATIM3_CH4NPOL + int "ATIM3 Channel 4 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH4NOUT + ---help--- + ATIM3 Channel 4 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM3_CH4NIDLE + int "ATIM3 Channel 4 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH4NOUT + ---help--- + ATIM3 Channel 4 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM3_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_ATIM3_CHANNEL + int "ATIM3 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If ATIM3 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_ATIM3_CHMODE + int "ATIM3 Channel Mode" + default 6 + range 0 11 + ---help--- + ATIM3 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_ATIM3_PWM + +config N32H7_ATIM3_QE + bool "ATIM3 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve ATIM3 for use as a quadrature encoder interface. + +endif # N32H7_ATIM3 + +config N32H7_ATIM4 + bool "ATIM4" + default n + ---help--- + Enable Advanced Timer ATIM4. + +if N32H7_ATIM4 + +config N32H7_ATIM4_PWM + bool "ATIM4 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve ATIM4 for use by PWM. + +if N32H7_ATIM4_PWM + +config N32H7_ATIM4_MODE + int "ATIM4 Mode" + default 0 + range 0 4 + ---help--- + Specifies the ATIM4 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +config N32H7_ATIM4_LOCK + int "ATIM4 Lock Level" + default 0 + range 0 3 + ---help--- + ATIM4 BDTR lock level configuration. + +config N32H7_ATIM4_TDTS + int "ATIM4 t_DTS Division" + default 0 + range 0 2 + ---help--- + ATIM4 dead-time and sampling clock division: 0=tCK_INT, 1=2*tCK_INT, 2=4*tCK_INT. + +config N32H7_ATIM4_DEADTIME + int "ATIM4 Initial Dead-time" + default 0 + range 0 255 + ---help--- + ATIM4 initial dead-time value (0-255). + +config N32H7_ATIM4_BREAK1 + bool "ATIM4 Break1 Enable" + default n + ---help--- + Enable Break1 input for ATIM4. + +config N32H7_ATIM4_BRK1POL + int "ATIM4 Break1 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_BREAK1 + ---help--- + ATIM4 Break1 polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_BREAK2 + bool "ATIM4 Break2 Enable" + default n + ---help--- + Enable Break2 input for ATIM4 (ATIM only). + +config N32H7_ATIM4_BRK2POL + int "ATIM4 Break2 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_BREAK2 + ---help--- + ATIM4 Break2 polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_BRK2FLT + int "ATIM4 Break2 Filter" + default 0 + range 0 15 + depends on N32H7_ATIM4_BREAK2 + ---help--- + ATIM4 Break2 filter value (0-15). + +if N32H7_PWM_MULTICHAN + +config N32H7_ATIM4_CHANNEL1 + bool "ATIM4 Channel 1" + default n + +if N32H7_ATIM4_CHANNEL1 + +config N32H7_ATIM4_CH1OUT + bool "ATIM4 Channel 1 Output Enable" + default N32H7_ATIM4_CHANNEL1 + ---help--- + Enable output for ATIM4 Channel 1. If disabled, the channel will not be used. + +config N32H7_ATIM4_CH1MODE + int "ATIM4 Channel 1 Mode" + default 6 + depends on N32H7_ATIM4_CH1OUT + range 0 11 + ---help--- + ATIM4 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM4_CH1POL + int "ATIM4 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH1OUT + ---help--- + ATIM4 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_CH1IDLE + int "ATIM4 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH1OUT + ---help--- + ATIM4 Channel 1 idle state: 0=inactive, 1=active. + +config N32H7_ATIM4_CH1NOUT + bool "ATIM4 Channel 1 Complementary Output Enable" + default n + depends on N32H7_ATIM4_CH1OUT + ---help--- + Enable complementary output for ATIM4 Channel 1. + +config N32H7_ATIM4_CH1NPOL + int "ATIM4 Channel 1 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH1NOUT + ---help--- + ATIM4 Channel 1 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_CH1NIDLE + int "ATIM4 Channel 1 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH1NOUT + ---help--- + ATIM4 Channel 1 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM4_CHANNEL1 + +config N32H7_ATIM4_CHANNEL2 + bool "ATIM4 Channel 2" + default n + +if N32H7_ATIM4_CHANNEL2 + +config N32H7_ATIM4_CH2OUT + bool "ATIM4 Channel 2 Output Enable" + default N32H7_ATIM4_CHANNEL2 + ---help--- + Enable output for ATIM4 Channel 2. If disabled, the channel will not be used. + +config N32H7_ATIM4_CH2MODE + int "ATIM4 Channel 2 Mode" + default 6 + depends on N32H7_ATIM4_CH2OUT + range 0 11 + ---help--- + ATIM4 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM4_CH2POL + int "ATIM4 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH2OUT + ---help--- + ATIM4 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_CH2IDLE + int "ATIM4 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH2OUT + ---help--- + ATIM4 Channel 2 idle state: 0=inactive, 1=active. + +config N32H7_ATIM4_CH2NOUT + bool "ATIM4 Channel 2 Complementary Output Enable" + default n + depends on N32H7_ATIM4_CH2OUT + ---help--- + Enable complementary output for ATIM4 Channel 2. + +config N32H7_ATIM4_CH2NPOL + int "ATIM4 Channel 2 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH2NOUT + ---help--- + ATIM4 Channel 2 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_CH2NIDLE + int "ATIM4 Channel 2 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH2NOUT + ---help--- + ATIM4 Channel 2 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM4_CHANNEL2 + +config N32H7_ATIM4_CHANNEL3 + bool "ATIM4 Channel 3" + default n + +if N32H7_ATIM4_CHANNEL3 + +config N32H7_ATIM4_CH3OUT + bool "ATIM4 Channel 3 Output Enable" + default N32H7_ATIM4_CHANNEL3 + ---help--- + Enable output for ATIM4 Channel 3. If disabled, the channel will not be used. + +config N32H7_ATIM4_CH3MODE + int "ATIM4 Channel 3 Mode" + default 6 + depends on N32H7_ATIM4_CH3OUT + range 0 11 + ---help--- + ATIM4 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM4_CH3POL + int "ATIM4 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH3OUT + ---help--- + ATIM4 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_CH3IDLE + int "ATIM4 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH3OUT + ---help--- + ATIM4 Channel 3 idle state: 0=inactive, 1=active. + +config N32H7_ATIM4_CH3NOUT + bool "ATIM4 Channel 3 Complementary Output Enable" + default n + depends on N32H7_ATIM4_CH3OUT + ---help--- + Enable complementary output for ATIM4 Channel 3. + +config N32H7_ATIM4_CH3NPOL + int "ATIM4 Channel 3 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH3NOUT + ---help--- + ATIM4 Channel 3 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_CH3NIDLE + int "ATIM4 Channel 3 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH3NOUT + ---help--- + ATIM4 Channel 3 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM4_CHANNEL3 + +config N32H7_ATIM4_CHANNEL4 + bool "ATIM4 Channel 4" + default n + +if N32H7_ATIM4_CHANNEL4 + +config N32H7_ATIM4_CH4OUT + bool "ATIM4 Channel 4 Output Enable" + default N32H7_ATIM4_CHANNEL4 + ---help--- + Enable output for ATIM4 Channel 4. If disabled, the channel will not be used. + +config N32H7_ATIM4_CH4MODE + int "ATIM4 Channel 4 Mode" + default 6 + depends on N32H7_ATIM4_CH4OUT + range 0 11 + ---help--- + ATIM4 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_ATIM4_CH4POL + int "ATIM4 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH4OUT + ---help--- + ATIM4 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_CH4IDLE + int "ATIM4 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH4OUT + ---help--- + ATIM4 Channel 4 idle state: 0=inactive, 1=active. + +config N32H7_ATIM4_CH4NOUT + bool "ATIM4 Channel 4 Complementary Output Enable" + default n + depends on N32H7_ATIM4_CH4OUT + ---help--- + Enable complementary output for ATIM4 Channel 4. + +config N32H7_ATIM4_CH4NPOL + int "ATIM4 Channel 4 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH4NOUT + ---help--- + ATIM4 Channel 4 complementary polarity: 0=active high, 1=active low. + +config N32H7_ATIM4_CH4NIDLE + int "ATIM4 Channel 4 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH4NOUT + ---help--- + ATIM4 Channel 4 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_ATIM4_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_ATIM4_CHANNEL + int "ATIM4 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If ATIM4 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_ATIM4_CHMODE + int "ATIM4 Channel Mode" + default 6 + range 0 11 + ---help--- + ATIM4 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_ATIM4_PWM + +config N32H7_ATIM4_QE + bool "ATIM4 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve ATIM4 for use as a quadrature encoder interface. + +endif # N32H7_ATIM4 + +endif # N32H7_TIMER_ADVANCED + +if N32H7_TIMER_GTIMA + +config N32H7_GTIMA1 + bool "GTIMA1" + default n + ---help--- + Enable General-purpose Timer A GTIMA1. + +if N32H7_GTIMA1 + +config N32H7_GTIMA1_PWM + bool "GTIMA1 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMA1 for use by PWM. + +if N32H7_GTIMA1_PWM + +config N32H7_GTIMA1_MODE + int "GTIMA1 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMA1 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMA1_CHANNEL1 + bool "GTIMA1 Channel 1" + default n + +if N32H7_GTIMA1_CHANNEL1 + +config N32H7_GTIMA1_CH1OUT + bool "GTIMA1 Channel 1 Output Enable" + default N32H7_GTIMA1_CHANNEL1 + ---help--- + Enable output for GTIMA1 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMA1_CH1MODE + int "GTIMA1 Channel 1 Mode" + default 6 + depends on N32H7_GTIMA1_CH1OUT + range 0 9 + ---help--- + GTIMA1 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA1_CH1POL + int "GTIMA1 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH1OUT + ---help--- + GTIMA1 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA1_CH1IDLE + int "GTIMA1 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH1OUT + ---help--- + GTIMA1 Channel 1 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA1_CHANNEL1 + +config N32H7_GTIMA1_CHANNEL2 + bool "GTIMA1 Channel 2" + default n + +if N32H7_GTIMA1_CHANNEL2 + +config N32H7_GTIMA1_CH2OUT + bool "GTIMA1 Channel 2 Output Enable" + default N32H7_GTIMA1_CHANNEL2 + ---help--- + Enable output for GTIMA1 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMA1_CH2MODE + int "GTIMA1 Channel 2 Mode" + default 6 + depends on N32H7_GTIMA1_CH2OUT + range 0 9 + ---help--- + GTIMA1 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA1_CH2POL + int "GTIMA1 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH2OUT + ---help--- + GTIMA1 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA1_CH2IDLE + int "GTIMA1 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH2OUT + ---help--- + GTIMA1 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA1_CHANNEL2 + +config N32H7_GTIMA1_CHANNEL3 + bool "GTIMA1 Channel 3" + default n + +if N32H7_GTIMA1_CHANNEL3 + +config N32H7_GTIMA1_CH3OUT + bool "GTIMA1 Channel 3 Output Enable" + default N32H7_GTIMA1_CHANNEL3 + ---help--- + Enable output for GTIMA1 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMA1_CH3MODE + int "GTIMA1 Channel 3 Mode" + default 6 + depends on N32H7_GTIMA1_CH3OUT + range 0 9 + ---help--- + GTIMA1 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA1_CH3POL + int "GTIMA1 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH3OUT + ---help--- + GTIMA1 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA1_CH3IDLE + int "GTIMA1 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH3OUT + ---help--- + GTIMA1 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA1_CHANNEL3 + +config N32H7_GTIMA1_CHANNEL4 + bool "GTIMA1 Channel 4" + default n + +if N32H7_GTIMA1_CHANNEL4 + +config N32H7_GTIMA1_CH4OUT + bool "GTIMA1 Channel 4 Output Enable" + default N32H7_GTIMA1_CHANNEL4 + ---help--- + Enable output for GTIMA1 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMA1_CH4MODE + int "GTIMA1 Channel 4 Mode" + default 6 + depends on N32H7_GTIMA1_CH4OUT + range 0 9 + ---help--- + GTIMA1 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA1_CH4POL + int "GTIMA1 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH4OUT + ---help--- + GTIMA1 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA1_CH4IDLE + int "GTIMA1 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH4OUT + ---help--- + GTIMA1 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA1_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMA1_CHANNEL + int "GTIMA1 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMA1 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMA1_CHMODE + int "GTIMA1 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMA1 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMA1_PWM + +config N32H7_GTIMA1_QE + bool "GTIMA1 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMA1 for use as a quadrature encoder interface. + +endif # N32H7_GTIMA1 + +config N32H7_GTIMA2 + bool "GTIMA2" + default n + ---help--- + Enable General-purpose Timer A GTIMA2. + +if N32H7_GTIMA2 + +config N32H7_GTIMA2_PWM + bool "GTIMA2 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMA2 for use by PWM. + +if N32H7_GTIMA2_PWM + +config N32H7_GTIMA2_MODE + int "GTIMA2 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMA2 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMA2_CHANNEL1 + bool "GTIMA2 Channel 1" + default n + +if N32H7_GTIMA2_CHANNEL1 + +config N32H7_GTIMA2_CH1OUT + bool "GTIMA2 Channel 1 Output Enable" + default N32H7_GTIMA2_CHANNEL1 + ---help--- + Enable output for GTIMA2 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMA2_CH1MODE + int "GTIMA2 Channel 1 Mode" + default 6 + depends on N32H7_GTIMA2_CH1OUT + range 0 9 + ---help--- + GTIMA2 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA2_CH1POL + int "GTIMA2 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH1OUT + ---help--- + GTIMA2 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA2_CH1IDLE + int "GTIMA2 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH1OUT + ---help--- + GTIMA2 Channel 1 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA2_CHANNEL1 + +config N32H7_GTIMA2_CHANNEL2 + bool "GTIMA2 Channel 2" + default n + +if N32H7_GTIMA2_CHANNEL2 + +config N32H7_GTIMA2_CH2OUT + bool "GTIMA2 Channel 2 Output Enable" + default N32H7_GTIMA2_CHANNEL2 + ---help--- + Enable output for GTIMA2 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMA2_CH2MODE + int "GTIMA2 Channel 2 Mode" + default 6 + depends on N32H7_GTIMA2_CH2OUT + range 0 9 + ---help--- + GTIMA2 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA2_CH2POL + int "GTIMA2 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH2OUT + ---help--- + GTIMA2 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA2_CH2IDLE + int "GTIMA2 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH2OUT + ---help--- + GTIMA2 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA2_CHANNEL2 + +config N32H7_GTIMA2_CHANNEL3 + bool "GTIMA2 Channel 3" + default n + +if N32H7_GTIMA2_CHANNEL3 + +config N32H7_GTIMA2_CH3OUT + bool "GTIMA2 Channel 3 Output Enable" + default N32H7_GTIMA2_CHANNEL3 + ---help--- + Enable output for GTIMA2 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMA2_CH3MODE + int "GTIMA2 Channel 3 Mode" + default 6 + depends on N32H7_GTIMA2_CH3OUT + range 0 9 + ---help--- + GTIMA2 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA2_CH3POL + int "GTIMA2 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH3OUT + ---help--- + GTIMA2 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA2_CH3IDLE + int "GTIMA2 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH3OUT + ---help--- + GTIMA2 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA2_CHANNEL3 + +config N32H7_GTIMA2_CHANNEL4 + bool "GTIMA2 Channel 4" + default n + +if N32H7_GTIMA2_CHANNEL4 + +config N32H7_GTIMA2_CH4OUT + bool "GTIMA2 Channel 4 Output Enable" + default N32H7_GTIMA2_CHANNEL4 + ---help--- + Enable output for GTIMA2 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMA2_CH4MODE + int "GTIMA2 Channel 4 Mode" + default 6 + depends on N32H7_GTIMA2_CH4OUT + range 0 9 + ---help--- + GTIMA2 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA2_CH4POL + int "GTIMA2 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH4OUT + ---help--- + GTIMA2 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA2_CH4IDLE + int "GTIMA2 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH4OUT + ---help--- + GTIMA2 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA2_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMA2_CHANNEL + int "GTIMA2 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMA2 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMA2_CHMODE + int "GTIMA2 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMA2 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMA2_PWM + +config N32H7_GTIMA2_QE + bool "GTIMA2 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMA2 for use as a quadrature encoder interface. + +endif # N32H7_GTIMA2 + +config N32H7_GTIMA3 + bool "GTIMA3" + default n + ---help--- + Enable General-purpose Timer A GTIMA3. + +if N32H7_GTIMA3 + +config N32H7_GTIMA3_PWM + bool "GTIMA3 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMA3 for use by PWM. + +if N32H7_GTIMA3_PWM + +config N32H7_GTIMA3_MODE + int "GTIMA3 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMA3 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMA3_CHANNEL1 + bool "GTIMA3 Channel 1" + default n + +if N32H7_GTIMA3_CHANNEL1 + +config N32H7_GTIMA3_CH1OUT + bool "GTIMA3 Channel 1 Output Enable" + default N32H7_GTIMA3_CHANNEL1 + ---help--- + Enable output for GTIMA3 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMA3_CH1MODE + int "GTIMA3 Channel 1 Mode" + default 6 + depends on N32H7_GTIMA3_CH1OUT + range 0 9 + ---help--- + GTIMA3 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA3_CH1POL + int "GTIMA3 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH1OUT + ---help--- + GTIMA3 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA3_CH1IDLE + int "GTIMA3 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH1OUT + ---help--- + GTIMA3 Channel 1 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA3_CHANNEL1 + +config N32H7_GTIMA3_CHANNEL2 + bool "GTIMA3 Channel 2" + default n + +if N32H7_GTIMA3_CHANNEL2 + +config N32H7_GTIMA3_CH2OUT + bool "GTIMA3 Channel 2 Output Enable" + default N32H7_GTIMA3_CHANNEL2 + ---help--- + Enable output for GTIMA3 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMA3_CH2MODE + int "GTIMA3 Channel 2 Mode" + default 6 + depends on N32H7_GTIMA3_CH2OUT + range 0 9 + ---help--- + GTIMA3 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA3_CH2POL + int "GTIMA3 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH2OUT + ---help--- + GTIMA3 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA3_CH2IDLE + int "GTIMA3 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH2OUT + ---help--- + GTIMA3 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA3_CHANNEL2 + +config N32H7_GTIMA3_CHANNEL3 + bool "GTIMA3 Channel 3" + default n + +if N32H7_GTIMA3_CHANNEL3 + +config N32H7_GTIMA3_CH3OUT + bool "GTIMA3 Channel 3 Output Enable" + default N32H7_GTIMA3_CHANNEL3 + ---help--- + Enable output for GTIMA3 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMA3_CH3MODE + int "GTIMA3 Channel 3 Mode" + default 6 + depends on N32H7_GTIMA3_CH3OUT + range 0 9 + ---help--- + GTIMA3 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA3_CH3POL + int "GTIMA3 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH3OUT + ---help--- + GTIMA3 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA3_CH3IDLE + int "GTIMA3 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH3OUT + ---help--- + GTIMA3 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA3_CHANNEL3 + +config N32H7_GTIMA3_CHANNEL4 + bool "GTIMA3 Channel 4" + default n + +if N32H7_GTIMA3_CHANNEL4 + +config N32H7_GTIMA3_CH4OUT + bool "GTIMA3 Channel 4 Output Enable" + default N32H7_GTIMA3_CHANNEL4 + ---help--- + Enable output for GTIMA3 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMA3_CH4MODE + int "GTIMA3 Channel 4 Mode" + default 6 + depends on N32H7_GTIMA3_CH4OUT + range 0 9 + ---help--- + GTIMA3 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA3_CH4POL + int "GTIMA3 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH4OUT + ---help--- + GTIMA3 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA3_CH4IDLE + int "GTIMA3 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH4OUT + ---help--- + GTIMA3 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA3_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMA3_CHANNEL + int "GTIMA3 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMA3 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMA3_CHMODE + int "GTIMA3 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMA3 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMA3_PWM + +config N32H7_GTIMA3_QE + bool "GTIMA3 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMA3 for use as a quadrature encoder interface. + +endif # N32H7_GTIMA3 + +config N32H7_GTIMA4 + bool "GTIMA4" + default n + ---help--- + Enable General-purpose Timer A GTIMA4. + +if N32H7_GTIMA4 + +config N32H7_GTIMA4_PWM + bool "GTIMA4 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMA4 for use by PWM. + +if N32H7_GTIMA4_PWM + +config N32H7_GTIMA4_MODE + int "GTIMA4 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMA4 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMA4_CHANNEL1 + bool "GTIMA4 Channel 1" + default n + +if N32H7_GTIMA4_CHANNEL1 + +config N32H7_GTIMA4_CH1OUT + bool "GTIMA4 Channel 1 Output Enable" + default N32H7_GTIMA4_CHANNEL1 + ---help--- + Enable output for GTIMA4 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMA4_CH1MODE + int "GTIMA4 Channel 1 Mode" + default 6 + depends on N32H7_GTIMA4_CH1OUT + range 0 9 + ---help--- + GTIMA4 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA4_CH1POL + int "GTIMA4 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH1OUT + ---help--- + GTIMA4 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA4_CH1IDLE + int "GTIMA4 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH1OUT + ---help--- + GTIMA4 Channel 1 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA4_CHANNEL1 + +config N32H7_GTIMA4_CHANNEL2 + bool "GTIMA4 Channel 2" + default n + +if N32H7_GTIMA4_CHANNEL2 + +config N32H7_GTIMA4_CH2OUT + bool "GTIMA4 Channel 2 Output Enable" + default N32H7_GTIMA4_CHANNEL2 + ---help--- + Enable output for GTIMA4 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMA4_CH2MODE + int "GTIMA4 Channel 2 Mode" + default 6 + depends on N32H7_GTIMA4_CH2OUT + range 0 9 + ---help--- + GTIMA4 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA4_CH2POL + int "GTIMA4 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH2OUT + ---help--- + GTIMA4 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA4_CH2IDLE + int "GTIMA4 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH2OUT + ---help--- + GTIMA4 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA4_CHANNEL2 + +config N32H7_GTIMA4_CHANNEL3 + bool "GTIMA4 Channel 3" + default n + +if N32H7_GTIMA4_CHANNEL3 + +config N32H7_GTIMA4_CH3OUT + bool "GTIMA4 Channel 3 Output Enable" + default N32H7_GTIMA4_CHANNEL3 + ---help--- + Enable output for GTIMA4 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMA4_CH3MODE + int "GTIMA4 Channel 3 Mode" + default 6 + depends on N32H7_GTIMA4_CH3OUT + range 0 9 + ---help--- + GTIMA4 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA4_CH3POL + int "GTIMA4 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH3OUT + ---help--- + GTIMA4 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA4_CH3IDLE + int "GTIMA4 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH3OUT + ---help--- + GTIMA4 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA4_CHANNEL3 + +config N32H7_GTIMA4_CHANNEL4 + bool "GTIMA4 Channel 4" + default n + +if N32H7_GTIMA4_CHANNEL4 + +config N32H7_GTIMA4_CH4OUT + bool "GTIMA4 Channel 4 Output Enable" + default N32H7_GTIMA4_CHANNEL4 + ---help--- + Enable output for GTIMA4 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMA4_CH4MODE + int "GTIMA4 Channel 4 Mode" + default 6 + depends on N32H7_GTIMA4_CH4OUT + range 0 9 + ---help--- + GTIMA4 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA4_CH4POL + int "GTIMA4 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH4OUT + ---help--- + GTIMA4 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA4_CH4IDLE + int "GTIMA4 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH4OUT + ---help--- + GTIMA4 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA4_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMA4_CHANNEL + int "GTIMA4 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMA4 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMA4_CHMODE + int "GTIMA4 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMA4 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMA4_PWM + +config N32H7_GTIMA4_QE + bool "GTIMA4 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMA4 for use as a quadrature encoder interface. + +endif # N32H7_GTIMA4 + +config N32H7_GTIMA5 + bool "GTIMA5" + default n + ---help--- + Enable General-purpose Timer A GTIMA5. + +if N32H7_GTIMA5 + +config N32H7_GTIMA5_PWM + bool "GTIMA5 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMA5 for use by PWM. + +if N32H7_GTIMA5_PWM + +config N32H7_GTIMA5_MODE + int "GTIMA5 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMA5 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMA5_CHANNEL1 + bool "GTIMA5 Channel 1" + default n + +if N32H7_GTIMA5_CHANNEL1 + +config N32H7_GTIMA5_CH1OUT + bool "GTIMA5 Channel 1 Output Enable" + default N32H7_GTIMA5_CHANNEL1 + ---help--- + Enable output for GTIMA5 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMA5_CH1MODE + int "GTIMA5 Channel 1 Mode" + default 6 + depends on N32H7_GTIMA5_CH1OUT + range 0 9 + ---help--- + GTIMA5 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA5_CH1POL + int "GTIMA5 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH1OUT + ---help--- + GTIMA5 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA5_CH1IDLE + int "GTIMA5 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH1OUT + ---help--- + GTIMA5 Channel 1 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA5_CHANNEL1 + +config N32H7_GTIMA5_CHANNEL2 + bool "GTIMA5 Channel 2" + default n + +if N32H7_GTIMA5_CHANNEL2 + +config N32H7_GTIMA5_CH2OUT + bool "GTIMA5 Channel 2 Output Enable" + default N32H7_GTIMA5_CHANNEL2 + ---help--- + Enable output for GTIMA5 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMA5_CH2MODE + int "GTIMA5 Channel 2 Mode" + default 6 + depends on N32H7_GTIMA5_CH2OUT + range 0 9 + ---help--- + GTIMA5 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA5_CH2POL + int "GTIMA5 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH2OUT + ---help--- + GTIMA5 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA5_CH2IDLE + int "GTIMA5 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH2OUT + ---help--- + GTIMA5 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA5_CHANNEL2 + +config N32H7_GTIMA5_CHANNEL3 + bool "GTIMA5 Channel 3" + default n + +if N32H7_GTIMA5_CHANNEL3 + +config N32H7_GTIMA5_CH3OUT + bool "GTIMA5 Channel 3 Output Enable" + default N32H7_GTIMA5_CHANNEL3 + ---help--- + Enable output for GTIMA5 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMA5_CH3MODE + int "GTIMA5 Channel 3 Mode" + default 6 + depends on N32H7_GTIMA5_CH3OUT + range 0 9 + ---help--- + GTIMA5 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA5_CH3POL + int "GTIMA5 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH3OUT + ---help--- + GTIMA5 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA5_CH3IDLE + int "GTIMA5 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH3OUT + ---help--- + GTIMA5 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA5_CHANNEL3 + +config N32H7_GTIMA5_CHANNEL4 + bool "GTIMA5 Channel 4" + default n + +if N32H7_GTIMA5_CHANNEL4 + +config N32H7_GTIMA5_CH4OUT + bool "GTIMA5 Channel 4 Output Enable" + default N32H7_GTIMA5_CHANNEL4 + ---help--- + Enable output for GTIMA5 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMA5_CH4MODE + int "GTIMA5 Channel 4 Mode" + default 6 + depends on N32H7_GTIMA5_CH4OUT + range 0 9 + ---help--- + GTIMA5 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA5_CH4POL + int "GTIMA5 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH4OUT + ---help--- + GTIMA5 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA5_CH4IDLE + int "GTIMA5 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH4OUT + ---help--- + GTIMA5 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA5_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMA5_CHANNEL + int "GTIMA5 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMA5 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMA5_CHMODE + int "GTIMA5 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMA5 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMA5_PWM + +config N32H7_GTIMA5_QE + bool "GTIMA5 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMA5 for use as a quadrature encoder interface. + +endif # N32H7_GTIMA5 + +config N32H7_GTIMA6 + bool "GTIMA6" + default n + ---help--- + Enable General-purpose Timer A GTIMA6. + +if N32H7_GTIMA6 + +config N32H7_GTIMA6_PWM + bool "GTIMA6 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMA6 for use by PWM. + +if N32H7_GTIMA6_PWM + +config N32H7_GTIMA6_MODE + int "GTIMA6 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMA6 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMA6_CHANNEL1 + bool "GTIMA6 Channel 1" + default n + +if N32H7_GTIMA6_CHANNEL1 + +config N32H7_GTIMA6_CH1OUT + bool "GTIMA6 Channel 1 Output Enable" + default N32H7_GTIMA6_CHANNEL1 + ---help--- + Enable output for GTIMA6 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMA6_CH1MODE + int "GTIMA6 Channel 1 Mode" + default 6 + depends on N32H7_GTIMA6_CH1OUT + range 0 9 + ---help--- + GTIMA6 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA6_CH1POL + int "GTIMA6 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH1OUT + ---help--- + GTIMA6 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA6_CH1IDLE + int "GTIMA6 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH1OUT + ---help--- + GTIMA6 Channel 1 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA6_CHANNEL1 + +config N32H7_GTIMA6_CHANNEL2 + bool "GTIMA6 Channel 2" + default n + +if N32H7_GTIMA6_CHANNEL2 + +config N32H7_GTIMA6_CH2OUT + bool "GTIMA6 Channel 2 Output Enable" + default N32H7_GTIMA6_CHANNEL2 + ---help--- + Enable output for GTIMA6 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMA6_CH2MODE + int "GTIMA6 Channel 2 Mode" + default 6 + depends on N32H7_GTIMA6_CH2OUT + range 0 9 + ---help--- + GTIMA6 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA6_CH2POL + int "GTIMA6 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH2OUT + ---help--- + GTIMA6 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA6_CH2IDLE + int "GTIMA6 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH2OUT + ---help--- + GTIMA6 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA6_CHANNEL2 + +config N32H7_GTIMA6_CHANNEL3 + bool "GTIMA6 Channel 3" + default n + +if N32H7_GTIMA6_CHANNEL3 + +config N32H7_GTIMA6_CH3OUT + bool "GTIMA6 Channel 3 Output Enable" + default N32H7_GTIMA6_CHANNEL3 + ---help--- + Enable output for GTIMA6 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMA6_CH3MODE + int "GTIMA6 Channel 3 Mode" + default 6 + depends on N32H7_GTIMA6_CH3OUT + range 0 9 + ---help--- + GTIMA6 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA6_CH3POL + int "GTIMA6 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH3OUT + ---help--- + GTIMA6 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA6_CH3IDLE + int "GTIMA6 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH3OUT + ---help--- + GTIMA6 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA6_CHANNEL3 + +config N32H7_GTIMA6_CHANNEL4 + bool "GTIMA6 Channel 4" + default n + +if N32H7_GTIMA6_CHANNEL4 + +config N32H7_GTIMA6_CH4OUT + bool "GTIMA6 Channel 4 Output Enable" + default N32H7_GTIMA6_CHANNEL4 + ---help--- + Enable output for GTIMA6 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMA6_CH4MODE + int "GTIMA6 Channel 4 Mode" + default 6 + depends on N32H7_GTIMA6_CH4OUT + range 0 9 + ---help--- + GTIMA6 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA6_CH4POL + int "GTIMA6 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH4OUT + ---help--- + GTIMA6 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA6_CH4IDLE + int "GTIMA6 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH4OUT + ---help--- + GTIMA6 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA6_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMA6_CHANNEL + int "GTIMA6 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMA6 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMA6_CHMODE + int "GTIMA6 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMA6 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMA6_PWM + +config N32H7_GTIMA6_QE + bool "GTIMA6 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMA6 for use as a quadrature encoder interface. + +endif # N32H7_GTIMA6 + +config N32H7_GTIMA7 + bool "GTIMA7" + default n + ---help--- + Enable General-purpose Timer A GTIMA7. + +if N32H7_GTIMA7 + +config N32H7_GTIMA7_PWM + bool "GTIMA7 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMA7 for use by PWM. + +if N32H7_GTIMA7_PWM + +config N32H7_GTIMA7_MODE + int "GTIMA7 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMA7 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMA7_CHANNEL1 + bool "GTIMA7 Channel 1" + default n + +if N32H7_GTIMA7_CHANNEL1 + +config N32H7_GTIMA7_CH1OUT + bool "GTIMA7 Channel 1 Output Enable" + default N32H7_GTIMA7_CHANNEL1 + ---help--- + Enable output for GTIMA7 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMA7_CH1MODE + int "GTIMA7 Channel 1 Mode" + default 6 + depends on N32H7_GTIMA7_CH1OUT + range 0 9 + ---help--- + GTIMA7 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA7_CH1POL + int "GTIMA7 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH1OUT + ---help--- + GTIMA7 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA7_CH1IDLE + int "GTIMA7 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH1OUT + ---help--- + GTIMA7 Channel 1 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA7_CHANNEL1 + +config N32H7_GTIMA7_CHANNEL2 + bool "GTIMA7 Channel 2" + default n + +if N32H7_GTIMA7_CHANNEL2 + +config N32H7_GTIMA7_CH2OUT + bool "GTIMA7 Channel 2 Output Enable" + default N32H7_GTIMA7_CHANNEL2 + ---help--- + Enable output for GTIMA7 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMA7_CH2MODE + int "GTIMA7 Channel 2 Mode" + default 6 + depends on N32H7_GTIMA7_CH2OUT + range 0 9 + ---help--- + GTIMA7 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA7_CH2POL + int "GTIMA7 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH2OUT + ---help--- + GTIMA7 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA7_CH2IDLE + int "GTIMA7 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH2OUT + ---help--- + GTIMA7 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA7_CHANNEL2 + +config N32H7_GTIMA7_CHANNEL3 + bool "GTIMA7 Channel 3" + default n + +if N32H7_GTIMA7_CHANNEL3 + +config N32H7_GTIMA7_CH3OUT + bool "GTIMA7 Channel 3 Output Enable" + default N32H7_GTIMA7_CHANNEL3 + ---help--- + Enable output for GTIMA7 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMA7_CH3MODE + int "GTIMA7 Channel 3 Mode" + default 6 + depends on N32H7_GTIMA7_CH3OUT + range 0 9 + ---help--- + GTIMA7 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA7_CH3POL + int "GTIMA7 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH3OUT + ---help--- + GTIMA7 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA7_CH3IDLE + int "GTIMA7 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH3OUT + ---help--- + GTIMA7 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA7_CHANNEL3 + +config N32H7_GTIMA7_CHANNEL4 + bool "GTIMA7 Channel 4" + default n + +if N32H7_GTIMA7_CHANNEL4 + +config N32H7_GTIMA7_CH4OUT + bool "GTIMA7 Channel 4 Output Enable" + default N32H7_GTIMA7_CHANNEL4 + ---help--- + Enable output for GTIMA7 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMA7_CH4MODE + int "GTIMA7 Channel 4 Mode" + default 6 + depends on N32H7_GTIMA7_CH4OUT + range 0 9 + ---help--- + GTIMA7 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMA7_CH4POL + int "GTIMA7 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH4OUT + ---help--- + GTIMA7 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMA7_CH4IDLE + int "GTIMA7 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH4OUT + ---help--- + GTIMA7 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMA7_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMA7_CHANNEL + int "GTIMA7 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMA7 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMA7_CHMODE + int "GTIMA7 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMA7 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMA7_PWM + +config N32H7_GTIMA7_QE + bool "GTIMA7 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMA7 for use as a quadrature encoder interface. + +endif # N32H7_GTIMA7 + +endif # N32H7_TIMER_GTIMA + +if N32H7_TIMER_GTIMB + +config N32H7_GTIMB1 + bool "GTIMB1" + default n + ---help--- + Enable General-purpose Timer B GTIMB1. + +if N32H7_GTIMB1 + +config N32H7_GTIMB1_PWM + bool "GTIMB1 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMB1 for use by PWM. + +if N32H7_GTIMB1_PWM + +config N32H7_GTIMB1_MODE + int "GTIMB1 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMB1 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +config N32H7_GTIMB1_LOCK + int "GTIMB1 Lock Level" + default 0 + range 0 3 + ---help--- + GTIMB1 BDTR lock level configuration. + +config N32H7_GTIMB1_TDTS + int "GTIMB1 t_DTS Division" + default 0 + range 0 2 + ---help--- + GTIMB1 dead-time and sampling clock division: 0=tCK_INT, 1=2*tCK_INT, 2=4*tCK_INT. + +config N32H7_GTIMB1_DEADTIME + int "GTIMB1 Initial Dead-time" + default 0 + range 0 255 + ---help--- + GTIMB1 initial dead-time value (0-255). + +config N32H7_GTIMB1_BREAK1 + bool "GTIMB1 Break1 Enable" + default n + ---help--- + Enable Break1 input for GTIMB1. + +config N32H7_GTIMB1_BRK1POL + int "GTIMB1 Break1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_BREAK1 + ---help--- + GTIMB1 Break1 polarity: 0=active high, 1=active low. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMB1_CHANNEL1 + bool "GTIMB1 Channel 1" + default n + +if N32H7_GTIMB1_CHANNEL1 + +config N32H7_GTIMB1_CH1OUT + bool "GTIMB1 Channel 1 Output Enable" + default N32H7_GTIMB1_CHANNEL1 + ---help--- + Enable output for GTIMB1 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMB1_CH1MODE + int "GTIMB1 Channel 1 Mode" + default 6 + depends on N32H7_GTIMB1_CH1OUT + range 0 9 + ---help--- + GTIMB1 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB1_CH1POL + int "GTIMB1 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH1OUT + ---help--- + GTIMB1 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB1_CH1IDLE + int "GTIMB1 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH1OUT + ---help--- + GTIMB1 Channel 1 idle state: 0=inactive, 1=active. + +config N32H7_GTIMB1_CH1NOUT + bool "GTIMB1 Channel 1 Complementary Output Enable" + default n + depends on N32H7_GTIMB1_CH1OUT + ---help--- + Enable complementary output for GTIMB1 Channel 1. + +config N32H7_GTIMB1_CH1NPOL + int "GTIMB1 Channel 1 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH1NOUT + ---help--- + GTIMB1 Channel 1 complementary polarity: 0=active high, 1=active low. + +config N32H7_GTIMB1_CH1NIDLE + int "GTIMB1 Channel 1 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH1NOUT + ---help--- + GTIMB1 Channel 1 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB1_CHANNEL1 + +config N32H7_GTIMB1_CHANNEL2 + bool "GTIMB1 Channel 2" + default n + +if N32H7_GTIMB1_CHANNEL2 + +config N32H7_GTIMB1_CH2OUT + bool "GTIMB1 Channel 2 Output Enable" + default N32H7_GTIMB1_CHANNEL2 + ---help--- + Enable output for GTIMB1 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMB1_CH2MODE + int "GTIMB1 Channel 2 Mode" + default 6 + depends on N32H7_GTIMB1_CH2OUT + range 0 9 + ---help--- + GTIMB1 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB1_CH2POL + int "GTIMB1 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH2OUT + ---help--- + GTIMB1 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB1_CH2IDLE + int "GTIMB1 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH2OUT + ---help--- + GTIMB1 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB1_CHANNEL2 + +config N32H7_GTIMB1_CHANNEL3 + bool "GTIMB1 Channel 3" + default n + +if N32H7_GTIMB1_CHANNEL3 + +config N32H7_GTIMB1_CH3OUT + bool "GTIMB1 Channel 3 Output Enable" + default N32H7_GTIMB1_CHANNEL3 + ---help--- + Enable output for GTIMB1 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMB1_CH3MODE + int "GTIMB1 Channel 3 Mode" + default 6 + depends on N32H7_GTIMB1_CH3OUT + range 0 9 + ---help--- + GTIMB1 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB1_CH3POL + int "GTIMB1 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH3OUT + ---help--- + GTIMB1 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB1_CH3IDLE + int "GTIMB1 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH3OUT + ---help--- + GTIMB1 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB1_CHANNEL3 + +config N32H7_GTIMB1_CHANNEL4 + bool "GTIMB1 Channel 4" + default n + +if N32H7_GTIMB1_CHANNEL4 + +config N32H7_GTIMB1_CH4OUT + bool "GTIMB1 Channel 4 Output Enable" + default N32H7_GTIMB1_CHANNEL4 + ---help--- + Enable output for GTIMB1 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMB1_CH4MODE + int "GTIMB1 Channel 4 Mode" + default 6 + depends on N32H7_GTIMB1_CH4OUT + range 0 9 + ---help--- + GTIMB1 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB1_CH4POL + int "GTIMB1 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH4OUT + ---help--- + GTIMB1 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB1_CH4IDLE + int "GTIMB1 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH4OUT + ---help--- + GTIMB1 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB1_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMB1_CHANNEL + int "GTIMB1 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMB1 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMB1_CHMODE + int "GTIMB1 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMB1 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMB1_PWM + +config N32H7_GTIMB1_QE + bool "GTIMB1 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMB1 for use as a quadrature encoder interface. + +endif # N32H7_GTIMB1 + +config N32H7_GTIMB2 + bool "GTIMB2" + default n + ---help--- + Enable General-purpose Timer B GTIMB2. + +if N32H7_GTIMB2 + +config N32H7_GTIMB2_PWM + bool "GTIMB2 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMB2 for use by PWM. + +if N32H7_GTIMB2_PWM + +config N32H7_GTIMB2_MODE + int "GTIMB2 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMB2 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +config N32H7_GTIMB2_LOCK + int "GTIMB2 Lock Level" + default 0 + range 0 3 + ---help--- + GTIMB2 BDTR lock level configuration. + +config N32H7_GTIMB2_TDTS + int "GTIMB2 t_DTS Division" + default 0 + range 0 2 + ---help--- + GTIMB2 dead-time and sampling clock division: 0=tCK_INT, 1=2*tCK_INT, 2=4*tCK_INT. + +config N32H7_GTIMB2_DEADTIME + int "GTIMB2 Initial Dead-time" + default 0 + range 0 255 + ---help--- + GTIMB2 initial dead-time value (0-255). + +config N32H7_GTIMB2_BREAK1 + bool "GTIMB2 Break1 Enable" + default n + ---help--- + Enable Break1 input for GTIMB2. + +config N32H7_GTIMB2_BRK1POL + int "GTIMB2 Break1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_BREAK1 + ---help--- + GTIMB2 Break1 polarity: 0=active high, 1=active low. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMB2_CHANNEL1 + bool "GTIMB2 Channel 1" + default n + +if N32H7_GTIMB2_CHANNEL1 + +config N32H7_GTIMB2_CH1OUT + bool "GTIMB2 Channel 1 Output Enable" + default N32H7_GTIMB2_CHANNEL1 + ---help--- + Enable output for GTIMB2 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMB2_CH1MODE + int "GTIMB2 Channel 1 Mode" + default 6 + depends on N32H7_GTIMB2_CH1OUT + range 0 9 + ---help--- + GTIMB2 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB2_CH1POL + int "GTIMB2 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH1OUT + ---help--- + GTIMB2 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB2_CH1IDLE + int "GTIMB2 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH1OUT + ---help--- + GTIMB2 Channel 1 idle state: 0=inactive, 1=active. + +config N32H7_GTIMB2_CH1NOUT + bool "GTIMB2 Channel 1 Complementary Output Enable" + default n + depends on N32H7_GTIMB2_CH1OUT + ---help--- + Enable complementary output for GTIMB2 Channel 1. + +config N32H7_GTIMB2_CH1NPOL + int "GTIMB2 Channel 1 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH1NOUT + ---help--- + GTIMB2 Channel 1 complementary polarity: 0=active high, 1=active low. + +config N32H7_GTIMB2_CH1NIDLE + int "GTIMB2 Channel 1 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH1NOUT + ---help--- + GTIMB2 Channel 1 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB2_CHANNEL1 + +config N32H7_GTIMB2_CHANNEL2 + bool "GTIMB2 Channel 2" + default n + +if N32H7_GTIMB2_CHANNEL2 + +config N32H7_GTIMB2_CH2OUT + bool "GTIMB2 Channel 2 Output Enable" + default N32H7_GTIMB2_CHANNEL2 + ---help--- + Enable output for GTIMB2 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMB2_CH2MODE + int "GTIMB2 Channel 2 Mode" + default 6 + depends on N32H7_GTIMB2_CH2OUT + range 0 9 + ---help--- + GTIMB2 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB2_CH2POL + int "GTIMB2 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH2OUT + ---help--- + GTIMB2 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB2_CH2IDLE + int "GTIMB2 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH2OUT + ---help--- + GTIMB2 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB2_CHANNEL2 + +config N32H7_GTIMB2_CHANNEL3 + bool "GTIMB2 Channel 3" + default n + +if N32H7_GTIMB2_CHANNEL3 + +config N32H7_GTIMB2_CH3OUT + bool "GTIMB2 Channel 3 Output Enable" + default N32H7_GTIMB2_CHANNEL3 + ---help--- + Enable output for GTIMB2 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMB2_CH3MODE + int "GTIMB2 Channel 3 Mode" + default 6 + depends on N32H7_GTIMB2_CH3OUT + range 0 9 + ---help--- + GTIMB2 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB2_CH3POL + int "GTIMB2 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH3OUT + ---help--- + GTIMB2 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB2_CH3IDLE + int "GTIMB2 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH3OUT + ---help--- + GTIMB2 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB2_CHANNEL3 + +config N32H7_GTIMB2_CHANNEL4 + bool "GTIMB2 Channel 4" + default n + +if N32H7_GTIMB2_CHANNEL4 + +config N32H7_GTIMB2_CH4OUT + bool "GTIMB2 Channel 4 Output Enable" + default N32H7_GTIMB2_CHANNEL4 + ---help--- + Enable output for GTIMB2 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMB2_CH4MODE + int "GTIMB2 Channel 4 Mode" + default 6 + depends on N32H7_GTIMB2_CH4OUT + range 0 9 + ---help--- + GTIMB2 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB2_CH4POL + int "GTIMB2 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH4OUT + ---help--- + GTIMB2 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB2_CH4IDLE + int "GTIMB2 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH4OUT + ---help--- + GTIMB2 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB2_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMB2_CHANNEL + int "GTIMB2 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMB2 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMB2_CHMODE + int "GTIMB2 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMB2 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMB2_PWM + +config N32H7_GTIMB2_QE + bool "GTIMB2 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMB2 for use as a quadrature encoder interface. + +endif # N32H7_GTIMB2 + +config N32H7_GTIMB3 + bool "GTIMB3" + default n + ---help--- + Enable General-purpose Timer B GTIMB3. + +if N32H7_GTIMB3 + +config N32H7_GTIMB3_PWM + bool "GTIMB3 PWM" + default n + depends on N32H7_PWM + ---help--- + Reserve GTIMB3 for use by PWM. + +if N32H7_GTIMB3_PWM + +config N32H7_GTIMB3_MODE + int "GTIMB3 Mode" + default 0 + range 0 4 + ---help--- + Specifies the GTIMB3 timer mode: 0=up, 1=down, 2=center1, 3=center2, 4=center3. + +config N32H7_GTIMB3_LOCK + int "GTIMB3 Lock Level" + default 0 + range 0 3 + ---help--- + GTIMB3 BDTR lock level configuration. + +config N32H7_GTIMB3_TDTS + int "GTIMB3 t_DTS Division" + default 0 + range 0 2 + ---help--- + GTIMB3 dead-time and sampling clock division: 0=tCK_INT, 1=2*tCK_INT, 2=4*tCK_INT. + +config N32H7_GTIMB3_DEADTIME + int "GTIMB3 Initial Dead-time" + default 0 + range 0 255 + ---help--- + GTIMB3 initial dead-time value (0-255). + +config N32H7_GTIMB3_BREAK1 + bool "GTIMB3 Break1 Enable" + default n + ---help--- + Enable Break1 input for GTIMB3. + +config N32H7_GTIMB3_BRK1POL + int "GTIMB3 Break1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_BREAK1 + ---help--- + GTIMB3 Break1 polarity: 0=active high, 1=active low. + +if N32H7_PWM_MULTICHAN + +config N32H7_GTIMB3_CHANNEL1 + bool "GTIMB3 Channel 1" + default n + +if N32H7_GTIMB3_CHANNEL1 + +config N32H7_GTIMB3_CH1OUT + bool "GTIMB3 Channel 1 Output Enable" + default N32H7_GTIMB3_CHANNEL1 + ---help--- + Enable output for GTIMB3 Channel 1. If disabled, the channel will not be used. + +config N32H7_GTIMB3_CH1MODE + int "GTIMB3 Channel 1 Mode" + default 6 + depends on N32H7_GTIMB3_CH1OUT + range 0 9 + ---help--- + GTIMB3 Channel 1 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB3_CH1POL + int "GTIMB3 Channel 1 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH1OUT + ---help--- + GTIMB3 Channel 1 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB3_CH1IDLE + int "GTIMB3 Channel 1 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH1OUT + ---help--- + GTIMB3 Channel 1 idle state: 0=inactive, 1=active. + +config N32H7_GTIMB3_CH1NOUT + bool "GTIMB3 Channel 1 Complementary Output Enable" + default n + depends on N32H7_GTIMB3_CH1OUT + ---help--- + Enable complementary output for GTIMB3 Channel 1. + +config N32H7_GTIMB3_CH1NPOL + int "GTIMB3 Channel 1 Complementary Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH1NOUT + ---help--- + GTIMB3 Channel 1 complementary polarity: 0=active high, 1=active low. + +config N32H7_GTIMB3_CH1NIDLE + int "GTIMB3 Channel 1 Complementary Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH1NOUT + ---help--- + GTIMB3 Channel 1 complementary idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB3_CHANNEL1 + +config N32H7_GTIMB3_CHANNEL2 + bool "GTIMB3 Channel 2" + default n + +if N32H7_GTIMB3_CHANNEL2 + +config N32H7_GTIMB3_CH2OUT + bool "GTIMB3 Channel 2 Output Enable" + default N32H7_GTIMB3_CHANNEL2 + ---help--- + Enable output for GTIMB3 Channel 2. If disabled, the channel will not be used. + +config N32H7_GTIMB3_CH2MODE + int "GTIMB3 Channel 2 Mode" + default 6 + depends on N32H7_GTIMB3_CH2OUT + range 0 9 + ---help--- + GTIMB3 Channel 2 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB3_CH2POL + int "GTIMB3 Channel 2 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH2OUT + ---help--- + GTIMB3 Channel 2 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB3_CH2IDLE + int "GTIMB3 Channel 2 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH2OUT + ---help--- + GTIMB3 Channel 2 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB3_CHANNEL2 + +config N32H7_GTIMB3_CHANNEL3 + bool "GTIMB3 Channel 3" + default n + +if N32H7_GTIMB3_CHANNEL3 + +config N32H7_GTIMB3_CH3OUT + bool "GTIMB3 Channel 3 Output Enable" + default N32H7_GTIMB3_CHANNEL3 + ---help--- + Enable output for GTIMB3 Channel 3. If disabled, the channel will not be used. + +config N32H7_GTIMB3_CH3MODE + int "GTIMB3 Channel 3 Mode" + default 6 + depends on N32H7_GTIMB3_CH3OUT + range 0 9 + ---help--- + GTIMB3 Channel 3 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB3_CH3POL + int "GTIMB3 Channel 3 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH3OUT + ---help--- + GTIMB3 Channel 3 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB3_CH3IDLE + int "GTIMB3 Channel 3 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH3OUT + ---help--- + GTIMB3 Channel 3 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB3_CHANNEL3 + +config N32H7_GTIMB3_CHANNEL4 + bool "GTIMB3 Channel 4" + default n + +if N32H7_GTIMB3_CHANNEL4 + +config N32H7_GTIMB3_CH4OUT + bool "GTIMB3 Channel 4 Output Enable" + default N32H7_GTIMB3_CHANNEL4 + ---help--- + Enable output for GTIMB3 Channel 4. If disabled, the channel will not be used. + +config N32H7_GTIMB3_CH4MODE + int "GTIMB3 Channel 4 Mode" + default 6 + depends on N32H7_GTIMB3_CH4OUT + range 0 9 + ---help--- + GTIMB3 Channel 4 mode. See enum n32_pwm_chanmode_e. + +config N32H7_GTIMB3_CH4POL + int "GTIMB3 Channel 4 Polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH4OUT + ---help--- + GTIMB3 Channel 4 output polarity: 0=active high, 1=active low. + +config N32H7_GTIMB3_CH4IDLE + int "GTIMB3 Channel 4 Idle State" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH4OUT + ---help--- + GTIMB3 Channel 4 idle state: 0=inactive, 1=active. + +endif # N32H7_GTIMB3_CHANNEL4 + +endif # N32H7_PWM_MULTICHAN + +if N32H7_PWM_MULTICHAN = n + +config N32H7_GTIMB3_CHANNEL + int "GTIMB3 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If GTIMB3 is enabled for PWM, specifies the timer output channel {1..4}. + +config N32H7_GTIMB3_CHMODE + int "GTIMB3 Channel Mode" + default 6 + range 0 9 + ---help--- + GTIMB3 channel mode. See enum n32_pwm_chanmode_e. + +endif # N32H7_PWM_MULTICHAN = n + +endif # N32H7_GTIMB3_PWM + +config N32H7_GTIMB3_QE + bool "GTIMB3 Quadrature Encoder" + default n + depends on SENSORS_QENCODER + ---help--- + Reserve GTIMB3 for use as a quadrature encoder interface. + +endif # N32H7_GTIMB3 + +endif # N32H7_TIMER_GTIMB + +if N32H7_TIMER_BASIC + +config N32H7_BTIM1 + bool "BTIM1" + default n + ---help--- + Enable Basic Timer BTIM1. BTIM timers are 32-bit. + +config N32H7_BTIM2 + bool "BTIM2" + default n + ---help--- + Enable Basic Timer BTIM2. BTIM timers are 32-bit. + +config N32H7_BTIM3 + bool "BTIM3" + default n + ---help--- + Enable Basic Timer BTIM3. BTIM timers are 32-bit. + +config N32H7_BTIM4 + bool "BTIM4" + default n + ---help--- + Enable Basic Timer BTIM4. BTIM timers are 32-bit. + +endif # N32H7_TIMER_BASIC + +config N32H7_PWM + bool "PWM support" + default n + select PWM + ---help--- + Enable PWM support for N32H7 timers. + +config N32H7_PWM_LL_OPS + bool "PWM low-level operations" + default n + depends on N32H7_PWM + ---help--- + Enable low-level PWM ops for direct register access. + +config N32H7_PWM_MULTICHAN + bool "PWM Multiple Output Channels" + default n + depends on N32H7_PWM + select ARCH_HAVE_PWM_MULTICHAN + ---help--- + Specifies that the PWM driver supports multiple output + channels per timer. + +menu "N32H7 TIMx Outputs Configuration" + depends on N32H7_PWM + +config N32H7_ATIM1_CH1POL + int "ATIM1 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH1OUT + +config N32H7_ATIM1_CH1IDLE + int "ATIM1 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH1OUT + +config N32H7_ATIM1_CH1NPOL + int "ATIM1 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH1NOUT + +config N32H7_ATIM1_CH1NIDLE + int "ATIM1 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH1NOUT + +config N32H7_ATIM1_CH2POL + int "ATIM1 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH2OUT + +config N32H7_ATIM1_CH2IDLE + int "ATIM1 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH2OUT + +config N32H7_ATIM1_CH3POL + int "ATIM1 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH3OUT + +config N32H7_ATIM1_CH3IDLE + int "ATIM1 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH3OUT + +config N32H7_ATIM1_CH4POL + int "ATIM1 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH4OUT + +config N32H7_ATIM1_CH4IDLE + int "ATIM1 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM1_CH4OUT + +config N32H7_ATIM2_CH1POL + int "ATIM2 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH1OUT + +config N32H7_ATIM2_CH1IDLE + int "ATIM2 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH1OUT + +config N32H7_ATIM2_CH1NPOL + int "ATIM2 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH1NOUT + +config N32H7_ATIM2_CH1NIDLE + int "ATIM2 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH1NOUT + +config N32H7_ATIM2_CH2POL + int "ATIM2 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH2OUT + +config N32H7_ATIM2_CH2IDLE + int "ATIM2 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH2OUT + +config N32H7_ATIM2_CH3POL + int "ATIM2 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH3OUT + +config N32H7_ATIM2_CH3IDLE + int "ATIM2 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH3OUT + +config N32H7_ATIM2_CH4POL + int "ATIM2 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH4OUT + +config N32H7_ATIM2_CH4IDLE + int "ATIM2 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM2_CH4OUT + +config N32H7_ATIM3_CH1POL + int "ATIM3 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH1OUT + +config N32H7_ATIM3_CH1IDLE + int "ATIM3 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH1OUT + +config N32H7_ATIM3_CH1NPOL + int "ATIM3 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH1NOUT + +config N32H7_ATIM3_CH1NIDLE + int "ATIM3 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH1NOUT + +config N32H7_ATIM3_CH2POL + int "ATIM3 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH2OUT + +config N32H7_ATIM3_CH2IDLE + int "ATIM3 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH2OUT + +config N32H7_ATIM3_CH3POL + int "ATIM3 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH3OUT + +config N32H7_ATIM3_CH3IDLE + int "ATIM3 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH3OUT + +config N32H7_ATIM3_CH4POL + int "ATIM3 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH4OUT + +config N32H7_ATIM3_CH4IDLE + int "ATIM3 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM3_CH4OUT + +config N32H7_ATIM4_CH1POL + int "ATIM4 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH1OUT + +config N32H7_ATIM4_CH1IDLE + int "ATIM4 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH1OUT + +config N32H7_ATIM4_CH1NPOL + int "ATIM4 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH1NOUT + +config N32H7_ATIM4_CH1NIDLE + int "ATIM4 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH1NOUT + +config N32H7_ATIM4_CH2POL + int "ATIM4 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH2OUT + +config N32H7_ATIM4_CH2IDLE + int "ATIM4 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH2OUT + +config N32H7_ATIM4_CH3POL + int "ATIM4 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH3OUT + +config N32H7_ATIM4_CH3IDLE + int "ATIM4 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH3OUT + +config N32H7_ATIM4_CH4POL + int "ATIM4 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH4OUT + +config N32H7_ATIM4_CH4IDLE + int "ATIM4 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_ATIM4_CH4OUT + +config N32H7_GTIMA1_CH1POL + int "GTIMA1 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH1OUT + +config N32H7_GTIMA1_CH1IDLE + int "GTIMA1 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH1OUT + +config N32H7_GTIMA1_CH2POL + int "GTIMA1 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH2OUT + +config N32H7_GTIMA1_CH2IDLE + int "GTIMA1 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH2OUT + +config N32H7_GTIMA1_CH3POL + int "GTIMA1 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH3OUT + +config N32H7_GTIMA1_CH3IDLE + int "GTIMA1 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH3OUT + +config N32H7_GTIMA1_CH4POL + int "GTIMA1 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH4OUT + +config N32H7_GTIMA1_CH4IDLE + int "GTIMA1 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA1_CH4OUT + +config N32H7_GTIMA2_CH1POL + int "GTIMA2 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH1OUT + +config N32H7_GTIMA2_CH1IDLE + int "GTIMA2 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH1OUT + +config N32H7_GTIMA2_CH2POL + int "GTIMA2 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH2OUT + +config N32H7_GTIMA2_CH2IDLE + int "GTIMA2 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH2OUT + +config N32H7_GTIMA2_CH3POL + int "GTIMA2 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH3OUT + +config N32H7_GTIMA2_CH3IDLE + int "GTIMA2 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH3OUT + +config N32H7_GTIMA2_CH4POL + int "GTIMA2 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH4OUT + +config N32H7_GTIMA2_CH4IDLE + int "GTIMA2 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA2_CH4OUT + +config N32H7_GTIMA3_CH1POL + int "GTIMA3 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH1OUT + +config N32H7_GTIMA3_CH1IDLE + int "GTIMA3 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH1OUT + +config N32H7_GTIMA3_CH2POL + int "GTIMA3 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH2OUT + +config N32H7_GTIMA3_CH2IDLE + int "GTIMA3 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH2OUT + +config N32H7_GTIMA3_CH3POL + int "GTIMA3 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH3OUT + +config N32H7_GTIMA3_CH3IDLE + int "GTIMA3 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH3OUT + +config N32H7_GTIMA3_CH4POL + int "GTIMA3 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH4OUT + +config N32H7_GTIMA3_CH4IDLE + int "GTIMA3 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA3_CH4OUT + +config N32H7_GTIMA4_CH1POL + int "GTIMA4 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH1OUT + +config N32H7_GTIMA4_CH1IDLE + int "GTIMA4 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH1OUT + +config N32H7_GTIMA4_CH2POL + int "GTIMA4 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH2OUT + +config N32H7_GTIMA4_CH2IDLE + int "GTIMA4 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH2OUT + +config N32H7_GTIMA4_CH3POL + int "GTIMA4 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH3OUT + +config N32H7_GTIMA4_CH3IDLE + int "GTIMA4 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH3OUT + +config N32H7_GTIMA4_CH4POL + int "GTIMA4 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH4OUT + +config N32H7_GTIMA4_CH4IDLE + int "GTIMA4 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA4_CH4OUT + +config N32H7_GTIMA5_CH1POL + int "GTIMA5 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH1OUT + +config N32H7_GTIMA5_CH1IDLE + int "GTIMA5 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH1OUT + +config N32H7_GTIMA5_CH2POL + int "GTIMA5 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH2OUT + +config N32H7_GTIMA5_CH2IDLE + int "GTIMA5 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH2OUT + +config N32H7_GTIMA5_CH3POL + int "GTIMA5 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH3OUT + +config N32H7_GTIMA5_CH3IDLE + int "GTIMA5 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH3OUT + +config N32H7_GTIMA5_CH4POL + int "GTIMA5 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH4OUT + +config N32H7_GTIMA5_CH4IDLE + int "GTIMA5 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA5_CH4OUT + +config N32H7_GTIMA6_CH1POL + int "GTIMA6 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH1OUT + +config N32H7_GTIMA6_CH1IDLE + int "GTIMA6 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH1OUT + +config N32H7_GTIMA6_CH2POL + int "GTIMA6 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH2OUT + +config N32H7_GTIMA6_CH2IDLE + int "GTIMA6 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH2OUT + +config N32H7_GTIMA6_CH3POL + int "GTIMA6 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH3OUT + +config N32H7_GTIMA6_CH3IDLE + int "GTIMA6 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH3OUT + +config N32H7_GTIMA6_CH4POL + int "GTIMA6 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH4OUT + +config N32H7_GTIMA6_CH4IDLE + int "GTIMA6 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA6_CH4OUT + +config N32H7_GTIMA7_CH1POL + int "GTIMA7 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH1OUT + +config N32H7_GTIMA7_CH1IDLE + int "GTIMA7 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH1OUT + +config N32H7_GTIMA7_CH2POL + int "GTIMA7 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH2OUT + +config N32H7_GTIMA7_CH2IDLE + int "GTIMA7 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH2OUT + +config N32H7_GTIMA7_CH3POL + int "GTIMA7 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH3OUT + +config N32H7_GTIMA7_CH3IDLE + int "GTIMA7 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH3OUT + +config N32H7_GTIMA7_CH4POL + int "GTIMA7 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH4OUT + +config N32H7_GTIMA7_CH4IDLE + int "GTIMA7 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMA7_CH4OUT + +config N32H7_GTIMB1_CH1POL + int "GTIMB1 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH1OUT + +config N32H7_GTIMB1_CH1IDLE + int "GTIMB1 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH1OUT + +config N32H7_GTIMB1_CH1NPOL + int "GTIMB1 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH1NOUT + +config N32H7_GTIMB1_CH1NIDLE + int "GTIMB1 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH1NOUT + +config N32H7_GTIMB1_CH2POL + int "GTIMB1 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH2OUT + +config N32H7_GTIMB1_CH2IDLE + int "GTIMB1 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH2OUT + +config N32H7_GTIMB1_CH3POL + int "GTIMB1 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH3OUT + +config N32H7_GTIMB1_CH3IDLE + int "GTIMB1 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH3OUT + +config N32H7_GTIMB1_CH4POL + int "GTIMB1 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH4OUT + +config N32H7_GTIMB1_CH4IDLE + int "GTIMB1 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB1_CH4OUT + +config N32H7_GTIMB2_CH1POL + int "GTIMB2 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH1OUT + +config N32H7_GTIMB2_CH1IDLE + int "GTIMB2 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH1OUT + +config N32H7_GTIMB2_CH1NPOL + int "GTIMB2 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH1NOUT + +config N32H7_GTIMB2_CH1NIDLE + int "GTIMB2 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH1NOUT + +config N32H7_GTIMB2_CH2POL + int "GTIMB2 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH2OUT + +config N32H7_GTIMB2_CH2IDLE + int "GTIMB2 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH2OUT + +config N32H7_GTIMB2_CH3POL + int "GTIMB2 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH3OUT + +config N32H7_GTIMB2_CH3IDLE + int "GTIMB2 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH3OUT + +config N32H7_GTIMB2_CH4POL + int "GTIMB2 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH4OUT + +config N32H7_GTIMB2_CH4IDLE + int "GTIMB2 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB2_CH4OUT + +config N32H7_GTIMB3_CH1POL + int "GTIMB3 Channel 1 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH1OUT + +config N32H7_GTIMB3_CH1IDLE + int "GTIMB3 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH1OUT + +config N32H7_GTIMB3_CH1NPOL + int "GTIMB3 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH1NOUT + +config N32H7_GTIMB3_CH1NIDLE + int "GTIMB3 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH1NOUT + +config N32H7_GTIMB3_CH2POL + int "GTIMB3 Channel 2 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH2OUT + +config N32H7_GTIMB3_CH2IDLE + int "GTIMB3 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH2OUT + +config N32H7_GTIMB3_CH3POL + int "GTIMB3 Channel 3 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH3OUT + +config N32H7_GTIMB3_CH3IDLE + int "GTIMB3 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH3OUT + +config N32H7_GTIMB3_CH4POL + int "GTIMB3 Channel 4 Output polarity" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH4OUT + +config N32H7_GTIMB3_CH4IDLE + int "GTIMB3 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on N32H7_GTIMB3_CH4OUT + +endmenu # N32H7 TIMx Outputs Configuration + +endmenu # Timer Configuration + +menuconfig N32H7_CAPTURE + bool "Timer Input Capture support" + select CAPTURE + default n + ---help--- + Enable input capture support for N32H7 timers. + +if N32H7_CAPTURE + +config N32H7_ATIM1_CAP + bool "ATIM1 Capture" + default n + ---help--- + Enable input capture on ATIM1. + +if N32H7_ATIM1_CAP +config N32H7_ATIM1_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_ATIM1_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_ATIM1_CAP + +config N32H7_ATIM2_CAP + bool "ATIM2 Capture" + default n + ---help--- + Enable input capture on ATIM2. + +if N32H7_ATIM2_CAP +config N32H7_ATIM2_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_ATIM2_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_ATIM2_CAP + +config N32H7_ATIM3_CAP + bool "ATIM3 Capture" + default n + ---help--- + Enable input capture on ATIM3. + +if N32H7_ATIM3_CAP +config N32H7_ATIM3_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_ATIM3_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_ATIM3_CAP + +config N32H7_ATIM4_CAP + bool "ATIM4 Capture" + default n + ---help--- + Enable input capture on ATIM4. + +if N32H7_ATIM4_CAP +config N32H7_ATIM4_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_ATIM4_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_ATIM4_CAP + +config N32H7_GTIMA1_CAP + bool "GTIMA1 Capture" + default n + ---help--- + Enable input capture on GTIMA1. + +if N32H7_GTIMA1_CAP +config N32H7_GTIMA1_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMA1_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMA1_CAP + +config N32H7_GTIMA2_CAP + bool "GTIMA2 Capture" + default n + ---help--- + Enable input capture on GTIMA2. + +if N32H7_GTIMA2_CAP +config N32H7_GTIMA2_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMA2_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMA2_CAP + +config N32H7_GTIMA3_CAP + bool "GTIMA3 Capture" + default n + ---help--- + Enable input capture on GTIMA3. + +if N32H7_GTIMA3_CAP +config N32H7_GTIMA3_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMA3_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMA3_CAP + +config N32H7_GTIMA4_CAP + bool "GTIMA4 Capture" + default n + ---help--- + Enable input capture on GTIMA4. + +if N32H7_GTIMA4_CAP +config N32H7_GTIMA4_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMA4_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMA4_CAP + +config N32H7_GTIMA5_CAP + bool "GTIMA5 Capture" + default n + ---help--- + Enable input capture on GTIMA5. + +if N32H7_GTIMA5_CAP +config N32H7_GTIMA5_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMA5_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMA5_CAP + +config N32H7_GTIMA6_CAP + bool "GTIMA6 Capture" + default n + ---help--- + Enable input capture on GTIMA6. + +if N32H7_GTIMA6_CAP +config N32H7_GTIMA6_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMA6_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMA6_CAP + +config N32H7_GTIMA7_CAP + bool "GTIMA7 Capture" + default n + ---help--- + Enable input capture on GTIMA7. + +if N32H7_GTIMA7_CAP +config N32H7_GTIMA7_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMA7_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMA7_CAP + +config N32H7_GTIMB1_CAP + bool "GTIMB1 Capture" + default n + ---help--- + Enable input capture on GTIMB1. + +if N32H7_GTIMB1_CAP +config N32H7_GTIMB1_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMB1_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMB1_CAP + +config N32H7_GTIMB2_CAP + bool "GTIMB2 Capture" + default n + ---help--- + Enable input capture on GTIMB2. + +if N32H7_GTIMB2_CAP +config N32H7_GTIMB2_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMB2_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMB2_CAP + +config N32H7_GTIMB3_CAP + bool "GTIMB3 Capture" + default n + ---help--- + Enable input capture on GTIMB3. + +if N32H7_GTIMB3_CAP +config N32H7_GTIMB3_CHANNEL + int "Capture channel (1 or 2)" + default 1 + range 1 2 + ---help--- + Select the input capture channel (only 1 or 2 are supported for PWM input). + +config N32H7_GTIMB3_CLOCK + int "Timer counting frequency (Hz)" + default 1000000 + ---help--- + Actual clock frequency after prescaler. This affects resolution and range. + Higher frequency gives better resolution but shorter maximum period. + +endif # N32H7_GTIMB3_CAP +endif # N32H7_CAPTURE + +endif # ARCH_CHIP_N32H7 diff --git a/arch/arm/src/n32h7/Make.defs b/arch/arm/src/n32h7/Make.defs new file mode 100644 index 0000000000000..16a213bff157a --- /dev/null +++ b/arch/arm/src/n32h7/Make.defs @@ -0,0 +1,191 @@ +############################################################################ +# arch/arm/src/n32h7/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +# Common ARM and Cortex-M7 files + +include armv7-m/Make.defs + +CHIP_CSRCS = n32_allocateheap.c n32_exti_gpio.c n32_gpio.c n32_irq.c \ + n32_rcc.c n32_lowputc.c n32_serial.c n32_cordic.c n32_uid.c \ + n32_systemreset.c n32_start.c + +ifeq ($(CONFIG_N32H7_PROGMEM),y) +CHIP_CSRCS += n32_flash.c +endif + +ifeq ($(CONFIG_ARCH_N32H7_DUALCORE),y) +CHIP_CSRCS += n32_dualcore.c +endif + +ifeq ($(CONFIG_N32H7_HSEM),y) +CHIP_CSRCS += n32_hsem.c +endif + +ifeq ($(CONFIG_RPTUN),y) +CHIP_CSRCS += n32_rptun.c +endif + +ifeq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += n32_tickless.c +else +CHIP_CSRCS += n32_timerisr.c +endif + +ifeq ($(CONFIG_N32H7_ONESHOT),y) +CHIP_CSRCS += n32_oneshot.c +endif + +ifeq ($(CONFIG_ONESHOT),y) +CHIP_CSRCS += n32_oneshot_lowerhalf.c +endif + +ifeq ($(CONFIG_ARM_MPU),y) +CHIP_CSRCS += n32_mpuinit.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += n32_userspace.c +endif + +ifeq ($(CONFIG_N32H7_ADC),y) +CHIP_CSRCS += n32_adc.c +endif + +ifeq ($(CONFIG_N32H7_FDCAN),y) +CHIP_CSRCS += n32_fdcan_sock.c +endif + +ifeq ($(CONFIG_N32H7_BBSRAM),y) +CHIP_CSRCS += n32_bbsram.c +endif + +ifeq ($(CONFIG_N32H7_DMA),y) +CHIP_CSRCS += n32_dma.c +endif + +ifeq ($(CONFIG_N32H7_FMC),y) +CHIP_CSRCS += n32_fmc.c +endif + +ifeq ($(CONFIG_N32H7_IWDG)$(CONFIG_N32H7_RTC_LSICLOCK),yy) +CHIP_CSRCS += n32_lsi.c +endif + +ifeq ($(CONFIG_N32H7_RTC_LSECLOCK),y) +CHIP_CSRCS += n32_lse.c +endif + +ifeq ($(CONFIG_N32H7_I2C),y) +CHIP_CSRCS += n32_i2c.c +endif + +ifeq ($(CONFIG_N32H7_PWR),y) +CHIP_CSRCS += n32_pwr.c +endif + +ifeq ($(CONFIG_ARCH_IDLE_CUSTOM),y) +CHIP_CSRCS += n32_idle.c +endif + +ifeq ($(CONFIG_N32H7_QUADSPI),y) +CHIP_CSRCS += n32_qspi.c +endif + +ifeq ($(CONFIG_N32H7_RTC),y) +CHIP_CSRCS += n32_rtc.c +ifeq ($(CONFIG_RTC_ALARM),y) +CHIP_CSRCS += n32_exti_alarm.c +endif +ifeq ($(CONFIG_RTC_PERIODIC),y) +CHIP_CSRCS += n32_exti_wakeup.c +endif +ifeq ($(CONFIG_RTC_DRIVER),y) +CHIP_CSRCS += n32_rtc_lowerhalf.c +endif +endif + +ifeq ($(CONFIG_N32H7_SPI),y) +CHIP_CSRCS += n32_spi.c +endif + +ifeq ($(CONFIG_SPI_SLAVE),y) +CHIP_CSRCS += n32_spi_slave.c +endif + +ifeq ($(CONFIG_N32H7_SDMMC),y) +CHIP_CSRCS += n32_sdmmc.c +endif + +ifeq ($(CONFIG_TIMER),y) +CHIP_CSRCS += n32_tim_lowerhalf.c +endif + +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += n32_usbhsdev.c +endif + +ifeq ($(CONFIG_USBHOST),y) +CHIP_CSRCS += n32_usbhshost.c +endif + +ifeq ($(CONFIG_N32H7_TIM),y) +CHIP_CSRCS += n32_tim.c +endif + +ifeq ($(CONFIG_N32H7_LPTIM),y) +CHIP_CSRCS += n32_lptim.c +endif + +ifeq ($(CONFIG_N32H7_CAPTURE),y) +CHIP_CSRCS += n32_capture.c +endif + +ifeq ($(CONFIG_CAPTURE),y) +CHIP_CSRCS += n32_capture_lowerhalf.c +endif + +ifeq ($(CONFIG_N32H7_PWM),y) +CHIP_CSRCS += n32_pwm.c +endif + +ifeq ($(CONFIG_N32H7_ETHMAC),y) +CHIP_CSRCS += n32_ethernet.c +endif + +ifeq ($(CONFIG_SENSORS_QENCODER),y) +CHIP_CSRCS += n32_qencoder.c +endif + +ifeq ($(CONFIG_PM),y) +CHIP_CSRCS += n32_pmsleep.c n32_pmstandby.c n32_pmstop.c +ifneq ($(CONFIG_ARCH_CUSTOM_PMINIT),y) +CHIP_CSRCS += n32_pminitialize.c +endif +endif + +ifeq ($(CONFIG_N32H7_IWDG),y) +CHIP_CSRCS += n32_iwdg.c +endif + +ifeq ($(CONFIG_N32H7_WWDG),y) +CHIP_CSRCS += n32_wwdg.c +endif diff --git a/arch/arm/src/n32h7/chip.h b/arch/arm/src/n32h7/chip.h new file mode 100644 index 0000000000000..ad227e1931dd7 --- /dev/null +++ b/arch/arm/src/n32h7/chip.h @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/arm/src/n32h7/chip.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_CHIP_H +#define __ARCH_ARM_SRC_N32H7_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/n32h7_pinmap.h" +#include "hardware/n32h7_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If the common ARMv7-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/n32h7/chip.h header file. + */ + +#define ARMV7M_PERIPHERAL_INTERRUPTS N32H7_IRQ_NEXTINTS + +/* Cache line sizes (in bytes)for the N32H7 */ + +#define ARMV7M_DCACHE_LINESIZE 32 /* 32 bytes (8 words) */ +#define ARMV7M_ICACHE_LINESIZE 32 /* 32 bytes (8 words) */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_ARM_SRC_N32H7_CHIP_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h76x_afio.h b/arch/arm/src/n32h7/hardware/n32h76x_afio.h new file mode 100644 index 0000000000000..8ac81800642e7 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h76x_afio.h @@ -0,0 +1,802 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h76x_afio.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_AFIO_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_AFIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + + #include + #include "chip.h" + #include "hardware/n32h7_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define N32_AFIO_XSPI1_NON_OFFSET(n) (0x0008 + (n) * 4) +#define N32_AFIO_EXTI_CFG_OFFSET(n) (0x0018 + (n) * 4) +#define N32_AFIO_TOL5V_CFG0_2_OFFSET(n) (0x0028 + (n) * 4) +#define N32_AFIO_TOL5V_CFG3_6_OFFSET(n) (0x003C + (n) * 4) +#define N32_AFIO_EFT_CFG_OFFSET(n) (0x0054 + (n) * 4) +#define N32_AFIO_DIGEFT_CFG_OFFSET(n) (0x006C + (n) * 4) +#define N32_AFIO_SHRT1_EXEV_CFG_OFFSET(n) (0x0084 + (n) * 4) +#define N32_AFIO_SHRT2_EXEV_CFG_OFFSET(n) (0x008C + (n) * 4) +#define N32_AFIO_SDRAM_HSMOD_CFG_OFFSET(n) (0x0098 + (n) * 4) +#define N32_AFIO_SDRAM_VREF_EN_OFFSET(n) (0x00D8 + (n) * 4) +#define N32_AFIO_SDRAMDSN_CFG_OFFSET(n) (0x00E4 + (n) * 4) +#define N32_AFIO_SDRAMDSP_CFG_OFFSET(n) (0x00F0 + (n) * 4) + +#define N32_AFIO_RMP_CFG_OFFSET 0x0000 /* Mapping Configuration Register */ +#define N32_AFIO_FILTER_CFG_OFFSET 0x0004 /* IOM Filter Control Register */ +#define N32_AFIO_XSPI1_NON0_OFFSET 0x0008 /* XSPI1 Nonce Register 0 */ +#define N32_AFIO_XSPI1_NON1_OFFSET 0x000C /* XSPI1 Nonce Register 1 */ +#define N32_AFIO_XSPI1_NON2_OFFSET 0x0010 /* XSPI1 Nonce Register 2 */ +#define N32_AFIO_ADCRMP_CFG_OFFSET 0x0014 /* ADC Remap Configure Register */ +#define N32_AFIO_EXTI_CFG0_OFFSET 0x0018 /* External Interrupt Config Reg 0 */ +#define N32_AFIO_EXTI_CFG1_OFFSET 0x001C /* External Interrupt Config Reg 1 */ +#define N32_AFIO_EXTI_CFG2_OFFSET 0x0020 /* External Interrupt Config Reg 2 */ +#define N32_AFIO_EXTI_CFG3_OFFSET 0x0024 /* External Interrupt Config Reg 3 */ +#define N32_AFIO_TOL5V_CFG0_OFFSET 0x0028 /* IO Port 5V Tolerance Config Reg 0 */ +#define N32_AFIO_TOL5V_CFG1_OFFSET 0x002C /* IO Port 5V Tolerance Config Reg 1 */ +#define N32_AFIO_TOL5V_CFG2_OFFSET 0x0030 /* IO Port 5V Tolerance Config Reg 2 */ +#define N32_AFIO_SHRT1_FALT_CFG_OFFSET 0x0034 /* SHRTIM1 Fat Config Register */ +#define N32_AFIO_SHRT2_FALT_CFG_OFFSET 0x0038 /* SHRTIM2 Fat Config Register */ +#define N32_AFIO_TOL5V_CFG3_OFFSET 0x003C /* IO Port 5V Tolerance Config Reg 3 */ +#define N32_AFIO_TOL5V_CFG4_OFFSET 0x0044 /* IO Port 5V Tolerance Config Reg 4 */ +#define N32_AFIO_TOL5V_CFG5_OFFSET 0x0048 /* IO Port 5V Tolerance Config Reg 5 */ +#define N32_AFIO_TOL5V_CFG6_OFFSET 0x004C /* IO Port 5V Tolerance Config Reg 6 */ +#define N32_AFIO_EFT_CFG0_OFFSET 0x0054 /* IO Port Analog Filtering Config Reg 0 */ +#define N32_AFIO_EFT_CFG1_OFFSET 0x0058 /* IO Port Analog Filtering Config Reg 1 */ +#define N32_AFIO_EFT_CFG2_OFFSET 0x005C /* IO Port Analog Filtering Config Reg 2 */ +#define N32_AFIO_EFT_CFG3_OFFSET 0x0060 /* IO Port Analog Filtering Config Reg 3 */ +#define N32_AFIO_EFT_CFG4_OFFSET 0x0064 /* IO Port Analog Filtering Config Reg 4 */ +#define N32_AFIO_EFT_CFG5_OFFSET 0x0068 /* IO Port Analog Filtering Config Reg 5 */ +#define N32_AFIO_DIGEFT_CFG0_OFFSET 0x006C /* IO Port Digital Filtering Config Reg 0 */ +#define N32_AFIO_DIGEFT_CFG1_OFFSET 0x0070 /* IO Port Digital Filtering Config Reg 1 */ +#define N32_AFIO_DIGEFT_CFG2_OFFSET 0x0074 /* IO Port Digital Filtering Config Reg 2 */ +#define N32_AFIO_DIGEFT_CFG3_OFFSET 0x0078 /* IO Port Digital Filtering Config Reg 3 */ +#define N32_AFIO_DIGEFT_CFG4_OFFSET 0x007C /* IO Port Digital Filtering Config Reg 4 */ +#define N32_AFIO_DIGEFT_CFG5_OFFSET 0x0080 /* IO Port Digital Filtering Config Reg 5 */ +#define N32_AFIO_SHRT1_EXEV_CFG0_OFFSET 0x0084 /* SHRTIM1 External Event Config Reg 0 */ +#define N32_AFIO_SHRT1_EXEV_CFG1_OFFSET 0x0088 /* SHRTIM1 External Event Config Reg 1 */ +#define N32_AFIO_SHRT2_EXEV_CFG0_OFFSET 0x008C /* SHRTIM2 External Event Config Reg 0 */ +#define N32_AFIO_SHRT2_EXEV_CFG1_OFFSET 0x0090 /* SHRTIM2 External Event Config Reg 1 */ +#define N32_AFIO_SIP_PUPD_OFFSET 0x0094 /* SIP Pl-up/Pl-down Config Register */ +#define N32_AFIO_SDRAM_HSMOD_CFG0_OFFSET 0x0098 /* SDRAM HS MODE Config Register 0 */ +#define N32_AFIO_SDRAM_HSMOD_CFG1_OFFSET 0x009C /* SDRAM HS MODE Config Register 1 */ +#define N32_AFIO_SDRAM_HSMOD_CFG2_OFFSET 0x00A0 /* SDRAM HS MODE Config Register 2 */ +#define N32_AFIO_SDRAM_HSMOD_CFG3_OFFSET 0x00A4 /* SDRAM HS MODE Config Register 3 */ +#define N32_AFIO_SDRAM_HSMOD_CFG4_OFFSET 0x00A8 /* SDRAM HS MODE Config Register 4 */ +#define N32_AFIO_SIP_SR_OFFSET 0x00B0 /* SIP SR Configuration Register */ +#define N32_AFIO_SIP_DS_OFFSET 0x00B4 /* SIP DS Configuration Register */ +#define N32_AFIO_ADCSW_CFG_OFFSET 0x00D0 /* ADC Switch Configuration Register */ +#define N32_AFIO_SDRAM_VREF_EN0_OFFSET 0x00D8 /* SDRAM VREF Enable 0 Config Register */ +#define N32_AFIO_SDRAM_VREF_EN1_OFFSET 0x00DC /* SDRAM VREF Enable 1 Config Register */ +#define N32_AFIO_SDRAM_VREF_EN2_OFFSET 0x00E0 /* SDRAM VREF Enable 2 Config Register */ +#define N32_AFIO_SDRAMDSN_CFG0_OFFSET 0x00E4 /* SDRAM DSN 0 Config Register */ +#define N32_AFIO_SDRAMDSN_CFG1_OFFSET 0x00E8 /* SDRAM DSN 1 Config Register */ +#define N32_AFIO_SDRAMDSN_CFG2_OFFSET 0x00EC /* SDRAM DSN 2 Config Register */ +#define N32_AFIO_SDRAMDSP_CFG0_OFFSET 0x00F0 /* SDRAM DSP 0 Config Register */ +#define N32_AFIO_SDRAMDSP_CFG1_OFFSET 0x00F4 /* SDRAM DSP 1 Config Register */ +#define N32_AFIO_SDRAMDSP_CFG2_OFFSET 0x00F8 /* SDRAM DSP 2 Config Register */ + +/* Register Addresses *******************************************************/ + +#define N32_AFIO_XSPI1_NON(n) (N32_AFIO_BASE + N32_AFIO_XSPI1_NON_OFFSET(n)) +#define N32_AFIO_EXTI_CFG(n) (N32_AFIO_BASE + N32_AFIO_EXTI_CFG_OFFSET(n)) +#define N32_AFIO_TOL5V_CFG0_2(n) (N32_AFIO_BASE + N32_AFIO_TOL5V_CFG0_2_OFFSET(n)) +#define N32_AFIO_TOL5V_CFG3_6(n) (N32_AFIO_BASE + N32_AFIO_TOL5V_CFG3_6_OFFSET(n)) +#define N32_AFIO_EFT_CFG(n) (N32_AFIO_BASE + N32_AFIO_EFT_CFG_OFFSET(n)) +#define N32_AFIO_DIGEFT_CFG(n) (N32_AFIO_BASE + N32_AFIO_DIGEFT_CFG_OFFSET(n)) +#define N32_AFIO_SHRT1_EXEV_CFG(n) (N32_AFIO_BASE + N32_AFIO_SHRT1_EXEV_CFG_OFFSET(n)) +#define N32_AFIO_SHRT2_EXEV_CFG(n) (N32_AFIO_BASE + N32_AFIO_SHRT2_EXEV_CFG_OFFSET(n)) +#define N32_AFIO_SDRAM_HSMOD_CFG(n) (N32_AFIO_BASE + N32_AFIO_SDRAM_HSMOD_CFG_OFFSET(n)) +#define N32_AFIO_SDRAM_VREF_EN(n) (N32_AFIO_BASE + N32_AFIO_SDRAM_VREF_EN_OFFSET(n)) +#define N32_AFIO_SDRAMDSN_CFG(n) (N32_AFIO_BASE + N32_AFIO_SDRAMDSN_CFG_OFFSET(n)) +#define N32_AFIO_SDRAMDSP_CFG(n) (N32_AFIO_BASE + N32_AFIO_SDRAMDSP_CFG_OFFSET(n)) + +#define N32_AFIO_RMP_CFG (N32_AFIO_BASE + N32_AFIO_RMP_CFG_OFFSET) +#define N32_AFIO_FILTER_CFG (N32_AFIO_BASE + N32_AFIO_FILTER_CFG_OFFSET) +#define N32_AFIO_XSPI1_NON0 (N32_AFIO_BASE + N32_AFIO_XSPI1_NON0_OFFSET) +#define N32_AFIO_XSPI1_NON1 (N32_AFIO_BASE + N32_AFIO_XSPI1_NON1_OFFSET) +#define N32_AFIO_XSPI1_NON2 (N32_AFIO_BASE + N32_AFIO_XSPI1_NON2_OFFSET) +#define N32_AFIO_ADCRMP_CFG (N32_AFIO_BASE + N32_AFIO_ADCRMP_CFG_OFFSET) +#define N32_AFIO_EXTI_CFG0 (N32_AFIO_BASE + N32_AFIO_EXTI_CFG0_OFFSET) +#define N32_AFIO_EXTI_CFG1 (N32_AFIO_BASE + N32_AFIO_EXTI_CFG1_OFFSET) +#define N32_AFIO_EXTI_CFG2 (N32_AFIO_BASE + N32_AFIO_EXTI_CFG2_OFFSET) +#define N32_AFIO_EXTI_CFG3 (N32_AFIO_BASE + N32_AFIO_EXTI_CFG3_OFFSET) +#define N32_AFIO_TOL5V_CFG0 (N32_AFIO_BASE + N32_AFIO_TOL5V_CFG0_OFFSET) +#define N32_AFIO_TOL5V_CFG1 (N32_AFIO_BASE + N32_AFIO_TOL5V_CFG1_OFFSET) +#define N32_AFIO_TOL5V_CFG2 (N32_AFIO_BASE + N32_AFIO_TOL5V_CFG2_OFFSET) +#define N32_AFIO_SHRT1_FALT_CFG (N32_AFIO_BASE + N32_AFIO_SHRT1_FALT_CFG_OFFSET) +#define N32_AFIO_SHRT2_FALT_CFG (N32_AFIO_BASE + N32_AFIO_SHRT2_FALT_CFG_OFFSET) +#define N32_AFIO_TOL5V_CFG3 (N32_AFIO_BASE + N32_AFIO_TOL5V_CFG3_OFFSET) +#define N32_AFIO_TOL5V_CFG4 (N32_AFIO_BASE + N32_AFIO_TOL5V_CFG4_OFFSET) +#define N32_AFIO_TOL5V_CFG5 (N32_AFIO_BASE + N32_AFIO_TOL5V_CFG5_OFFSET) +#define N32_AFIO_TOL5V_CFG6 (N32_AFIO_BASE + N32_AFIO_TOL5V_CFG6_OFFSET) +#define N32_AFIO_EFT_CFG0 (N32_AFIO_BASE + N32_AFIO_EFT_CFG0_OFFSET) +#define N32_AFIO_EFT_CFG1 (N32_AFIO_BASE + N32_AFIO_EFT_CFG1_OFFSET) +#define N32_AFIO_EFT_CFG2 (N32_AFIO_BASE + N32_AFIO_EFT_CFG2_OFFSET) +#define N32_AFIO_EFT_CFG3 (N32_AFIO_BASE + N32_AFIO_EFT_CFG3_OFFSET) +#define N32_AFIO_EFT_CFG4 (N32_AFIO_BASE + N32_AFIO_EFT_CFG4_OFFSET) +#define N32_AFIO_EFT_CFG5 (N32_AFIO_BASE + N32_AFIO_EFT_CFG5_OFFSET) +#define N32_AFIO_DIGEFT_CFG0 (N32_AFIO_BASE + N32_AFIO_DIGEFT_CFG0_OFFSET) +#define N32_AFIO_DIGEFT_CFG1 (N32_AFIO_BASE + N32_AFIO_DIGEFT_CFG1_OFFSET) +#define N32_AFIO_DIGEFT_CFG2 (N32_AFIO_BASE + N32_AFIO_DIGEFT_CFG2_OFFSET) +#define N32_AFIO_DIGEFT_CFG3 (N32_AFIO_BASE + N32_AFIO_DIGEFT_CFG3_OFFSET) +#define N32_AFIO_DIGEFT_CFG4 (N32_AFIO_BASE + N32_AFIO_DIGEFT_CFG4_OFFSET) +#define N32_AFIO_DIGEFT_CFG5 (N32_AFIO_BASE + N32_AFIO_DIGEFT_CFG5_OFFSET) +#define N32_AFIO_SHRT1_EXEV_CFG0 (N32_AFIO_BASE + N32_AFIO_SHRT1_EXEV_CFG0_OFFSET) +#define N32_AFIO_SHRT1_EXEV_CFG1 (N32_AFIO_BASE + N32_AFIO_SHRT1_EXEV_CFG1_OFFSET) +#define N32_AFIO_SHRT2_EXEV_CFG0 (N32_AFIO_BASE + N32_AFIO_SHRT2_EXEV_CFG0_OFFSET) +#define N32_AFIO_SHRT2_EXEV_CFG1 (N32_AFIO_BASE + N32_AFIO_SHRT2_EXEV_CFG1_OFFSET) +#define N32_AFIO_SIP_PUPD (N32_AFIO_BASE + N32_AFIO_SIP_PUPD_OFFSET) +#define N32_AFIO_SDRAM_HSMOD_CFG0 (N32_AFIO_BASE + N32_AFIO_SDRAM_HSMOD_CFG0_OFFSET) +#define N32_AFIO_SDRAM_HSMOD_CFG1 (N32_AFIO_BASE + N32_AFIO_SDRAM_HSMOD_CFG1_OFFSET) +#define N32_AFIO_SDRAM_HSMOD_CFG2 (N32_AFIO_BASE + N32_AFIO_SDRAM_HSMOD_CFG2_OFFSET) +#define N32_AFIO_SDRAM_HSMOD_CFG3 (N32_AFIO_BASE + N32_AFIO_SDRAM_HSMOD_CFG3_OFFSET) +#define N32_AFIO_SDRAM_HSMOD_CFG4 (N32_AFIO_BASE + N32_AFIO_SDRAM_HSMOD_CFG4_OFFSET) +#define N32_AFIO_SIP_SR (N32_AFIO_BASE + N32_AFIO_SIP_SR_OFFSET) +#define N32_AFIO_SIP_DS (N32_AFIO_BASE + N32_AFIO_SIP_DS_OFFSET) +#define N32_AFIO_ADCSW_CFG (N32_AFIO_BASE + N32_AFIO_ADCSW_CFG_OFFSET) +#define N32_AFIO_SDRAM_VREF_EN0 (N32_AFIO_BASE + N32_AFIO_SDRAM_VREF_EN0_OFFSET) +#define N32_AFIO_SDRAM_VREF_EN1 (N32_AFIO_BASE + N32_AFIO_SDRAM_VREF_EN1_OFFSET) +#define N32_AFIO_SDRAM_VREF_EN2 (N32_AFIO_BASE + N32_AFIO_SDRAM_VREF_EN2_OFFSET) +#define N32_AFIO_SDRAMDSN_CFG0 (N32_AFIO_BASE + N32_AFIO_SDRAMDSN_CFG0_OFFSET) +#define N32_AFIO_SDRAMDSN_CFG1 (N32_AFIO_BASE + N32_AFIO_SDRAMDSN_CFG1_OFFSET) +#define N32_AFIO_SDRAMDSN_CFG2 (N32_AFIO_BASE + N32_AFIO_SDRAMDSN_CFG2_OFFSET) +#define N32_AFIO_SDRAMDSP_CFG0 (N32_AFIO_BASE + N32_AFIO_SDRAMDSP_CFG0_OFFSET) +#define N32_AFIO_SDRAMDSP_CFG1 (N32_AFIO_BASE + N32_AFIO_SDRAMDSP_CFG1_OFFSET) +#define N32_AFIO_SDRAMDSP_CFG2 (N32_AFIO_BASE + N32_AFIO_SDRAMDSP_CFG2_OFFSET) + +/* Register Bit Definitions *************************************************/ + +/* AFIO_RMP_CFG - AFIO Mapping Configuration Register (Offset: 0x00) */ + +/* Single-bit fields */ +#define N32_AFIO_RMP_CFG_EXTL_AFLTBYPS (1 << 30) /* Bit 30: Bypass analog filter for EXTI */ +#define N32_AFIO_RMP_CFG_SIP_SDRAM_SEL (1 << 29) /* Bit 29: Set SIP SDRAM PAD priority */ +#define N32_AFIO_RMP_CFG_SPI4SEL (1 << 28) /* Bit 28: Select SPI4/I2S4 function */ +#define N32_AFIO_RMP_CFG_SPI3SEL (1 << 27) /* Bit 27: Select SPI3/I2S3 function */ +#define N32_AFIO_RMP_CFG_SPI2SEL (1 << 26) /* Bit 26: Select SPI2/I2S2 function */ +#define N32_AFIO_RMP_CFG_SPI1SEL (1 << 25) /* Bit 25: Select SPI1/I2S1 function */ +#define N32_AFIO_RMP_CFG_SDMMC1_CLKFB (1 << 24) /* Bit 24: SDMMC1 clock input selection */ +#define N32_AFIO_RMP_CFG_SDMMC2_CLKFB (1 << 23) /* Bit 23: SDMMC2 clock input selection */ +#define N32_AFIO_RMP_CFG_XSPI2_EDN (1 << 19) /* Bit 19: XSPI2 endian selection */ +#define N32_AFIO_RMP_CFG_XSPI1_EDN (1 << 18) /* Bit 18: XSPI1 endian selection */ +#define N32_AFIO_RMP_CFG_FEMCSEL (1 << 17) /* Bit 17: FEMC work mode selection */ +#define N32_AFIO_RMP_CFG_FEMC_NOBYTE (1 << 16) /* Bit 16: FEMC byte strokes support */ +#define N32_AFIO_RMP_CFG_ETH2_PHY (1 << 15) /* Bit 15: ETH2 PHY selection */ +#define N32_AFIO_RMP_CFG_SPI7_NSS (1 << 12) /* Bit 12: SPI7 NSS idle mode */ +#define N32_AFIO_RMP_CFG_SPI6_NSS (1 << 11) /* Bit 11: SPI6 NSS idle mode */ +#define N32_AFIO_RMP_CFG_SPI5_NSS (1 << 10) /* Bit 10: SPI5 NSS idle mode */ +#define N32_AFIO_RMP_CFG_SPI4_NSS (1 << 9) /* Bit 9: SPI4 NSS idle mode */ +#define N32_AFIO_RMP_CFG_SPI3_NSS (1 << 8) /* Bit 8: SPI3 NSS idle mode */ +#define N32_AFIO_RMP_CFG_SPI2_NSS (1 << 7) /* Bit 7: SPI2 NSS idle mode */ +#define N32_AFIO_RMP_CFG_SPI1_NSS (1 << 6) /* Bit 6: SPI1 NSS idle mode */ + +/* Multi-bit fields */ + +/* I2S_FDUP[1:0] (Bits 22-21) */ +#define N32_AFIO_RMP_CFG_I2S_FDUP_SHIFT (21) /* I2S full duplex mode selection shift */ +#define N32_AFIO_RMP_CFG_I2S_FDUP_MASK (0x3 << N32_AFIO_RMP_CFG_I2S_FDUP_SHIFT) +# define N32_AFIO_RMP_CFG_I2S1_FDUP (0x0 << N32_AFIO_RMP_CFG_I2S_FDUP_SHIFT) /* I2S1 full duplex */ +# define N32_AFIO_RMP_CFG_I2S2_FDUP (0x1 << N32_AFIO_RMP_CFG_I2S_FDUP_SHIFT) /* I2S2 full duplex */ +# define N32_AFIO_RMP_CFG_I2S3_FDUP (0x2 << N32_AFIO_RMP_CFG_I2S_FDUP_SHIFT) /* I2S3 full duplex */ +# define N32_AFIO_RMP_CFG_I2S4_FDUP (0x3 << N32_AFIO_RMP_CFG_I2S_FDUP_SHIFT) /* I2S4 full duplex */ + +/* ETH1_PHY[1:0] (Bits 14-13) */ +#define N32_AFIO_RMP_CFG_ETH1_PHY_SHIFT (13) /* ETH1 PHY selection shift */ +#define N32_AFIO_RMP_CFG_ETH1_PHY_MASK (0x3 << N32_AFIO_RMP_CFG_ETH1_PHY_SHIFT) +# define N32_AFIO_RMP_CFG_ETH1_GMII (0x0 << N32_AFIO_RMP_CFG_ETH1_PHY_SHIFT) /* GMII mode */ +# define N32_AFIO_RMP_CFG_ETH1_RGMII (0x1 << N32_AFIO_RMP_CFG_ETH1_PHY_SHIFT) /* RGMII mode */ +# define N32_AFIO_RMP_CFG_ETH1_RMII (0x2 << N32_AFIO_RMP_CFG_ETH1_PHY_SHIFT) /* RMII mode */ +# define N32_AFIO_RMP_CFG_ETH1_MII (0x3 << N32_AFIO_RMP_CFG_ETH1_PHY_SHIFT) /* MII mode */ + +/* SIP_FLASHSEL[2:0] (Bits 2-0) */ +#define N32_AFIO_RMP_CFG_SIP_FLASHSEL_SHIFT (0) /* SIP flash model selection shift */ +#define N32_AFIO_RMP_CFG_SIP_FLASHSEL_MASK (0x7 << N32_AFIO_RMP_CFG_SIP_FLASHSEL_SHIFT) +# define N32_AFIO_RMP_CFG_SIP_IS25WJ032F (0x0 << N32_AFIO_RMP_CFG_SIP_FLASHSEL_SHIFT) /* IS25WJ032F */ +# define N32_AFIO_RMP_CFG_SIP_IS25LP016D (0x1 << N32_AFIO_RMP_CFG_SIP_FLASHSEL_SHIFT) /* IS25LP016D/WP016D */ +# define N32_AFIO_RMP_CFG_SIP_XM25LU32CK (0x2 << N32_AFIO_RMP_CFG_SIP_FLASHSEL_SHIFT) /* XM25LU32CK */ +# define N32_AFIO_RMP_CFG_SIP_GT25Q16A (0x3 << N32_AFIO_RMP_CFG_SIP_FLASHSEL_SHIFT) /* GT25Q16A */ +# define N32_AFIO_RMP_CFG_SIP_GT25Q32A (0x4 << N32_AFIO_RMP_CFG_SIP_FLASHSEL_SHIFT) /* GT25Q32A */ +# define N32_AFIO_RMP_CFG_SIP_DISABLE (0x7 << N32_AFIO_RMP_CFG_SIP_FLASHSEL_SHIFT) /* Disable SIP */ + +/* AFIO_FILTER_CFG - AFIO IOM Filter Control Register (Offset: 0x04) */ + +/* Filter configuration field */ +#define N32_AFIO_FILTER_CFG_IDFLITCFG_SHIFT (0) /* Bits 6-0: Glitch Filter stage control shift */ +#define N32_AFIO_FILTER_CFG_IDFLITCFG_MASK (0x7F << N32_AFIO_FILTER_CFG_IDFLITCFG_SHIFT) +# define N32_AFIO_FILTER_CFG_BYPASS (0x00 << N32_AFIO_FILTER_CFG_IDFLITCFG_SHIFT) /* Filter bypass */ + +/* AFIO_XSPI1_NON0 - AFIO XSPI1 Nonce Register 0 (Offset: 0x08) */ + +/* 32-bit nonce value */ +#define N32_AFIO_XSPI1_NON0_NONCE_SHIFT (0) /* Nonce [31:0] shift */ +#define N32_AFIO_XSPI1_NON0_NONCE_MASK (0xFFFFFFFF << N32_AFIO_XSPI1_NON0_NONCE_SHIFT) + +/* AFIO_XSPI1_NON1 - AFIO XSPI1 Nonce Register 1 (Offset: 0x0C) */ + +/* 32-bit nonce value */ +#define N32_AFIO_XSPI1_NON1_NONCE_SHIFT (0) /* Nonce [63:32] shift */ +#define N32_AFIO_XSPI1_NON1_NONCE_MASK (0xFFFFFFFF << N32_AFIO_XSPI1_NON1_NONCE_SHIFT) + +/* AFIO_XSPI1_NON2 - AFIO XSPI1 Nonce Register 2 (Offset: 0x10) */ + +/* 32-bit nonce value */ +#define N32_AFIO_XSPI1_NON2_NONCE_SHIFT (0) /* Nonce [95:64] shift */ +#define N32_AFIO_XSPI1_NON2_NONCE_MASK (0xFFFFFFFF << N32_AFIO_XSPI1_NON2_NONCE_SHIFT) + +/* AFIO_ADCRMP_CFG - AFIO ADC Remap Configure Register (Offset: 0x14) */ + +/* ADC1 External Trigger Selections */ +#define N32_AFIO_ADCRMP_CFG_ADC1_INJ_EXTI_SHIFT (20) /* Bits 23-20: ADC1 injection channel external trigger */ +#define N32_AFIO_ADCRMP_CFG_ADC1_INJ_EXTI_MASK (0xF << N32_AFIO_ADCRMP_CFG_ADC1_INJ_EXTI_SHIFT) +#define N32_AFIO_ADCRMP_CFG_ADC1_REG_EXTI_SHIFT (16) /* Bits 19-16: ADC1 regular channel external trigger */ +#define N32_AFIO_ADCRMP_CFG_ADC1_REG_EXTI_MASK (0xF << N32_AFIO_ADCRMP_CFG_ADC1_REG_EXTI_SHIFT) + +/* ADC2 External Trigger Selections */ +#define N32_AFIO_ADCRMP_CFG_ADC2_INJ_EXTI_SHIFT (12) /* Bits 15-12: ADC2 injection channel external trigger */ +#define N32_AFIO_ADCRMP_CFG_ADC2_INJ_EXTI_MASK (0xF << N32_AFIO_ADCRMP_CFG_ADC2_INJ_EXTI_SHIFT) +#define N32_AFIO_ADCRMP_CFG_ADC2_REG_EXTI_SHIFT (8) /* Bits 11-8: ADC2 regular channel external trigger */ +#define N32_AFIO_ADCRMP_CFG_ADC2_REG_EXTI_MASK (0xF << N32_AFIO_ADCRMP_CFG_ADC2_REG_EXTI_SHIFT) + +/* ADC3 External Trigger Selections */ +#define N32_AFIO_ADCRMP_CFG_ADC3_INJ_EXTI_SHIFT (4) /* Bits 7-4: ADC3 injection channel external trigger */ +#define N32_AFIO_ADCRMP_CFG_ADC3_INJ_EXTI_MASK (0xF << N32_AFIO_ADCRMP_CFG_ADC3_INJ_EXTI_SHIFT) +#define N32_AFIO_ADCRMP_CFG_ADC3_REG_EXTI_SHIFT (0) /* Bits 3-0: ADC3 regular channel external trigger */ +#define N32_AFIO_ADCRMP_CFG_ADC3_REG_EXTI_MASK (0xF << N32_AFIO_ADCRMP_CFG_ADC3_REG_EXTI_SHIFT) + +/* EXTI Line Selection Values (applies to all ADC trigger fields) */ +#define N32_AFIO_ADC_EXTI_LINE0 0x0 +#define N32_AFIO_ADC_EXTI_LINE1 0x1 +#define N32_AFIO_ADC_EXTI_LINE2 0x2 +#define N32_AFIO_ADC_EXTI_LINE3 0x3 +#define N32_AFIO_ADC_EXTI_LINE4 0x4 +#define N32_AFIO_ADC_EXTI_LINE5 0x5 +#define N32_AFIO_ADC_EXTI_LINE6 0x6 +#define N32_AFIO_ADC_EXTI_LINE7 0x7 +#define N32_AFIO_ADC_EXTI_LINE8 0x8 +#define N32_AFIO_ADC_EXTI_LINE9 0x9 +#define N32_AFIO_ADC_EXTI_LINE10 0xA +#define N32_AFIO_ADC_EXTI_LINE11 0xB +#define N32_AFIO_ADC_EXTI_LINE12 0xC +#define N32_AFIO_ADC_EXTI_LINE13 0xD +#define N32_AFIO_ADC_EXTI_LINE14 0xE +#define N32_AFIO_ADC_EXTI_LINE15 0xF + +/* AFIO External Interrupt Configuration Registers */ + +/* EXTI port selection values */ +#define N32_AFIO_EXTICR_PORTA 0x00 /* 0000: PA[x] pin */ +#define N32_AFIO_EXTICR_PORTB 0x01 /* 0001: PB[x] pin */ +#define N32_AFIO_EXTICR_PORTC 0x02 /* 0010: PC[x] pin */ +#define N32_AFIO_EXTICR_PORTD 0x03 /* 0011: PD[x] pin */ +#define N32_AFIO_EXTICR_PORTE 0x04 /* 0100: PE[x] pin */ +#define N32_AFIO_EXTICR_PORTF 0x05 /* 0101: PF[x] pin */ +#define N32_AFIO_EXTICR_PORTG 0x06 /* 0110: PG[x] pin */ +#define N32_AFIO_EXTICR_PORTH 0x07 /* 0111: PH[x] pin */ +#define N32_AFIO_EXTICR_PORTI 0x08 /* 1000: PI[x] pin */ +#define N32_AFIO_EXTICR_PORTJ 0x09 /* 1001: PJ[x] pin */ +#define N32_AFIO_EXTICR_PORTK 0x0A /* 1010: PK[x] pin */ + +/* Common field definitions */ +#define N32_AFIO_EXTICR_PORT_MASK 0xFF /* 8-bit port selection mask */ +#define N32_AFIO_EXTICR_EXTI_WIDTH 8 /* Bits per EXTI line config */ +#define N32_AFIO_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 3) +#define N32_AFIO_EXTICR_EXTI_MASK(g) (N32_AFIO_EXTICR_PORT_MASK << (N32_AFIO_EXTICR_EXTI_SHIFT(g))) + +/* AFIO_EXTI_CFG0 (Offset: 0x18) */ +#define N32_AFIO_EXTI_CFG0_EXTI0_SHIFT 0 /* Bits 7-0: EXTI0 configuration */ +#define N32_AFIO_EXTI_CFG0_EXTI0_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG0_EXTI0_SHIFT) +#define N32_AFIO_EXTI_CFG0_EXTI1_SHIFT 8 /* Bits 15-8: EXTI1 configuration */ +#define N32_AFIO_EXTI_CFG0_EXTI1_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG0_EXTI1_SHIFT) +#define N32_AFIO_EXTI_CFG0_EXTI2_SHIFT 16 /* Bits 23-16: EXTI2 configuration */ +#define N32_AFIO_EXTI_CFG0_EXTI2_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG0_EXTI2_SHIFT) +#define N32_AFIO_EXTI_CFG0_EXTI3_SHIFT 24 /* Bits 31-24: EXTI3 configuration */ +#define N32_AFIO_EXTI_CFG0_EXTI3_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG0_EXTI3_SHIFT) + +/* AFIO_EXTI_CFG1 (Offset: 0x1C) */ +#define N32_AFIO_EXTI_CFG1_EXTI4_SHIFT 0 /* Bits 7-0: EXTI4 configuration */ +#define N32_AFIO_EXTI_CFG1_EXTI4_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG1_EXTI4_SHIFT) +#define N32_AFIO_EXTI_CFG1_EXTI5_SHIFT 8 /* Bits 15-8: EXTI5 configuration */ +#define N32_AFIO_EXTI_CFG1_EXTI5_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG1_EXTI5_SHIFT) +#define N32_AFIO_EXTI_CFG1_EXTI6_SHIFT 16 /* Bits 23-16: EXTI6 configuration */ +#define N32_AFIO_EXTI_CFG1_EXTI6_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG1_EXTI6_SHIFT) +#define N32_AFIO_EXTI_CFG1_EXTI7_SHIFT 24 /* Bits 31-24: EXTI7 configuration */ +#define N32_AFIO_EXTI_CFG1_EXTI7_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG1_EXTI7_SHIFT) + +/* AFIO_EXTI_CFG2 (Offset: 0x20) */ +#define N32_AFIO_EXTI_CFG2_EXTI8_SHIFT 0 /* Bits 7-0: EXTI8 configuration */ +#define N32_AFIO_EXTI_CFG2_EXTI8_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG2_EXTI8_SHIFT) +#define N32_AFIO_EXTI_CFG2_EXTI9_SHIFT 8 /* Bits 15-8: EXTI9 configuration */ +#define N32_AFIO_EXTI_CFG2_EXTI9_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG2_EXTI9_SHIFT) +#define N32_AFIO_EXTI_CFG2_EXTI10_SHIFT 16 /* Bits 23-16: EXTI10 configuration */ +#define N32_AFIO_EXTI_CFG2_EXTI10_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG2_EXTI10_SHIFT) +#define N32_AFIO_EXTI_CFG2_EXTI11_SHIFT 24 /* Bits 31-24: EXTI11 configuration */ +#define N32_AFIO_EXTI_CFG2_EXTI11_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG2_EXTI11_SHIFT) + +/* AFIO_EXTI_CFG3 (Offset: 0x24) */ +#define N32_AFIO_EXTI_CFG3_EXTI12_SHIFT 0 /* Bits 7-0: EXTI12 configuration */ +#define N32_AFIO_EXTI_CFG3_EXTI12_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG3_EXTI12_SHIFT) +#define N32_AFIO_EXTI_CFG3_EXTI13_SHIFT 8 /* Bits 15-8: EXTI13 configuration */ +#define N32_AFIO_EXTI_CFG3_EXTI13_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG3_EXTI13_SHIFT) +#define N32_AFIO_EXTI_CFG3_EXTI14_SHIFT 16 /* Bits 23-16: EXTI14 configuration */ +#define N32_AFIO_EXTI_CFG3_EXTI14_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG3_EXTI14_SHIFT) +#define N32_AFIO_EXTI_CFG3_EXTI15_SHIFT 24 /* Bits 31-24: EXTI15 configuration */ +#define N32_AFIO_EXTI_CFG3_EXTI15_MASK (N32_AFIO_EXTICR_PORT_MASK << N32_AFIO_EXTI_CFG3_EXTI15_SHIFT) + +/* AFIO_TOL5V_CFG0 (Offset: 0x28) */ +#define N32_AFIO_TOL5V_CFG0_PA7TOLENN (1 << 9) /* Bit 9: PA7 5V tolerance */ +#define N32_AFIO_TOL5V_CFG0_PA6TOLENN (1 << 8) /* Bit 8: PA6 5V tolerance */ +#define N32_AFIO_TOL5V_CFG0_PA5TOLENN (1 << 7) /* Bit 7: PA5 5V tolerance */ +#define N32_AFIO_TOL5V_CFG0_PA4TOLENN (1 << 6) /* Bit 6: PA4 5V tolerance */ +#define N32_AFIO_TOL5V_CFG0_PA3TOLENN (1 << 5) /* Bit 5: PA3 5V tolerance */ +#define N32_AFIO_TOL5V_CFG0_PA2TOLENN (1 << 4) /* Bit 4: PA2 5V tolerance */ +#define N32_AFIO_TOL5V_CFG0_PA1_CTOLENN (1 << 3) /* Bit 3: PA1_C 5V tolerance */ +#define N32_AFIO_TOL5V_CFG0_PA1TOLENN (1 << 2) /* Bit 2: PA1 5V tolerance */ +#define N32_AFIO_TOL5V_CFG0_PA0_CTOLENN (1 << 1) /* Bit 1: PA0_C 5V tolerance */ +#define N32_AFIO_TOL5V_CFG0_PA0TOLENN (1 << 0) /* Bit 0: PA0 5V tolerance */ + +/* AFIO_TOL5V_CFG1 (Offset: 0x2C) */ +#define N32_AFIO_TOL5V_CFG1_PB1TOLENN (1 << 1) /* Bit 1: PB1 5V tolerance */ +#define N32_AFIO_TOL5V_CFG1_PB0TOLENN (1 << 0) /* Bit 0: PB0 5V tolerance */ + +/* AFIO_TOL5V_CFG2 (Offset: 0x30) */ +#define N32_AFIO_TOL5V_CFG2_PC13TOLENN (1 << 10) /* Bit 10: PC13 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC8TOLENN (1 << 9) /* Bit 9: PC8 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC6TOLENN (1 << 8) /* Bit 8: PC6 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC5TOLENN (1 << 7) /* Bit 7: PC5 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC4TOLENN (1 << 6) /* Bit 6: PC4 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC3_CTOLENN (1 << 5) /* Bit 5: PC3_C 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC3TOLENN (1 << 4) /* Bit 4: PC3 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC2_CTOLENN (1 << 3) /* Bit 3: PC2_C 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC2TOLENN (1 << 2) /* Bit 2: PC2 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC1TOLENN (1 << 1) /* Bit 1: PC1 5V tolerance */ +#define N32_AFIO_TOL5V_CFG2_PC0TOLENN (1 << 0) /* Bit 0: PC0 5V tolerance */ + +/* AFIO_TOL5V_CFG3 (Offset: 0x3C) */ +#define N32_AFIO_TOL5V_CFG3_PF14TOLENN (1 << 11) /* Bit 11: PF14 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF13TOLENN (1 << 10) /* Bit 10: PF13 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF12TOLENN (1 << 9) /* Bit 9: PF12 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF11TOLENN (1 << 8) /* Bit 8: PF11 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF10TOLENN (1 << 7) /* Bit 7: PF10 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF9TOLENN (1 << 6) /* Bit 6: PF9 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF8TOLENN (1 << 5) /* Bit 5: PF8 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF7TOLENN (1 << 4) /* Bit 4: PF7 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF6TOLENN (1 << 3) /* Bit 3: PF6 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF5TOLENN (1 << 2) /* Bit 2: PF5 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF4TOLENN (1 << 1) /* Bit 1: PF4 5V tolerance */ +#define N32_AFIO_TOL5V_CFG3_PF3TOLENN (1 << 0) /* Bit 0: PF3 5V tolerance */ + +/* AFIO_TOL5V_CFG4 (Offset: 0x44) */ +#define N32_AFIO_TOL5V_CFG4_PH5TOLENN (1 << 3) /* Bit 3: PH5 5V tolerance */ +#define N32_AFIO_TOL5V_CFG4_PH4TOLENN (1 << 2) /* Bit 2: PH4 5V tolerance */ +#define N32_AFIO_TOL5V_CFG4_PH3TOLENN (1 << 1) /* Bit 1: PH3 5V tolerance */ +#define N32_AFIO_TOL5V_CFG4_PH2TOLENN (1 << 0) /* Bit 0: PH2 5V tolerance */ + +/* AFIO_TOL5V_CFG6 (Offset: 0x4C) */ +#define N32_AFIO_TOL5V_CFG6_PI7TOLENN (1 << 5) /* Bit 5: PI7 5V tolerance */ +#define N32_AFIO_TOL5V_CFG6_PI6TOLENN (1 << 4) /* Bit 4: PI6 5V tolerance */ +#define N32_AFIO_TOL5V_CFG6_PI5TOLENN (1 << 3) /* Bit 3: PI5 5V tolerance */ +#define N32_AFIO_TOL5V_CFG6_PI4TOLENN (1 << 2) /* Bit 2: PI4 5V tolerance */ +#define N32_AFIO_TOL5V_CFG6_PI3TOLENN (1 << 1) /* Bit 1: PI3 5V tolerance */ +#define N32_AFIO_TOL5V_CFG6_PI0TOLENN (1 << 0) /* Bit 0: PI0 5V tolerance */ + +/* AFIO_SHRT1_FALT_CFG (Offset: 0x34) */ + +/* Fault channel selection values */ +#define N32_AFIO_SHRT1_FAULT_PA15 0x1 +#define N32_AFIO_SHRT1_FAULT_PB3 0x2 +#define N32_AFIO_SHRT1_FAULT_PC11 0x3 +#define N32_AFIO_SHRT1_FAULT_PD4 0x4 +#define N32_AFIO_SHRT1_FAULT_PE4 0x5 +#define N32_AFIO_SHRT1_FAULT_PG9 0x6 +#define N32_AFIO_SHRT1_FAULT_PG10 0x7 +#define N32_AFIO_SHRT1_FAULT_PI6 0x8 +#define N32_AFIO_SHRT1_FAULT_PI15 0x9 +#define N32_AFIO_SHRT1_FAULT_PK2 0xA + +/* Fault channel configuration fields */ +#define N32_AFIO_SHRT1_FAULT1_SHIFT (0) /* Bits 3-0: Fault channel 1 */ +#define N32_AFIO_SHRT1_FAULT1_MASK (0xF << N32_AFIO_SHRT1_FAULT1_SHIFT) +#define N32_AFIO_SHRT1_FAULT2_SHIFT (4) /* Bits 7-4: Fault channel 2 */ +#define N32_AFIO_SHRT1_FAULT2_MASK (0xF << N32_AFIO_SHRT1_FAULT2_SHIFT) +#define N32_AFIO_SHRT1_FAULT3_SHIFT (8) /* Bits 11-8: Fault channel 3 */ +#define N32_AFIO_SHRT1_FAULT3_MASK (0xF << N32_AFIO_SHRT1_FAULT3_SHIFT) +#define N32_AFIO_SHRT1_FAULT4_SHIFT (12) /* Bits 15-12: Fault channel 4 */ +#define N32_AFIO_SHRT1_FAULT4_MASK (0xF << N32_AFIO_SHRT1_FAULT4_SHIFT) +#define N32_AFIO_SHRT1_FAULT5_SHIFT (16) /* Bits 19-16: Fault channel 5 */ +#define N32_AFIO_SHRT1_FAULT5_MASK (0xF << N32_AFIO_SHRT1_FAULT5_SHIFT) +#define N32_AFIO_SHRT1_FAULT6_SHIFT (20) /* Bits 23-20: Fault channel 6 */ +#define N32_AFIO_SHRT1_FAULT6_MASK (0xF << N32_AFIO_SHRT1_FAULT6_SHIFT) + +/* AFIO_SHRT2_FALT_CFG (Offset: 0x38) */ + +/* Fault channel selection values */ +#define N32_AFIO_SHRT2_FAULT_PC5 0x1 +#define N32_AFIO_SHRT2_FAULT_PD1 0x2 +#define N32_AFIO_SHRT2_FAULT_PD15 0x3 +#define N32_AFIO_SHRT2_FAULT_PF9 0x4 +#define N32_AFIO_SHRT2_FAULT_PF13 0x5 +#define N32_AFIO_SHRT2_FAULT_PG1 0x6 +#define N32_AFIO_SHRT2_FAULT_PI0 0x7 +#define N32_AFIO_SHRT2_FAULT_PJ9 0x8 +#define N32_AFIO_SHRT2_FAULT_PI13 0x9 +#define N32_AFIO_SHRT2_FAULT_PJ0 0xA +#define N32_AFIO_SHRT2_FAULT_PK1 0xB +#define N32_AFIO_SHRT2_FAULT_PK6 0xC + +/* Fault channel configuration fields */ +#define N32_AFIO_SHRT2_FAULT1_SHIFT (0) /* Bits 3-0: Fault channel 1 */ +#define N32_AFIO_SHRT2_FAULT1_MASK (0xF << N32_AFIO_SHRT2_FAULT1_SHIFT) +#define N32_AFIO_SHRT2_FAULT2_SHIFT (4) /* Bits 7-4: Fault channel 2 */ +#define N32_AFIO_SHRT2_FAULT2_MASK (0xF << N32_AFIO_SHRT2_FAULT2_SHIFT) +#define N32_AFIO_SHRT2_FAULT3_SHIFT (8) /* Bits 11-8: Fault channel 3 */ +#define N32_AFIO_SHRT2_FAULT3_MASK (0xF << N32_AFIO_SHRT2_FAULT3_SHIFT) +#define N32_AFIO_SHRT2_FAULT4_SHIFT (12) /* Bits 15-12: Fault channel 4 */ +#define N32_AFIO_SHRT2_FAULT4_MASK (0xF << N32_AFIO_SHRT2_FAULT4_SHIFT) +#define N32_AFIO_SHRT2_FAULT5_SHIFT (16) /* Bits 19-16: Fault channel 5 */ +#define N32_AFIO_SHRT2_FAULT5_MASK (0xF << N32_AFIO_SHRT2_FAULT5_SHIFT) +#define N32_AFIO_SHRT2_FAULT6_SHIFT (20) /* Bits 23-20: Fault channel 6 */ +#define N32_AFIO_SHRT2_FAULT6_MASK (0xF << N32_AFIO_SHRT2_FAULT6_SHIFT) + +/* Analog Filtering Configuration Registers */ + +/* AFIO_EFT_CFG0 - IO Port Analog Filtering Config 0 (Offset: 0x54) */ +#define N32_AFIO_EFT_CFG0_PA_EFTEN_MASK 0xFFFF /* PAx EFT enable (x=0-15) */ +#define N32_AFIO_EFT_CFG0_PA_EFTEN_SHIFT 0 +#define N32_AFIO_EFT_CFG0_PB_EFTEN_MASK 0xFFFF0000 /* PBx EFT enable (x=0-15) */ +#define N32_AFIO_EFT_CFG0_PB_EFTEN_SHIFT 16 + +/* AFIO_EFT_CFG1 - IO Port Analog Filtering Config 1 (Offset: 0x58) */ +#define N32_AFIO_EFT_CFG1_PC_EFTEN_MASK 0xFFFF /* PCx EFT enable (x=0-15) */ +#define N32_AFIO_EFT_CFG1_PC_EFTEN_SHIFT 0 +#define N32_AFIO_EFT_CFG1_PD_EFTEN_MASK 0xFFFF0000 /* PDx EFT enable (x=0-15) */ +#define N32_AFIO_EFT_CFG1_PD_EFTEN_SHIFT 16 + +/* AFIO_EFT_CFG2 - IO Port Analog Filtering Config 2 (Offset: 0x5C) */ + +/* Note: High word has no supported pads (reserved) */ +#define N32_AFIO_EFT_CFG2_PE_EFTEN_MASK 0xFFFF /* PEx EFT enable (x=0-15) */ +#define N32_AFIO_EFT_CFG2_PE_EFTEN_SHIFT 0 + +/* AFIO_EFT_CFG3 - IO Port Analog Filtering Config 3 (Offset: 0x60) */ +#define N32_AFIO_EFT_CFG3_PG_EFTEN_MASK 0xFFFF /* PGx EFT enable (x=0-15) */ +#define N32_AFIO_EFT_CFG3_PG_EFTEN_SHIFT 0 +#define N32_AFIO_EFT_CFG3_PH_EFTEN_MASK 0xFFFF0000 /* PHx EFT enable (x=0-15) */ +#define N32_AFIO_EFT_CFG3_PH_EFTEN_SHIFT 16 + +/* AFIO_EFT_CFG4 - IO Port Analog Filtering Config 4 (Offset: 0x64) */ +#define N32_AFIO_EFT_CFG4_PJ_EFTEN_MASK 0xFFFF /* PJx EFT enable (x=0-15) */ +#define N32_AFIO_EFT_CFG4_PJ_EFTEN_SHIFT 0 +#define N32_AFIO_EFT_CFG4_PI_EFTEN_MASK 0xFFFF0000 /* PIx EFT enable (x=0-15) */ +#define N32_AFIO_EFT_CFG4_PI_EFTEN_SHIFT 16 + +/* AFIO_EFT_CFG5 - IO Port Analog Filtering Config 5 (Offset: 0x68) */ +#define N32_AFIO_EFT_CFG5_PK_EFTEN_MASK 0xFF /* PKx EFT enable (x=0-7) */ +#define N32_AFIO_EFT_CFG5_PK_EFTEN_SHIFT 0 +#define N32_AFIO_EFT_CFG5_BOOT_EFTEN (1 << 8) /* Bit 8: BOOT pin EFT enable */ +#define N32_AFIO_EFT_CFG5_JRST_EFTBYPS (1 << 9) /* Bit 9: JTAG RST bypass */ + +/* Digital Filtering Configuration Registers */ + +/* AFIO_DIGEFT_CFG0 - IO Port Digital Filtering Config 0 (Offset: 0x6C) */ +#define N32_AFIO_DIGEFT_CFG0_PA_DIGEFTEN_MASK 0xFFFF /* PAx digital filter enable (x=0-15) */ +#define N32_AFIO_DIGEFT_CFG0_PA_DIGEFTEN_SHIFT 0 +#define N32_AFIO_DIGEFT_CFG0_PB_DIGEFTEN_MASK 0xFFFF0000 /* PBx digital filter enable (x=0-15) */ +#define N32_AFIO_DIGEFT_CFG0_PB_DIGEFTEN_SHIFT 16 + +/* AFIO_DIGEFT_CFG1 - IO Port Digital Filtering Config 1 (Offset: 0x70) */ +#define N32_AFIO_DIGEFT_CFG1_PC_DIGEFTEN_MASK 0xFFFF /* PCx digital filter enable (x=0-15) */ +#define N32_AFIO_DIGEFT_CFG1_PC_DIGEFTEN_SHIFT 0 +#define N32_AFIO_DIGEFT_CFG1_PD_DIGEFTEN_MASK 0xFFFF0000 /* PDx digital filter enable (x=0-15) */ +#define N32_AFIO_DIGEFT_CFG1_PD_DIGEFTEN_SHIFT 16 + +/* AFIO_DIGEFT_CFG2 - IO Port Digital Filtering Config 2 (Offset: 0x74) */ +#define N32_AFIO_DIGEFT_CFG2_PE_DIGEFTEN_MASK 0xFFFF /* PEx digital filter enable (x=0-15) */ +#define N32_AFIO_DIGEFT_CFG2_PE_DIGEFTEN_SHIFT 0 +#define N32_AFIO_DIGEFT_CFG2_PF_DIGEFTEN_MASK 0xFFFF0000 /* PFx digital filter enable (x=0-15) */ +#define N32_AFIO_DIGEFT_CFG2_PF_DIGEFTEN_SHIFT 16 + +/* AFIO_DIGEFT_CFG3 - IO Port Digital Filtering Config 3 (Offset: 0x78) */ +#define N32_AFIO_DIGEFT_CFG3_PG_DIGEFTEN_MASK 0xFFFF /* PGx digital filter enable (x=0-15) */ +#define N32_AFIO_DIGEFT_CFG3_PG_DIGEFTEN_SHIFT 0 +#define N32_AFIO_DIGEFT_CFG3_PH_DIGEFTEN_MASK 0xFFFF0000 /* PHx digital filter enable (x=0-15) */ +#define N32_AFIO_DIGEFT_CFG3_PH_DIGEFTEN_SHIFT 16 + +/* AFIO_DIGEFT_CFG4 - IO Port Digital Filtering Config 4 (Offset: 0x7C) */ +#define N32_AFIO_DIGEFT_CFG4_PJ_DIGEFTEN_MASK 0xFFFF /* PJx digital filter enable (x=0-15) */ +#define N32_AFIO_DIGEFT_CFG4_PJ_DIGEFTEN_SHIFT 0 +#define N32_AFIO_DIGEFT_CFG4_PI_DIGEFTEN_MASK 0x7FFF0000 /* PIx digital filter enable (x=0-6, bit16-22) */ +#define N32_AFIO_DIGEFT_CFG4_PI_DIGEFTEN_SHIFT 16 + +/* AFIO_DIGEFT_CFG5 - IO Port Digital Filtering Config 5 (Offset: 0x80) */ +#define N32_AFIO_DIGEFT_CFG5_PK_DIGEFTEN_MASK 0xFF /* PKx digital filter enable (x=0-7) */ +#define N32_AFIO_DIGEFT_CFG5_PK_DIGEFTEN_SHIFT 0 +#define N32_AFIO_DIGEFT_CFG5_RESERVED_MASK 0xFFFFFF00 /* Reserved bits (8-31) */ + +/* SHRTIM1 External Event Configuration Registers */ + +/* AFIO_SHRT1_EXEV_CFG0 - SHRTIM1 External Event Config 0 (Offset: 0x84) */ +#define N32_AFIO_SHRT1_EXEV_CFG0_EV1_MASK 0x1F /* EXEV1 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG0_EV1_SHIFT 0 +#define N32_AFIO_SHRT1_EXEV_CFG0_EV2_MASK 0x1F /* EXEV2 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG0_EV2_SHIFT 5 +#define N32_AFIO_SHRT1_EXEV_CFG0_EV3_MASK 0x1F /* EXEV3 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG0_EV3_SHIFT 10 +#define N32_AFIO_SHRT1_EXEV_CFG0_EV4_MASK 0x1F /* EXEV4 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG0_EV4_SHIFT 15 +#define N32_AFIO_SHRT1_EXEV_CFG0_EV5_MASK 0x1F /* EXEV5 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG0_EV5_SHIFT 20 +#define N32_AFIO_SHRT1_EXEV_CFG0_RESERVED_MASK 0xFE000000 /* Reserved bits (25-31) */ + +/* AFIO_SHRT1_EXEV_CFG1 - SHRTIM1 External Event Config 1 (Offset: 0x88) */ +#define N32_AFIO_SHRT1_EXEV_CFG1_EV6_MASK 0x1F /* EXEV6 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG1_EV6_SHIFT 0 +#define N32_AFIO_SHRT1_EXEV_CFG1_EV7_MASK 0x1F /* EXEV7 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG1_EV7_SHIFT 5 +#define N32_AFIO_SHRT1_EXEV_CFG1_EV8_MASK 0x1F /* EXEV8 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG1_EV8_SHIFT 10 +#define N32_AFIO_SHRT1_EXEV_CFG1_EV9_MASK 0x1F /* EXEV9 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG1_EV9_SHIFT 15 +#define N32_AFIO_SHRT1_EXEV_CFG1_EV10_MASK 0x1F /* EXEV10 event source (5-bit) */ +#define N32_AFIO_SHRT1_EXEV_CFG1_EV10_SHIFT 20 +#define N32_AFIO_SHRT1_EXEV_CFG1_RESERVED_MASK 0xFE000000 /* Reserved bits (25-31) */ + +/* SHRTIM2 External Event Configuration Registers */ + +/* AFIO_SHRT2_EXEV_CFG0 - SHRTIM2 External Event Config 0 (Offset: 0x8C) */ +#define N32_AFIO_SHRT2_EXEV_CFG0_EV1_MASK 0x1F /* EXEV1 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG0_EV1_SHIFT 0 +#define N32_AFIO_SHRT2_EXEV_CFG0_EV2_MASK 0x1F /* EXEV2 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG0_EV2_SHIFT 5 +#define N32_AFIO_SHRT2_EXEV_CFG0_EV3_MASK 0x1F /* EXEV3 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG0_EV3_SHIFT 10 +#define N32_AFIO_SHRT2_EXEV_CFG0_EV4_MASK 0x1F /* EXEV4 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG0_EV4_SHIFT 15 +#define N32_AFIO_SHRT2_EXEV_CFG0_EV5_MASK 0x1F /* EXEV5 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG0_EV5_SHIFT 20 +#define N32_AFIO_SHRT2_EXEV_CFG0_RESERVED_MASK 0xFE000000 /* Reserved bits (25-31) */ + +/* AFIO_SHRT2_EXEV_CFG1 - SHRTIM2 External Event Config 1 (Offset: 0x90) */ +#define N32_AFIO_SHRT2_EXEV_CFG1_EV6_MASK 0x1F /* EXEV6 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG1_EV6_SHIFT 0 +#define N32_AFIO_SHRT2_EXEV_CFG1_EV7_MASK 0x1F /* EXEV7 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG1_EV7_SHIFT 5 +#define N32_AFIO_SHRT2_EXEV_CFG1_EV8_MASK 0x1F /* EXEV8 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG1_EV8_SHIFT 10 +#define N32_AFIO_SHRT2_EXEV_CFG1_EV9_MASK 0x1F /* EXEV9 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG1_EV9_SHIFT 15 +#define N32_AFIO_SHRT2_EXEV_CFG1_EV10_MASK 0x1F /* EXEV10 event source (5-bit) */ +#define N32_AFIO_SHRT2_EXEV_CFG1_EV10_SHIFT 20 +#define N32_AFIO_SHRT2_EXEV_CFG1_RESERVED_MASK 0xFE000000 /* Reserved bits (25-31) */ + +/* Event source encoding (for all EXEVx fields) */ +#define N32_EXEV_SOURCE_PB4 0x01 +#define N32_EXEV_SOURCE_PB5 0x02 +#define N32_EXEV_SOURCE_PB6 0x03 +#define N32_EXEV_SOURCE_PB7 0x04 +#define N32_EXEV_SOURCE_PC10 0x05 +#define N32_EXEV_SOURCE_PC12 0x06 +#define N32_EXEV_SOURCE_PD5 0x07 +#define N32_EXEV_SOURCE_PD8 0x08 +#define N32_EXEV_SOURCE_PD9 0x09 +#define N32_EXEV_SOURCE_PE6 0x0A +#define N32_EXEV_SOURCE_PG0 0x0B +#define N32_EXEV_SOURCE_PG11 0x0C +#define N32_EXEV_SOURCE_PG12 0x0D +#define N32_EXEV_SOURCE_PG13 0x0E +#define N32_EXEV_SOURCE_PI14 0x0F +#define N32_EXEV_SOURCE_PJ5 0x10 +#define N32_EXEV_SOURCE_PK3 0x11 +#define N32_EXEV_SOURCE_PK4 0x12 + +/* SHRTIM2 specific sources */ +#define N32_EXEV_SOURCE_PA2 0x01 +#define N32_EXEV_SOURCE_PC4 0x02 +#define N32_EXEV_SOURCE_PD0 0x03 +#define N32_EXEV_SOURCE_PD11 0x04 +#define N32_EXEV_SOURCE_PE3 0x05 +#define N32_EXEV_SOURCE_PE14 0x06 +#define N32_EXEV_SOURCE_PF10 0x07 +#define N32_EXEV_SOURCE_PG8 0x08 +#define N32_EXEV_SOURCE_PG15 0x09 +#define N32_EXEV_SOURCE_PH7 0x0A +#define N32_EXEV_SOURCE_PH8 0x0B +#define N32_EXEV_SOURCE_PH10 0x0C +#define N32_EXEV_SOURCE_PH11 0x0D +#define N32_EXEV_SOURCE_PH12 0x0E +#define N32_EXEV_SOURCE_PI11 0x0F +#define N32_EXEV_SOURCE_PJ2 0x10 +#define N32_EXEV_SOURCE_PJ14 0x11 +#define N32_EXEV_SOURCE_PK0 0x12 + +/* SIP Pull-up/Pull-down Configuration Register (AFIO_SIP_PUPD) */ +#define N32_AFIO_SIP_PUPD_PUPD0_MASK 0x03 /* SIP pad0 pull config */ +#define N32_AFIO_SIP_PUPD_PUPD0_SHIFT 0 +#define N32_AFIO_SIP_PUPD_PUPD1_MASK 0x0C /* SIP pad1 pull config */ +#define N32_AFIO_SIP_PUPD_PUPD1_SHIFT 2 +#define N32_AFIO_SIP_PUPD_PUPD2_MASK 0x30 /* SIP pad2 pull config */ +#define N32_AFIO_SIP_PUPD_PUPD2_SHIFT 4 +#define N32_AFIO_SIP_PUPD_PUPD3_MASK 0xC0 /* SIP pad3 pull config */ +#define N32_AFIO_SIP_PUPD_PUPD3_SHIFT 6 +#define N32_AFIO_SIP_PUPD_PUPD4_MASK 0x300 /* SIP pad4 pull config */ +#define N32_AFIO_SIP_PUPD_PUPD4_SHIFT 8 +#define N32_AFIO_SIP_PUPD_PUPD5_MASK 0xC00 /* SIP pad5 pull config */ +#define N32_AFIO_SIP_PUPD_PUPD5_SHIFT 10 +#define N32_AFIO_SIP_PUPD_PUPD6_MASK 0x3000 /* SIP pad6 pull config */ +#define N32_AFIO_SIP_PUPD_PUPD6_SHIFT 12 +#define N32_AFIO_SIP_PUPD_PUPD7_MASK 0xC000 /* SIP pad7 pull config */ +#define N32_AFIO_SIP_PUPD_PUPD7_SHIFT 14 +#define N32_AFIO_SIP_PUPD_RESERVED_MASK 0xFFFF0000 /* Reserved bits (16-31) */ + +/* Pull configuration values (for each PUPDx field) */ +#define N32_PUPD_NONE 0x0 /* No pull-up or pull-down */ +#define N32_PUPD_UP 0x1 /* Pull-up enabled */ +#define N32_PUPD_DOWN 0x2 /* Pull-down enabled */ +#define N32_PUPD_RESV 0x3 /* Reserved (do not use) */ + +/* SDRAM High-Speed Mode Configuration Registers */ + +/* AFIO_SDRAM_HSMOD_CFG0 - SDRAM HS Mode Config 0 (Offset: 0x98) */ +#define N32_AFIO_SDRAM_HSMOD_CFG0_HSA_MASK 0xFFFF /* Port A HS enable */ +#define N32_AFIO_SDRAM_HSMOD_CFG0_HSA_SHIFT 0 +#define N32_AFIO_SDRAM_HSMOD_CFG0_HSB_MASK 0xFFFF0000 /* Port B HS enable */ +#define N32_AFIO_SDRAM_HSMOD_CFG0_HSB_SHIFT 16 + +/* AFIO_SDRAM_HSMOD_CFG1 - SDRAM HS Mode Config 1 (Offset: 0x9C) */ +#define N32_AFIO_SDRAM_HSMOD_CFG1_HSC_MASK 0xFFFF /* Port C HS enable */ +#define N32_AFIO_SDRAM_HSMOD_CFG1_HSC_SHIFT 0 +#define N32_AFIO_SDRAM_HSMOD_CFG1_HSD_MASK 0xFFFF0000 /* Port D HS enable */ +#define N32_AFIO_SDRAM_HSMOD_CFG1_HSD_SHIFT 16 + +/* AFIO_SDRAM_HSMOD_CFG2 - SDRAM HS Mode Config 2 (Offset: 0xA0) */ +#define N32_AFIO_SDRAM_HSMOD_CFG2_HSE_MASK 0xFFFF /* Port E HS enable */ +#define N32_AFIO_SDRAM_HSMOD_CFG2_HSE_SHIFT 0 +#define N32_AFIO_SDRAM_HSMOD_CFG2_HSF_MASK 0xFFFF0000 /* Port F HS enable */ +#define N32_AFIO_SDRAM_HSMOD_CFG2_HSF_SHIFT 16 + +/* AFIO_SDRAM_HSMOD_CFG3 - SDRAM HS Mode Config 3 (Offset: 0xA4) */ +#define N32_AFIO_SDRAM_HSMOD_CFG3_HSG_MASK 0xFFFF /* Port G HS enable */ +#define N32_AFIO_SDRAM_HSMOD_CFG3_HSG_SHIFT 0 +#define N32_AFIO_SDRAM_HSMOD_CFG3_HSH_MASK 0xFFFF0000 /* Port H HS enable */ +#define N32_AFIO_SDRAM_HSMOD_CFG3_HSH_SHIFT 16 + +/* AFIO_SDRAM_HSMOD_CFG4 - SDRAM HS Mode Config 4 (Offset: 0xA8) */ +#define N32_AFIO_SDRAM_HSMOD_CFG4_HSI_MASK 0xFFFF /* Port I HS enable */ +#define N32_AFIO_SDRAM_HSMOD_CFG4_HSI_SHIFT 0 +#define N32_AFIO_SDRAM_HSMOD_CFG4_RESERVED_MASK 0xFFFF0000 /* Reserved bits (16-31) */ + +/* HS_EN bit values */ +#define N32_HS_DISABLE 0 /* Disable high-speed mode */ +#define N32_HS_ENABLE 1 /* Enable high-speed mode */ + +/* SIP Slew Rate Configuration Register (AFIO_SIP_SR) */ +#define N32_AFIO_SIP_SR_SR0_MASK 0x01 /* Pad0 slew rate control */ +#define N32_AFIO_SIP_SR_SR0_SHIFT 0 +#define N32_AFIO_SIP_SR_SR1_MASK 0x02 /* Pad1 slew rate control */ +#define N32_AFIO_SIP_SR_SR1_SHIFT 1 +#define N32_AFIO_SIP_SR_SR2_MASK 0x04 /* Pad2 slew rate control */ +#define N32_AFIO_SIP_SR_SR2_SHIFT 2 +#define N32_AFIO_SIP_SR_SR3_MASK 0x08 /* Pad3 slew rate control */ +#define N32_AFIO_SIP_SR_SR3_SHIFT 3 +#define N32_AFIO_SIP_SR_SR4_MASK 0x10 /* Pad4 slew rate control */ +#define N32_AFIO_SIP_SR_SR4_SHIFT 4 +#define N32_AFIO_SIP_SR_SR5_MASK 0x20 /* Pad5 slew rate control */ +#define N32_AFIO_SIP_SR_SR5_SHIFT 5 +#define N32_AFIO_SIP_SR_SR6_MASK 0x40 /* Pad6 slew rate control */ +#define N32_AFIO_SIP_SR_SR6_SHIFT 6 +#define N32_AFIO_SIP_SR_SR7_MASK 0x80 /* Pad7 slew rate control */ +#define N32_AFIO_SIP_SR_SR7_SHIFT 7 +#define N32_AFIO_SIP_SR_RESERVED_MASK 0xFFFFFF00 /* Reserved bits (8-31) */ + +/* Slew Rate values */ +#define N32_SR_FAST 0 /* Fast slew rate */ +#define N32_SR_SLOW 1 /* Slow slew rate */ + +/* SIP Driver Strength Configuration Register (AFIO_SIP_DS) */ +#define N32_AFIO_SIP_DS_DS0_MASK 0x03 /* Pad0 driver strength */ +#define N32_AFIO_SIP_DS_DS0_SHIFT 0 +#define N32_AFIO_SIP_DS_DS1_MASK 0x0C /* Pad1 driver strength */ +#define N32_AFIO_SIP_DS_DS1_SHIFT 2 +#define N32_AFIO_SIP_DS_DS2_MASK 0x30 /* Pad2 driver strength */ +#define N32_AFIO_SIP_DS_DS2_SHIFT 4 +#define N32_AFIO_SIP_DS_DS3_MASK 0xC0 /* Pad3 driver strength */ +#define N32_AFIO_SIP_DS_DS3_SHIFT 6 +#define N32_AFIO_SIP_DS_DS4_MASK 0x300 /* Pad4 driver strength */ +#define N32_AFIO_SIP_DS_DS4_SHIFT 8 +#define N32_AFIO_SIP_DS_DS5_MASK 0xC00 /* Pad5 driver strength */ +#define N32_AFIO_SIP_DS_DS5_SHIFT 10 +#define N32_AFIO_SIP_DS_DS6_MASK 0x3000 /* Pad6 driver strength */ +#define N32_AFIO_SIP_DS_DS6_SHIFT 12 +#define N32_AFIO_SIP_DS_DS7_MASK 0xC000 /* Pad7 driver strength */ +#define N32_AFIO_SIP_DS_DS7_SHIFT 14 +#define N32_AFIO_SIP_DS_RESERVED_MASK 0xFFFF0000 /* Reserved bits (16-31) */ + +/* Driver Strength values (for each DSy field) */ +#define N32_DS_2MA 0x0 /* 2mA drive strength */ +#define N32_DS_8MA 0x1 /* 8mA drive strength */ +#define N32_DS_4MA 0x2 /* 4mA drive strength */ +#define N32_DS_12MA 0x3 /* 12mA drive strength */ + +/* ADC Switch Configuration Register (AFIO_ADCSW_CFG) */ +#define N32_AFIO_ADCSW_CFG_SWPA0_C_MASK 0x0F /* PA0_C switch config */ +#define N32_AFIO_ADCSW_CFG_SWPA0_C_SHIFT 0 +#define N32_AFIO_ADCSW_CFG_SWPC2_C_MASK 0xF0 /* PC2_C switch config */ +#define N32_AFIO_ADCSW_CFG_SWPC2_C_SHIFT 4 +#define N32_AFIO_ADCSW_CFG_SWPC3_C_MASK 0x300 /* PC3_C switch config */ +#define N32_AFIO_ADCSW_CFG_SWPC3_C_SHIFT 8 +#define N32_AFIO_ADCSW_CFG_SWPA1_C_MASK 0xC00 /* PA1_C switch config */ +#define N32_AFIO_ADCSW_CFG_SWPA1_C_SHIFT 10 +#define N32_AFIO_ADCSW_CFG_SWPJ15_MASK 0x3000 /* PJ15 switch config */ +#define N32_AFIO_ADCSW_CFG_SWPJ15_SHIFT 12 +#define N32_AFIO_ADCSW_CFG_VBAT (1 << 14) /* VBAT monitor enable */ +#define N32_AFIO_ADCSW_CFG_DAC_OUT2_MASK 0xE0000 /* DACx_OUT2 config */ +#define N32_AFIO_ADCSW_CFG_DAC_OUT2_SHIFT 17 +#define N32_AFIO_ADCSW_CFG_SWPJ0 (1 << 18) /* PJ0 switch open */ +#define N32_AFIO_ADCSW_CFG_SWPJ3 (1 << 19) /* PJ3 switch open */ +#define N32_AFIO_ADCSW_CFG_TEMP (1 << 20) /* Temp monitor enable */ +#define N32_AFIO_ADCSW_CFG_SWPJ4 (1 << 21) /* PJ4 switch open */ +#define N32_AFIO_ADCSW_CFG_SWPJ5 (1 << 22) /* PJ5 switch open */ +#define N32_AFIO_ADCSW_CFG_DAC_OUT1_MASK 0xE000000 /* DACx_OUT1 config */ +#define N32_AFIO_ADCSW_CFG_DAC_OUT1_SHIFT 23 +#define N32_AFIO_ADCSW_CFG_SWPJ6 (1 << 26) /* PJ6 switch open */ +#define N32_AFIO_ADCSW_CFG_SWPJ7 (1 << 27) /* PJ7 switch open */ +#define N32_AFIO_ADCSW_CFG_VREF (1 << 28) /* VREF monitor enable */ +#define N32_AFIO_ADCSW_CFG_RESERVED_MASK 0xE0000000 /* Reserved bits (29-31) */ + +/* DAC monitor values */ +#define N32_DAC_MON_DISABLE 0x0 /* Disable monitor */ +#define N32_DAC1_MON_EN 0x1 /* Enable DAC1 monitor */ +#define N32_DAC2_MON_EN 0x2 /* Enable DAC2 monitor */ +#define N32_DAC3_MON_EN 0x4 /* Enable DAC3 monitor */ + +/* SDRAM DSN Configuration Registers */ +#define N32_AFIO_SDRAM_DSN_CFG0_OFFSET 0xE4 +#define N32_AFIO_SDRAM_DSN_CFG1_OFFSET 0xE8 +#define N32_AFIO_SDRAM_DSN_CFG2_OFFSET 0xEC + +/* SDRAM DSP Configuration Registers */ +#define N32_AFIO_SDRAM_DSP_CFG0_OFFSET 0xF0 +#define N32_AFIO_SDRAM_DSP_CFG1_OFFSET 0xF4 +#define N32_AFIO_SDRAM_DSP_CFG2_OFFSET 0xF8 + +/* SDRAM pad mapping (for VREF_EN, DSN, DSP) */ +#define N32_SDRAM_PAD_PA4 0 +#define N32_SDRAM_PAD_PA5 1 +#define N32_SDRAM_PAD_PA7 2 +#define N32_SDRAM_PAD_PB5 3 +#define N32_SDRAM_PAD_PB6 4 +#define N32_SDRAM_PAD_PB14 5 +#define N32_SDRAM_PAD_PB15 6 +#define N32_SDRAM_PAD_PC0 7 +/* ... (complete mapping from Table 12-118) */ +#define N32_SDRAM_PAD_PI10 72 + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_AFIO_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h76x_dmamux.h b/arch/arm/src/n32h7/hardware/n32h76x_dmamux.h new file mode 100644 index 0000000000000..32bdaf0fecd63 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h76x_dmamux.h @@ -0,0 +1,1253 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h76x_dmamux.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + ****************************************************************************/ + + #ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_DMAMUX_H + #define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_DMAMUX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "n32h7_dma.h" +#include "n32h7_dmamux.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ========================================================================== + * DMAMUX1 Request Mapping (REQ) + * ========================================================================== + */ + +/* Internal Request Generators */ +#define DMAMUX1_REQ_GEN0 1 +#define DMAMUX1_REQ_GEN1 2 +#define DMAMUX1_REQ_GEN2 3 +#define DMAMUX1_REQ_GEN3 4 +#define DMAMUX1_REQ_GEN4 5 +#define DMAMUX1_REQ_GEN5 6 +#define DMAMUX1_REQ_GEN6 7 +#define DMAMUX1_REQ_GEN7 8 + +/* ADCs */ +#define DMAMUX1_REQ_ADC1 9 +#define DMAMUX1_REQ_ADC2 10 +#define DMAMUX1_REQ_ADC3 11 + +/* SHRTIM */ +#define DMAMUX1_REQ_SHRTIM1_DMA0 12 +#define DMAMUX1_REQ_SHRTIM1_DMA1 13 +#define DMAMUX1_REQ_SHRTIM1_DMA2 14 +#define DMAMUX1_REQ_SHRTIM1_DMA3 15 +#define DMAMUX1_REQ_SHRTIM1_DMA4 16 +#define DMAMUX1_REQ_SHRTIM1_DMA5 17 +#define DMAMUX1_REQ_SHRTIM1_DMA6 18 +#define DMAMUX1_REQ_SHRTIM2_DMA0 19 +#define DMAMUX1_REQ_SHRTIM2_DMA1 20 +#define DMAMUX1_REQ_SHRTIM2_DMA2 21 +#define DMAMUX1_REQ_SHRTIM2_DMA3 22 +#define DMAMUX1_REQ_SHRTIM2_DMA4 23 +#define DMAMUX1_REQ_SHRTIM2_DMA5 24 +#define DMAMUX1_REQ_SHRTIM2_DMA6 25 + +/* ATIM */ +#define DMAMUX1_REQ_ATIM1_UP 26 +#define DMAMUX1_REQ_ATIM1_CH1 27 +#define DMAMUX1_REQ_ATIM1_CH2 28 +#define DMAMUX1_REQ_ATIM1_CH3 29 +#define DMAMUX1_REQ_ATIM1_CH4 30 +#define DMAMUX1_REQ_ATIM1_COM 31 +#define DMAMUX1_REQ_ATIM1_TRG 32 +#define DMAMUX1_REQ_ATIM2_UP 33 +#define DMAMUX1_REQ_ATIM2_CH1 34 +#define DMAMUX1_REQ_ATIM2_CH2 35 +#define DMAMUX1_REQ_ATIM2_CH3 36 +#define DMAMUX1_REQ_ATIM2_CH4 37 +#define DMAMUX1_REQ_ATIM2_COM 38 +#define DMAMUX1_REQ_ATIM2_TRG 39 +#define DMAMUX1_REQ_ATIM3_UP 40 +#define DMAMUX1_REQ_ATIM3_CH1 41 +#define DMAMUX1_REQ_ATIM3_CH2 42 +#define DMAMUX1_REQ_ATIM3_CH3 43 +#define DMAMUX1_REQ_ATIM3_CH4 44 +#define DMAMUX1_REQ_ATIM3_COM 45 +#define DMAMUX1_REQ_ATIM3_TRG 46 +#define DMAMUX1_REQ_ATIM4_UP 47 +#define DMAMUX1_REQ_ATIM4_CH1 48 +#define DMAMUX1_REQ_ATIM4_CH2 49 +#define DMAMUX1_REQ_ATIM4_CH3 50 +#define DMAMUX1_REQ_ATIM4_CH4 51 +#define DMAMUX1_REQ_ATIM4_COM 52 +#define DMAMUX1_REQ_ATIM4_TRG 53 + +/* GTIMA */ +#define DMAMUX1_REQ_GTIMA1_CH1 54 +#define DMAMUX1_REQ_GTIMA1_CH2 55 +#define DMAMUX1_REQ_GTIMA1_CH3 56 +#define DMAMUX1_REQ_GTIMA1_CH4 57 +#define DMAMUX1_REQ_GTIMA1_TRG 58 +#define DMAMUX1_REQ_GTIMA1_UP 59 +#define DMAMUX1_REQ_GTIMA2_CH1 60 +#define DMAMUX1_REQ_GTIMA2_CH2 61 +#define DMAMUX1_REQ_GTIMA2_CH3 62 +#define DMAMUX1_REQ_GTIMA2_CH4 63 +#define DMAMUX1_REQ_GTIMA2_TRG 64 +#define DMAMUX1_REQ_GTIMA2_UP 65 +#define DMAMUX1_REQ_GTIMA3_CH1 66 +#define DMAMUX1_REQ_GTIMA3_CH2 67 +#define DMAMUX1_REQ_GTIMA3_CH3 68 +#define DMAMUX1_REQ_GTIMA3_CH4 69 +#define DMAMUX1_REQ_GTIMA3_TRG 70 +#define DMAMUX1_REQ_GTIMA3_UP 71 +#define DMAMUX1_REQ_GTIMA4_CH1 72 +#define DMAMUX1_REQ_GTIMA4_CH2 73 +#define DMAMUX1_REQ_GTIMA4_CH3 74 +#define DMAMUX1_REQ_GTIMA4_CH4 75 +#define DMAMUX1_REQ_GTIMA4_TRG 76 +#define DMAMUX1_REQ_GTIMA4_UP 77 +#define DMAMUX1_REQ_GTIMA5_CH1 78 +#define DMAMUX1_REQ_GTIMA5_CH2 79 +#define DMAMUX1_REQ_GTIMA5_CH3 80 +#define DMAMUX1_REQ_GTIMA5_CH4 81 +#define DMAMUX1_REQ_GTIMA5_TRG 82 +#define DMAMUX1_REQ_GTIMA5_UP 83 +#define DMAMUX1_REQ_GTIMA6_CH1 84 +#define DMAMUX1_REQ_GTIMA6_CH2 85 +#define DMAMUX1_REQ_GTIMA6_CH3 86 +#define DMAMUX1_REQ_GTIMA6_CH4 87 +#define DMAMUX1_REQ_GTIMA6_TRG 88 +#define DMAMUX1_REQ_GTIMA6_UP 89 +#define DMAMUX1_REQ_GTIMA7_CH1 90 +#define DMAMUX1_REQ_GTIMA7_CH2 91 +#define DMAMUX1_REQ_GTIMA7_CH3 92 +#define DMAMUX1_REQ_GTIMA7_CH4 93 +#define DMAMUX1_REQ_GTIMA7_TRG 94 +#define DMAMUX1_REQ_GTIMA7_UP 95 + +/* GTIMB */ +#define DMAMUX1_REQ_GTIMB1_CH1 96 +#define DMAMUX1_REQ_GTIMB1_CH2 97 +#define DMAMUX1_REQ_GTIMB1_CH3 98 +#define DMAMUX1_REQ_GTIMB1_CH4 99 +#define DMAMUX1_REQ_GTIMB1_TRG 100 +#define DMAMUX1_REQ_GTIMB1_UP 101 +#define DMAMUX1_REQ_GTIMB2_CH1 102 +#define DMAMUX1_REQ_GTIMB2_CH2 103 +#define DMAMUX1_REQ_GTIMB2_CH3 104 +#define DMAMUX1_REQ_GTIMB2_CH4 105 +#define DMAMUX1_REQ_GTIMB2_TRG 106 +#define DMAMUX1_REQ_GTIMB2_UP 107 +#define DMAMUX1_REQ_GTIMB3_CH1 108 +#define DMAMUX1_REQ_GTIMB3_CH2 109 +#define DMAMUX1_REQ_GTIMB3_CH3 110 +#define DMAMUX1_REQ_GTIMB3_CH4 111 +#define DMAMUX1_REQ_GTIMB3_TRG 112 +#define DMAMUX1_REQ_GTIMB3_UP 113 + +/* I2C */ +#define DMAMUX1_REQ_I2C1_RX 114 +#define DMAMUX1_REQ_I2C1_TX 115 +#define DMAMUX1_REQ_I2C2_RX 116 +#define DMAMUX1_REQ_I2C2_TX 117 +#define DMAMUX1_REQ_I2C3_RX 118 +#define DMAMUX1_REQ_I2C3_TX 119 +#define DMAMUX1_REQ_I2C4_RX 120 +#define DMAMUX1_REQ_I2C4_TX 121 +#define DMAMUX1_REQ_I2C5_RX 122 +#define DMAMUX1_REQ_I2C5_TX 123 +#define DMAMUX1_REQ_I2C6_RX 124 +#define DMAMUX1_REQ_I2C6_TX 125 +#define DMAMUX1_REQ_I2C7_RX 126 +#define DMAMUX1_REQ_I2C7_TX 127 +#define DMAMUX1_REQ_I2C8_RX 128 +#define DMAMUX1_REQ_I2C8_TX 129 +#define DMAMUX1_REQ_I2C9_RX 130 +#define DMAMUX1_REQ_I2C9_TX 131 +#define DMAMUX1_REQ_I2C10_RX 132 +#define DMAMUX1_REQ_I2C10_TX 133 + +/* USART */ +#define DMAMUX1_REQ_USART1_RX 134 +#define DMAMUX1_REQ_USART1_TX 135 +#define DMAMUX1_REQ_USART2_RX 136 +#define DMAMUX1_REQ_USART2_TX 137 +#define DMAMUX1_REQ_USART3_RX 138 +#define DMAMUX1_REQ_USART3_TX 139 +#define DMAMUX1_REQ_USART4_RX 140 +#define DMAMUX1_REQ_USART4_TX 141 +#define DMAMUX1_REQ_USART5_RX 142 +#define DMAMUX1_REQ_USART5_TX 143 +#define DMAMUX1_REQ_USART6_RX 144 +#define DMAMUX1_REQ_USART6_TX 145 +#define DMAMUX1_REQ_USART7_RX 146 +#define DMAMUX1_REQ_USART7_TX 147 +#define DMAMUX1_REQ_USART8_RX 148 +#define DMAMUX1_REQ_USART8_TX 149 + +/* UART */ +#define DMAMUX1_REQ_UART9_RX 150 +#define DMAMUX1_REQ_UART9_TX 151 +#define DMAMUX1_REQ_UART10_RX 152 +#define DMAMUX1_REQ_UART10_TX 153 +#define DMAMUX1_REQ_UART11_RX 154 +#define DMAMUX1_REQ_UART11_TX 155 +#define DMAMUX1_REQ_UART12_RX 156 +#define DMAMUX1_REQ_UART12_TX 157 +#define DMAMUX1_REQ_UART13_RX 158 +#define DMAMUX1_REQ_UART13_TX 159 +#define DMAMUX1_REQ_UART14_RX 160 +#define DMAMUX1_REQ_UART14_TX 161 +#define DMAMUX1_REQ_UART15_RX 162 +#define DMAMUX1_REQ_UART15_TX 163 + +/* SPI */ +#define DMAMUX1_REQ_SPI1_RX 164 +#define DMAMUX1_REQ_SPI1_TX 173 +#define DMAMUX1_REQ_SPI2_RX 166 +#define DMAMUX1_REQ_SPI2_TX 175 +#define DMAMUX1_REQ_SPI3_RX 168 +#define DMAMUX1_REQ_SPI3_TX 177 +#define DMAMUX1_REQ_SPI4_RX 170 +#define DMAMUX1_REQ_SPI4_TX 179 +#define DMAMUX1_REQ_SPI5_RX 172 +#define DMAMUX1_REQ_SPI5_TX 181 +#define DMAMUX1_REQ_SPI6_RX 174 +#define DMAMUX1_REQ_SPI6_TX 183 +#define DMAMUX1_REQ_SPI7_RX 176 +#define DMAMUX1_REQ_SPI7_TX 185 + +/* I2S */ +#define DMAMUX1_REQ_I2S1_RX 165 +#define DMAMUX1_REQ_I2S1_TX 174 +#define DMAMUX1_REQ_I2S2_RX 167 +#define DMAMUX1_REQ_I2S2_TX 176 +#define DMAMUX1_REQ_I2S3_RX 169 +#define DMAMUX1_REQ_I2S3_TX 178 +#define DMAMUX1_REQ_I2S4_RX 171 +#define DMAMUX1_REQ_I2S4_TX 180 + +/* LPUART */ +#define DMAMUX1_REQ_LPUART1_RX 186 +#define DMAMUX1_REQ_LPUART1_TX 187 +#define DMAMUX1_REQ_LPUART2_RX 188 +#define DMAMUX1_REQ_LPUART2_TX 189 + +/* DSMU */ +#define DMAMUX1_REQ_DSMU0 192 +#define DMAMUX1_REQ_DSMU1 193 +#define DMAMUX1_REQ_DSMU2 194 +#define DMAMUX1_REQ_DSMU3 195 + +/* FDCAN */ +#define DMAMUX1_REQ_FDCAN1 196 +#define DMAMUX1_REQ_FDCAN2 197 +#define DMAMUX1_REQ_FDCAN3 198 +#define DMAMUX1_REQ_FDCAN4 199 +#define DMAMUX1_REQ_FDCAN5 200 +#define DMAMUX1_REQ_FDCAN6 201 +#define DMAMUX1_REQ_FDCAN7 202 +#define DMAMUX1_REQ_FDCAN8 203 + +/* CORDIC */ +#define DMAMUX1_REQ_CORDIC_RD 204 +#define DMAMUX1_REQ_CORDIC_WR 205 + +/* FMAU */ +#define DMAMUX1_REQ_FMAU_RD 206 +#define DMAMUX1_REQ_FMAU_WR 207 + +/* BTIM */ +#define DMAMUX1_REQ_BTIM1 208 +#define DMAMUX1_REQ_BTIM2 209 +#define DMAMUX1_REQ_BTIM3 210 +#define DMAMUX1_REQ_BTIM4 211 + +/* GTIMB */ +#define DMAMUX1_REQ_GTIMB1_COM 212 +#define DMAMUX1_REQ_GTIMB2_COM 213 +#define DMAMUX1_REQ_GTIMB3_COM 214 + +/* DAC */ +#define DMAMUX1_REQ_DAC12_0 190 +#define DMAMUX1_REQ_DAC12_1 191 +#define DMAMUX1_REQ_DAC34_0 215 +#define DMAMUX1_REQ_DAC34_1 216 +#define DMAMUX1_REQ_DAC56_0 217 +#define DMAMUX1_REQ_DAC56_1 218 + +/* ========================================================================== + * DMAMUX1 Trigger Mapping (TRG) + * ========================================================================== + */ + +#define DMAMUX1_TRG_EVT0_7 0 +#define DMAMUX1_TRG_EVT8_15 1 +#define DMAMUX1_TRG_EVT16_23 2 + +#define DMAMUX1_TRG_LPTIMER1_OUT 3 +#define DMAMUX1_TRG_LPTIMER2_OUT 4 +#define DMAMUX1_TRG_LPTIMER3_OUT 5 +#define DMAMUX1_TRG_LPTIMER4_OUT 6 +#define DMAMUX1_TRG_LPTIMER5_OUT 7 + +#define DMAMUX1_TRG_IOM_EXTI0 8 + +#define DMAMUX1_TRG_FDCAN1_IRQ0 9 +#define DMAMUX1_TRG_FDCAN2_IRQ0 10 +#define DMAMUX1_TRG_FDCAN3_IRQ0 11 +#define DMAMUX1_TRG_FDCAN4_IRQ0 12 +#define DMAMUX1_TRG_FDCAN5_IRQ0 13 +#define DMAMUX1_TRG_FDCAN6_IRQ0 14 +#define DMAMUX1_TRG_FDCAN7_IRQ0 15 +#define DMAMUX1_TRG_FDCAN8_IRQ0 16 + +#define DMAMUX1_TRG_FDCAN1_IRQ1 17 +#define DMAMUX1_TRG_FDCAN2_IRQ1 18 +#define DMAMUX1_TRG_FDCAN3_IRQ1 19 +#define DMAMUX1_TRG_FDCAN4_IRQ1 20 +#define DMAMUX1_TRG_FDCAN5_IRQ1 21 +#define DMAMUX1_TRG_FDCAN6_IRQ1 22 +#define DMAMUX1_TRG_FDCAN7_IRQ1 23 +#define DMAMUX1_TRG_FDCAN8_IRQ1 24 + +/* ========================================================================== + * DMAMUX1 Synchronization Mapping (SYNC) + * ========================================================================== + */ + +#define DMAMUX1_SYNC_EVT0_7 0 +#define DMAMUX1_SYNC_EVT8_15 1 +#define DMAMUX1_SYNC_EVT16_23 2 + +#define DMAMUX1_SYNC_LPTIMER1_OUT 3 +#define DMAMUX1_SYNC_LPTIMER2_OUT 4 +#define DMAMUX1_SYNC_LPTIMER3_OUT 5 +#define DMAMUX1_SYNC_LPTIMER4_OUT 6 +#define DMAMUX1_SYNC_LPTIMER5_OUT 7 + +#define DMAMUX1_SYNC_IOM_EXTI0 8 + +/* ========================================================================== + * DMAMUX2 Request Mapping (REQ) + * ========================================================================== + */ + +#define DMAMUX2_REQ_GEN0 1 +#define DMAMUX2_REQ_GEN1 2 +#define DMAMUX2_REQ_GEN2 3 +#define DMAMUX2_REQ_GEN3 4 +#define DMAMUX2_REQ_GEN4 5 +#define DMAMUX2_REQ_GEN5 6 +#define DMAMUX2_REQ_GEN6 7 +#define DMAMUX2_REQ_GEN7 8 + +#define DMAMUX2_REQ_GEN8 9 +#define DMAMUX2_REQ_GEN9 10 +#define DMAMUX2_REQ_GEN10 11 +#define DMAMUX2_REQ_GEN11 12 +#define DMAMUX2_REQ_GEN12 13 +#define DMAMUX2_REQ_GEN13 14 +#define DMAMUX2_REQ_GEN14 15 +#define DMAMUX2_REQ_GEN15 16 + +#define DMAMUX2_REQ_XSPI1_TX 25 +#define DMAMUX2_REQ_XSPI1_RX 26 +#define DMAMUX2_REQ_XSPI2_TX 27 +#define DMAMUX2_REQ_XSPI2_RX 28 + +/* ========================================================================== + * DMAMUX2 Trigger Mapping (TRG) + * ========================================================================== + */ + +#define DMAMUX2_TRG_DMA1_INT_TFR0 0 +#define DMAMUX2_TRG_DMA1_INT_TFR1 1 +#define DMAMUX2_TRG_DMA1_INT_TFR2 2 +#define DMAMUX2_TRG_DMA1_INT_TFR3 3 +#define DMAMUX2_TRG_DMA1_INT_TFR4 4 +#define DMAMUX2_TRG_DMA1_INT_TFR5 5 +#define DMAMUX2_TRG_DMA1_INT_TFR6 6 +#define DMAMUX2_TRG_DMA1_INT_TFR7 7 + +#define DMAMUX2_TRG_DMA2_INT_TFR0 8 +#define DMAMUX2_TRG_DMA2_INT_TFR1 9 +#define DMAMUX2_TRG_DMA2_INT_TFR2 10 +#define DMAMUX2_TRG_DMA2_INT_TFR3 11 +#define DMAMUX2_TRG_DMA2_INT_TFR4 12 +#define DMAMUX2_TRG_DMA2_INT_TFR5 13 +#define DMAMUX2_TRG_DMA2_INT_TFR6 14 +#define DMAMUX2_TRG_DMA2_INT_TFR7 15 + +#define DMAMUX2_TRG_DMA3_INT_TFR0 16 +#define DMAMUX2_TRG_DMA3_INT_TFR1 17 +#define DMAMUX2_TRG_DMA3_INT_TFR2 18 +#define DMAMUX2_TRG_DMA3_INT_TFR3 19 +#define DMAMUX2_TRG_DMA3_INT_TFR4 20 +#define DMAMUX2_TRG_DMA3_INT_TFR5 21 +#define DMAMUX2_TRG_DMA3_INT_TFR6 22 +#define DMAMUX2_TRG_DMA3_INT_TFR7 23 + +#define DMAMUX2_TRG_LCDC_LI_IT 24 +#define DMAMUX2_TRG_GPU_SPEC_INT 25 +#define DMAMUX2_TRG_JPEG_SGDMA_H2P_INT 26 +#define DMAMUX2_TRG_JPEG_SGDMA_P2H_INT 27 +#define DMAMUX2_TRG_MIPI_DSI_INT 28 +#define DMAMUX2_TRG_USB1_INT 29 +#define DMAMUX2_TRG_USB2_INT 30 +#define DMAMUX2_TRG_SDMMC1_INT 31 +#define DMAMUX2_TRG_SDMMC2_INT 32 +#define DMAMUX2_TRG_DVP1_INT 33 +#define DMAMUX2_TRG_DVP2_INT 34 +#define DMAMUX2_TRG_ETH1_INT 35 +#define DMAMUX2_TRG_ETH2_INT 36 +#define DMAMUX2_TRG_SDPU_INT 37 + +/* ========================================================================== + * DMAMUX2 Synchronization Mapping (SYNC) + * ========================================================================== + */ + +#define DMAMUX2_SYNC_INTERNAL 0 + +/* ========================================================================== + * DMAMAP Definitions for DMAMUX1 + * ========================================================================== + */ + +/* DMA1 Mappings */ +#define DMAMAP_DMA1_1GEN0 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN0) +#define DMAMAP_DMA1_1GEN1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN1) +#define DMAMAP_DMA1_1GEN2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN2) +#define DMAMAP_DMA1_1GEN3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN3) +#define DMAMAP_DMA1_1GEN4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN4) +#define DMAMAP_DMA1_1GEN5 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN5) +#define DMAMAP_DMA1_1GEN6 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN6) +#define DMAMAP_DMA1_1GEN7 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN7) + +#define DMAMAP_DMA1_ADC1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ADC1) +#define DMAMAP_DMA1_ADC2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ADC2) +#define DMAMAP_DMA1_ADC3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ADC3) + +#define DMAMAP_DMA1_SHRTIM1_DMA0 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM1_DMA0) +#define DMAMAP_DMA1_SHRTIM1_DMA1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM1_DMA1) +#define DMAMAP_DMA1_SHRTIM1_DMA2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM1_DMA2) +#define DMAMAP_DMA1_SHRTIM1_DMA3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM1_DMA3) +#define DMAMAP_DMA1_SHRTIM1_DMA4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM1_DMA4) +#define DMAMAP_DMA1_SHRTIM1_DMA5 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM1_DMA5) +#define DMAMAP_DMA1_SHRTIM1_DMA6 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM1_DMA6) + +#define DMAMAP_DMA1_SHRTIM2_DMA0 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM2_DMA0) +#define DMAMAP_DMA1_SHRTIM2_DMA1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM2_DMA1) +#define DMAMAP_DMA1_SHRTIM2_DMA2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM2_DMA2) +#define DMAMAP_DMA1_SHRTIM2_DMA3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM2_DMA3) +#define DMAMAP_DMA1_SHRTIM2_DMA4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM2_DMA4) +#define DMAMAP_DMA1_SHRTIM2_DMA5 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM2_DMA5) +#define DMAMAP_DMA1_SHRTIM2_DMA6 DMAMAP_MAP(DMA1, DMAMUX1_REQ_SHRTIM2_DMA6) + +#define DMAMAP_DMA1_ATIM1_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM1_UP) +#define DMAMAP_DMA1_ATIM1_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM1_CH1) +#define DMAMAP_DMA1_ATIM1_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM1_CH2) +#define DMAMAP_DMA1_ATIM1_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM1_CH3) +#define DMAMAP_DMA1_ATIM1_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM1_CH4) +#define DMAMAP_DMA1_ATIM1_COM DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM1_COM) +#define DMAMAP_DMA1_ATIM1_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM1_TRG) + +#define DMAMAP_DMA1_ATIM2_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM2_UP) +#define DMAMAP_DMA1_ATIM2_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM2_CH1) +#define DMAMAP_DMA1_ATIM2_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM2_CH2) +#define DMAMAP_DMA1_ATIM2_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM2_CH3) +#define DMAMAP_DMA1_ATIM2_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM2_CH4) +#define DMAMAP_DMA1_ATIM2_COM DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM2_COM) +#define DMAMAP_DMA1_ATIM2_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM2_TRG) + +#define DMAMAP_DMA1_ATIM3_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM3_UP) +#define DMAMAP_DMA1_ATIM3_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM3_CH1) +#define DMAMAP_DMA1_ATIM3_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM3_CH2) +#define DMAMAP_DMA1_ATIM3_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM3_CH3) +#define DMAMAP_DMA1_ATIM3_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM3_CH4) +#define DMAMAP_DMA1_ATIM3_COM DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM3_COM) +#define DMAMAP_DMA1_ATIM3_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM3_TRG) + +#define DMAMAP_DMA1_ATIM4_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM4_UP) +#define DMAMAP_DMA1_ATIM4_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM4_CH1) +#define DMAMAP_DMA1_ATIM4_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM4_CH2) +#define DMAMAP_DMA1_ATIM4_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM4_CH3) +#define DMAMAP_DMA1_ATIM4_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM4_CH4) +#define DMAMAP_DMA1_ATIM4_COM DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM4_COM) +#define DMAMAP_DMA1_ATIM4_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_ATIM4_TRG) + +#define DMAMAP_DMA1_GTIMA1_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA1_CH1) +#define DMAMAP_DMA1_GTIMA1_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA1_CH2) +#define DMAMAP_DMA1_GTIMA1_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA1_CH3) +#define DMAMAP_DMA1_GTIMA1_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA1_CH4) +#define DMAMAP_DMA1_GTIMA1_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA1_TRG) +#define DMAMAP_DMA1_GTIMA1_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA1_UP) + +#define DMAMAP_DMA1_GTIMA2_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA2_CH1) +#define DMAMAP_DMA1_GTIMA2_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA2_CH2) +#define DMAMAP_DMA1_GTIMA2_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA2_CH3) +#define DMAMAP_DMA1_GTIMA2_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA2_CH4) +#define DMAMAP_DMA1_GTIMA2_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA2_TRG) +#define DMAMAP_DMA1_GTIMA2_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA2_UP) + +#define DMAMAP_DMA1_GTIMA3_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA3_CH1) +#define DMAMAP_DMA1_GTIMA3_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA3_CH2) +#define DMAMAP_DMA1_GTIMA3_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA3_CH3) +#define DMAMAP_DMA1_GTIMA3_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA3_CH4) +#define DMAMAP_DMA1_GTIMA3_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA3_TRG) +#define DMAMAP_DMA1_GTIMA3_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA3_UP) + +#define DMAMAP_DMA1_GTIMA4_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA4_CH1) +#define DMAMAP_DMA1_GTIMA4_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA4_CH2) +#define DMAMAP_DMA1_GTIMA4_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA4_CH3) +#define DMAMAP_DMA1_GTIMA4_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA4_CH4) +#define DMAMAP_DMA1_GTIMA4_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA4_TRG) +#define DMAMAP_DMA1_GTIMA4_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA4_UP) + +#define DMAMAP_DMA1_GTIMA5_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA5_CH1) +#define DMAMAP_DMA1_GTIMA5_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA5_CH2) +#define DMAMAP_DMA1_GTIMA5_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA5_CH3) +#define DMAMAP_DMA1_GTIMA5_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA5_CH4) +#define DMAMAP_DMA1_GTIMA5_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA5_TRG) +#define DMAMAP_DMA1_GTIMA5_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA5_UP) + +#define DMAMAP_DMA1_GTIMA6_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA6_CH1) +#define DMAMAP_DMA1_GTIMA6_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA6_CH2) +#define DMAMAP_DMA1_GTIMA6_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA6_CH3) +#define DMAMAP_DMA1_GTIMA6_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA6_CH4) +#define DMAMAP_DMA1_GTIMA6_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA6_TRG) +#define DMAMAP_DMA1_GTIMA6_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA6_UP) + +#define DMAMAP_DMA1_GTIMA7_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA7_CH1) +#define DMAMAP_DMA1_GTIMA7_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA7_CH2) +#define DMAMAP_DMA1_GTIMA7_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA7_CH3) +#define DMAMAP_DMA1_GTIMA7_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA7_CH4) +#define DMAMAP_DMA1_GTIMA7_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA7_TRG) +#define DMAMAP_DMA1_GTIMA7_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMA7_UP) + +#define DMAMAP_DMA1_GTIMB1_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB1_CH1) +#define DMAMAP_DMA1_GTIMB1_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB1_CH2) +#define DMAMAP_DMA1_GTIMB1_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB1_CH3) +#define DMAMAP_DMA1_GTIMB1_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB1_CH4) +#define DMAMAP_DMA1_GTIMB1_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB1_TRG) +#define DMAMAP_DMA1_GTIMB1_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB1_UP) + +#define DMAMAP_DMA1_GTIMB2_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB2_CH1) +#define DMAMAP_DMA1_GTIMB2_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB2_CH2) +#define DMAMAP_DMA1_GTIMB2_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB2_CH3) +#define DMAMAP_DMA1_GTIMB2_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB2_CH4) +#define DMAMAP_DMA1_GTIMB2_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB2_TRG) +#define DMAMAP_DMA1_GTIMB2_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB2_UP) + +#define DMAMAP_DMA1_GTIMB3_CH1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB3_CH1) +#define DMAMAP_DMA1_GTIMB3_CH2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB3_CH2) +#define DMAMAP_DMA1_GTIMB3_CH3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB3_CH3) +#define DMAMAP_DMA1_GTIMB3_CH4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB3_CH4) +#define DMAMAP_DMA1_GTIMB3_TRG DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB3_TRG) +#define DMAMAP_DMA1_GTIMB3_UP DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB3_UP) + +#define DMAMAP_DMA1_I2C1_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C1_RX) +#define DMAMAP_DMA1_I2C1_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C1_TX) +#define DMAMAP_DMA1_I2C2_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C2_RX) +#define DMAMAP_DMA1_I2C2_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C2_TX) +#define DMAMAP_DMA1_I2C3_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C3_RX) +#define DMAMAP_DMA1_I2C3_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C3_TX) +#define DMAMAP_DMA1_I2C4_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C4_RX) +#define DMAMAP_DMA1_I2C4_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C4_TX) +#define DMAMAP_DMA1_I2C5_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C5_RX) +#define DMAMAP_DMA1_I2C5_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C5_TX) +#define DMAMAP_DMA1_I2C6_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C6_RX) +#define DMAMAP_DMA1_I2C6_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C6_TX) +#define DMAMAP_DMA1_I2C7_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C7_RX) +#define DMAMAP_DMA1_I2C7_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C7_TX) +#define DMAMAP_DMA1_I2C8_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C8_RX) +#define DMAMAP_DMA1_I2C8_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C8_TX) +#define DMAMAP_DMA1_I2C9_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C9_RX) +#define DMAMAP_DMA1_I2C9_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C9_TX) +#define DMAMAP_DMA1_I2C10_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C10_RX) +#define DMAMAP_DMA1_I2C10_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2C10_TX) + +#define DMAMAP_DMA1_USART1_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART1_RX) +#define DMAMAP_DMA1_USART1_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART1_TX) +#define DMAMAP_DMA1_USART2_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART2_RX) +#define DMAMAP_DMA1_USART2_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART2_TX) +#define DMAMAP_DMA1_USART3_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART3_RX) +#define DMAMAP_DMA1_USART3_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART3_TX) +#define DMAMAP_DMA1_USART4_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART4_RX) +#define DMAMAP_DMA1_USART4_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART4_TX) +#define DMAMAP_DMA1_USART5_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART5_RX) +#define DMAMAP_DMA1_USART5_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART5_TX) +#define DMAMAP_DMA1_USART6_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART6_RX) +#define DMAMAP_DMA1_USART6_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART6_TX) +#define DMAMAP_DMA1_USART7_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART7_RX) +#define DMAMAP_DMA1_USART7_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART7_TX) +#define DMAMAP_DMA1_USART8_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART8_RX) +#define DMAMAP_DMA1_USART8_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_USART8_TX) + +#define DMAMAP_DMA1_UART9_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART9_RX) +#define DMAMAP_DMA1_UART9_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART9_TX) +#define DMAMAP_DMA1_UART10_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART10_RX) +#define DMAMAP_DMA1_UART10_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART10_TX) +#define DMAMAP_DMA1_UART11_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART11_RX) +#define DMAMAP_DMA1_UART11_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART11_TX) +#define DMAMAP_DMA1_UART12_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART12_RX) +#define DMAMAP_DMA1_UART12_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART12_TX) +#define DMAMAP_DMA1_UART13_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART13_RX) +#define DMAMAP_DMA1_UART13_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART13_TX) +#define DMAMAP_DMA1_UART14_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART14_RX) +#define DMAMAP_DMA1_UART14_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART14_TX) +#define DMAMAP_DMA1_UART15_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART15_RX) +#define DMAMAP_DMA1_UART15_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_UART15_TX) + +#define DMAMAP_DMA1_SPI1_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI1_RX) +#define DMAMAP_DMA1_SPI1_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI1_TX) +#define DMAMAP_DMA1_SPI2_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI2_RX) +#define DMAMAP_DMA1_SPI2_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI2_TX) +#define DMAMAP_DMA1_SPI3_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI3_RX) +#define DMAMAP_DMA1_SPI3_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI3_TX) +#define DMAMAP_DMA1_SPI4_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI4_RX) +#define DMAMAP_DMA1_SPI4_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI4_TX) +#define DMAMAP_DMA1_SPI5_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI5_RX) +#define DMAMAP_DMA1_SPI5_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI5_TX) +#define DMAMAP_DMA1_SPI6_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI6_RX) +#define DMAMAP_DMA1_SPI6_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI6_TX) +#define DMAMAP_DMA1_SPI7_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI7_RX) +#define DMAMAP_DMA1_SPI7_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_SPI7_TX) + +#define DMAMAP_DMA1_I2S1_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2S1_RX) +#define DMAMAP_DMA1_I2S1_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2S1_TX) +#define DMAMAP_DMA1_I2S2_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2S2_RX) +#define DMAMAP_DMA1_I2S2_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2S2_TX) +#define DMAMAP_DMA1_I2S3_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2S3_RX) +#define DMAMAP_DMA1_I2S3_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2S3_TX) +#define DMAMAP_DMA1_I2S4_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2S4_RX) +#define DMAMAP_DMA1_I2S4_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_I2S4_TX) + +#define DMAMAP_DMA1_LPUART1_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_LPUART1_RX) +#define DMAMAP_DMA1_LPUART1_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_LPUART1_TX) +#define DMAMAP_DMA1_LPUART2_RX DMAMAP_MAP(DMA1, DMAMUX1_REQ_LPUART2_RX) +#define DMAMAP_DMA1_LPUART2_TX DMAMAP_MAP(DMA1, DMAMUX1_REQ_LPUART2_TX) + +#define DMAMAP_DMA1_DSMU0 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DSMU0) +#define DMAMAP_DMA1_DSMU1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DSMU1) +#define DMAMAP_DMA1_DSMU2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DSMU2) +#define DMAMAP_DMA1_DSMU3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DSMU3) + +#define DMAMAP_DMA1_FDCAN1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_FDCAN1) +#define DMAMAP_DMA1_FDCAN2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_FDCAN2) +#define DMAMAP_DMA1_FDCAN3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_FDCAN3) +#define DMAMAP_DMA1_FDCAN4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_FDCAN4) +#define DMAMAP_DMA1_FDCAN5 DMAMAP_MAP(DMA1, DMAMUX1_REQ_FDCAN5) +#define DMAMAP_DMA1_FDCAN6 DMAMAP_MAP(DMA1, DMAMUX1_REQ_FDCAN6) +#define DMAMAP_DMA1_FDCAN7 DMAMAP_MAP(DMA1, DMAMUX1_REQ_FDCAN7) +#define DMAMAP_DMA1_FDCAN8 DMAMAP_MAP(DMA1, DMAMUX1_REQ_FDCAN8) + +#define DMAMAP_DMA1_CORDIC_RD DMAMAP_MAP(DMA1, DMAMUX1_REQ_CORDIC_RD) +#define DMAMAP_DMA1_CORDIC_WR DMAMAP_MAP(DMA1, DMAMUX1_REQ_CORDIC_WR) + +#define DMAMAP_DMA1_FMAU_RD DMAMAP_MAP(DMA1, DMAMUX1_REQ_FMAU_RD) +#define DMAMAP_DMA1_FMAU_WR DMAMAP_MAP(DMA1, DMAMUX1_REQ_FMAU_WR) + +#define DMAMAP_DMA1_BTIM1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_BTIM1) +#define DMAMAP_DMA1_BTIM2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_BTIM2) +#define DMAMAP_DMA1_BTIM3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_BTIM3) +#define DMAMAP_DMA1_BTIM4 DMAMAP_MAP(DMA1, DMAMUX1_REQ_BTIM4) + +#define DMAMAP_DMA1_GTIMB1_COM DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB1_COM) +#define DMAMAP_DMA1_GTIMB2_COM DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB2_COM) +#define DMAMAP_DMA1_GTIMB3_COM DMAMAP_MAP(DMA1, DMAMUX1_REQ_GTIMB3_COM) + +#define DMAMAP_DMA1_DAC12_0 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DAC12_0) +#define DMAMAP_DMA1_DAC12_1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DAC12_1) +#define DMAMAP_DMA1_DAC34_0 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DAC34_0) +#define DMAMAP_DMA1_DAC34_1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DAC34_1) +#define DMAMAP_DMA1_DAC56_0 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DAC56_0) +#define DMAMAP_DMA1_DAC56_1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_DAC56_1) + +/* DMA2 Mappings */ +#define DMAMAP_DMA2_2GEN0 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GEN0) +#define DMAMAP_DMA2_2GEN1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GEN1) +#define DMAMAP_DMA2_2GEN2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GEN2) +#define DMAMAP_DMA2_2GEN3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GEN3) +#define DMAMAP_DMA2_2GEN4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GEN4) +#define DMAMAP_DMA2_2GEN5 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GEN5) +#define DMAMAP_DMA2_2GEN6 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GEN6) +#define DMAMAP_DMA2_2GEN7 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GEN7) + +#define DMAMAP_DMA2_ADC1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ADC1) +#define DMAMAP_DMA2_ADC2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ADC2) +#define DMAMAP_DMA2_ADC3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ADC3) + +#define DMAMAP_DMA2_SHRTIM1_DMA0 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM1_DMA0) +#define DMAMAP_DMA2_SHRTIM1_DMA1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM1_DMA1) +#define DMAMAP_DMA2_SHRTIM1_DMA2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM1_DMA2) +#define DMAMAP_DMA2_SHRTIM1_DMA3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM1_DMA3) +#define DMAMAP_DMA2_SHRTIM1_DMA4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM1_DMA4) +#define DMAMAP_DMA2_SHRTIM1_DMA5 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM1_DMA5) +#define DMAMAP_DMA2_SHRTIM1_DMA6 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM1_DMA6) + +#define DMAMAP_DMA2_SHRTIM2_DMA0 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM2_DMA0) +#define DMAMAP_DMA2_SHRTIM2_DMA1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM2_DMA1) +#define DMAMAP_DMA2_SHRTIM2_DMA2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM2_DMA2) +#define DMAMAP_DMA2_SHRTIM2_DMA3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM2_DMA3) +#define DMAMAP_DMA2_SHRTIM2_DMA4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM2_DMA4) +#define DMAMAP_DMA2_SHRTIM2_DMA5 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM2_DMA5) +#define DMAMAP_DMA2_SHRTIM2_DMA6 DMAMAP_MAP(DMA2, DMAMUX1_REQ_SHRTIM2_DMA6) + +#define DMAMAP_DMA2_ATIM1_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM1_UP) +#define DMAMAP_DMA2_ATIM1_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM1_CH1) +#define DMAMAP_DMA2_ATIM1_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM1_CH2) +#define DMAMAP_DMA2_ATIM1_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM1_CH3) +#define DMAMAP_DMA2_ATIM1_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM1_CH4) +#define DMAMAP_DMA2_ATIM1_COM DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM1_COM) +#define DMAMAP_DMA2_ATIM1_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM1_TRG) + +#define DMAMAP_DMA2_ATIM2_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM2_UP) +#define DMAMAP_DMA2_ATIM2_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM2_CH1) +#define DMAMAP_DMA2_ATIM2_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM2_CH2) +#define DMAMAP_DMA2_ATIM2_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM2_CH3) +#define DMAMAP_DMA2_ATIM2_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM2_CH4) +#define DMAMAP_DMA2_ATIM2_COM DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM2_COM) +#define DMAMAP_DMA2_ATIM2_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM2_TRG) + +#define DMAMAP_DMA2_ATIM3_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM3_UP) +#define DMAMAP_DMA2_ATIM3_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM3_CH1) +#define DMAMAP_DMA2_ATIM3_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM3_CH2) +#define DMAMAP_DMA2_ATIM3_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM3_CH3) +#define DMAMAP_DMA2_ATIM3_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM3_CH4) +#define DMAMAP_DMA2_ATIM3_COM DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM3_COM) +#define DMAMAP_DMA2_ATIM3_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM3_TRG) + +#define DMAMAP_DMA2_ATIM4_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM4_UP) +#define DMAMAP_DMA2_ATIM4_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM4_CH1) +#define DMAMAP_DMA2_ATIM4_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM4_CH2) +#define DMAMAP_DMA2_ATIM4_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM4_CH3) +#define DMAMAP_DMA2_ATIM4_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM4_CH4) +#define DMAMAP_DMA2_ATIM4_COM DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM4_COM) +#define DMAMAP_DMA2_ATIM4_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_ATIM4_TRG) + +#define DMAMAP_DMA2_GTIMA1_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA1_CH1) +#define DMAMAP_DMA2_GTIMA1_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA1_CH2) +#define DMAMAP_DMA2_GTIMA1_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA1_CH3) +#define DMAMAP_DMA2_GTIMA1_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA1_CH4) +#define DMAMAP_DMA2_GTIMA1_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA1_TRG) +#define DMAMAP_DMA2_GTIMA1_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA1_UP) + +#define DMAMAP_DMA2_GTIMA2_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA2_CH1) +#define DMAMAP_DMA2_GTIMA2_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA2_CH2) +#define DMAMAP_DMA2_GTIMA2_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA2_CH3) +#define DMAMAP_DMA2_GTIMA2_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA2_CH4) +#define DMAMAP_DMA2_GTIMA2_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA2_TRG) +#define DMAMAP_DMA2_GTIMA2_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA2_UP) + +#define DMAMAP_DMA2_GTIMA3_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA3_CH1) +#define DMAMAP_DMA2_GTIMA3_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA3_CH2) +#define DMAMAP_DMA2_GTIMA3_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA3_CH3) +#define DMAMAP_DMA2_GTIMA3_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA3_CH4) +#define DMAMAP_DMA2_GTIMA3_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA3_TRG) +#define DMAMAP_DMA2_GTIMA3_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA3_UP) + +#define DMAMAP_DMA2_GTIMA4_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA4_CH1) +#define DMAMAP_DMA2_GTIMA4_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA4_CH2) +#define DMAMAP_DMA2_GTIMA4_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA4_CH3) +#define DMAMAP_DMA2_GTIMA4_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA4_CH4) +#define DMAMAP_DMA2_GTIMA4_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA4_TRG) +#define DMAMAP_DMA2_GTIMA4_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA4_UP) + +#define DMAMAP_DMA2_GTIMA5_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA5_CH1) +#define DMAMAP_DMA2_GTIMA5_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA5_CH2) +#define DMAMAP_DMA2_GTIMA5_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA5_CH3) +#define DMAMAP_DMA2_GTIMA5_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA5_CH4) +#define DMAMAP_DMA2_GTIMA5_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA5_TRG) +#define DMAMAP_DMA2_GTIMA5_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA5_UP) + +#define DMAMAP_DMA2_GTIMA6_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA6_CH1) +#define DMAMAP_DMA2_GTIMA6_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA6_CH2) +#define DMAMAP_DMA2_GTIMA6_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA6_CH3) +#define DMAMAP_DMA2_GTIMA6_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA6_CH4) +#define DMAMAP_DMA2_GTIMA6_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA6_TRG) +#define DMAMAP_DMA2_GTIMA6_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA6_UP) + +#define DMAMAP_DMA2_GTIMA7_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA7_CH1) +#define DMAMAP_DMA2_GTIMA7_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA7_CH2) +#define DMAMAP_DMA2_GTIMA7_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA7_CH3) +#define DMAMAP_DMA2_GTIMA7_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA7_CH4) +#define DMAMAP_DMA2_GTIMA7_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA7_TRG) +#define DMAMAP_DMA2_GTIMA7_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMA7_UP) + +#define DMAMAP_DMA2_GTIMB1_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB1_CH1) +#define DMAMAP_DMA2_GTIMB1_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB1_CH2) +#define DMAMAP_DMA2_GTIMB1_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB1_CH3) +#define DMAMAP_DMA2_GTIMB1_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB1_CH4) +#define DMAMAP_DMA2_GTIMB1_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB1_TRG) +#define DMAMAP_DMA2_GTIMB1_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB1_UP) + +#define DMAMAP_DMA2_GTIMB2_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB2_CH1) +#define DMAMAP_DMA2_GTIMB2_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB2_CH2) +#define DMAMAP_DMA2_GTIMB2_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB2_CH3) +#define DMAMAP_DMA2_GTIMB2_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB2_CH4) +#define DMAMAP_DMA2_GTIMB2_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB2_TRG) +#define DMAMAP_DMA2_GTIMB2_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB2_UP) + +#define DMAMAP_DMA2_GTIMB3_CH1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB3_CH1) +#define DMAMAP_DMA2_GTIMB3_CH2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB3_CH2) +#define DMAMAP_DMA2_GTIMB3_CH3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB3_CH3) +#define DMAMAP_DMA2_GTIMB3_CH4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB3_CH4) +#define DMAMAP_DMA2_GTIMB3_TRG DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB3_TRG) +#define DMAMAP_DMA2_GTIMB3_UP DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB3_UP) + +#define DMAMAP_DMA2_I2C1_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C1_RX) +#define DMAMAP_DMA2_I2C1_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C1_TX) +#define DMAMAP_DMA2_I2C2_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C2_RX) +#define DMAMAP_DMA2_I2C2_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C2_TX) +#define DMAMAP_DMA2_I2C3_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C3_RX) +#define DMAMAP_DMA2_I2C3_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C3_TX) +#define DMAMAP_DMA2_I2C4_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C4_RX) +#define DMAMAP_DMA2_I2C4_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C4_TX) +#define DMAMAP_DMA2_I2C5_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C5_RX) +#define DMAMAP_DMA2_I2C5_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C5_TX) +#define DMAMAP_DMA2_I2C6_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C6_RX) +#define DMAMAP_DMA2_I2C6_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C6_TX) +#define DMAMAP_DMA2_I2C7_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C7_RX) +#define DMAMAP_DMA2_I2C7_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C7_TX) +#define DMAMAP_DMA2_I2C8_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C8_RX) +#define DMAMAP_DMA2_I2C8_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C8_TX) +#define DMAMAP_DMA2_I2C9_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C9_RX) +#define DMAMAP_DMA2_I2C9_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C9_TX) +#define DMAMAP_DMA2_I2C10_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C10_RX) +#define DMAMAP_DMA2_I2C10_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2C10_TX) + +#define DMAMAP_DMA2_USART1_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART1_RX) +#define DMAMAP_DMA2_USART1_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART1_TX) +#define DMAMAP_DMA2_USART2_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART2_RX) +#define DMAMAP_DMA2_USART2_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART2_TX) +#define DMAMAP_DMA2_USART3_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART3_RX) +#define DMAMAP_DMA2_USART3_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART3_TX) +#define DMAMAP_DMA2_USART4_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART4_RX) +#define DMAMAP_DMA2_USART4_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART4_TX) +#define DMAMAP_DMA2_USART5_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART5_RX) +#define DMAMAP_DMA2_USART5_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART5_TX) +#define DMAMAP_DMA2_USART6_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART6_RX) +#define DMAMAP_DMA2_USART6_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART6_TX) +#define DMAMAP_DMA2_USART7_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART7_RX) +#define DMAMAP_DMA2_USART7_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART7_TX) +#define DMAMAP_DMA2_USART8_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART8_RX) +#define DMAMAP_DMA2_USART8_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_USART8_TX) + +#define DMAMAP_DMA2_UART9_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART9_RX) +#define DMAMAP_DMA2_UART9_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART9_TX) +#define DMAMAP_DMA2_UART10_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART10_RX) +#define DMAMAP_DMA2_UART10_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART10_TX) +#define DMAMAP_DMA2_UART11_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART11_RX) +#define DMAMAP_DMA2_UART11_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART11_TX) +#define DMAMAP_DMA2_UART12_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART12_RX) +#define DMAMAP_DMA2_UART12_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART12_TX) +#define DMAMAP_DMA2_UART13_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART13_RX) +#define DMAMAP_DMA2_UART13_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART13_TX) +#define DMAMAP_DMA2_UART14_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART14_RX) +#define DMAMAP_DMA2_UART14_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART14_TX) +#define DMAMAP_DMA2_UART15_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART15_RX) +#define DMAMAP_DMA2_UART15_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_UART15_TX) + +#define DMAMAP_DMA2_SPI1_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI1_RX) +#define DMAMAP_DMA2_SPI1_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI1_TX) +#define DMAMAP_DMA2_SPI2_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI2_RX) +#define DMAMAP_DMA2_SPI2_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI2_TX) +#define DMAMAP_DMA2_SPI3_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI3_RX) +#define DMAMAP_DMA2_SPI3_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI3_TX) +#define DMAMAP_DMA2_SPI4_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI4_RX) +#define DMAMAP_DMA2_SPI4_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI4_TX) +#define DMAMAP_DMA2_SPI5_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI5_RX) +#define DMAMAP_DMA2_SPI5_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI5_TX) +#define DMAMAP_DMA2_SPI6_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI6_RX) +#define DMAMAP_DMA2_SPI6_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI6_TX) +#define DMAMAP_DMA2_SPI7_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI7_RX) +#define DMAMAP_DMA2_SPI7_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_SPI7_TX) + +#define DMAMAP_DMA2_I2S1_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2S1_RX) +#define DMAMAP_DMA2_I2S1_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2S1_TX) +#define DMAMAP_DMA2_I2S2_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2S2_RX) +#define DMAMAP_DMA2_I2S2_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2S2_TX) +#define DMAMAP_DMA2_I2S3_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2S3_RX) +#define DMAMAP_DMA2_I2S3_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2S3_TX) +#define DMAMAP_DMA2_I2S4_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2S4_RX) +#define DMAMAP_DMA2_I2S4_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_I2S4_TX) + +#define DMAMAP_DMA2_LPUART1_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_LPUART1_RX) +#define DMAMAP_DMA2_LPUART1_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_LPUART1_TX) +#define DMAMAP_DMA2_LPUART2_RX DMAMAP_MAP(DMA2, DMAMUX1_REQ_LPUART2_RX) +#define DMAMAP_DMA2_LPUART2_TX DMAMAP_MAP(DMA2, DMAMUX1_REQ_LPUART2_TX) + +#define DMAMAP_DMA2_DSMU0 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DSMU0) +#define DMAMAP_DMA2_DSMU1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DSMU1) +#define DMAMAP_DMA2_DSMU2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DSMU2) +#define DMAMAP_DMA2_DSMU3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DSMU3) + +#define DMAMAP_DMA2_FDCAN1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_FDCAN1) +#define DMAMAP_DMA2_FDCAN2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_FDCAN2) +#define DMAMAP_DMA2_FDCAN3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_FDCAN3) +#define DMAMAP_DMA2_FDCAN4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_FDCAN4) +#define DMAMAP_DMA2_FDCAN5 DMAMAP_MAP(DMA2, DMAMUX1_REQ_FDCAN5) +#define DMAMAP_DMA2_FDCAN6 DMAMAP_MAP(DMA2, DMAMUX1_REQ_FDCAN6) +#define DMAMAP_DMA2_FDCAN7 DMAMAP_MAP(DMA2, DMAMUX1_REQ_FDCAN7) +#define DMAMAP_DMA2_FDCAN8 DMAMAP_MAP(DMA2, DMAMUX1_REQ_FDCAN8) + +#define DMAMAP_DMA2_CORDIC_RD DMAMAP_MAP(DMA2, DMAMUX1_REQ_CORDIC_RD) +#define DMAMAP_DMA2_CORDIC_WR DMAMAP_MAP(DMA2, DMAMUX1_REQ_CORDIC_WR) + +#define DMAMAP_DMA2_FMAU_RD DMAMAP_MAP(DMA2, DMAMUX1_REQ_FMAU_RD) +#define DMAMAP_DMA2_FMAU_WR DMAMAP_MAP(DMA2, DMAMUX1_REQ_FMAU_WR) + +#define DMAMAP_DMA2_BTIM1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_BTIM1) +#define DMAMAP_DMA2_BTIM2 DMAMAP_MAP(DMA2, DMAMUX1_REQ_BTIM2) +#define DMAMAP_DMA2_BTIM3 DMAMAP_MAP(DMA2, DMAMUX1_REQ_BTIM3) +#define DMAMAP_DMA2_BTIM4 DMAMAP_MAP(DMA2, DMAMUX1_REQ_BTIM4) + +#define DMAMAP_DMA2_GTIMB1_COM DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB1_COM) +#define DMAMAP_DMA2_GTIMB2_COM DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB2_COM) +#define DMAMAP_DMA2_GTIMB3_COM DMAMAP_MAP(DMA2, DMAMUX1_REQ_GTIMB3_COM) + +#define DMAMAP_DMA2_DAC12_0 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DAC12_0) +#define DMAMAP_DMA2_DAC12_1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DAC12_1) +#define DMAMAP_DMA2_DAC34_0 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DAC34_0) +#define DMAMAP_DMA2_DAC34_1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DAC34_1) +#define DMAMAP_DMA2_DAC56_0 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DAC56_0) +#define DMAMAP_DMA2_DAC56_1 DMAMAP_MAP(DMA2, DMAMUX1_REQ_DAC56_1) + +/* DMA3 Mappings */ +#define DMAMAP_DMA3_GEN0 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GEN0) +#define DMAMAP_DMA3_GEN1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GEN1) +#define DMAMAP_DMA3_GEN2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GEN2) +#define DMAMAP_DMA3_GEN3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GEN3) +#define DMAMAP_DMA3_GEN4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GEN4) +#define DMAMAP_DMA3_GEN5 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GEN5) +#define DMAMAP_DMA3_GEN6 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GEN6) +#define DMAMAP_DMA3_GEN7 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GEN7) + +#define DMAMAP_DMA3_ADC1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ADC1) +#define DMAMAP_DMA3_ADC2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ADC2) +#define DMAMAP_DMA3_ADC3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ADC3) + +#define DMAMAP_DMA3_SHRTIM1_DMA0 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM1_DMA0) +#define DMAMAP_DMA3_SHRTIM1_DMA1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM1_DMA1) +#define DMAMAP_DMA3_SHRTIM1_DMA2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM1_DMA2) +#define DMAMAP_DMA3_SHRTIM1_DMA3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM1_DMA3) +#define DMAMAP_DMA3_SHRTIM1_DMA4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM1_DMA4) +#define DMAMAP_DMA3_SHRTIM1_DMA5 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM1_DMA5) +#define DMAMAP_DMA3_SHRTIM1_DMA6 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM1_DMA6) + +#define DMAMAP_DMA3_SHRTIM2_DMA0 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM2_DMA0) +#define DMAMAP_DMA3_SHRTIM2_DMA1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM2_DMA1) +#define DMAMAP_DMA3_SHRTIM2_DMA2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM2_DMA2) +#define DMAMAP_DMA3_SHRTIM2_DMA3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM2_DMA3) +#define DMAMAP_DMA3_SHRTIM2_DMA4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM2_DMA4) +#define DMAMAP_DMA3_SHRTIM2_DMA5 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM2_DMA5) +#define DMAMAP_DMA3_SHRTIM2_DMA6 DMAMAP_MAP(DMA3, DMAMUX1_REQ_SHRTIM2_DMA6) + +#define DMAMAP_DMA3_ATIM1_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM1_UP) +#define DMAMAP_DMA3_ATIM1_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM1_CH1) +#define DMAMAP_DMA3_ATIM1_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM1_CH2) +#define DMAMAP_DMA3_ATIM1_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM1_CH3) +#define DMAMAP_DMA3_ATIM1_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM1_CH4) +#define DMAMAP_DMA3_ATIM1_COM DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM1_COM) +#define DMAMAP_DMA3_ATIM1_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM1_TRG) + +#define DMAMAP_DMA3_ATIM2_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM2_UP) +#define DMAMAP_DMA3_ATIM2_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM2_CH1) +#define DMAMAP_DMA3_ATIM2_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM2_CH2) +#define DMAMAP_DMA3_ATIM2_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM2_CH3) +#define DMAMAP_DMA3_ATIM2_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM2_CH4) +#define DMAMAP_DMA3_ATIM2_COM DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM2_COM) +#define DMAMAP_DMA3_ATIM2_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM2_TRG) + +#define DMAMAP_DMA3_ATIM3_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM3_UP) +#define DMAMAP_DMA3_ATIM3_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM3_CH1) +#define DMAMAP_DMA3_ATIM3_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM3_CH2) +#define DMAMAP_DMA3_ATIM3_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM3_CH3) +#define DMAMAP_DMA3_ATIM3_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM3_CH4) +#define DMAMAP_DMA3_ATIM3_COM DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM3_COM) +#define DMAMAP_DMA3_ATIM3_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM3_TRG) + +#define DMAMAP_DMA3_ATIM4_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM4_UP) +#define DMAMAP_DMA3_ATIM4_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM4_CH1) +#define DMAMAP_DMA3_ATIM4_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM4_CH2) +#define DMAMAP_DMA3_ATIM4_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM4_CH3) +#define DMAMAP_DMA3_ATIM4_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM4_CH4) +#define DMAMAP_DMA3_ATIM4_COM DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM4_COM) +#define DMAMAP_DMA3_ATIM4_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_ATIM4_TRG) + +#define DMAMAP_DMA3_GTIMA1_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA1_CH1) +#define DMAMAP_DMA3_GTIMA1_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA1_CH2) +#define DMAMAP_DMA3_GTIMA1_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA1_CH3) +#define DMAMAP_DMA3_GTIMA1_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA1_CH4) +#define DMAMAP_DMA3_GTIMA1_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA1_TRG) +#define DMAMAP_DMA3_GTIMA1_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA1_UP) + +#define DMAMAP_DMA3_GTIMA2_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA2_CH1) +#define DMAMAP_DMA3_GTIMA2_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA2_CH2) +#define DMAMAP_DMA3_GTIMA2_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA2_CH3) +#define DMAMAP_DMA3_GTIMA2_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA2_CH4) +#define DMAMAP_DMA3_GTIMA2_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA2_TRG) +#define DMAMAP_DMA3_GTIMA2_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA2_UP) + +#define DMAMAP_DMA3_GTIMA3_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA3_CH1) +#define DMAMAP_DMA3_GTIMA3_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA3_CH2) +#define DMAMAP_DMA3_GTIMA3_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA3_CH3) +#define DMAMAP_DMA3_GTIMA3_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA3_CH4) +#define DMAMAP_DMA3_GTIMA3_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA3_TRG) +#define DMAMAP_DMA3_GTIMA3_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA3_UP) + +#define DMAMAP_DMA3_GTIMA4_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA4_CH1) +#define DMAMAP_DMA3_GTIMA4_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA4_CH2) +#define DMAMAP_DMA3_GTIMA4_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA4_CH3) +#define DMAMAP_DMA3_GTIMA4_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA4_CH4) +#define DMAMAP_DMA3_GTIMA4_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA4_TRG) +#define DMAMAP_DMA3_GTIMA4_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA4_UP) + +#define DMAMAP_DMA3_GTIMA5_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA5_CH1) +#define DMAMAP_DMA3_GTIMA5_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA5_CH2) +#define DMAMAP_DMA3_GTIMA5_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA5_CH3) +#define DMAMAP_DMA3_GTIMA5_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA5_CH4) +#define DMAMAP_DMA3_GTIMA5_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA5_TRG) +#define DMAMAP_DMA3_GTIMA5_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA5_UP) + +#define DMAMAP_DMA3_GTIMA6_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA6_CH1) +#define DMAMAP_DMA3_GTIMA6_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA6_CH2) +#define DMAMAP_DMA3_GTIMA6_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA6_CH3) +#define DMAMAP_DMA3_GTIMA6_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA6_CH4) +#define DMAMAP_DMA3_GTIMA6_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA6_TRG) +#define DMAMAP_DMA3_GTIMA6_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA6_UP) + +#define DMAMAP_DMA3_GTIMA7_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA7_CH1) +#define DMAMAP_DMA3_GTIMA7_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA7_CH2) +#define DMAMAP_DMA3_GTIMA7_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA7_CH3) +#define DMAMAP_DMA3_GTIMA7_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA7_CH4) +#define DMAMAP_DMA3_GTIMA7_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA7_TRG) +#define DMAMAP_DMA3_GTIMA7_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMA7_UP) + +#define DMAMAP_DMA3_GTIMB1_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB1_CH1) +#define DMAMAP_DMA3_GTIMB1_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB1_CH2) +#define DMAMAP_DMA3_GTIMB1_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB1_CH3) +#define DMAMAP_DMA3_GTIMB1_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB1_CH4) +#define DMAMAP_DMA3_GTIMB1_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB1_TRG) +#define DMAMAP_DMA3_GTIMB1_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB1_UP) + +#define DMAMAP_DMA3_GTIMB2_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB2_CH1) +#define DMAMAP_DMA3_GTIMB2_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB2_CH2) +#define DMAMAP_DMA3_GTIMB2_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB2_CH3) +#define DMAMAP_DMA3_GTIMB2_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB2_CH4) +#define DMAMAP_DMA3_GTIMB2_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB2_TRG) +#define DMAMAP_DMA3_GTIMB2_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB2_UP) + +#define DMAMAP_DMA3_GTIMB3_CH1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB3_CH1) +#define DMAMAP_DMA3_GTIMB3_CH2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB3_CH2) +#define DMAMAP_DMA3_GTIMB3_CH3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB3_CH3) +#define DMAMAP_DMA3_GTIMB3_CH4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB3_CH4) +#define DMAMAP_DMA3_GTIMB3_TRG DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB3_TRG) +#define DMAMAP_DMA3_GTIMB3_UP DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB3_UP) + +#define DMAMAP_DMA3_I2C1_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C1_RX) +#define DMAMAP_DMA3_I2C1_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C1_TX) +#define DMAMAP_DMA3_I2C2_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C2_RX) +#define DMAMAP_DMA3_I2C2_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C2_TX) +#define DMAMAP_DMA3_I2C3_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C3_RX) +#define DMAMAP_DMA3_I2C3_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C3_TX) +#define DMAMAP_DMA3_I2C4_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C4_RX) +#define DMAMAP_DMA3_I2C4_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C4_TX) +#define DMAMAP_DMA3_I2C5_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C5_RX) +#define DMAMAP_DMA3_I2C5_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C5_TX) +#define DMAMAP_DMA3_I2C6_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C6_RX) +#define DMAMAP_DMA3_I2C6_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C6_TX) +#define DMAMAP_DMA3_I2C7_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C7_RX) +#define DMAMAP_DMA3_I2C7_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C7_TX) +#define DMAMAP_DMA3_I2C8_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C8_RX) +#define DMAMAP_DMA3_I2C8_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C8_TX) +#define DMAMAP_DMA3_I2C9_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C9_RX) +#define DMAMAP_DMA3_I2C9_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C9_TX) +#define DMAMAP_DMA3_I2C10_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C10_RX) +#define DMAMAP_DMA3_I2C10_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2C10_TX) + +#define DMAMAP_DMA3_USART1_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART1_RX) +#define DMAMAP_DMA3_USART1_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART1_TX) +#define DMAMAP_DMA3_USART2_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART2_RX) +#define DMAMAP_DMA3_USART2_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART2_TX) +#define DMAMAP_DMA3_USART3_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART3_RX) +#define DMAMAP_DMA3_USART3_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART3_TX) +#define DMAMAP_DMA3_USART4_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART4_RX) +#define DMAMAP_DMA3_USART4_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART4_TX) +#define DMAMAP_DMA3_USART5_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART5_RX) +#define DMAMAP_DMA3_USART5_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART5_TX) +#define DMAMAP_DMA3_USART6_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART6_RX) +#define DMAMAP_DMA3_USART6_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART6_TX) +#define DMAMAP_DMA3_USART7_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART7_RX) +#define DMAMAP_DMA3_USART7_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART7_TX) +#define DMAMAP_DMA3_USART8_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART8_RX) +#define DMAMAP_DMA3_USART8_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_USART8_TX) + +#define DMAMAP_DMA3_UART9_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART9_RX) +#define DMAMAP_DMA3_UART9_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART9_TX) +#define DMAMAP_DMA3_UART10_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART10_RX) +#define DMAMAP_DMA3_UART10_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART10_TX) +#define DMAMAP_DMA3_UART11_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART11_RX) +#define DMAMAP_DMA3_UART11_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART11_TX) +#define DMAMAP_DMA3_UART12_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART12_RX) +#define DMAMAP_DMA3_UART12_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART12_TX) +#define DMAMAP_DMA3_UART13_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART13_RX) +#define DMAMAP_DMA3_UART13_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART13_TX) +#define DMAMAP_DMA3_UART14_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART14_RX) +#define DMAMAP_DMA3_UART14_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART14_TX) +#define DMAMAP_DMA3_UART15_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART15_RX) +#define DMAMAP_DMA3_UART15_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_UART15_TX) + +#define DMAMAP_DMA3_SPI1_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI1_RX) +#define DMAMAP_DMA3_SPI1_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI1_TX) +#define DMAMAP_DMA3_SPI2_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI2_RX) +#define DMAMAP_DMA3_SPI2_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI2_TX) +#define DMAMAP_DMA3_SPI3_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI3_RX) +#define DMAMAP_DMA3_SPI3_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI3_TX) +#define DMAMAP_DMA3_SPI4_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI4_RX) +#define DMAMAP_DMA3_SPI4_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI4_TX) +#define DMAMAP_DMA3_SPI5_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI5_RX) +#define DMAMAP_DMA3_SPI5_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI5_TX) +#define DMAMAP_DMA3_SPI6_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI6_RX) +#define DMAMAP_DMA3_SPI6_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI6_TX) +#define DMAMAP_DMA3_SPI7_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI7_RX) +#define DMAMAP_DMA3_SPI7_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_SPI7_TX) + +#define DMAMAP_DMA3_I2S1_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2S1_RX) +#define DMAMAP_DMA3_I2S1_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2S1_TX) +#define DMAMAP_DMA3_I2S2_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2S2_RX) +#define DMAMAP_DMA3_I2S2_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2S2_TX) +#define DMAMAP_DMA3_I2S3_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2S3_RX) +#define DMAMAP_DMA3_I2S3_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2S3_TX) +#define DMAMAP_DMA3_I2S4_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2S4_RX) +#define DMAMAP_DMA3_I2S4_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_I2S4_TX) + +#define DMAMAP_DMA3_LPUART1_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_LPUART1_RX) +#define DMAMAP_DMA3_LPUART1_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_LPUART1_TX) +#define DMAMAP_DMA3_LPUART2_RX DMAMAP_MAP(DMA3, DMAMUX1_REQ_LPUART2_RX) +#define DMAMAP_DMA3_LPUART2_TX DMAMAP_MAP(DMA3, DMAMUX1_REQ_LPUART2_TX) + +#define DMAMAP_DMA3_DSMU0 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DSMU0) +#define DMAMAP_DMA3_DSMU1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DSMU1) +#define DMAMAP_DMA3_DSMU2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DSMU2) +#define DMAMAP_DMA3_DSMU3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DSMU3) + +#define DMAMAP_DMA3_FDCAN1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_FDCAN1) +#define DMAMAP_DMA3_FDCAN2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_FDCAN2) +#define DMAMAP_DMA3_FDCAN3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_FDCAN3) +#define DMAMAP_DMA3_FDCAN4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_FDCAN4) +#define DMAMAP_DMA3_FDCAN5 DMAMAP_MAP(DMA3, DMAMUX1_REQ_FDCAN5) +#define DMAMAP_DMA3_FDCAN6 DMAMAP_MAP(DMA3, DMAMUX1_REQ_FDCAN6) +#define DMAMAP_DMA3_FDCAN7 DMAMAP_MAP(DMA3, DMAMUX1_REQ_FDCAN7) +#define DMAMAP_DMA3_FDCAN8 DMAMAP_MAP(DMA3, DMAMUX1_REQ_FDCAN8) + +#define DMAMAP_DMA3_CORDIC_RD DMAMAP_MAP(DMA3, DMAMUX1_REQ_CORDIC_RD) +#define DMAMAP_DMA3_CORDIC_WR DMAMAP_MAP(DMA3, DMAMUX1_REQ_CORDIC_WR) + +#define DMAMAP_DMA3_FMAU_RD DMAMAP_MAP(DMA3, DMAMUX1_REQ_FMAU_RD) +#define DMAMAP_DMA3_FMAU_WR DMAMAP_MAP(DMA3, DMAMUX1_REQ_FMAU_WR) + +#define DMAMAP_DMA3_BTIM1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_BTIM1) +#define DMAMAP_DMA3_BTIM2 DMAMAP_MAP(DMA3, DMAMUX1_REQ_BTIM2) +#define DMAMAP_DMA3_BTIM3 DMAMAP_MAP(DMA3, DMAMUX1_REQ_BTIM3) +#define DMAMAP_DMA3_BTIM4 DMAMAP_MAP(DMA3, DMAMUX1_REQ_BTIM4) + +#define DMAMAP_DMA3_GTIMB1_COM DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB1_COM) +#define DMAMAP_DMA3_GTIMB2_COM DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB2_COM) +#define DMAMAP_DMA3_GTIMB3_COM DMAMAP_MAP(DMA3, DMAMUX1_REQ_GTIMB3_COM) + +#define DMAMAP_DMA3_DAC12_0 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DAC12_0) +#define DMAMAP_DMA3_DAC12_1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DAC12_1) +#define DMAMAP_DMA3_DAC34_0 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DAC34_0) +#define DMAMAP_DMA3_DAC34_1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DAC34_1) +#define DMAMAP_DMA3_DAC56_0 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DAC56_0) +#define DMAMAP_DMA3_DAC56_1 DMAMAP_MAP(DMA3, DMAMUX1_REQ_DAC56_1) + +/* ========================================================================== + * DMAMAP Definitions for DMAMUX2 + * ========================================================================== + */ + +/* DMA1 Mappings */ +#define DMAMAP_DMA1_GEN0 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN0) +#define DMAMAP_DMA1_GEN1 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN1) +#define DMAMAP_DMA1_GEN2 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN2) +#define DMAMAP_DMA1_GEN3 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN3) +#define DMAMAP_DMA1_GEN4 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN4) +#define DMAMAP_DMA1_GEN5 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN5) +#define DMAMAP_DMA1_GEN6 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN6) +#define DMAMAP_DMA1_GEN7 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN7) +#define DMAMAP_DMA1_GEN8 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN8) +#define DMAMAP_DMA1_GEN9 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN9) +#define DMAMAP_DMA1_GEN10 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN10) +#define DMAMAP_DMA1_GEN11 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN11) +#define DMAMAP_DMA1_GEN12 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN12) +#define DMAMAP_DMA1_GEN13 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN13) +#define DMAMAP_DMA1_GEN14 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN14) +#define DMAMAP_DMA1_GEN15 DMAMAP_MAP(DMA1, DMAMUX2_REQ_GEN15) +#define DMAMAP_DMA1_XSPI1_TX DMAMAP_MAP(DMA1, DMAMUX2_REQ_XSPI1_TX) +#define DMAMAP_DMA1_XSPI1_RX DMAMAP_MAP(DMA1, DMAMUX2_REQ_XSPI1_RX) +#define DMAMAP_DMA1_XSPI2_TX DMAMAP_MAP(DMA1, DMAMUX2_REQ_XSPI2_TX) +#define DMAMAP_DMA1_XSPI2_RX DMAMAP_MAP(DMA1, DMAMUX2_REQ_XSPI2_RX) + +/* DMA2 Mappings */ +#define DMAMAP_DMA2_GEN0 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN0) +#define DMAMAP_DMA2_GEN1 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN1) +#define DMAMAP_DMA2_GEN2 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN2) +#define DMAMAP_DMA2_GEN3 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN3) +#define DMAMAP_DMA2_GEN4 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN4) +#define DMAMAP_DMA2_GEN5 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN5) +#define DMAMAP_DMA2_GEN6 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN6) +#define DMAMAP_DMA2_GEN7 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN7) +#define DMAMAP_DMA2_GEN8 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN8) +#define DMAMAP_DMA2_GEN9 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN9) +#define DMAMAP_DMA2_GEN10 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN10) +#define DMAMAP_DMA2_GEN11 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN11) +#define DMAMAP_DMA2_GEN12 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN12) +#define DMAMAP_DMA2_GEN13 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN13) +#define DMAMAP_DMA2_GEN14 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN14) +#define DMAMAP_DMA2_GEN15 DMAMAP_MAP(DMA2, DMAMUX2_REQ_GEN15) +#define DMAMAP_DMA2_XSPI1_TX DMAMAP_MAP(DMA2, DMAMUX2_REQ_XSPI1_TX) +#define DMAMAP_DMA2_XSPI1_RX DMAMAP_MAP(DMA2, DMAMUX2_REQ_XSPI1_RX) +#define DMAMAP_DMA2_XSPI2_TX DMAMAP_MAP(DMA2, DMAMUX2_REQ_XSPI2_TX) +#define DMAMAP_DMA2_XSPI2_RX DMAMAP_MAP(DMA2, DMAMUX2_REQ_XSPI2_RX) + +/* DMA3 Mappings */ +#define DMAMAP_DMA3_2GEN0 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN0) +#define DMAMAP_DMA3_2GEN1 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN1) +#define DMAMAP_DMA3_2GEN2 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN2) +#define DMAMAP_DMA3_2GEN3 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN3) +#define DMAMAP_DMA3_2GEN4 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN4) +#define DMAMAP_DMA3_2GEN5 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN5) +#define DMAMAP_DMA3_2GEN6 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN6) +#define DMAMAP_DMA3_2GEN7 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN7) +#define DMAMAP_DMA3_2GEN8 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN8) +#define DMAMAP_DMA3_2GEN9 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN9) +#define DMAMAP_DMA3_2GEN10 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN10) +#define DMAMAP_DMA3_2GEN11 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN11) +#define DMAMAP_DMA3_2GEN12 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN12) +#define DMAMAP_DMA3_2GEN13 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN13) +#define DMAMAP_DMA3_2GEN14 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN14) +#define DMAMAP_DMA3_2GEN15 DMAMAP_MAP(DMA3, DMAMUX2_REQ_GEN15) +#define DMAMAP_DMA3_XSPI1_TX DMAMAP_MAP(DMA3, DMAMUX2_REQ_XSPI1_TX) +#define DMAMAP_DMA3_XSPI1_RX DMAMAP_MAP(DMA3, DMAMUX2_REQ_XSPI1_RX) +#define DMAMAP_DMA3_XSPI2_TX DMAMAP_MAP(DMA3, DMAMUX2_REQ_XSPI2_TX) +#define DMAMAP_DMA3_XSPI2_RX DMAMAP_MAP(DMA3, DMAMUX2_REQ_XSPI2_RX) + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_DMAMUX_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h76x_gpio.h b/arch/arm/src/n32h7/hardware/n32h76x_gpio.h new file mode 100644 index 0000000000000..099ab93e96efd --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h76x_gpio.h @@ -0,0 +1,415 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h76x_gpio.h + * + * Licensed 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_N32H7_HARDWARE_N32H76X_GPIO_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define N32_GPIO_MODER_OFFSET 0x0000 /* Port mode register */ +#define N32_GPIO_OTYPER_OFFSET 0x0004 /* Output type register */ +#define N32_GPIO_SR_OFFSET 0x0008 /* Output speed register */ +#define N32_GPIO_PUPD_OFFSET 0x000c /* Pull-up/pull-down register */ +#define N32_GPIO_PID_OFFSET 0x0010 /* Input data register */ +#define N32_GPIO_POD_OFFSET 0x0014 /* Output data register */ +#define N32_GPIO_PBSC_OFFSET 0x0018 /* Bit set/reset register */ +#define N32_GPIO_PLOCK_OFFSET 0x001c /* Configuration lock register */ +#define N32_GPIO_AFL_OFFSET 0x0020 /* Alternate function low register */ +#define N32_GPIO_AFH_OFFSET 0x0024 /* Alternate function high register */ +#define N32_GPIO_PBC_OFFSET 0x0028 /* Bit clear register */ +#define N32_GPIO_DS_OFFSET 0x002c /* Driver strength configuration register */ + +/* Register Addresses *******************************************************/ + +#if N32H7_NGPIO > 0 +# define N32_GPIOA_MODER (N32_GPIOA_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOA_OTYPER (N32_GPIOA_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOA_SR (N32_GPIOA_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOA_PUPD (N32_GPIOA_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOA_PID (N32_GPIOA_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOA_POD (N32_GPIOA_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOA_PBSC (N32_GPIOA_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOA_PLOCK (N32_GPIOA_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOA_AFL (N32_GPIOA_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOA_AFH (N32_GPIOA_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOA_PBC (N32_GPIOA_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOA_DS (N32_GPIOA_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 1 +# define N32_GPIOB_MODER (N32_GPIOB_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOB_OTYPER (N32_GPIOB_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOB_SR (N32_GPIOB_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOB_PUPD (N32_GPIOB_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOB_PID (N32_GPIOB_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOB_POD (N32_GPIOB_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOB_PBSC (N32_GPIOB_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOB_PLOCK (N32_GPIOB_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOB_AFL (N32_GPIOB_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOB_AFH (N32_GPIOB_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOB_PBC (N32_GPIOB_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOB_DS (N32_GPIOB_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 2 +# define N32_GPIOC_MODER (N32_GPIOC_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOC_OTYPER (N32_GPIOC_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOC_SR (N32_GPIOC_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOC_PUPD (N32_GPIOC_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOC_PID (N32_GPIOC_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOC_POD (N32_GPIOC_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOC_PBSC (N32_GPIOC_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOC_PLOCK (N32_GPIOC_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOC_AFL (N32_GPIOC_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOC_AFH (N32_GPIOC_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOC_PBC (N32_GPIOC_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOC_DS (N32_GPIOC_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 3 +# define N32_GPIOD_MODER (N32_GPIOD_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOD_OTYPER (N32_GPIOD_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOD_SR (N32_GPIOD_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOD_PUPD (N32_GPIOD_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOD_PID (N32_GPIOD_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOD_POD (N32_GPIOD_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOD_PBSC (N32_GPIOD_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOD_PLOCK (N32_GPIOD_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOD_AFL (N32_GPIOD_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOD_AFH (N32_GPIOD_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOD_PBC (N32_GPIOD_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOD_DS (N32_GPIOD_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 4 +# define N32_GPIOE_MODER (N32_GPIOE_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOE_OTYPER (N32_GPIOE_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOE_SR (N32_GPIOE_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOE_PUPD (N32_GPIOE_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOE_PID (N32_GPIOE_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOE_POD (N32_GPIOE_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOE_PBSC (N32_GPIOE_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOE_PLOCK (N32_GPIOE_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOE_AFL (N32_GPIOE_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOE_AFH (N32_GPIOE_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOE_PBC (N32_GPIOE_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOE_DS (N32_GPIOE_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 5 +# define N32_GPIOF_MODER (N32_GPIOF_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOF_OTYPER (N32_GPIOF_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOF_SR (N32_GPIOF_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOF_PUPD (N32_GPIOF_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOF_PID (N32_GPIOF_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOF_POD (N32_GPIOF_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOF_PBSC (N32_GPIOF_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOF_PLOCK (N32_GPIOF_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOF_AFL (N32_GPIOF_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOF_AFH (N32_GPIOF_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOF_PBC (N32_GPIOF_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOF_DS (N32_GPIOF_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 6 +# define N32_GPIOG_MODER (N32_GPIOG_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOG_OTYPER (N32_GPIOG_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOG_SR (N32_GPIOG_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOG_PUPD (N32_GPIOG_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOG_PID (N32_GPIOG_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOG_POD (N32_GPIOG_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOG_PBSC (N32_GPIOG_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOG_PLOCK (N32_GPIOG_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOG_AFL (N32_GPIOG_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOG_AFH (N32_GPIOG_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOG_PBC (N32_GPIOG_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOG_DS (N32_GPIOG_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 7 +# define N32_GPIOH_MODER (N32_GPIOH_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOH_OTYPER (N32_GPIOH_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOH_SR (N32_GPIOH_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOH_PUPD (N32_GPIOH_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOH_PID (N32_GPIOH_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOH_POD (N32_GPIOH_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOH_PBSC (N32_GPIOH_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOH_PLOCK (N32_GPIOH_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOH_AFL (N32_GPIOH_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOH_AFH (N32_GPIOH_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOH_PBC (N32_GPIOH_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOH_DS (N32_GPIOH_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 8 +# define N32_GPIOI_MODER (N32_GPIOI_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOI_OTYPER (N32_GPIOI_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOI_SR (N32_GPIOI_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOI_PUPD (N32_GPIOI_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOI_PID (N32_GPIOI_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOI_POD (N32_GPIOI_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOI_PBSC (N32_GPIOI_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOI_PLOCK (N32_GPIOI_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOI_AFL (N32_GPIOI_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOI_AFH (N32_GPIOI_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOI_PBC (N32_GPIOI_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOI_DS (N32_GPIOI_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 9 +# define N32_GPIOJ_MODER (N32_GPIOJ_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOJ_OTYPER (N32_GPIOJ_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOJ_SR (N32_GPIOJ_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOJ_PUPD (N32_GPIOJ_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOJ_PID (N32_GPIOJ_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOJ_POD (N32_GPIOJ_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOJ_PBSC (N32_GPIOJ_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOJ_PLOCK (N32_GPIOJ_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOJ_AFL (N32_GPIOJ_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOJ_AFH (N32_GPIOJ_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOJ_PBC (N32_GPIOJ_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOJ_DS (N32_GPIOJ_BASE + N32_GPIO_DS_OFFSET) +#endif + +#if N32H7_NGPIO > 10 +# define N32_GPIOK_MODER (N32_GPIOK_BASE + N32_GPIO_MODER_OFFSET) +# define N32_GPIOK_OTYPER (N32_GPIOK_BASE + N32_GPIO_OTYPER_OFFSET) +# define N32_GPIOK_SR (N32_GPIOK_BASE + N32_GPIO_SR_OFFSET) +# define N32_GPIOK_PUPD (N32_GPIOK_BASE + N32_GPIO_PUPD_OFFSET) +# define N32_GPIOK_PID (N32_GPIOK_BASE + N32_GPIO_PID_OFFSET) +# define N32_GPIOK_POD (N32_GPIOK_BASE + N32_GPIO_POD_OFFSET) +# define N32_GPIOK_PBSC (N32_GPIOK_BASE + N32_GPIO_PBSC_OFFSET) +# define N32_GPIOK_PLOCK (N32_GPIOK_BASE + N32_GPIO_PLOCK_OFFSET) +# define N32_GPIOK_AFL (N32_GPIOK_BASE + N32_GPIO_AFL_OFFSET) +# define N32_GPIOK_AFH (N32_GPIOK_BASE + N32_GPIO_AFH_OFFSET) +# define N32_GPIOK_PBC (N32_GPIOK_BASE + N32_GPIO_PBC_OFFSET) +# define N32_GPIOK_DS (N32_GPIOK_BASE + N32_GPIO_DS_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) * 2) +#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 slew rate register */ + +#define GPIO_SR_SLOW_SLEW(n) (1 << (n)) /* 1=Slow slew rate */ +#define GPIO_SR_FAST_SLEW(n) (0) /* 0=Fast slew rate */ + +/* 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_PID(n) (1 << (n)) + +/* GPIO port output data register */ + +#define GPIO_POD(n) (1 << (n)) + +/* GPIO port bit set/reset register */ + +#define GPIO_PBSC_SET(n) (1 << (n)) +#define GPIO_PBSC_RESET(n) (1 << (n + 16)) + +/* GPIO port configuration lock register */ + +#define GPIO_PLOCKR(n) (1 << (n)) +#define GPIO_PLOCKK (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 data bit clear register */ + +#define GPIO_PBC(n) (1 << (n)) + +/* GPIO port driver strength configuration register */ + +#define GPIO_DS_2mA (0) /* Drive strength is 2mA */ +#define GPIO_DS_4mA (2) /* Drive strength is 4mA */ +#define GPIO_DS_8mA (1) /* Drive strength is 8mA */ +#define GPIO_DS_12mA (3) /* Drive strength is 12mA */ + +#define GPIO_DS_SHIFT(n) ((n) << 1) +#define GPIO_DS_MASK(n) (3 << GPIO_DS_SHIFT(n)) + +#define GPIO_DS_SHIFT0 (0) +#define GPIO_DS_MASK0 (3 << GPIO_DS_SHIFT0) +#define GPIO_DS_SHIFT1 (2) +#define GPIO_DS_MASK1 (3 << GPIO_DS_SHIFT1) +#define GPIO_DS_SHIFT2 (4) +#define GPIO_DS_MASK2 (3 << GPIO_DS_SHIFT2) +#define GPIO_DS_SHIFT3 (6) +#define GPIO_DS_MASK3 (3 << GPIO_DS_SHIFT3) +#define GPIO_DS_SHIFT4 (8) +#define GPIO_DS_MASK4 (3 << GPIO_DS_SHIFT4) +#define GPIO_DS_SHIFT5 (10) +#define GPIO_DS_MASK5 (3 << GPIO_DS_SHIFT5) +#define GPIO_DS_SHIFT6 (12) +#define GPIO_DS_MASK6 (3 << GPIO_DS_SHIFT6) +#define GPIO_DS_SHIFT7 (14) +#define GPIO_DS_MASK7 (3 << GPIO_DS_SHIFT7) +#define GPIO_DS_SHIFT8 (16) +#define GPIO_DS_MASK8 (3 << GPIO_DS_SHIFT8) +#define GPIO_DS_SHIFT9 (18) +#define GPIO_DS_MASK9 (3 << GPIO_DS_SHIFT9) +#define GPIO_DS_SHIFT10 (20) +#define GPIO_DS_MASK10 (3 << GPIO_DS_SHIFT10) +#define GPIO_DS_SHIFT11 (22) +#define GPIO_DS_MASK11 (3 << GPIO_DS_SHIFT11) +#define GPIO_DS_SHIFT12 (24) +#define GPIO_DS_MASK12 (3 << GPIO_DS_SHIFT12) +#define GPIO_DS_SHIFT13 (26) +#define GPIO_DS_MASK13 (3 << GPIO_DS_SHIFT13) +#define GPIO_DS_SHIFT14 (28) +#define GPIO_DS_MASK14 (3 << GPIO_DS_SHIFT14) +#define GPIO_DS_SHIFT15 (30) +#define GPIO_DS_MASK15 (3 << GPIO_DS_SHIFT15) + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_GPIO_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h76x_memorymap.h b/arch/arm/src/n32h7/hardware/n32h76x_memorymap.h new file mode 100644 index 0000000000000..a6fb6a638e573 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h76x_memorymap.h @@ -0,0 +1,284 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h76x_memorymap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + + #ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_MEMORYMAP_H + #define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* N32H76X Address Blocks ***************************************************/ + +#define N32_VECTOR_SIZE 0x000003E4 + +#define N32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb CODE block */ +#define N32_RAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb RAM block */ +#define N32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb Peripheral blocks */ +#define N32_EXTMEM_BASE 0x60000000 /* 0x60000000-0x9fffffff: 1Gb External memory blocks */ +#define N32_EXTDEV_BASE 0xa0000000 /* 0xa0000000-0xdfffffff: 1Gb External device blocks */ +#define N32_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M7 block */ + +#define N32_PERIPH_SIZE 0x20000000 +#define N32_ITCRAM_SIZE 0x00020000 +#define N32_DTCRAM_SIZE 0x000E0000 + +#define N32_REGION_MASK 0xff000000 +#define N32_IS_RAM(a) ((((uint32_t)(a)) & N32_REGION_MASK) == N32_RAM_BASE) +#define N32_IS_EXTMEM(a) ((((uint32_t)(a)) & N32_REGION_MASK) == N32_EXTMEM_BASE) + +/* Code Base Addresses ******************************************************/ + +#define N32_ITCRAM_BASE 0x00000000 /* 0x00000000-0x0001ffff: ITCM */ +#define N32_FLASH_BANK1 0x15000000 /* 0x15000000-0x151fffff: FLASH memory 1 */ +#define N32_FLASH_BANK2 0x17000000 /* 0x17000000-0x18ffffff: FLASH memory 2 */ +#define N32_FLASH_BASE N32_FLASH_BANK1 + +#if defined(CONFIG_N32H7_FLASH_CONFIG_I) + #define N32_FLASH_SIZE (0x00200000-0x00020000) +#endif +#if defined(CONFIG_N32H7_FLASH_CONFIG_K) + #define N32_FLASH_SIZE (0x00400000-0x00020000) +#endif + +/* SRAM Base Addresses ******************************************************/ + +#define N32_DTCRAM_BASE 0x20000000 /* 0x20000000-0x200cffff: DTCM-RAM on TCM interface */ +#define N32_AXISRAM_BASE 0x24000000 /* 0x24000000-0x2401ffff: System AXI SRAM */ + +#ifdef CONFIG_ARCH_CHIP_N32H7_CORTEXM7 +# define N32_AHBSRAM_BASE 0x30000000 /* 0x30000000-0x30057fff: System SRAM1 */ +#else +# error "CONFIG_ARCH_CHIP_N32H7_CORTEXM7 not defined" +#endif +#define N32_BSRAM_BASE 0x38000000 /* 0x38800000-0x38800fff: System Backup SRAM */ + +/* Peripheral Base Addresses ************************************************/ + +#define N32_PREGION_MASK 0xff000000 +#define N32_D2_BASE 0x40000000 /* 0x40000000-0x401403ff: D2 domain */ +# define N32_APB1_BASE 0x40000000 /* 0x40000000-0x4003ffff: APB1 */ +# define N32_AHB1_BASE 0x40040000 /* 0x40040000-0x400affff: AHB1 */ +# define N32_AHB9_BASE 0x400b0000 /* 0x400b0000-0x400cffff: AHB9 */ +# define N32_APB2_BASE 0x400d0000 /* 0x400d0000-0x400effff: APB2 */ +# define N32_AHB2_BASE 0x400f0000 /* 0x400f0000-0x401403ff: AHB2 */ +#define N32_D1_BASE 0x50000000 /* 0x50000000-0x51120fff: D1 domain */ +# define N32_APB3_BASE 0x50000000 /* 0x50000000-0x50090fff: APB6 */ +# define N32_AHB3_BASE 0x51000000 /* 0x51000000-0x51120fff: AHB6 */ +#define N32_D3_BASE 0x58000000 /* 0x58000000-0x58036fff: D3 domain */ +# define N32_APB4_BASE 0x58000000 /* 0x58000000-0x58005bff: APB5 */ +# define N32_AHB4_BASE 0x58030000 /* 0x58030000-0x58036fff: AHB5 */ + +/* APB1 Base Addresses ******************************************************/ + +#define N32_FDCAN1_BASE 0x40000000 +#define N32_FDCAN2_BASE 0x40000400 +#define N32_FDCAN5_BASE 0x40000800 +#define N32_FDCAN6_BASE 0x40000c00 +#define N32_AHB_ICACHE_BASE 0x40008000 +#define N32_AHB_DCACHE_BASE 0x40009000 +#define N32_BTIMER1_BASE 0x4000a000 +#define N32_BTIMER2_BASE 0x4000a400 +#define N32_GTIMERB1_BASE 0x4000a800 +#define N32_GTIMERB2_BASE 0x4000ac00 +#define N32_GTIMERB3_BASE 0x4000b000 +#define N32_GTIMERA4_BASE 0x4000b400 +#define N32_GTIMERA5_BASE 0x4000b800 +#define N32_GTIMERA6_BASE 0x4000bc00 +#define N32_GTIMERA7_BASE 0x4000c000 +#define N32_USART1_BASE 0x4000c400 +#define N32_USART2_BASE 0x4000c800 +#define N32_USART3_BASE 0x4000cc00 +#define N32_USART4_BASE 0x4000d000 +#define N32_UART9_BASE 0x4000d400 +#define N32_UART10_BASE 0x4000d800 +#define N32_UART11_BASE 0x4000dc00 +#define N32_UART12_BASE 0x4000e000 +#define N32_SPI3_BASE 0x4000e400 +#define N32_I2C1_BASE 0x4000e800 +#define N32_I2C2_BASE 0x4000ec00 +#define N32_I2C3_BASE 0x4000f000 +#define N32_I2S3_BASE 0x4000f400 +#define N32_I2S4_BASE 0x4000f800 +#define N32_DAC12_BASE 0x4000fc00 +#define N32_WWDG2_BASE 0x40010000 +#define N32_BTIMER3_BASE 0x40010800 +#define N32_BTIMER4_BASE 0x40010c00 + +/* AHB1 Base Addresses ******************************************************/ + +#define N32_ETH2_BASE 0x40042000 +#define N32_ADC1_BASE 0x40044000 +#define N32_ADC2_BASE 0x40044400 +#define N32_ADC3_BASE 0x40044800 +#define N32_AHB_CACHE_PARMON_BASE 0x40045000 +#define N32_DMAMUX1_BASE 0x40046400 +#define N32_DMA1_BASE 0x40046800 +#define N32_DMA2_BASE 0x40046C00 +#define N32_DMA3_BASE 0x40047000 +#define N32_SDMMC2_CFG_BASE 0x4004A000 +#define N32_SDHOST2_BASE 0x40050000 +#define N32_USBCTRL2_BASE 0x40060000 +#define N32_USBCTRL2_WRAPPER_BASE 0x400A0000 + +/* AHB9 Base Addresses ******************************************************/ + +#define N32_ESC_BASE 0x400B0000 +#define N32_ESC_WRAPPER_BASE 0x400C0000 + +/* APB2 Base Addresses ******************************************************/ + +#define N32_FDCAN3_BASE 0x400D0000 +#define N32_FDCAN4_BASE 0x400D0400 +#define N32_FDCAN7_BASE 0x400D0800 +#define N32_FDCAN8_BASE 0x400D0C00 +#define N32_SHRTIM1_BASE 0x400D8000 +#define N32_SHRTIM2_BASE 0x400D9000 +#define N32_DSMU_BASE 0x400DA000 +#define N32_ATIMER1_BASE 0x400DB000 +#define N32_ATIMER2_BASE 0x400DB400 +#define N32_I2S1_BASE 0x400DB800 +#define N32_I2S2_BASE 0x400DBC00 +#define N32_SPI1_BASE 0x400DC000 +#define N32_SPI2_BASE 0x400DC400 +#define N32_GTIMERA1_BASE 0x400DC800 +#define N32_GTIMERA2_BASE 0x400DCC00 +#define N32_GTIMERA3_BASE 0x400DD000 +#define N32_I2C4_BASE 0x400DD400 +#define N32_I2C5_BASE 0x400DD800 +#define N32_I2C6_BASE 0x400DDC00 +#define N32_USART5_BASE 0x400DE000 +#define N32_USART6_BASE 0x400DE400 +#define N32_USART7_BASE 0x400DE800 +#define N32_USART8_BASE 0x400DEC00 +#define N32_UART13_BASE 0x400DF000 +#define N32_UART14_BASE 0x400DF400 +#define N32_UART15_BASE 0x400DF800 + +/* AHB2 Base Addresses ******************************************************/ + +#define N32_ECCMON2_BASE 0x400F0000 +#define N32_CORDIC_BASE 0x400F1000 +#define N32_FMAC_BASE 0x400F1400 +#define N32_DAC34_BASE 0x400F1800 +#define N32_DAC56_BASE 0x400F1C00 +#define N32_SDPU_BASE 0x400F2000 +#define N32_ETH1_BASE 0x400F4000 +#define N32_SEMA4_BASE 0x400F6000 +#define N32_DCMUA_BASE 0x400F7000 +#define N32_DCMUB_BASE 0x400F8000 +#define N32_USBCTRL1_BASE 0x40100000 +#define N32_USBCTRL1_WRAPPER_BASE 0x40140000 + +/* APB6 Base Addresses ******************************************************/ + +#define N32_DSIHOST_BASE 0x50000000 +#define N32_2_5D_GPU_BASE 0x50040000 +#define N32_DVP1_BASE 0x50048000 +#define N32_DVP2_BASE 0x50049000 +#define N32_LCDC_BASE 0x5004a000 +#define N32_WWDG1_BASE 0x5004a800 +#define N32_DSIHOST_WRAPPER_BASE 0x5004ac00 +#define N32_TCMSRAMC_BASE 0x5004b000 +#define N32_FEMC_BASE 0x5004c000 +#define N32_JPEG_ENC_BASE 0x50060000 +#define N32_JPEG_RBC_BASE 0x50070000 +#define N32_JPEG_H2P_SGDMA_BASE 0x50070400 +#define N32_JPEG_DEC_BASE 0x50080000 +#define N32_JPEG_BRC_BASE 0x50090000 +#define N32_JPEG_P2H_SGDMA_BASE 0x50090400 +#define N32_JPEG_CTRL_BASE 0x50090800 + +/* AHB6 Base Addresses ******************************************************/ + +#define N32_GPV_BASE 0x51000000 +#define N32_xSPI1_BASE 0x51100000 +#define N32_xSPI2_BASE 0x51101000 +#define N32_MDMA_BASE 0x51102000 +#define N32_ECCMON1_BASE 0x51104000 +#define N32_MMU_BASE 0x51105000 +#define N32_SDRAM_BASE 0x51106000 +#define N32_SDMMC1_CFG_BASE 0x51107000 +#define N32_SDHOST1_BASE 0x51110000 +#define N32_OTPC_BASE 0x51118000 +#define N32_DMAMUX2_BASE 0x51120000 +#define N32_MDMA_WRAPPER_BASE 0x51120800 + +/* APB5 Base Addresses ******************************************************/ +#define N32_EXTI_WKUP_BASE 0x58000000 +#define N32_AFEC_BASE 0x58000400 +#define N32_LPUART1_BASE 0x58000800 +#define N32_LPUART2_BASE 0x58000C00 +#define N32_LPTIMER1_BASE 0x58001000 +#define N32_LPTIMER_BASE 0x58001400 +#define N32_LPTIMER3_BASE 0x58001800 +#define N32_LPTIMER4_BASE 0x58001C00 +#define N32_SPI4_BASE 0x58002000 +#define N32_SPI5_BASE 0x58002400 +#define N32_SPI6_BASE 0x58002800 +#define N32_SPI7_BASE 0x58002C00 +#define N32_I2C7_BASE 0x58003000 +#define N32_I2C8_BASE 0x58003400 +#define N32_I2C9_BASE 0x58003800 +#define N32_I2C10_BASE 0x58003C00 +#define N32_ATIMER3_BASE 0x58004000 +#define N32_ATIMER4_BASE 0x58004400 +#define N32_COMPCTRL_BASE 0x58004800 +#define N32_IWDG1_BASE 0x58004C00 +#define N32_IWDG2_BASE 0x58005000 +#define N32_RTC_BASE 0x58005400 +#define N32_LPTIMER5_BASE 0x58005800 + +/* AHB5 Base Addresses ******************************************************/ +#define N32_AFIO_BASE 0x58032400 +#define N32_CRC_BASE 0x58032000 +#define N32_PWR_BASE 0x58031000 +#define N32_RCC_BASE 0x58030000 +#define N32_GPIOA_BASE 0x58032800 +#define N32_GPIOB_BASE 0x58032C00 +#define N32_GPIOC_BASE 0x58033000 +#define N32_GPIOD_BASE 0x58033400 +#define N32_GPIOE_BASE 0x58033800 +#define N32_GPIOF_BASE 0x58033C00 +#define N32_GPIOG_BASE 0x58034000 +#define N32_GPIOH_BASE 0x58034400 +#define N32_GPIOI_BASE 0x58034800 +#define N32_GPIOJ_BASE 0x58034C00 +#define N32_GPIOK_BASE 0x58035000 +#define N32_ECCMON3_BASE 0x58036000 + +#define N32_SYSMEM_UID 0x0238 + +/* The DBGMCU registers are accessible to the debugger via the APB-D bus + * at base address 0xe00e1000. They are also accessible by the processor + * core at base address 0x58035400. + */ + +#define N32_DEBUGMCU_BASE 0x58035400 + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_MEMORYMAP_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h76x_pinmap.h b/arch/arm/src/n32h7/hardware/n32h76x_pinmap.h new file mode 100644 index 0000000000000..5cc9726332ab9 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h76x_pinmap.h @@ -0,0 +1,1225 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h76x_pinmap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_PINMAP_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_PINMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "n32_gpio.h" + +#if defined(CONFIG_N32H7_N32H76X) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Alternate Pin Functions. + * All members of the N32H76|7xxx family share the same pin multiplexing + *(although they may differ in the pins physically available). + * + * 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 CAN1_RX connects via PA11 on some board, then the following definitions + * should appear in the board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configure PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as + * frequency, open-drain/push-pull, and pull-up/down! Just the basics are + * defined for most pins in this file. + */ + +/* MCO */ +#define GPIO_MCO1_0 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN8) +#define GPIO_MCO2_0 (GPIO_ALT|GPIO_AF15|GPIO_PORTC|GPIO_PIN9) + +/* Timestamp */ +#define GPIO_TIMESTAMP_TRIG_IN_0 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN13) +#define GPIO_TIMESTAMP_TRIG_IN_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN14) +#define GPIO_TIMESTAMP_TRIG_IN_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTC|GPIO_PIN15) + +/* JTAG/SWD */ +#define GPIO_JTMS_SWDIO_0 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN13) +#define GPIO_JTCK_SWCLK_0 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN14) +#define GPIO_JTDI_0 (GPIO_ALT|GPIO_AF15|GPIO_PORTA|GPIO_PIN15) +#define GPIO_JTDO_0 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN3) +#define GPIO_NJTRST_0 (GPIO_ALT|GPIO_AF15|GPIO_PORTB|GPIO_PIN4) + +/* SHRTIM1 */ +#define GPIO_SHRTIM1_CHA1_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SHRTIM1_CHA2_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_SHRTIM1_CHB1_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_SHRTIM1_CHB2_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_SHRTIM1_CHC1_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_SHRTIM1_CHC2_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_SHRTIM1_CHD1_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_SHRTIM1_CHD2_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_SHRTIM1_CHE1_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN6) +#define GPIO_SHRTIM1_CHE2_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN7) +#define GPIO_SHRTIM1_CHF1_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN4) +#define GPIO_SHRTIM1_CHF2_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN5) +#define GPIO_SHRTIM1_SCIN_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_SHRTIM1_SCIN_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN0) +#define GPIO_SHRTIM1_SCOUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SHRTIM1_SCOUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN1) + +/* SHRTIM2 */ +#define GPIO_SHRTIM2_CHA1_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN0) +#define GPIO_SHRTIM2_CHA2_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN1) +#define GPIO_SHRTIM2_CHB1_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) +#define GPIO_SHRTIM2_CHB2_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN3) +#define GPIO_SHRTIM2_CHC1_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN4) +#define GPIO_SHRTIM2_CHC2_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN5) +#define GPIO_SHRTIM2_CHD1_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN2) +#define GPIO_SHRTIM2_CHD2_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN3) +#define GPIO_SHRTIM2_CHE1_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN4) +#define GPIO_SHRTIM2_CHE2_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN5) +#define GPIO_SHRTIM2_CHF1_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN14) +#define GPIO_SHRTIM2_CHF2_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN15) +#define GPIO_SHRTIM2_SCIN_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN8) +#define GPIO_SHRTIM2_SCIN_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN2) +#define GPIO_SHRTIM2_SCOUT_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN9) +#define GPIO_SHRTIM2_SCOUT_1 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN3) + +/* ATIM1 */ +#define GPIO_ATIM1_ETR_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN12) +#define GPIO_ATIM1_ETR_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN5) +#define GPIO_ATIM1_ETR_2 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN7) +#define GPIO_ATIM1_BKIN1_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ATIM1_BKIN1_1 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN15) +#define GPIO_ATIM1_BKIN1_2 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ATIM1_BKIN2_0 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN6) +#define GPIO_ATIM1_BKIN2_1 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN4) +#define GPIO_ATIM1_CH1IN_0 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN8) +#define GPIO_ATIM1_CH1IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN9) +#define GPIO_ATIM1_CH1OUT_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_ATIM1_CH1OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9) +#define GPIO_ATIM1_CH2IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN9) +#define GPIO_ATIM1_CH2IN_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN11) +#define GPIO_ATIM1_CH2OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_ATIM1_CH2OUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11) +#define GPIO_ATIM1_CH3IN_0 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN10) +#define GPIO_ATIM1_CH3IN_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN13) +#define GPIO_ATIM1_CH3OUT_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_ATIM1_CH3OUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13) +#define GPIO_ATIM1_CH4IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN11) +#define GPIO_ATIM1_CH4IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN14) +#define GPIO_ATIM1_CH4OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_ATIM1_CH4OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14) +#define GPIO_ATIM1_CH1NOUT_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ATIM1_CH1NOUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ATIM1_CH1NOUT_2 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN8) +#define GPIO_ATIM1_CH2NOUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ATIM1_CH2NOUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_ATIM1_CH2NOUT_2 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN10) +#define GPIO_ATIM1_CH3NOUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ATIM1_CH3NOUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_ATIM1_CH3NOUT_2 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN12) +#define GPIO_ATIM1_CH4NOUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN2) +#define GPIO_ATIM1_CH4NOUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN10) +#define GPIO_ATIM1_CH4NOUT_2 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) + +/* ATIM2 */ +#define GPIO_ATIM2_ETR_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ATIM2_ETR_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN8) +#define GPIO_ATIM2_ETR_2 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN3) +#define GPIO_ATIM2_BKIN1_0 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ATIM2_BKIN1_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN2) +#define GPIO_ATIM2_BKIN1_2 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN4) +#define GPIO_ATIM2_BKIN2_0 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN3) +#define GPIO_ATIM2_BKIN2_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN8) +#define GPIO_ATIM2_CH1IN_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_ATIM2_CH1IN_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN5) +#define GPIO_ATIM2_CH1OUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_ATIM2_CH1OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5) +#define GPIO_ATIM2_CH2IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN6) +#define GPIO_ATIM2_CH2IN_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_ATIM2_CH2OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6) +#define GPIO_ATIM2_CH2OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_ATIM2_CH3IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_ATIM2_CH3IN_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN7) +#define GPIO_ATIM2_CH3OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_ATIM2_CH3OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7) +#define GPIO_ATIM2_CH4IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN2) +#define GPIO_ATIM2_CH4IN_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ATIM2_CH4OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2) +#define GPIO_ATIM2_CH4OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ATIM2_CH1NOUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ATIM2_CH1NOUT_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ATIM2_CH1NOUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN1) +#define GPIO_ATIM2_CH2NOUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN13) +#define GPIO_ATIM2_CH2NOUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ATIM2_CH2NOUT_2 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_ATIM2_CH3NOUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ATIM2_CH3NOUT_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_ATIM2_CH3NOUT_2 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN15) +#define GPIO_ATIM2_CH4NOUT_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN2) +#define GPIO_ATIM2_CH4NOUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0) + +/* ATIM3 */ +#define GPIO_ATIM3_ETR_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ATIM3_ETR_1 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN12) +#define GPIO_ATIM3_BKIN1_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN5) +#define GPIO_ATIM3_BKIN1_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN7) +#define GPIO_ATIM3_BKIN2_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN14) +#define GPIO_ATIM3_BKIN2_1 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN15) +#define GPIO_ATIM3_CH1IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ATIM3_CH1IN_1 (GPIO_ALT|GPIO_AF10|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ATIM3_CH1OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ATIM3_CH1OUT_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ATIM3_CH2IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ATIM3_CH2IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10) +#define GPIO_ATIM3_CH2OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ATIM3_CH2OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) +#define GPIO_ATIM3_CH3IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN10) +#define GPIO_ATIM3_CH3IN_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN8) +#define GPIO_ATIM3_CH3OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN10) +#define GPIO_ATIM3_CH3OUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN8) +#define GPIO_ATIM3_CH4IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ATIM3_CH4IN_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN14) +#define GPIO_ATIM3_CH4OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ATIM3_CH4OUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN14) +#define GPIO_ATIM3_CH1NOUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) +#define GPIO_ATIM3_CH2NOUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) +#define GPIO_ATIM3_CH3NOUT_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN9) +#define GPIO_ATIM3_CH4NOUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15) + +/* GTIMA1 */ +#define GPIO_GTIMA1_ETR_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_GTIMA1_ETR_1 (GPIO_ALT|GPIO_AF10|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_GTIMA1_ETR_2 (GPIO_ALT|GPIO_AF10|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15) +#define GPIO_GTIMA1_ETR_3 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN4) +#define GPIO_GTIMA1_CH1IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN0) +#define GPIO_GTIMA1_CH1IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_GTIMA1_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5) +#define GPIO_GTIMA1_CH1IN_3 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15) +#define GPIO_GTIMA1_CH1OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN0) +#define GPIO_GTIMA1_CH1OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_GTIMA1_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) +#define GPIO_GTIMA1_CH1OUT_3 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15) +#define GPIO_GTIMA1_CH2IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN1) +#define GPIO_GTIMA1_CH2IN_1 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_GTIMA1_CH2IN_2 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN3) +#define GPIO_GTIMA1_CH2OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN1) +#define GPIO_GTIMA1_CH2OUT_1 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_GTIMA1_CH2OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) +#define GPIO_GTIMA1_CH3IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN2) +#define GPIO_GTIMA1_CH3IN_1 (GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_GTIMA1_CH3IN_2 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN10) +#define GPIO_GTIMA1_CH3OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) +#define GPIO_GTIMA1_CH3OUT_1 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_GTIMA1_CH3OUT_2 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_GTIMA1_CH4IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN3) +#define GPIO_GTIMA1_CH4IN_1 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_GTIMA1_CH4IN_2 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN11) +#define GPIO_GTIMA1_CH4OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN3) +#define GPIO_GTIMA1_CH4OUT_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_GTIMA1_CH4OUT_2 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) + +/* GTIMA2 */ +#define GPIO_GTIMA2_ETR_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN2) +#define GPIO_GTIMA2_ETR_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#define GPIO_GTIMA2_CH1IN_0 (GPIO_ALT|GPIO_AF11|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6) +#define GPIO_GTIMA2_CH1IN_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6) +#define GPIO_GTIMA2_CH1IN_2 (GPIO_ALT|GPIO_AF10|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN4) +#define GPIO_GTIMA2_CH1OUT_0 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6) +#define GPIO_GTIMA2_CH1OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_GTIMA2_CH1OUT_2 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) +#define GPIO_GTIMA2_CH2IN_0 (GPIO_ALT|GPIO_AF12|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7) +#define GPIO_GTIMA2_CH2IN_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7) +#define GPIO_GTIMA2_CH2IN_2 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN5) +#define GPIO_GTIMA2_CH2OUT_0 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_GTIMA2_CH2OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_GTIMA2_CH2OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_GTIMA2_CH3IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN0) +#define GPIO_GTIMA2_CH3IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8) +#define GPIO_GTIMA2_CH3IN_2 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN6) +#define GPIO_GTIMA2_CH3OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_GTIMA2_CH3OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_GTIMA2_CH3OUT_2 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) +#define GPIO_GTIMA2_CH4IN_0 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN1) +#define GPIO_GTIMA2_CH4IN_1 (GPIO_ALT|GPIO_AF10|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9) +#define GPIO_GTIMA2_CH4IN_2 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN7) +#define GPIO_GTIMA2_CH4OUT_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_GTIMA2_CH4OUT_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_GTIMA2_CH4OUT_2 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) + +/* GTIMA3 */ +#define GPIO_GTIMA3_ETR_0 (GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN11) +#define GPIO_GTIMA3_ETR_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0) +#define GPIO_GTIMA3_CH1IN_0 (GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN12) +#define GPIO_GTIMA3_CH1IN_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN6) +#define GPIO_GTIMA3_CH1OUT_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12) +#define GPIO_GTIMA3_CH1OUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) +#define GPIO_GTIMA3_CH2IN_0 (GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN13) +#define GPIO_GTIMA3_CH2IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN7) +#define GPIO_GTIMA3_CH2OUT_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) +#define GPIO_GTIMA3_CH2OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_GTIMA3_CH3IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN14) +#define GPIO_GTIMA3_CH3IN_1 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#define GPIO_GTIMA3_CH3OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN14) +#define GPIO_GTIMA3_CH3OUT_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_GTIMA3_CH4IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN15) +#define GPIO_GTIMA3_CH4IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9) +#define GPIO_GTIMA3_CH4OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15) +#define GPIO_GTIMA3_CH4OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) + +/* GTIMA4 */ +#define GPIO_GTIMA4_ETR_0 (GPIO_ALT|GPIO_AF10|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN4) +#define GPIO_GTIMA4_ETR_1 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN8) +#define GPIO_GTIMA4_CH1IN_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_GTIMA4_CH1IN_1 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10) +#define GPIO_GTIMA4_CH1OUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_GTIMA4_CH1OUT_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) +#define GPIO_GTIMA4_CH2IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_GTIMA4_CH2IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN11) +#define GPIO_GTIMA4_CH2OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_GTIMA4_CH2OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) +#define GPIO_GTIMA4_CH3IN_0 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_GTIMA4_CH3IN_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN12) +#define GPIO_GTIMA4_CH3OUT_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_GTIMA4_CH3OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) +#define GPIO_GTIMA4_CH4IN_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_GTIMA4_CH4IN_1 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN0) +#define GPIO_GTIMA4_CH4OUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_GTIMA4_CH4OUT_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0) + +/* GTIMA5 */ +#define GPIO_GTIMA5_ETR_0 (GPIO_ALT|GPIO_AF10|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN2) +#define GPIO_GTIMA5_ETR_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN3) +#define GPIO_GTIMA5_CH1IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN0) +#define GPIO_GTIMA5_CH1IN_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN6) +#define GPIO_GTIMA5_CH1IN_2 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN12) +#define GPIO_GTIMA5_CH1OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN0) +#define GPIO_GTIMA5_CH1OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) +#define GPIO_GTIMA5_CH1OUT_2 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN12) +#define GPIO_GTIMA5_CH2IN_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN1) +#define GPIO_GTIMA5_CH2IN_1 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN7) +#define GPIO_GTIMA5_CH2IN_2 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN13) +#define GPIO_GTIMA5_CH2OUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN1) +#define GPIO_GTIMA5_CH2OUT_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) +#define GPIO_GTIMA5_CH2OUT_2 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +#define GPIO_GTIMA5_CH3IN_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN2) +#define GPIO_GTIMA5_CH3IN_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN8) +#define GPIO_GTIMA5_CH3IN_2 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN14) +#define GPIO_GTIMA5_CH3OUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) +#define GPIO_GTIMA5_CH3OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8) +#define GPIO_GTIMA5_CH3OUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +#define GPIO_GTIMA5_CH4IN_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN3) +#define GPIO_GTIMA5_CH4IN_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_GTIMA5_CH4OUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN3) +#define GPIO_GTIMA5_CH4OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9) + +/* GTIMA6 */ +#define GPIO_GTIMA6_ETR_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN2) +#define GPIO_GTIMA6_ETR_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN3) +#define GPIO_GTIMA6_CH1IN_0 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN11) +#define GPIO_GTIMA6_CH1OUT_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN11) +#define GPIO_GTIMA6_CH2IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN12) +#define GPIO_GTIMA6_CH2OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN12) +#define GPIO_GTIMA6_CH3IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN13) +#define GPIO_GTIMA6_CH3OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN13) +#define GPIO_GTIMA6_CH4IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN14) +#define GPIO_GTIMA6_CH4OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN14) + +/* GTIMA7 */ +#define GPIO_GTIMA7_ETR_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN11) +#define GPIO_GTIMA7_ETR_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN14) +#define GPIO_GTIMA7_CH1IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN6) +#define GPIO_GTIMA7_CH1IN_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN14) +#define GPIO_GTIMA7_CH1OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) +#define GPIO_GTIMA7_CH1OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_GTIMA7_CH2IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN9) +#define GPIO_GTIMA7_CH2IN_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN15) +#define GPIO_GTIMA7_CH2OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) +#define GPIO_GTIMA7_CH2OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_GTIMA7_CH3IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN9) +#define GPIO_GTIMA7_CH3IN_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN12) +#define GPIO_GTIMA7_CH3OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN9) +#define GPIO_GTIMA7_CH3OUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN12) +#define GPIO_GTIMA7_CH4IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN10) +#define GPIO_GTIMA7_CH4IN_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN13) +#define GPIO_GTIMA7_CH4OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN10) +#define GPIO_GTIMA7_CH4OUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN13) + +/* GTIMB1 */ +#define GPIO_GTIMB1_ETR_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN2) +#define GPIO_GTIMB1_ETR_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN1) +#define GPIO_GTIMB1_CH1NIN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN4) +#define GPIO_GTIMB1_CH1NIN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1) +#define GPIO_GTIMB1_CH1NOUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN4) +#define GPIO_GTIMB1_CH1NOUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_GTIMB1_CH1PIN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN5) +#define GPIO_GTIMB1_CH1PIN_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2) +#define GPIO_GTIMB1_CH1PIN_2 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN12) +#define GPIO_GTIMB1_CH1POUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5) +#define GPIO_GTIMB1_CH1POUT_1 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_GTIMB1_CH1POUT_2 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN12) +#define GPIO_GTIMB1_CH2IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN6) +#define GPIO_GTIMB1_CH2IN_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3) +#define GPIO_GTIMB1_CH2OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6) +#define GPIO_GTIMB1_CH2OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_GTIMB1_CH3IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0) +#define GPIO_GTIMB1_CH3OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN0) +#define GPIO_GTIMB1_CH4IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN1) +#define GPIO_GTIMB1_CH4OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN1) +#define GPIO_GTIMB1_BRK_0 (GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN3) +#define GPIO_GTIMB1_BRK_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0) +#define GPIO_GTIMB1_BRK_2 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN2) + +/* GTIMB2 */ +#define GPIO_GTIMB2_ETR_0 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN2) +#define GPIO_GTIMB2_ETR_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN5) +#define GPIO_GTIMB2_CH1NIN_0 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN8) +#define GPIO_GTIMB2_CH1NIN_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN0) +#define GPIO_GTIMB2_CH1NIN_2 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN6) +#define GPIO_GTIMB2_CH1NOUT_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8) +#define GPIO_GTIMB2_CH1NOUT_1 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN0) +#define GPIO_GTIMB2_CH1NOUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) +#define GPIO_GTIMB2_CH1PIN_0 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN6) +#define GPIO_GTIMB2_CH1PIN_1 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN1) +#define GPIO_GTIMB2_CH1PIN_2 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8) +#define GPIO_GTIMB2_CH1POUT_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) +#define GPIO_GTIMB2_CH1POUT_1 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN1) +#define GPIO_GTIMB2_CH1POUT_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_GTIMB2_CH2IN_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN5) +#define GPIO_GTIMB2_CH2IN_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN2) +#define GPIO_GTIMB2_CH2OUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN5) +#define GPIO_GTIMB2_CH2OUT_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2) +#define GPIO_GTIMB2_CH3IN_0 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN4) +#define GPIO_GTIMB2_CH3IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN3) +#define GPIO_GTIMB2_CH3OUT_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN4) +#define GPIO_GTIMB2_CH3OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN3) +#define GPIO_GTIMB2_CH4IN_0 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN3) +#define GPIO_GTIMB2_CH4IN_1 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN4) +#define GPIO_GTIMB2_CH4OUT_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN3) +#define GPIO_GTIMB2_CH4OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN4) +#define GPIO_GTIMB2_BRK_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN10) +#define GPIO_GTIMB2_BRK_1 (GPIO_ALT|GPIO_AF11|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN4) + +/* GTIMB3 */ +#define GPIO_GTIMB3_ETR_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN5) +#define GPIO_GTIMB3_ETR_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN15) +#define GPIO_GTIMB3_CH1NIN_0 (GPIO_ALT|GPIO_AF10|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN9) +#define GPIO_GTIMB3_CH1NIN_2 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN7) +#define GPIO_GTIMB3_CH1NOUT_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9) +#define GPIO_GTIMB3_CH1NOUT_2 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_GTIMB3_CH1PIN_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN7) +#define GPIO_GTIMB3_CH1PIN_2 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9) +#define GPIO_GTIMB3_CH1POUT_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) +#define GPIO_GTIMB3_CH1POUT_2 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_GTIMB3_CH2IN_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN2) +#define GPIO_GTIMB3_CH2OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN2) +#define GPIO_GTIMB3_CH3IN_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN3) +#define GPIO_GTIMB3_CH3OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN3) +#define GPIO_GTIMB3_CH4IN_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN4) +#define GPIO_GTIMB3_CH4OUT_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN4) +#define GPIO_GTIMB3_BRK_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN6) +#define GPIO_GTIMB3_BRK_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN5) + +/* LPTIM1 */ +#define GPIO_LPTIM1_ETR_0 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN14) +#define GPIO_LPTIM1_ETR_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0) +#define GPIO_LPTIM1_IN1_0 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN12) +#define GPIO_LPTIM1_IN1_1 (GPIO_ALT|GPIO_AF10|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN12) +#define GPIO_LPTIM1_IN2_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN2) +#define GPIO_LPTIM1_IN2_1 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN11) +#define GPIO_LPTIM1_IN2_2 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN1) +#define GPIO_LPTIM1_OUT_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) +#define GPIO_LPTIM1_OUT_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) + +/* LPTIM2 */ +#define GPIO_LPTIM2_ETR_0 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN11) +#define GPIO_LPTIM2_ETR_1 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0) +#define GPIO_LPTIM2_IN1_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN10) +#define GPIO_LPTIM2_IN1_1 (GPIO_ALT|GPIO_AF5|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN12) +#define GPIO_LPTIM2_IN2_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN12) +#define GPIO_LPTIM2_IN2_1 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN11) +#define GPIO_LPTIM2_OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_LPTIM2_OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN10) + +/* LPTIM3 */ +#define GPIO_LPTIM3_ETR_0 (GPIO_ALT|GPIO_AF7|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN10) +#define GPIO_LPTIM3_IN1_0 (GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN8) +#define GPIO_LPTIM3_IN2_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN9) +#define GPIO_LPTIM3_OUT_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) + +/* LPTIM4 */ +#define GPIO_LPTIM4_ETR_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN15) +#define GPIO_LPTIM4_IN1_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN0) +#define GPIO_LPTIM4_IN2_0 (GPIO_ALT|GPIO_AF9|GPIO_FLOAT|GPIO_PORTG|GPIO_PIN1) +#define GPIO_LPTIM4_OUT_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) + +/* LPTIM5 */ +#define GPIO_LPTIM5_IN1_0 (GPIO_ALT|GPIO_AF8|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN6) +#define GPIO_LPTIM5_IN2_0 (GPIO_ALT|GPIO_AF6|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN7) +#define GPIO_LPTIM5_OUT_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) + +/* FDCAN1 */ +#define GPIO_FDCAN1_TX_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN8) +#define GPIO_FDCAN1_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN13) +#define GPIO_FDCAN1_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_FDCAN1_TX_3 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_FDCAN1_RX_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) +#define GPIO_FDCAN1_RX_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN1) +#define GPIO_FDCAN1_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN9) +#define GPIO_FDCAN1_RX_3 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) + +/* FDCAN2 */ +#define GPIO_FDCAN2_TX_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) +#define GPIO_FDCAN2_TX_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_FDCAN2_TX_2 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) +#define GPIO_FDCAN2_RX_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN8) +#define GPIO_FDCAN2_RX_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_FDCAN2_RX_2 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) + +/* FDCAN3 */ +#define GPIO_FDCAN3_TX_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) +#define GPIO_FDCAN3_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN15) +#define GPIO_FDCAN3_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) +#define GPIO_FDCAN3_TX_3 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FDCAN3_RX_0 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) +#define GPIO_FDCAN3_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN14) +#define GPIO_FDCAN3_RX_2 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12) +#define GPIO_FDCAN3_RX_3 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN10) + +/* FDCAN4 */ +#define GPIO_FDCAN4_TX_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN2) +#define GPIO_FDCAN4_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN10) +#define GPIO_FDCAN4_TX_2 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN0) +#define GPIO_FDCAN4_RX_0 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN3) +#define GPIO_FDCAN4_RX_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN11) +#define GPIO_FDCAN4_RX_2 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN1) + +/* USART1 */ +#define GPIO_USART1_TX_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN0) +#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN14) +#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN9) +#define GPIO_USART1_TX_3 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN6) +#define GPIO_USART1_RX_0 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN1) +#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN15) +#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_AF5|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN10) +#define GPIO_USART1_RX_3 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN7) +#define GPIO_USART1_CK_0 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN2) +#define GPIO_USART1_CK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN8) +#define GPIO_USART1_CTS_0 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN3) +#define GPIO_USART1_CTS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_RTS_DE_0 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN4) +#define GPIO_USART1_RTS_DE_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN12) + +/* USART2 */ +#define GPIO_USART2_TX_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN2) +#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN5) +#define GPIO_USART2_RX_0 (GPIO_ALT|GPIO_AF11|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN6) +#define GPIO_USART2_CK_0 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN4) +#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN7) +#define GPIO_USART2_CTS_0 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN0) +#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN3) +#define GPIO_USART2_RTS_DE_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART2_RTS_DE_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN4) + +/* USART3 */ +#define GPIO_USART3_TX_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN10) +#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN8) +#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN10) +#define GPIO_USART3_RX_0 (GPIO_ALT|GPIO_AF6|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN11) +#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_AF5|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN9) +#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN11) +#define GPIO_USART3_CK_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN12) +#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN12) +#define GPIO_USART3_CTS_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN10) +#define GPIO_USART3_RTS_DE_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART3_RTS_DE_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN14) + +/* USART4 */ +#define GPIO_USART4_TX_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN6) +#define GPIO_USART4_TX_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN14) +#define GPIO_USART4_RX_0 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN7) +#define GPIO_USART4_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN9) +#define GPIO_USART4_CK_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN7) +#define GPIO_USART4_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN8) +#define GPIO_USART4_CTS_0 (GPIO_ALT|GPIO_AF9|GPIO_PORTG|GPIO_PIN13) +#define GPIO_USART4_CTS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN15) +#define GPIO_USART4_RTS_DE_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN8) +#define GPIO_USART4_RTS_DE_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTG|GPIO_PIN12) + +/* USART5 */ +#define GPIO_USART5_TX_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN3) +#define GPIO_USART5_TX_1 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN12) +#define GPIO_USART5_RX_0 (GPIO_ALT|GPIO_AF6|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN2) +#define GPIO_USART5_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN11) +#define GPIO_USART5_CK_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTE|GPIO_PIN15) +#define GPIO_USART5_CK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN15) +#define GPIO_USART5_CTS_0 (GPIO_ALT|GPIO_AF10|GPIO_PORTG|GPIO_PIN13) +#define GPIO_USART5_RTS_DE_0 (GPIO_ALT|GPIO_AF11|GPIO_PORTG|GPIO_PIN14) + +/* USART6 */ +#define GPIO_USART6_TX_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN5) +#define GPIO_USART6_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN15) +#define GPIO_USART6_RX_0 (GPIO_ALT|GPIO_AF6|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN4) +#define GPIO_USART6_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN14) +#define GPIO_USART6_CK_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTE|GPIO_PIN14) +#define GPIO_USART6_CTS_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN4) +#define GPIO_USART6_RTS_DE_0 (GPIO_ALT|GPIO_AF9|GPIO_PORTG|GPIO_PIN5) + +/* USART7 */ +#define GPIO_USART7_TX_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN5) +#define GPIO_USART7_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN15) +#define GPIO_USART7_RX_0 (GPIO_ALT|GPIO_AF6|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN4) +#define GPIO_USART7_RX_1 (GPIO_ALT|GPIO_AF6|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN14) +#define GPIO_USART7_CK_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTH|GPIO_PIN3) +#define GPIO_USART7_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTF|GPIO_PIN13) +#define GPIO_USART7_CTS_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN2) +#define GPIO_USART7_RTS_DE_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN3) + +/* UART9 */ +#define GPIO_UART9_TX_0 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN0) +#define GPIO_UART9_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN12) +#define GPIO_UART9_TX_2 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN13) +#define GPIO_UART9_TX_3 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN10) +#define GPIO_UART9_TX_4 (GPIO_ALT|GPIO_AF5|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN1) +#define GPIO_UART9_TX_5 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN9) +#define GPIO_UART9_RX_0 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN9) +#define GPIO_UART9_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN1) +#define GPIO_UART9_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN11) +#define GPIO_UART9_RX_3 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN14) +#define GPIO_UART9_RX_4 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART9_RX_5 (GPIO_ALT|GPIO_AF6|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN0) +#define GPIO_UART9_RX_6 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN8) +#define GPIO_UART9_CTS_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN0) +#define GPIO_UART9_CTS_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN15) +#define GPIO_UART9_RTS_DE_0 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN14) +#define GPIO_UART9_RTS_DE_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN15) + +/* UART10 */ +#define GPIO_UART10_TX_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN12) +#define GPIO_UART10_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN13) +#define GPIO_UART10_TX_2 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN12) +#define GPIO_UART10_TX_3 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN6) +#define GPIO_UART10_RX_0 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN11) +#define GPIO_UART10_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN12) +#define GPIO_UART10_RX_2 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART10_RX_3 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN5) +#define GPIO_UART10_CTS_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTH|GPIO_PIN9) +#define GPIO_UART10_CTS_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN9) +#define GPIO_UART10_RTS_DE_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTH|GPIO_PIN8) +#define GPIO_UART10_RTS_DE_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN8) + +/* UART11 */ +#define GPIO_UART11_TX_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN7) +#define GPIO_UART11_TX_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN8) +#define GPIO_UART11_TX_2 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN15) +#define GPIO_UART11_TX_3 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN4) +#define GPIO_UART11_RX_0 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN6) +#define GPIO_UART11_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN7) +#define GPIO_UART11_RX_2 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN8) +#define GPIO_UART11_RX_3 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN3) +#define GPIO_UART11_CTS_0 (GPIO_ALT|GPIO_AF11|GPIO_PORTF|GPIO_PIN9) +#define GPIO_UART11_CTS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN10) +#define GPIO_UART11_RTS_DE_0 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN8) +#define GPIO_UART11_RTS_DE_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTE|GPIO_PIN9) + +/* UART12 */ +#define GPIO_UART12_TX_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN12) +#define GPIO_UART12_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN1) +#define GPIO_UART12_RX_2 (GPIO_ALT|GPIO_AF5|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN13) +#define GPIO_UART12_RX_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN0) +#define GPIO_UART12_CTS_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN14) +#define GPIO_UART12_RTS_DE_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN15) + +/* UART13 */ +#define GPIO_UART13_TX_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN1) +#define GPIO_UART13_TX_1 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN13) +#define GPIO_UART13_TX_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN15) +#define GPIO_UART13_RX_0 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN0) +#define GPIO_UART13_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN12) +#define GPIO_UART13_RX_2 (GPIO_ALT|GPIO_AF8|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN14) +#define GPIO_UART13_CTS_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTE|GPIO_PIN14) +#define GPIO_UART13_CTS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN12) +#define GPIO_UART13_CTS_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTD|GPIO_PIN0) +#define GPIO_UART13_RTS_DE_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTE|GPIO_PIN15) +#define GPIO_UART13_RTS_DE_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN13) + +/* UART14 */ +#define GPIO_UART14_TX_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN7) +#define GPIO_UART14_RX_0 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN6) +#define GPIO_UART14_CTS_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTH|GPIO_PIN9) +#define GPIO_UART14_RTS_DE_0 (GPIO_ALT|GPIO_AF9|GPIO_PORTH|GPIO_PIN8) + +/* UART15 */ +#define GPIO_UART15_TX_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN3) +#define GPIO_UART15_RX_0 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTH|GPIO_PIN2) +#define GPIO_UART15_CTS_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTH|GPIO_PIN5) +#define GPIO_UART15_RTS_DE_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTH|GPIO_PIN4) + +/* LPUART1 */ +#define GPIO_LPUART1_CTS_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN11) +#define GPIO_LPUART1_DE_RTS_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN12) +#define GPIO_LPUART1_RX_0 (GPIO_ALT|GPIO_AF6|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN10) +#define GPIO_LPUART1_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN7) +#define GPIO_LPUART1_TX_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN9) +#define GPIO_LPUART1_TX_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN6) + +/* LPUART2 */ +#define GPIO_LPUART2_CTS_0 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN2) +#define GPIO_LPUART2_DE_RTS_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTD|GPIO_PIN3) +#define GPIO_LPUART2_RX_0 (GPIO_ALT|GPIO_AF9|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN3) +#define GPIO_LPUART2_RX_1 (GPIO_ALT|GPIO_AF7|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN5) +#define GPIO_LPUART2_TX_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTI|GPIO_PIN2) +#define GPIO_LPUART2_TX_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN4) + +/* I2C1 */ +#define GPIO_I2C1_SCL_0 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN5) +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN4) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SDA_0 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN4) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF8|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN5) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SMBA_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN6) +#define GPIO_I2C1_SMBA_1 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN1) +#define GPIO_I2C1_SMBA_2 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) + +/* I2C2 */ +#define GPIO_I2C2_SCL_0 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN4) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA_0 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN5) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF7|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SMBA_0 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) +#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) +#define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) + +/* I2C3 */ +#define GPIO_I2C3_SCL_0 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN7) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN8) +#define GPIO_I2C3_SDA_0 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN8) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF12|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2C3_SMBA_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) +#define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) + +/* I2C4 */ +#define GPIO_I2C4_SCL_0 (GPIO_ALT|GPIO_AF8|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN14) +#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF8|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN11) +#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN12) +#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF12|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C4_SCL_4 (GPIO_ALT|GPIO_AF12|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C4_SDA_0 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN15) +#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN12) +#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF8|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN13) +#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C4_SMBA_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN13) +#define GPIO_I2C4_SMBA_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) +#define GPIO_I2C4_SMBA_2 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN11) +#define GPIO_I2C4_SMBA_3 (GPIO_ALT|GPIO_AF13|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2C4_SMBA_4 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) + +/* I2C5 */ +#define GPIO_I2C5_SCL_0 (GPIO_ALT|GPIO_AF12|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C5_SCL_1 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN8) +#define GPIO_I2C5_SCL_2 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN11) +#define GPIO_I2C5_SDA_0 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C5_SDA_1 (GPIO_ALT|GPIO_AF13|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2C5_SDA_2 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN10) +#define GPIO_I2C5_SMBA_0 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) +#define GPIO_I2C5_SMBA_1 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2C5_SMBA_2 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN12) + +/* I2C6 */ +#define GPIO_I2C6_SCL_0 (GPIO_ALT|GPIO_AF12|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN4) +#define GPIO_I2C6_SCL_1 (GPIO_ALT|GPIO_AF7|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN12) +#define GPIO_I2C6_SCL_2 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTE|GPIO_PIN14) +#define GPIO_I2C6_SDA_0 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN3) +#define GPIO_I2C6_SDA_1 (GPIO_ALT|GPIO_AF5|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN11) +#define GPIO_I2C6_SDA_2 (GPIO_ALT|GPIO_AF8|GPIO_OPENDRAIN|GPIO_PORTE|GPIO_PIN13) +#define GPIO_I2C6_SMBA_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN5) +#define GPIO_I2C6_SMBA_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN13) +#define GPIO_I2C6_SMBA_2 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN15) + +/* I2C7 */ +#define GPIO_I2C7_SCL_0 (GPIO_ALT|GPIO_AF7|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN13) +#define GPIO_I2C7_SCL_1 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTE|GPIO_PIN8) +#define GPIO_I2C7_SCL_2 (GPIO_ALT|GPIO_AF6|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN9) +#define GPIO_I2C7_SDA_0 (GPIO_ALT|GPIO_AF7|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN12) +#define GPIO_I2C7_SDA_1 (GPIO_ALT|GPIO_AF8|GPIO_OPENDRAIN|GPIO_PORTE|GPIO_PIN7) +#define GPIO_I2C7_SDA_2 (GPIO_ALT|GPIO_AF7|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN8) +#define GPIO_I2C7_SMBA_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN14) +#define GPIO_I2C7_SMBA_1 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9) +#define GPIO_I2C7_SMBA_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN10) + +/* I2C8 */ +#define GPIO_I2C8_SCL_0 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN15) +#define GPIO_I2C8_SCL_2 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN5) +#define GPIO_I2C8_SCL_3 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN3) +#define GPIO_I2C8_SDA_0 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN14) +#define GPIO_I2C8_SDA_2 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN4) +#define GPIO_I2C8_SDA_3 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN2) +#define GPIO_I2C8_SMBA_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) +#define GPIO_I2C8_SMBA_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN6) +#define GPIO_I2C8_SMBA_3 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN1) + +/* I2C9 */ +#define GPIO_I2C9_SCL_0 (GPIO_ALT|GPIO_AF7|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN11) +#define GPIO_I2C9_SCL_3 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN15) +#define GPIO_I2C9_SDA_0 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN10) +#define GPIO_I2C9_SDA_3 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN14) +#define GPIO_I2C9_SMBA_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN9) +#define GPIO_I2C9_SMBA_2 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN13) + +/* I2C10 */ +#define GPIO_I2C10_SCL_0 (GPIO_ALT|GPIO_AF11|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN1) +#define GPIO_I2C10_SCL_4 (GPIO_ALT|GPIO_AF9|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN6) +#define GPIO_I2C10_SDA_0 (GPIO_ALT|GPIO_AF8|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN0) +#define GPIO_I2C10_SDA_4 (GPIO_ALT|GPIO_AF10|GPIO_OPENDRAIN|GPIO_PORTI|GPIO_PIN5) +#define GPIO_I2C10_SMBA_0 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN3) +#define GPIO_I2C10_SMBA_3 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN4) + +/* SPI1 */ +#define GPIO_SPI1_NSS_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN10) +#define GPIO_SPI1_SCK_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN11) +#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI1_MISO_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN9) +#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI1_MOSI_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTD|GPIO_PIN7) + +/* SPI2 */ +#define GPIO_SPI2_NSS_0 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN11) +#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTI|GPIO_PIN0) +#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI2_SCK_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN9) +#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN12) +#define GPIO_SPI2_SCK_4 (GPIO_ALT|GPIO_AF6|GPIO_PORTI|GPIO_PIN1) +#define GPIO_SPI2_SCK_5 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN3) +#define GPIO_SPI2_MISO_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN2) +#define GPIO_SPI2_MISO_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN2) +#define GPIO_SPI2_MOSI_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTC|GPIO_PIN1) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SPI2_MOSI_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN3) + +/* SPI3 */ +#define GPIO_SPI3_NSS_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN4) +#define GPIO_SPI3_SCK_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN7) +#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_MISO_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN1) +#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTD|GPIO_PIN5) +#define GPIO_SPI3_MISO_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MOSI_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN2) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN6) + +/* SPI4 */ +#define GPIO_SPI4_NSS_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN0) +#define GPIO_SPI4_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI4_NSS_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTG|GPIO_PIN8) +#define GPIO_SPI4_NSS_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI4_SCK_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI4_SCK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI4_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN13) +#define GPIO_SPI4_SCK_3 (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI4_MISO_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI4_MISO_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN12) +#define GPIO_SPI4_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI4_MOSI_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI4_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN14) + +/* SPI5 */ +#define GPIO_SPI5_NSS_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN6) +#define GPIO_SPI5_NSS_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN5) +#define GPIO_SPI5_SCK_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTF|GPIO_PIN7) +#define GPIO_SPI5_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN6) +#define GPIO_SPI5_MISO_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN8) +#define GPIO_SPI5_MISO_1 (GPIO_ALT|GPIO_AF4|GPIO_PORTH|GPIO_PIN7) +#define GPIO_SPI5_MOSI_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN9) +#define GPIO_SPI5_MOSI_1 (GPIO_ALT|GPIO_AF3|GPIO_PORTF|GPIO_PIN11) + +/* SPI6 */ +#define GPIO_SPI6_NSS_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTE|GPIO_PIN4) +#define GPIO_SPI6_NSS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN2) +#define GPIO_SPI6_NSS_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTE|GPIO_PIN11) +#define GPIO_SPI6_SCK_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTE|GPIO_PIN2) +#define GPIO_SPI6_SCK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN3) +#define GPIO_SPI6_SCK_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTE|GPIO_PIN12) +#define GPIO_SPI6_MISO_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTE|GPIO_PIN5) +#define GPIO_SPI6_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTF|GPIO_PIN4) +#define GPIO_SPI6_MISO_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTE|GPIO_PIN13) +#define GPIO_SPI6_MOSI_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN6) +#define GPIO_SPI6_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTF|GPIO_PIN5) +#define GPIO_SPI6_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTE|GPIO_PIN14) + +/* SPI7 */ +#define GPIO_SPI7_NSS_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTI|GPIO_PIN12) +#define GPIO_SPI7_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTH|GPIO_PIN12) +#define GPIO_SPI7_NSS_3 (GPIO_ALT|GPIO_AF4|GPIO_PORTH|GPIO_PIN13) +#define GPIO_SPI7_SCK_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTI|GPIO_PIN8) +#define GPIO_SPI7_MISO_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTI|GPIO_PIN13) +#define GPIO_SPI7_MISO_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTH|GPIO_PIN14) +#define GPIO_SPI7_MOSI_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTI|GPIO_PIN14) +#define GPIO_SPI7_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTH|GPIO_PIN15) + +/* I2S1 */ +#define GPIO_I2S1_CK_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN5) +#define GPIO_I2S1_CK_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN11) +#define GPIO_I2S1_CK_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S1_CKIN_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2S1_MCK_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN4) +#define GPIO_I2S1_SDI_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN6) +#define GPIO_I2S1_SDI_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN9) +#define GPIO_I2S1_SDI_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN4) +#define GPIO_I2S1_SDO_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN7) +#define GPIO_I2S1_SDO_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN7) +#define GPIO_I2S1_WS_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN4) +#define GPIO_I2S1_WS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTA|GPIO_PIN15) +#define GPIO_I2S1_WS_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTG|GPIO_PIN10) + +/* I2S2 */ +#define GPIO_I2S2_CK_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2S2_CK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2S2_CK_2 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN9) +#define GPIO_I2S2_CK_3 (GPIO_ALT|GPIO_AF2|GPIO_PORTA|GPIO_PIN12) +#define GPIO_I2S2_CK_4 (GPIO_ALT|GPIO_AF7|GPIO_PORTI|GPIO_PIN1) +#define GPIO_I2S2_CK_5 (GPIO_ALT|GPIO_AF5|GPIO_PORTD|GPIO_PIN3) +#define GPIO_I2S2_CKIN_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2S2_MCK_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN6) +#define GPIO_I2S2_SDI_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN2) +#define GPIO_I2S2_SDI_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2S2_SDI_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTI|GPIO_PIN2) +#define GPIO_I2S2_SDO_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2S2_SDO_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN3) +#define GPIO_I2S2_SDO_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN15) +#define GPIO_I2S2_SDO_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTI|GPIO_PIN3) +#define GPIO_I2S2_WS_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN11) +#define GPIO_I2S2_WS_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTI|GPIO_PIN0) +#define GPIO_I2S2_WS_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN4) + +/* I2S3 */ +#define GPIO_I2S3_CK_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN10) +#define GPIO_I2S3_CK_1 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S3_CKIN_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2S3_MCK_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTC|GPIO_PIN7) +#define GPIO_I2S3_SDI_0 (GPIO_ALT|GPIO_AF5|GPIO_PORTC|GPIO_PIN11) +#define GPIO_I2S3_SDI_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTB|GPIO_PIN4) +#define GPIO_I2S3_SDO_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN2) +#define GPIO_I2S3_SDO_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTC|GPIO_PIN12) +#define GPIO_I2S3_SDO_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTD|GPIO_PIN6) +#define GPIO_I2S3_WS_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN4) +#define GPIO_I2S3_WS_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN15) + +/* I2S4 */ +#define GPIO_I2S4_CK_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN5) +#define GPIO_I2S4_CK_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN12) +#define GPIO_I2S4_CK_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTG|GPIO_PIN13) +#define GPIO_I2S4_CK_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN3) +#define GPIO_I2S4_CKIN_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN9) +#define GPIO_I2S4_MCK_0 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN3) +#define GPIO_I2S4_SDI_0 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN6) +#define GPIO_I2S4_SDI_1 (GPIO_ALT|GPIO_AF8|GPIO_PORTG|GPIO_PIN12) +#define GPIO_I2S4_SDI_2 (GPIO_ALT|GPIO_AF9|GPIO_PORTB|GPIO_PIN4) +#define GPIO_I2S4_SDO_0 (GPIO_ALT|GPIO_AF8|GPIO_PORTA|GPIO_PIN7) +#define GPIO_I2S4_SDO_1 (GPIO_ALT|GPIO_AF7|GPIO_PORTG|GPIO_PIN14) +#define GPIO_I2S4_WS_0 (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN0) +#define GPIO_I2S4_WS_1 (GPIO_ALT|GPIO_AF9|GPIO_PORTA|GPIO_PIN4) +#define GPIO_I2S4_WS_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTG|GPIO_PIN8) +#define GPIO_I2S4_WS_3 (GPIO_ALT|GPIO_AF7|GPIO_PORTA|GPIO_PIN15) + +/* SPI1/I2S1 */ +#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S1_SDO_2 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN5) + +/* SPI3/I2S3 */ +#define GPIO_SPI3_MOSI_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S3_SDO_3 (GPIO_ALT|GPIO_AF6|GPIO_PORTB|GPIO_PIN5) + +/* SPI4/I2S4 */ +#define GPIO_SPI4_MOSI_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2S4_SDO_2 (GPIO_ALT|GPIO_AF7|GPIO_PORTB|GPIO_PIN5) + +/* SPI2/I2S2 */ +#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SPI2_NSS_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2S2_WS_3 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2S2_WS_4 (GPIO_ALT|GPIO_AF5|GPIO_PORTB|GPIO_PIN12) + +/* XSPI1 */ +#define GPIO_XSPI_CLK_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTF|GPIO_PIN10) +#define GPIO_XSPI_CLK_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN2) +#define GPIO_XSPI_CLK_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN3) +#define GPIO_XSPI_IO0_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTF|GPIO_PIN8) +#define GPIO_XSPI_IO0_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN2) +#define GPIO_XSPI_IO0_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN1) +#define GPIO_XSPI_IO0_3 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN11) +#define GPIO_XSPI_IO0_4 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN9) +#define GPIO_XSPI_IO0_5 (GPIO_ALT|GPIO_AF2|GPIO_PORTC|GPIO_PIN3) +#define GPIO_XSPI_IO0_6 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN12) +#define GPIO_XSPI_IO1_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTF|GPIO_PIN9) +#define GPIO_XSPI_IO1_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN0) +#define GPIO_XSPI_IO1_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN12) +#define GPIO_XSPI_IO1_3 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN10) +#define GPIO_XSPI_IO2_0 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN3) +#define GPIO_XSPI_IO2_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN2) +#define GPIO_XSPI_IO2_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTF|GPIO_PIN7) +#define GPIO_XSPI_IO2_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7) +#define GPIO_XSPI_IO2_4 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN13) +#define GPIO_XSPI_IO2_5 (GPIO_ALT|GPIO_AF2|GPIO_PORTC|GPIO_PIN2) +#define GPIO_XSPI_IO3_0 (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN1) +#define GPIO_XSPI_IO3_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTF|GPIO_PIN6) +#define GPIO_XSPI_IO3_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN6) +#define GPIO_XSPI_IO3_3 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN13) +#define GPIO_XSPI_IO4_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN1) +#define GPIO_XSPI_IO4_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTH|GPIO_PIN2) +#define GPIO_XSPI_IO4_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN4) +#define GPIO_XSPI_IO4_3 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN7) +#define GPIO_XSPI_IO5_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN2) +#define GPIO_XSPI_IO5_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTH|GPIO_PIN3) +#define GPIO_XSPI_IO5_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTE|GPIO_PIN8) +#define GPIO_XSPI_IO5_3 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN5) +#define GPIO_XSPI_IO6_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTC|GPIO_PIN3) +#define GPIO_XSPI_IO6_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN6) +#define GPIO_XSPI_IO6_2 (GPIO_ALT|GPIO_AF2|GPIO_PORTE|GPIO_PIN9) +#define GPIO_XSPI_IO6_3 (GPIO_ALT|GPIO_AF0|GPIO_PORTG|GPIO_PIN9) +#define GPIO_XSPI_IO7_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTD|GPIO_PIN7) +#define GPIO_XSPI_IO7_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTE|GPIO_PIN10) +#define GPIO_XSPI_IO7_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTG|GPIO_PIN14) +#define GPIO_XSPI_DQS_0 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN2) +#define GPIO_XSPI_DQS_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN5) +#define GPIO_XSPI_DQS_2 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN1) +#define GPIO_XSPI1_NCLK_0 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN12) +#define GPIO_XSPI1_NCLK_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTI|GPIO_PIN15) +#define GPIO_XSPI1_NCLK_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN11) +#define GPIO_XSPI1_NCS1_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN10) +#define GPIO_XSPI1_NCS1_2 (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN6) +#define GPIO_XSPI1_NCS2_0 (GPIO_ALT|GPIO_AF2|GPIO_PORTE|GPIO_PIN7) +#define GPIO_XSPI1_NCS2_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN11) +#define GPIO_XSPI1_NCS3_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN8) +#define GPIO_XSPI1_NCS3_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN11) +#define GPIO_XSPI1_NCS4_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN9) +#define GPIO_XSPI1_NCS4_1 (GPIO_ALT|GPIO_AF0|GPIO_PORTG|GPIO_PIN6) +#define GPIO_XSPI1_NCSIN_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTE|GPIO_PIN10) +#define GPIO_XSPI1_NCSIN_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN1) + +/* ETH1 */ +#define GPIO_ETH1_CLK125_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN10) +#define GPIO_ETH1_GMII_GTX_CLK_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN5) +#define GPIO_ETH1_MII_RXD0_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ETH1_MII_RXD1_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ETH1_MII_RXD2_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ETH1_MII_RXD2_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6) +#define GPIO_ETH1_MII_RXD3_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ETH1_MII_RXD3_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN7) +#define GPIO_ETH1_GMII_RXD4_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN12) +#define GPIO_ETH1_GMII_RXD4_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN8) +#define GPIO_ETH1_GMII_RXD5_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13) +#define GPIO_ETH1_GMII_RXD5_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) +#define GPIO_ETH1_GMII_RXD6_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14) +#define GPIO_ETH1_GMII_RXD6_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) +#define GPIO_ETH1_GMII_RXD7_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN15) +#define GPIO_ETH1_GMII_RXD7_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) +#define GPIO_ETH1_MII_TXD0_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_ETH1_MII_TXD0_1 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +#define GPIO_ETH1_MII_TXD1_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_ETH1_MII_TXD1_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN12) +#define GPIO_ETH1_MII_TXD1_2 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +#define GPIO_ETH1_MII_TXD2_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN3) +#define GPIO_ETH1_MII_TXD2_1 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ETH1_MII_TXD2_2 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_ETH1_MII_TXD3_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN2) +#define GPIO_ETH1_MII_TXD3_1 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_ETH1_GMII_TXD4_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN0) +#define GPIO_ETH1_GMII_TXD4_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN4) +#define GPIO_ETH1_GMII_TXD5_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN1) +#define GPIO_ETH1_GMII_TXD5_1 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5) +#define GPIO_ETH1_GMII_TXD6_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN2) +#define GPIO_ETH1_GMII_TXD6_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6) +#define GPIO_ETH1_GMII_TXD7_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN3) +#define GPIO_ETH1_GMII_TXD7_1 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7) +#define GPIO_ETH1_MDC_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ETH1_MDIO_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ETH1_MII_COL_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN3) +#define GPIO_ETH1_MII_COL_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ETH1_MII_CRS_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ETH1_MII_CRS_1 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN2) +#define GPIO_ETH1_MII_RX_CLK_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ETH1_MII_RX_DV_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ETH1_MII_RX_ER_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN10) +#define GPIO_ETH1_MII_RX_ER_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_ETH1_MII_TX_CLK_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ETH1_MII_TX_EN_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_ETH1_MII_TX_EN_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) +#define GPIO_ETH1_MII_TX_ER_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN2) +#define GPIO_ETH1_MII_TX_ER_1 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_ETH1_PHY_INTN_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15) +#define GPIO_ETH1_PHY_INTN_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN7) +#define GPIO_ETH1_PHY_INTN_2 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN15) +#define GPIO_ETH1_PHY_INTN_3 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) +#define GPIO_ETH1_PPS_OUT_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN14) +#define GPIO_ETH1_PPS_OUT_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN8) +#define GPIO_ETH1_PPS_OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) + +/* ETH2 */ +#define GPIO_ETH2_MII_RXD0_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN2) +#define GPIO_ETH2_MII_RXD0_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN1) +#define GPIO_ETH2_MII_RXD0_2 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN9) +#define GPIO_ETH2_MII_RXD1_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN3) +#define GPIO_ETH2_MII_RXD1_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2) +#define GPIO_ETH2_MII_RXD1_2 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN10) +#define GPIO_ETH2_MII_RXD2_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN4) +#define GPIO_ETH2_MII_RXD3_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN5) +#define GPIO_ETH2_MII_TX_CLK_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN8) +#define GPIO_ETH2_MII_TX_CLK_1 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN0) +#define GPIO_ETH2_MII_TX_EN_0 (GPIO_ALT|GPIO_AF6|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN11) +#define GPIO_ETH2_MII_TX_EN_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN13) +#define GPIO_ETH2_MII_TX_ER_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN1) +#define GPIO_ETH2_MII_TXD0_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN4) +#define GPIO_ETH2_MII_TXD0_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN12) +#define GPIO_ETH2_MII_TXD0_2 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN14) +#define GPIO_ETH2_MII_TXD1_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN5) +#define GPIO_ETH2_MII_TXD1_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN13) +#define GPIO_ETH2_MII_TXD1_2 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN15) +#define GPIO_ETH2_MII_TXD2_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN14) +#define GPIO_ETH2_MII_TXD3_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN15) +#define GPIO_ETH2_PHY_INTN_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN4) +#define GPIO_ETH2_PHY_INTN_1 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN7) +#define GPIO_ETH2_PHY_INTN_2 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15) +#define GPIO_ETH2_PPS_OUT_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN10) +#define GPIO_ETH2_PPS_OUT_1 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN15) +#define GPIO_ETH2_PPS_OUT_2 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN10) +#define GPIO_ETH2_MDC_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ETH2_MDIO_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ETH2_MII_COL_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ETH2_MII_CRS_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ETH2_MII_RX_CLK_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN4) +#define GPIO_ETH2_MII_RX_CLK_2 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_ETH2_MII_RX_DV_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ETH2_MII_RX_DV_2 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) +#define GPIO_ETH2_MII_RX_ER_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN6) +#define GPIO_ETH2_MII_RX_ER_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN3) + +/* SDMMC1 */ +#define GPIO_SDMMC1_CD_0 (GPIO_ALT|GPIO_AF2|GPIO_PORTD|GPIO_PIN1) +#define GPIO_SDMMC1_CDIR_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDMMC1_D0_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SDMMC1_D0_1 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8) +#define GPIO_SDMMC1_D0DIR_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTG|GPIO_PIN6) +#define GPIO_SDMMC1_D1_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) +#define GPIO_SDMMC1_D2_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SDMMC1_D3_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SDMMC1_D4_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDMMC1_D4_1 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN14) +#define GPIO_SDMMC1_D5_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDMMC1_D5_1 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN15) +#define GPIO_SDMMC1_D6_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDMMC1_D6_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) +#define GPIO_SDMMC1_D7_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_SDMMC1_D7_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7) +#define GPIO_SDMMC1_CK_0 (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SDMMC1_CKIN_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDMMC1_CMD_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2) +#define GPIO_SDMMC1_D123DIR_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTC|GPIO_PIN7) +#define GPIO_SDMMC1_LEDCTRL_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_SDMMC1_LEDCTRL_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN11) +#define GPIO_SDMMC1_LEDCTRL_2 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN9) +#define GPIO_SDMMC1_LEDCTRL_3 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN8) +#define GPIO_SDMMC1_RST_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN3) +#define GPIO_SDMMC1_SEL_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN8) +#define GPIO_SDMMC1_SEL_1 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_SDMMC1_WP_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN0) + +/* SDMMC2 */ +#define GPIO_SDMMC2_CD_0 (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN5) +#define GPIO_SDMMC2_CDIR_0 (GPIO_ALT|GPIO_AF3|GPIO_PORTG|GPIO_PIN5) +#define GPIO_SDMMC2_D0_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SDMMC2_D0_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN9) +#define GPIO_SDMMC2_D0DIR_0 (GPIO_ALT|GPIO_AF1|GPIO_PORTG|GPIO_PIN13) +#define GPIO_SDMMC2_D1_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SDMMC2_D1_1 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN10) +#define GPIO_SDMMC2_D2_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN11) +#define GPIO_SDMMC2_D2_1 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SDMMC2_D3_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN12) +#define GPIO_SDMMC2_D3_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SDMMC2_D4_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN4) +#define GPIO_SDMMC2_D4_1 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDMMC2_D5_0 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN5) +#define GPIO_SDMMC2_D5_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDMMC2_D6_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN13) +#define GPIO_SDMMC2_D6_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDMMC2_D7_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN14) +#define GPIO_SDMMC2_D7_1 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7) +#define GPIO_SDMMC2_CK_0 (GPIO_ALT|GPIO_AF2|GPIO_PORTC|GPIO_PIN1) +#define GPIO_SDMMC2_CK_1 (GPIO_ALT|GPIO_AF1|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SDMMC2_CKIN_0 (GPIO_ALT|GPIO_AF2|GPIO_PORTC|GPIO_PIN4) +#define GPIO_SDMMC2_CKIN_1 (GPIO_ALT|GPIO_AF2|GPIO_PORTG|GPIO_PIN4) +#define GPIO_SDMMC2_CMD_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) +#define GPIO_SDMMC2_CMD_1 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN7) +#define GPIO_SDMMC2_D123DIR_0 (GPIO_ALT|GPIO_AF2|GPIO_PORTG|GPIO_PIN14) +#define GPIO_SDMMC2_LEDCTRL_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN11) +#define GPIO_SDMMC2_LEDCTRL_1 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN8) +#define GPIO_SDMMC2_LEDCTRL_2 (GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9) +#define GPIO_SDMMC2_RST_0 (GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN15) +#define GPIO_SDMMC2_SEL_0 (GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN8) +#define GPIO_SDMMC2_SEL_1 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN5) +#define GPIO_SDMMC2_WP_0 (GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN4) + +/* USBHS1 */ +#define GPIO_USBHS1_SOF_0 (GPIO_ALT|GPIO_AF8|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_USBHS1_VBUS_0 (GPIO_ALT|GPIO_AF9|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) +#define GPIO_USBHS1_ID_0 (GPIO_ALT|GPIO_AF7|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10) +#define GPIO_USBHS1_DM_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) +#define GPIO_USBHS1_DP_0 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12) + +/* USBHS2 */ +#define GPIO_USBHS2_SOF_0 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN4) +#define GPIO_USBHS2_ID_0 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_USBHS2_VBUS_0 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_USBHS2_DM_0 (GPIO_ALT|GPIO_AF12|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) +#define GPIO_USBHS2_DP_0 (GPIO_ALT|GPIO_AF11|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) + +#endif /* CONFIG_N32H7_N32H76X */ +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_PINMAP_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h76x_pwr.h b/arch/arm/src/n32h7/hardware/n32h76x_pwr.h new file mode 100644 index 0000000000000..2f99066485fb1 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h76x_pwr.h @@ -0,0 +1,712 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h76x_pwr.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_PWR_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_PWR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define N32_PWR_C1_PWR_CR_OFFSET 0x0000 /* Core1 power control register */ +#define N32_PWR_C1_PWR_CSR_OFFSET 0x0004 /* Core1 power status register */ +#define N32_PWR_C1_PWR_CR2_OFFSET 0x0008 /* Core1 power control register 2 */ + +#define N32_PWR_C2_PWR_CR_OFFSET 0x0020 /* Core2 power control register */ +#define N32_PWR_C2_PWR_CSR_OFFSET 0x0024 /* Core2 power status register */ +#define N32_PWR_C2_PWR_CR2_OFFSET 0x0028 /* Core2 power control register 2 */ + +#define N32_PWR_SYS_PWR_CR_OFFSET 0x0040 /* System power control register */ +#define N32_PWR_SYS_PWR_CSR_OFFSET 0x0044 /* System power status register */ +#define N32_PWR_SYS_PWR_CR2_OFFSET 0x0048 /* System power control register 2 */ +#define N32_PWR_SYS_PWR_CR3_OFFSET 0x004C /* System power control register 3 */ +#define N32_PWR_SYS_PWR_CR4_OFFSET 0x0050 /* System power control register 4 */ +#define N32_PWR_SYS_PWR_BOR_CR_OFFSET 0x0054 /* System brown-out reset control register */ +#define N32_PWR_IP_MEMPWR_CR_OFFSET 0x0058 /* IP memory power control register */ +#define N32_PWR_IP_MEMPWR_CSR_OFFSET 0x005C /* IP memory power status register */ + +#define N32_PWR_C1_MEM_LPCR1_OFFSET 0x0060 /* Core1 memory low-power control register 1 */ +#define N32_PWR_C1_MEM_LPSR1_OFFSET 0x0064 /* Core1 memory low-power status register 1 */ +#define N32_PWR_C1_TCM_PG0_OFFSET 0x0068 /* Core1 TCM power gating register 0 */ +#define N32_PWR_C1_TCM_PG1_OFFSET 0x006C /* Core1 TCM power gating register 1 */ +#define N32_PWR_C1_TCM_RET1N0_OFFSET 0x0070 /* Core1 TCM retention register 1N0 */ +#define N32_PWR_C1_TCM_RET1N1_OFFSET 0x0074 /* Core1 TCM retention register 1N1 */ +#define N32_PWR_C1_TCM_RET2N0_OFFSET 0x0078 /* Core1 TCM retention register 2N0 */ +#define N32_PWR_C1_TCM_RET2N1_OFFSET 0x007C /* Core1 TCM retention register 2N1 */ + +#define N32_PWR_C2_MEM_LPCR_OFFSET 0x0090 /* Core2 memory low-power control register */ + +#define N32_PWR_SYS_MEM_LPCR_OFFSET 0x00A0 /* System memory low-power control register */ + +#define N32_PWR_SYS_PWR_SHRT_CR_OFFSET 0x00B0 /* System power short control register */ +#define N32_PWR_SYS_PWR_MDMA_CR_OFFSET 0x00B4 /* System power MDMA control register */ +#define N32_PWR_SYS_PWR_ETHCAT_CR_OFFSET 0x00B8 /* System power EtherCAT control register */ + +#define N32_PWR_PWR_EMC_CR0_OFFSET 0x0100 /* EMC power control register 0 */ +#define N32_PWR_PWR_EMC_CR1_OFFSET 0x0104 /* EMC power control register 1 */ +#define N32_PWR_PWR_EMC_CR2_OFFSET 0x0108 /* EMC power control register 2 */ +#define N32_PWR_PWR_EMC_CR3_OFFSET 0x010C /* EMC power control register 3 */ +#define N32_PWR_PWR_EMC_CR4_OFFSET 0x0110 /* EMC power control register 4 */ +#define N32_PWR_PWR_EMC_CR5_OFFSET 0x0114 /* EMC power control register 5 */ +#define N32_PWR_PWR_EMC_CR6_OFFSET 0x0118 /* EMC power control register 6 */ +#define N32_PWR_PWR_EMC_CR7_OFFSET 0x011C /* EMC power control register 7 */ +#define N32_PWR_PWR_BKP_EMC_CR0_OFFSET 0x0120 /* Backup EMC power control register 0 */ +#define N32_PWR_PWR_BKP_EMC_CR1_OFFSET 0x0124 /* Backup EMC power control register 1 */ + +/* Register Addresses *******************************************************/ + +/** POR BOR DCDC VSEL Control Register **/ +#define PVD_Contrl (N32_AFEC_BASE + 0x2CU) +#define AVD_Contrl (N32_AFEC_BASE + 0x00U) +#define DCDC_Contrl (N32_AFEC_BASE + 0x30U) + +#define N32_PWR_C1_PWR_CR (N32_PWR_BASE + N32_PWR_C1_PWR_CR_OFFSET) +#define N32_PWR_C1_PWR_CSR (N32_PWR_BASE + N32_PWR_C1_PWR_CSR_OFFSET) +#define N32_PWR_C1_PWR_CR2 (N32_PWR_BASE + N32_PWR_C1_PWR_CR2_OFFSET) + +#define N32_PWR_C2_PWR_CR (N32_PWR_BASE + N32_PWR_C2_PWR_CR_OFFSET) +#define N32_PWR_C2_PWR_CSR (N32_PWR_BASE + N32_PWR_C2_PWR_CSR_OFFSET) +#define N32_PWR_C2_PWR_CR2 (N32_PWR_BASE + N32_PWR_C2_PWR_CR2_OFFSET) + +#define N32_PWR_SYS_PWR_CR (N32_PWR_BASE + N32_PWR_SYS_PWR_CR_OFFSET) +#define N32_PWR_SYS_PWR_CSR (N32_PWR_BASE + N32_PWR_SYS_PWR_CSR_OFFSET) +#define N32_PWR_SYS_PWR_CR2 (N32_PWR_BASE + N32_PWR_SYS_PWR_CR2_OFFSET) +#define N32_PWR_SYS_PWR_CR3 (N32_PWR_BASE + N32_PWR_SYS_PWR_CR3_OFFSET) +#define N32_PWR_SYS_PWR_CR4 (N32_PWR_BASE + N32_PWR_SYS_PWR_CR4_OFFSET) +#define N32_PWR_SYS_PWR_BOR_CR (N32_PWR_BASE + N32_PWR_SYS_PWR_BOR_CR_OFFSET) +#define N32_PWR_IP_MEMPWR_CR (N32_PWR_BASE + N32_PWR_IP_MEMPWR_CR_OFFSET) +#define N32_PWR_IP_MEMPWR_CSR (N32_PWR_BASE + N32_PWR_IP_MEMPWR_CSR_OFFSET) + +#define N32_PWR_C1_MEM_LPCR1 (N32_PWR_BASE + N32_PWR_C1_MEM_LPCR1_OFFSET) +#define N32_PWR_C1_MEM_LPSR1 (N32_PWR_BASE + N32_PWR_C1_MEM_LPSR1_OFFSET) +#define N32_PWR_C1_TCM_PG0 (N32_PWR_BASE + N32_PWR_C1_TCM_PG0_OFFSET) +#define N32_PWR_C1_TCM_PG1 (N32_PWR_BASE + N32_PWR_C1_TCM_PG1_OFFSET) +#define N32_PWR_C1_TCM_RET1N0 (N32_PWR_BASE + N32_PWR_C1_TCM_RET1N0_OFFSET) +#define N32_PWR_C1_TCM_RET1N1 (N32_PWR_BASE + N32_PWR_C1_TCM_RET1N1_OFFSET) +#define N32_PWR_C1_TCM_RET2N0 (N32_PWR_BASE + N32_PWR_C1_TCM_RET2N0_OFFSET) +#define N32_PWR_C1_TCM_RET2N1 (N32_PWR_BASE + N32_PWR_C1_TCM_RET2N1_OFFSET) + +#define N32_PWR_C2_MEM_LPCR (N32_PWR_BASE + N32_PWR_C2_MEM_LPCR_OFFSET) + +#define N32_PWR_SYS_MEM_LPCR (N32_PWR_BASE + N32_PWR_SYS_MEM_LPCR_OFFSET) + +#define N32_PWR_SYS_PWR_SHRT_CR (N32_PWR_BASE + N32_PWR_SYS_PWR_SHRT_CR_OFFSET) +#define N32_PWR_SYS_PWR_MDMA_CR (N32_PWR_BASE + N32_PWR_SYS_PWR_MDMA_CR_OFFSET) +#define N32_PWR_SYS_PWR_ETHCAT_CR (N32_PWR_BASE + N32_PWR_SYS_PWR_ETHCAT_CR_OFFSET) + +#define N32_PWR_PWR_EMC_CR0 (N32_PWR_BASE + N32_PWR_PWR_EMC_CR0_OFFSET) +#define N32_PWR_PWR_EMC_CR1 (N32_PWR_BASE + N32_PWR_PWR_EMC_CR1_OFFSET) +#define N32_PWR_PWR_EMC_CR2 (N32_PWR_BASE + N32_PWR_PWR_EMC_CR2_OFFSET) +#define N32_PWR_PWR_EMC_CR3 (N32_PWR_BASE + N32_PWR_PWR_EMC_CR3_OFFSET) +#define N32_PWR_PWR_EMC_CR4 (N32_PWR_BASE + N32_PWR_PWR_EMC_CR4_OFFSET) +#define N32_PWR_PWR_EMC_CR5 (N32_PWR_BASE + N32_PWR_PWR_EMC_CR5_OFFSET) +#define N32_PWR_PWR_EMC_CR6 (N32_PWR_BASE + N32_PWR_PWR_EMC_CR6_OFFSET) +#define N32_PWR_PWR_EMC_CR7 (N32_PWR_BASE + N32_PWR_PWR_EMC_CR7_OFFSET) +#define N32_PWR_PWR_BKP_EMC_CR0 (N32_PWR_BASE + N32_PWR_PWR_BKP_EMC_CR0_OFFSET) +#define N32_PWR_PWR_BKP_EMC_CR1 (N32_PWR_BASE + N32_PWR_PWR_BKP_EMC_CR1_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/** PVD level config **/ +#define PWR_PVD_LEVEL_MASK ((uint32_t)0x001E0000U) +#define PWR_PVD_LEVEL_1V78 ((uint32_t)0x00000000U) +#define PWR_PVD_LEVEL_1V88 ((uint32_t)0x00020000U) +#define PWR_PVD_LEVEL_1V98 ((uint32_t)0x00040000U) +#define PWR_PVD_LEVEL_2V08 ((uint32_t)0x00060000U) +#define PWR_PVD_LEVEL_2V18 ((uint32_t)0x00080000U) +#define PWR_PVD_LEVEL_2V28 ((uint32_t)0x000A0000U) +#define PWR_PVD_LEVEL_2V38 ((uint32_t)0x000C0000U) +#define PWR_PVD_LEVEL_2V48 ((uint32_t)0x000E0000U) +#define PWR_PVD_LEVEL_2V58 ((uint32_t)0x00100000U) +#define PWR_PVD_LEVEL_2V68 ((uint32_t)0x00120000U) +#define PWR_PVD_LEVEL_2V78 ((uint32_t)0x00140000U) +#define PWR_PVD_LEVEL_2V88 ((uint32_t)0x00160000U) +#define PWR_PVD_LEVEL_3V28 ((uint32_t)0x00180000U) +#define PWR_PVD_LEVEL_3V38 ((uint32_t)0x001A0000U) +#define PWR_PVD_LEVEL_3V48 ((uint32_t)0x001C0000U) +#define PWR_PVD_LEVEL_3V58 ((uint32_t)0x001E0000U) + +/** AVD level config **/ +#define PWR_AVD_LEVEL_MASK ((uint32_t)0x0000F000U) +#define PWR_AVD_LEVEL_1V78 ((uint32_t)0x00000000U) +#define PWR_AVD_LEVEL_1V88 ((uint32_t)0x00001000U) +#define PWR_AVD_LEVEL_1V98 ((uint32_t)0x00002000U) +#define PWR_AVD_LEVEL_2V08 ((uint32_t)0x00003000U) +#define PWR_AVD_LEVEL_2V18 ((uint32_t)0x00004000U) +#define PWR_AVD_LEVEL_2V28 ((uint32_t)0x00005000U) +#define PWR_AVD_LEVEL_2V38 ((uint32_t)0x00006000U) +#define PWR_AVD_LEVEL_2V48 ((uint32_t)0x00007000U) +#define PWR_AVD_LEVEL_2V58 ((uint32_t)0x00008000U) +#define PWR_AVD_LEVEL_2V68 ((uint32_t)0x00009000U) +#define PWR_AVD_LEVEL_2V78 ((uint32_t)0x0000A000U) +#define PWR_AVD_LEVEL_2V88 ((uint32_t)0x0000B000U) +#define PWR_AVD_LEVEL_3V28 ((uint32_t)0x0000C000U) +#define PWR_AVD_LEVEL_3V38 ((uint32_t)0x0000D000U) +#define PWR_AVD_LEVEL_3V48 ((uint32_t)0x0000E000U) +#define PWR_AVD_LEVEL_3V58 ((uint32_t)0x0000F000U) + +/* PWR M7 Control register 1 (PWR_M7CTRL1) */ +#define PWR_M7CTRL1_CVBTF (1 << 16) /* Bit 16: Clear VBAT flags */ +#define PWR_M7CTRL1_CSBF (1 << 3) /* Bit 3: Clear STANDBY flags */ +#define PWR_M7CTRL1_CWKUPF (1 << 2) /* Bit 2: Clear the pin wakeup bit */ +#define PWR_M7CTRL1_PDSEN (1 << 1) /* Bit 1: Power down deep sleep enable bit */ + +/* PWR M7 Control Status register (PWR_M7CTRLSTS) */ +#define PWR_M7CTRLSTS_WKUP6F (1 << 26) /* Bit 26: RTC wakeup flag */ +#define PWR_M7CTRLSTS_WKUP5F (1 << 25) /* Bit 25: WKUP5 pin PC1 wakeup flag */ +#define PWR_M7CTRLSTS_WKUP4F (1 << 24) /* Bit 24: WKUP4 pin PI11 wakeup flag */ +#define PWR_M7CTRLSTS_WKUP3F (1 << 23) /* Bit 23: WKUP3 pin PI8 wakeup flag */ +#define PWR_M7CTRLSTS_WKUP2F (1 << 22) /* Bit 22: WKUP2 pin PC13 wakeup flag */ +#define PWR_M7CTRLSTS_WKUP1F (1 << 21) /* Bit 21: WKUP1 pin PA2 wakeup flag */ +#define PWR_M7CTRLSTS_WKUP0F (1 << 20) /* Bit 20: WKUP0 pin PA0 wakeup flag */ + +#define PWR_M7CTRLSTS_WKUP5POL (1 << 19) /* Bit 19: Wake-up polarity for the WKUP5 pin PC1 */ +#define PWR_M7CTRLSTS_WKUP4POL (1 << 18) /* Bit 18: Wake-up polarity for the WKUP4 pin PI11 */ +#define PWR_M7CTRLSTS_WKUP3POL (1 << 17) /* Bit 17: Wake-up polarity for the WKUP3 pin PI8 */ +#define PWR_M7CTRLSTS_WKUP2POL (1 << 16) /* Bit 16: Wake-up polarity for the WKUP2 pin PC13 */ +#define PWR_M7CTRLSTS_WKUP1POL (1 << 15) /* Bit 15: Wake-up polarity for the WKUP1 pin PA2 */ +#define PWR_M7CTRLSTS_WKUP0POL (1 << 14) /* Bit 14: Wake-up polarity for the WKUP0 pin PA0 */ + +#define PWR_M7CTRLSTS_WKUP5EN (1 << 13) /* Bit 13: WKUP5 pin PC1 wakeup enable */ +#define PWR_M7CTRLSTS_WKUP4EN (1 << 12) /* Bit 12: WKUP4 pin PI11 wakeup enable */ +#define PWR_M7CTRLSTS_WKUP3EN (1 << 11) /* Bit 11: WKUP3 pin PI8 wakeup enable */ +#define PWR_M7CTRLSTS_WKUP2EN (1 << 10) /* Bit 10: WKUP2 pin PC13 wakeup enable */ +#define PWR_M7CTRLSTS_WKUP1EN (1 << 9) /* Bit 9: WKUP1 pin PA2 wakeup enable */ +#define PWR_M7CTRLSTS_WKUP0EN (1 << 8) /* Bit 8: WKUP0 pin PA0 wakeup enable */ + +#define PWR_M7CTRLSTS_VBATF (1 << 2) /* Bit 2: VBAT flag */ +#define PWR_M7CTRLSTS_SBF (1 << 1) /* Bit 1: STANDBY flag */ + +/* PWR M7 Control register 2 (PWR_M7CTRL2) */ +#define PWR_M7CTRL2_MEM_CNTVAL_SHIFT (25) /* Bits 25-30: Counter value for memory power ready count down */ +#define PWR_M7CTRL2_MEM_CNTVAL_MASK (0x3F << PWR_M7CTRL2_MEM_CNTVAL_SHIFT) + +#define PWR_M7CTRL2_PWR_CNTVAL_SHIFT (17) /* Bits 17-24: Counter value for CM7 logic power ready count down */ +#define PWR_M7CTRL2_PWR_CNTVAL_MASK (0xFF << PWR_M7CTRL2_PWR_CNTVAL_SHIFT) + +#define PWR_M7CTRL2_TCM_RDYMD_SHIFT (15) /* Bits 15-16: Selected the way of check TCM power ready for CM7 domain */ +#define PWR_M7CTRL2_TCM_RDYMD_MASK (0x3 << PWR_M7CTRL2_TCM_RDYMD_SHIFT) +# define PWR_M7CTRL2_TCM_RDYMD_RDY_ONLY (0x0 << PWR_M7CTRL2_TCM_RDYMD_SHIFT) /* 00: Check only RDY signal */ +# define PWR_M7CTRL2_TCM_RDYMD_DELAY (0x1 << PWR_M7CTRL2_TCM_RDYMD_SHIFT) /* 01: Check delay after enabled */ +# define PWR_M7CTRL2_TCM_RDYMD_RDY_DELAY (0x2 << PWR_M7CTRL2_TCM_RDYMD_SHIFT)/* 10: Check delay and RDY signal */ +# define PWR_M7CTRL2_TCM_RDYMD_DELAY_RDY (0x3 << PWR_M7CTRL2_TCM_RDYMD_SHIFT)/* 11: Check delay after RDY signal */ + +#define PWR_M7CTRL2_PWR_RDYMD_SHIFT (13) /* Bits 13-14: Selected the way of check power ready for CM7 domain */ +#define PWR_M7CTRL2_PWR_RDYMD_MASK (0x3 << PWR_M7CTRL2_PWR_RDYMD_SHIFT) +# define PWR_M7CTRL2_PWR_RDYMD_RDY_ONLY (0x0 << PWR_M7CTRL2_PWR_RDYMD_SHIFT) /* 00: Check only RDY signal */ +# define PWR_M7CTRL2_PWR_RDYMD_DELAY (0x1 << PWR_M7CTRL2_PWR_RDYMD_SHIFT) /* 01: Check delay after enabled */ +# define PWR_M7CTRL2_PWR_RDYMD_RDY_DELAY (0x2 << PWR_M7CTRL2_PWR_RDYMD_SHIFT)/* 10: Check delay and RDY signal */ +# define PWR_M7CTRL2_PWR_RDYMD_DELAY_RDY (0x3 << PWR_M7CTRL2_PWR_RDYMD_SHIFT)/* 11: Check delay after RDY signal */ + +#define PWR_M7CTRL2_HCLK_ONINSLP (1 << 12) /* Bit 12: HCLK on in sleep mode */ +#define PWR_M7CTRL2_NRST_WUPEN (1 << 11) /* Bit 11: NRST wakeup event enable in standby mode for M7 core */ +#define PWR_M7CTRL2_RTC_ALMWUPEN (1 << 8) /* Bit 8: RTC_ALARM wakeup enable in standby mode for M7 core */ +#define PWR_M7CTRL2_BSRSTBRET (1 << 2) /* Bit 2: Backup SRAM retention enable in STANDBY mode */ +#define PWR_M7CTRL2_BSRVBRET (1 << 1) /* Bit 1: Backup SRAM retention enable in VBAT mode */ +#define PWR_M7CTRL2_STOP2EN (1 << 0) /* Bit 0: M7 core STOP2 mode enable */ + +/* PWR M4 Control register 1 (PWR_M4CTRL1) */ +#define PWR_M4CTRL1_CVBTF (1 << 16) /* Bit 16: Clear VBAT flags */ +#define PWR_M4CTRL1_CSBF (1 << 3) /* Bit 3: Clear STANDBY flags */ +#define PWR_M4CTRL1_CWKUPF (1 << 2) /* Bit 2: Clear the pin wakeup bit */ +#define PWR_M4CTRL1_PDS (1 << 1) /* Bit 1: Power down deep sleep bit */ + +/* PWR M4 Control Status register (PWR_M4CTRLSTS) */ +#define PWR_M4CTRLSTS_WKUP6F (1 << 26) /* Bit 26: RTC wakeup flag */ +#define PWR_M4CTRLSTS_WKUP5F (1 << 25) /* Bit 25: WKUP5 pin PC1 wakeup flag */ +#define PWR_M4CTRLSTS_WKUP4F (1 << 24) /* Bit 24: WKUP4 pin PI11 wakeup flag */ +#define PWR_M4CTRLSTS_WKUP3F (1 << 23) /* Bit 23: WKUP3 pin PI8 wakeup flag */ +#define PWR_M4CTRLSTS_WKUP2F (1 << 22) /* Bit 22: WKUP2 pin PC13 wakeup flag */ +#define PWR_M4CTRLSTS_WKUP1F (1 << 21) /* Bit 21: WKUP1 pin PA2 wakeup flag */ +#define PWR_M4CTRLSTS_WKUP0F (1 << 20) /* Bit 20: WKUP0 pin PA0 wakeup flag */ + +#define PWR_M4CTRLSTS_WKUP5POL (1 << 19) /* Bit 19: Wake-up polarity for the WKUP5 pin PC1 */ +#define PWR_M4CTRLSTS_WKUP4POL (1 << 18) /* Bit 18: Wake-up polarity for the WKUP4 pin PI11 */ +#define PWR_M4CTRLSTS_WKUP3POL (1 << 17) /* Bit 17: Wake-up polarity for the WKUP3 pin PI8 */ +#define PWR_M4CTRLSTS_WKUP2POL (1 << 16) /* Bit 16: Wake-up polarity for the WKUP2 pin PC13 */ +#define PWR_M4CTRLSTS_WKUP1POL (1 << 15) /* Bit 15: Wake-up polarity for the WKUP1 pin PA2 */ +#define PWR_M4CTRLSTS_WKUP0POL (1 << 14) /* Bit 14: Wake-up polarity for the WKUP0 pin PA0 */ + +#define PWR_M4CTRLSTS_WKUP5EN (1 << 13) /* Bit 13: WKUP5 pin PC1 wakeup enable */ +#define PWR_M4CTRLSTS_WKUP4EN (1 << 12) /* Bit 12: WKUP4 pin PI11 wakeup enable */ +#define PWR_M4CTRLSTS_WKUP3EN (1 << 11) /* Bit 11: WKUP3 pin PI8 wakeup enable */ +#define PWR_M4CTRLSTS_WKUP2EN (1 << 10) /* Bit 10: WKUP2 pin PC13 wakeup enable */ +#define PWR_M4CTRLSTS_WKUP1EN (1 << 9) /* Bit 9: WKUP1 pin PA2 wakeup enable */ +#define PWR_M4CTRLSTS_WKUP0EN (1 << 8) /* Bit 8: WKUP0 pin PA0 wakeup enable */ + +#define PWR_M4CTRLSTS_VBATF (1 << 2) /* Bit 2: VBAT flag */ +#define PWR_M4CTRLSTS_SBF (1 << 1) /* Bit 1: STANDBY flag */ + +/* PWR M4 Control register 2 (PWR_M4CTRL2) */ +#define PWR_M4CTRL2_MEM_CNTVAL_SHIFT (25) /* Bits 25-30: Counter value for memory power ready count down */ +#define PWR_M4CTRL2_MEM_CNTVAL_MASK (0x3F << PWR_M4CTRL2_MEM_CNTVAL_SHIFT) + +#define PWR_M4CTRL2_PWR_CNTVAL_SHIFT (17) /* Bits 17-24: Counter value for CM4 logic power ready count down */ +#define PWR_M4CTRL2_PWR_CNTVAL_MASK (0xFF << PWR_M4CTRL2_PWR_CNTVAL_SHIFT) + +#define PWR_M4CTRL2_TCM_RDYMD_SHIFT (15) /* Bits 15-16: Selected the way of check TCM power ready for CM4 domain */ +#define PWR_M4CTRL2_TCM_RDYMD_MASK (0x3 << PWR_M4CTRL2_TCM_RDYMD_SHIFT) +# define PWR_M4CTRL2_TCM_RDYMD_RDY_ONLY (0x0 << PWR_M4CTRL2_TCM_RDYMD_SHIFT) /* 00: Check only RDY signal */ +# define PWR_M4CTRL2_TCM_RDYMD_DELAY (0x1 << PWR_M4CTRL2_TCM_RDYMD_SHIFT) /* 01: Check delay after enabled */ +# define PWR_M4CTRL2_TCM_RDYMD_RDY_DELAY (0x2 << PWR_M4CTRL2_TCM_RDYMD_SHIFT)/* 10: Check delay and RDY signal */ +# define PWR_M4CTRL2_TCM_RDYMD_DELAY_RDY (0x3 << PWR_M4CTRL2_TCM_RDYMD_SHIFT)/* 11: Check delay after RDY signal */ + +#define PWR_M4CTRL2_PWR_RDYMD_SHIFT (13) /* Bits 13-14: Selected the way of check power ready for CM4 domain */ +#define PWR_M4CTRL2_PWR_RDYMD_MASK (0x3 << PWR_M4CTRL2_PWR_RDYMD_SHIFT) +# define PWR_M4CTRL2_PWR_RDYMD_RDY_ONLY (0x0 << PWR_M4CTRL2_PWR_RDYMD_SHIFT) /* 00: Check only RDY signal */ +# define PWR_M4CTRL2_PWR_RDYMD_DELAY (0x1 << PWR_M4CTRL2_PWR_RDYMD_SHIFT) /* 01: Check delay after enabled */ +# define PWR_M4CTRL2_PWR_RDYMD_RDY_DELAY (0x2 << PWR_M4CTRL2_PWR_RDYMD_SHIFT)/* 10: Check delay and RDY signal */ +# define PWR_M4CTRL2_PWR_RDYMD_DELAY_RDY (0x3 << PWR_M4CTRL2_PWR_RDYMD_SHIFT)/* 11: Check delay after RDY signal */ + +#define PWR_M4CTRL2_HCLK_ONINSLP (1 << 12) /* Bit 12: HCLK on in sleep mode */ +#define PWR_M4CTRL2_NRST_WUPEN (1 << 11) /* Bit 11: NRST wakeup event enable in standby mode for M4 core */ +#define PWR_M4CTRL2_RTC_ALMWUPEN (1 << 8) /* Bit 8: RTC_ALARM wakeup enable in standby mode for M4 core */ +#define PWR_M4CTRL2_BSRSTBRET (1 << 2) /* Bit 2: Backup SRAM retention enable in STANDBY mode */ +#define PWR_M4CTRL2_BSRVBRET (1 << 1) /* Bit 1: Backup SRAM retention enable in VBAT mode */ +#define PWR_M4CTRL2_STOP2EN (1 << 0) /* Bit 0: M4 core STOP2 mode enable */ + +/* PWR System Control register 1 (PWR_SYSCTRL1) */ +#define PWR_SYSCTRL1_DCDC_VSELKEY_SHIFT (28) /* Bits 28-31: DCDC_VSELKEY_UNLOCK key */ +#define PWR_SYSCTRL1_DCDC_VSELKEY_MASK (0xF << PWR_SYSCTRL1_DCDC_VSELKEY_SHIFT) +# define PWR_SYSCTRL1_DCDC_VSELKEY_UNLOCK (0xF << PWR_SYSCTRL1_DCDC_VSELKEY_SHIFT) /* 1111: Unlock */ + +#define PWR_SYSCTRL1_NRST_DGFCNT_SHIFT (16) /* Bits 16-27: Digital Glitch Filter on NRST filtered pulse width configuration */ +#define PWR_SYSCTRL1_NRST_DGFCNT_MASK (0xFFF << PWR_SYSCTRL1_NRST_DGFCNT_SHIFT) + +#define PWR_SYSCTRL1_NRST_DGFBP (1 << 15) /* Bit 15: Bypass digital glitch Filter on NRST */ +#define PWR_SYSCTRL1_AGF_STBWUPPBP (1 << 13) /* Bit 13: Bypass analog glitch filter on standby wakeup pads */ +#define PWR_SYSCTRL1_AGF_DTASGBP (1 << 12) /* Bit 12: Bypass analog glitch filter on some digital to analog enable signals */ +#define PWR_SYSCTRL1_AGF_ARSTOBP (1 << 11) /* Bit 11: Bypass analog glitch filter on analog reset outputs */ +#define PWR_SYSCTRL1_DBKP (1 << 8) /* Bit 8: Disable write protection for the backup domain */ +#define PWR_SYSCTRL1_PVDEN (1 << 4) /* Bit 4: Power Voltage Detector (PVD) Enable */ +#define PWR_SYSCTRL1_AVDEN (1 << 3) /* Bit 3: Analog Voltage Detector (AVD) Enable */ +#define PWR_SYSCTRL1_BKPLDOEN (1 << 1) /* Bit 1: Backup LDO enable */ +#define PWR_SYSCTRL1_BKPLDO_CTRLEN (1 << 0) /* Bit 0: Backup LDO control enable */ + +/* PWR System Control Status register (PWR_SYSCTRLSTS) */ +#define PWR_SYSCTRLSTS_PVDO (1 << 4) /* Bit 4: PVD output */ +#define PWR_SYSCTRLSTS_AVDO (1 << 3) /* Bit 3: AVD output */ +#define PWR_SYSCTRLSTS_OTPPWRRDY (1 << 1) /* Bit 1: OTP Power Ready */ +#define PWR_SYSCTRLSTS_DCDCBPF (1 << 0) /* Bit 0: DCDC Bypass flag */ + +/* PWR System Control register 2 (PWR_SYSCTRL2) */ +#define PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT (24) /* Bits 24-26: Clock divisor for OTP low power mode */ +#define PWR_SYSCTRL2_OTP_LPCLKDIV_MASK (0x7 << PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT) +# define PWR_SYSCTRL2_OTP_LPCLKDIV_DIV1 (0x0 << PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT) /* 000: No division */ +# define PWR_SYSCTRL2_OTP_LPCLKDIV_DIV2 (0x1 << PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT) /* 001: Divide by 2 */ +# define PWR_SYSCTRL2_OTP_LPCLKDIV_DIV3 (0x2 << PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT) /* 010: Divide by 3 */ +# define PWR_SYSCTRL2_OTP_LPCLKDIV_DIV4 (0x3 << PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT) /* 011: Divide by 4 */ +# define PWR_SYSCTRL2_OTP_LPCLKDIV_DIV5 (0x4 << PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT) /* 100: Divide by 5 */ +# define PWR_SYSCTRL2_OTP_LPCLKDIV_DIV6 (0x5 << PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT) /* 101: Divide by 6 */ +# define PWR_SYSCTRL2_OTP_LPCLKDIV_DIV7 (0x6 << PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT) /* 110: Divide by 7 */ +# define PWR_SYSCTRL2_OTP_LPCLKDIV_DIV8 (0x7 << PWR_SYSCTRL2_OTP_LPCLKDIV_SHIFT) /* 111: Divide by 8 */ + +#define PWR_SYSCTRL2_OTP_FRCSTB (1 << 23) /* Bit 23: OTP force STBY */ +#define PWR_SYSCTRL2_OTP_FRCDSTB (1 << 22) /* Bit 22: OTP force DSTBY */ +#define PWR_SYSCTRL2_OTP_STB_INSTP0 (1 << 21) /* Bit 21: OTP STBY in STOP0 mode */ +#define PWR_SYSCTRL2_OTP_DSTB_INSTP0 (1 << 20) /* Bit 20: OTP DSTBY in STOP0 mode */ +#define PWR_SYSCTRL2_OTP_STB_INSTP2 (1 << 19) /* Bit 19: OTP STBY in STOP2 mode */ +#define PWR_SYSCTRL2_OTP_DSTB_INSTP2 (1 << 18) /* Bit 18: OTP DSTBY in STOP2 mode */ +#define PWR_SYSCTRL2_EXTI_MASKRSTEN (1 << 17) /* Bit 17: EXTI mask reset enable */ +#define PWR_SYSCTRL2_VDDDM_RDYMD (1 << 16) /* Bit 16: VDDDM ready mode */ +#define PWR_SYSCTRL2_BKPLDO_CTRLEN (1 << 11) /* Bit 11: Backup LDO control enable */ +#define PWR_SYSCTRL2_MR_STBOFFEN (1 << 1) /* Bit 1: Main regulator off in standby mode */ + +/* PWR System Control register 3 (PWR_SYSCTRL3) */ +#define PWR_SYSCTRL3_HSC2_PSWACK1 (1 << 22) /* Bit 22: HSC2 power switch ACK1 */ +#define PWR_SYSCTRL3_HSC1_PSWACK1 (1 << 21) /* Bit 21: HSC1 power switch ACK1 */ +#define PWR_SYSCTRL3_GRC_PSWACK1 (1 << 20) /* Bit 20: GRC power switch ACK1 */ + +#define PWR_SYSCTRL3_HSC2_PWRRDY (1 << 18) /* Bit 18: HSC2 power domain ready flag */ +#define PWR_SYSCTRL3_HSC1_PWRRDY (1 << 17) /* Bit 17: HSC1 power domain ready flag */ +#define PWR_SYSCTRL3_GRC_PWRRDY (1 << 16) /* Bit 16: GRC power domain ready flag */ + +#define PWR_SYSCTRL3_HSC2_ISNEN (1 << 10) /* Bit 10: HSC2 power domain isolation signal */ +#define PWR_SYSCTRL3_HSC1_ISNEN (1 << 9) /* Bit 9: HSC1 power domain isolation signal */ +#define PWR_SYSCTRL3_GRC_ISNEN (1 << 8) /* Bit 8: GRC power domain isolation signal */ + +#define PWR_SYSCTRL3_HSC2_FUCEN (1 << 6) /* Bit 6: HSC2 function mode enable */ +#define PWR_SYSCTRL3_HSC1_FUCEN (1 << 5) /* Bit 5: HSC1 function mode enable */ +#define PWR_SYSCTRL3_GRC_FUCEN (1 << 4) /* Bit 4: GRC function mode enable */ + +#define PWR_SYSCTRL3_HSC2_PGEN (1 << 2) /* Bit 2: HSC2 power gate enable */ +#define PWR_SYSCTRL3_HSC1_PGEN (1 << 1) /* Bit 1: HSC1 power gate enable */ +#define PWR_SYSCTRL3_GRC_PGEN (1 << 0) /* Bit 0: GRC power gate enable */ + +/* PWR System Control register 4 (PWR_SYSCTRL4) */ +#define PWR_SYSCTRL4_MR_LP_VSELEN (1 << 29) /* Bit 29: Enable targeting MR voltage output in low power mode */ +#define PWR_SYSCTRL4_DCDC_LP_VSEL_SHIFT (24) /* Bits 24-27: Targeting dcdc voltage in low power mode */ +#define PWR_SYSCTRL4_DCDC_LP_VSEL_MASK (0xF << PWR_SYSCTRL4_DCDC_LP_VSEL_SHIFT) +# define PWR_SYSCTRL4_DCDC_LP_VSEL_0_80V (0x5 << PWR_SYSCTRL4_DCDC_LP_VSEL_SHIFT) /* 0101: 0.80V */ +# define PWR_SYSCTRL4_DCDC_LP_VSEL_0_85V (0x6 << PWR_SYSCTRL4_DCDC_LP_VSEL_SHIFT) /* 0110: 0.85V */ +# define PWR_SYSCTRL4_DCDC_LP_VSEL_0_90V (0x7 << PWR_SYSCTRL4_DCDC_LP_VSEL_SHIFT) /* 0111: 0.90V */ + +#define PWR_SYSCTRL4_VDDD_LP_PORSEL_SHIFT (22) /* Bits 22-23: VDDD POR config in low power mode */ +#define PWR_SYSCTRL4_VDDD_LP_PORSEL_MASK (0x3 << PWR_SYSCTRL4_VDDD_LP_PORSEL_SHIFT) +# define PWR_SYSCTRL4_VDDD_LP_PORSEL_0_7V_0_65V (0x0 << PWR_SYSCTRL4_VDDD_LP_PORSEL_SHIFT) /* 00: POR 0.7V, PDR 0.65V */ +# define PWR_SYSCTRL4_VDDD_LP_PORSEL_0_7V_0_65V_ALT (0x1 << PWR_SYSCTRL4_VDDD_LP_PORSEL_SHIFT) /* 01: POR 0.7V, PDR 0.65V */ +# define PWR_SYSCTRL4_VDDD_LP_PORSEL_0_75V_0_7V (0x2 << PWR_SYSCTRL4_VDDD_LP_PORSEL_SHIFT) /* 10: POR 0.75V, PDR 0.7V */ +# define PWR_SYSCTRL4_VDDD_LP_PORSEL_0_8V_0_75V (0x3 << PWR_SYSCTRL4_VDDD_LP_PORSEL_SHIFT) /* 11: POR 0.8V, PDR 0.75V */ + +#define PWR_SYSCTRL4_DCDC_LP_PORVSEL_SHIFT (17) /* Bits 17-21: DCDC POR voltage value in low power mode */ +#define PWR_SYSCTRL4_DCDC_LP_PORVSEL_MASK (0x1F << PWR_SYSCTRL4_DCDC_LP_PORVSEL_SHIFT) +# define PWR_SYSCTRL4_DCDC_LP_PORVSEL_0_8V (0x5 << PWR_SYSCTRL4_DCDC_LP_PORVSEL_SHIFT) /* 00101: 0.8V */ +# define PWR_SYSCTRL4_DCDC_LP_PORVSEL_0_85V (0x6 << PWR_SYSCTRL4_DCDC_LP_PORVSEL_SHIFT) /* 00110: 0.85V */ +# define PWR_SYSCTRL4_DCDC_LP_PORVSEL_0_9V (0x7 << PWR_SYSCTRL4_DCDC_LP_PORVSEL_SHIFT) /* 00111: 0.9V */ + +#define PWR_SYSCTRL4_BG_LPVREF (1 << 16) /* Bit 16: Targeting BG ref in low power mode */ +#define PWR_SYSCTRL4_BG_VREF (1 << 15) /* Bit 15: BG voltage reference select */ +#define PWR_SYSCTRL4_VDDD_PORSEL_SHIFT (12) /* Bits 12-13: VDDD POR config in low power mode */ +#define PWR_SYSCTRL4_VDDD_PORSEL_MASK (0x3 << PWR_SYSCTRL4_VDDD_PORSEL_SHIFT) +# define PWR_SYSCTRL4_VDDD_PORSEL_0_7V_0_65V (0x0 << PWR_SYSCTRL4_VDDD_PORSEL_SHIFT) /* 00: POR 0.7V, PDR 0.65V */ +# define PWR_SYSCTRL4_VDDD_PORSEL_0_75V_0_7V (0x2 << PWR_SYSCTRL4_VDDD_PORSEL_SHIFT) /* 10: POR 0.75V, PDR 0.7V */ +# define PWR_SYSCTRL4_VDDD_PORSEL_0_8V_0_75V (0x3 << PWR_SYSCTRL4_VDDD_PORSEL_SHIFT) /* 11: POR 0.8V, PDR 0.75V */ + +#define PWR_SYSCTRL4_MLDO_LPO_VSEL_SHIFT (8) /* Bits 8-9: Output voltage of Main Regulator LDO option in SYS STOP2 and STANDBY mode */ +#define PWR_SYSCTRL4_MLDO_LPO_VSEL_MASK (0x3 << PWR_SYSCTRL4_MLDO_LPO_VSEL_SHIFT) +# define PWR_SYSCTRL4_MLDO_LPO_VSEL_0_8V (0x0 << PWR_SYSCTRL4_MLDO_LPO_VSEL_SHIFT) /* 00: 0.8V */ +# define PWR_SYSCTRL4_MLDO_LPO_VSEL_0_85V (0x1 << PWR_SYSCTRL4_MLDO_LPO_VSEL_SHIFT) /* 01: 0.85V */ +# define PWR_SYSCTRL4_MLDO_LPO_VSEL_0_9V (0x2 << PWR_SYSCTRL4_MLDO_LPO_VSEL_SHIFT) /* 10: 0.9V */ + +#define PWR_SYSCTRL4_MLDO_OVSEL_SHIFT (8) /* Bits 8-9: Output voltage of Main Regulator LDO option in SYS RUN mode */ +#define PWR_SYSCTRL4_MLDO_OVSEL_MASK (0x3 << PWR_SYSCTRL4_MLDO_OVSEL_SHIFT) +# define PWR_SYSCTRL4_MLDO_OVSEL_0_8V (0x0 << PWR_SYSCTRL4_MLDO_OVSEL_SHIFT) /* 00: 0.8V */ +# define PWR_SYSCTRL4_MLDO_OVSEL_0_85V (0x1 << PWR_SYSCTRL4_MLDO_OVSEL_SHIFT) /* 01: 0.85V */ +# define PWR_SYSCTRL4_MLDO_OVSEL_0_9V (0x2 << PWR_SYSCTRL4_MLDO_OVSEL_SHIFT) /* 10: 0.9V */ + +#define PWR_SYSCTRL4_DCD_FRCEN (1 << 3) /* Bit 3: DCDC force enable */ +#define PWR_SYSCTRL4_DCDEN (1 << 2) /* Bit 2: DCDC enable */ +#define PWR_SYSCTRL4_MLDOEN (1 << 1) /* Bit 1: Main regulator LDO enable */ +#define PWR_SYSCTRL4_VCORESRC (1 << 0) /* Bit 0: VCORE source select */ + +#define PWR_VCORESRC_MASK (PWR_SYSCTRL4_DCD_FRCEN|PWR_SYSCTRL4_DCDEN|\ + PWR_SYSCTRL4_MLDOEN|PWR_SYSCTRL4_VCORESRC) + +typedef enum +{ + PWR_VCORESRC_EXT = 0, + PWR_VCORESRC_LDO, + PWR_VCORESRC_SMPS, +} pwr_vcoresrc_e; + +/* PWR IP Memory Control register (PWR_IPMEMCTRL) */ +#define PWR_IPMEMCTRL_ESC_PGEN (1 << 12) /* Bit 12: ESC memory power gate enable */ +#define PWR_IPMEMCTRL_FMAC_PGEN (1 << 11) /* Bit 11: FMAC memory power gate enable */ +#define PWR_IPMEMCTRL_SDMMC1_PGEN (1 << 10) /* Bit 10: SDMMC1 memory power gate enable */ +#define PWR_IPMEMCTRL_USB1_PGEN (1 << 9) /* Bit 9: USB1 memory power gate enable */ +#define PWR_IPMEMCTRL_ETH1_PGEN (1 << 8) /* Bit 8: ETH1 memory power gate enable */ +#define PWR_IPMEMCTRL_SDMMC2_PGEN (1 << 7) /* Bit 7: SDMMC2 memory power gate enable */ +#define PWR_IPMEMCTRL_USB2_PGEN (1 << 6) /* Bit 6: USB2 memory power gate enable */ +#define PWR_IPMEMCTRL_ETH2_PGEN (1 << 5) /* Bit 5: ETH2 memory power gate enable */ +#define PWR_IPMEMCTRL_DVP_PGEN (1 << 4) /* Bit 4: DVP memory power gate enable */ +#define PWR_IPMEMCTRL_DSI_PGEN (1 << 3) /* Bit 3: DSI memory power gate enable */ +#define PWR_IPMEMCTRL_JPEG_PGEN (1 << 2) /* Bit 2: JPEG memory power gate enable */ +#define PWR_IPMEMCTRL_LCDC_PGEN (1 << 1) /* Bit 1: LCDC memory power gate enable */ +#define PWR_IPMEMCTRL_GPU_PGEN (1 << 0) /* Bit 0: GPU memory power gate enable */ + +/* PWR IP Memory Status register (PWR_IPMEMSTS) */ +#define PWR_IPMEMSTS_ALLIP_PRDY (1 << 31) /* Bit 31: ALL IP memory power ready flag */ +#define PWR_IPMEMSTS_ESC_PRDY (1 << 12) /* Bit 12: ESC memory power ready flag */ +#define PWR_IPMEMSTS_FMAC_PRDY (1 << 11) /* Bit 11: FMAC memory power ready flag */ +#define PWR_IPMEMSTS_SDMMC1_PRDY (1 << 10) /* Bit 10: SDMMC1 memory power ready flag */ +#define PWR_IPMEMSTS_USB1_PRDY (1 << 9) /* Bit 9: USB1 memory power ready flag */ +#define PWR_IPMEMSTS_ETH1_PRDY (1 << 8) /* Bit 8: ETH1 memory power ready flag */ +#define PWR_IPMEMSTS_SDMMC2_PRDY (1 << 7) /* Bit 7: SDMMC2 memory power ready flag */ +#define PWR_IPMEMSTS_USB2_PRDY (1 << 6) /* Bit 6: USB2 memory power ready flag */ +#define PWR_IPMEMSTS_ETH2_PRDY (1 << 5) /* Bit 5: ETH2 memory power ready flag */ +#define PWR_IPMEMSTS_DVP_PRDY (1 << 4) /* Bit 4: DVP memory power ready flag */ +#define PWR_IPMEMSTS_DSI_PRDY (1 << 3) /* Bit 3: DSI memory power ready flag */ +#define PWR_IPMEMSTS_JPEG_PRDY (1 << 2) /* Bit 2: JPEG memory power ready flag */ +#define PWR_IPMEMSTS_LCDC_PRDY (1 << 1) /* Bit 1: LCDC memory power ready flag */ +#define PWR_IPMEMSTS_GPU_PRDY (1 << 0) /* Bit 0: GPU memory power ready flag */ + +/* PWR CM7 Memory Low Power Control register (PWR_M7MEMLPCTRL) */ +#define PWR_M7MEMLPCTRL_MEM_PGCFG_SHIFT (2) /* Bits 2-3: Memory power gate sequence control */ +#define PWR_M7MEMLPCTRL_MEM_PGCFG_MASK (0x3 << PWR_M7MEMLPCTRL_MEM_PGCFG_SHIFT) +# define PWR_M7MEMLPCTRL_MEM_PGCFG_CM7ALL (0x0 << PWR_M7MEMLPCTRL_MEM_PGCFG_SHIFT) /* 00: All CM7 memories in one daisy chain */ +# define PWR_M7MEMLPCTRL_MEM_PGCFG_DITCM (0x1 << PWR_M7MEMLPCTRL_MEM_PGCFG_SHIFT) /* 01: D-cache -> I-cache -> TCM daisy */ +# define PWR_M7MEMLPCTRL_MEM_PGCFG_DIC (0x2 << PWR_M7MEMLPCTRL_MEM_PGCFG_SHIFT) /* 10: D-cache + I-cache -> every 4 pieces of TCM memory */ +# define PWR_M7MEMLPCTRL_MEM_PGCFG_ALL (0x3 << PWR_M7MEMLPCTRL_MEM_PGCFG_SHIFT) /* 11: All memory in one daisy chain */ + +#define PWR_M7MEMLPCTRL_MEM_RETSTP0EN_SHIFT (0) /* Bits 0-1: Memory retention mode select in STOP0 */ +#define PWR_M7MEMLPCTRL_MEM_RETSTP0EN_MASK (0x3 << PWR_M7MEMLPCTRL_MEM_RETSTP0EN_SHIFT) +# define PWR_M7MEMLPCTRL_MEM_RETSTP0EN_CHIP_DISABLE (0x0 << PWR_M7MEMLPCTRL_MEM_RETSTP0EN_SHIFT) /* 00: Chip disable mode */ +# define PWR_M7MEMLPCTRL_MEM_RETSTP0EN_PRECHARGE (0x1 << PWR_M7MEMLPCTRL_MEM_RETSTP0EN_SHIFT) /* 01: Precharge mode */ +# define PWR_M7MEMLPCTRL_MEM_RETSTP0EN_RETENTION1 (0x3 << PWR_M7MEMLPCTRL_MEM_RETSTP0EN_SHIFT) /* 11: Retention 1 mode */ + +#define PWR_M7MEMLPCTRL_MEM_PGSTP0EN_SHIFT (0) /* Bits 0-1: Memory power gate mode select in STOP0 */ +#define PWR_M7MEMLPCTRL_MEM_PGSTP0EN_MASK (0x3 << PWR_M7MEMLPCTRL_MEM_PGSTP0EN_SHIFT) +# define PWR_M7MEMLPCTRL_MEM_PGSTP0EN_CHIP_DISABLE (0x0 << PWR_M7MEMLPCTRL_MEM_PGSTP0EN_SHIFT) /* 00: Chip disable mode */ +# define PWR_M7MEMLPCTRL_MEM_PGSTP0EN_PRECHARGE (0x1 << PWR_M7MEMLPCTRL_MEM_PGSTP0EN_SHIFT) /* 01: Precharge mode */ +# define PWR_M7MEMLPCTRL_MEM_PGSTP0EN_RETENTION1 (0x3 << PWR_M7MEMLPCTRL_MEM_PGSTP0EN_SHIFT) /* 11: Retention 1 mode */ + +/* PWR CM7 Memory Low Power Status register (PWR_M7MEMLPSTS) */ +#define PWR_M7MEMLPSTS_TCMRDY (1 << 31) /* Bit 31: All enabled TCM memory power ready flag */ + +/* PWR CM7 TCM Part0 Program register (PWR_M7TCMPG0) */ +#define PWR_M7TCMPG0_TCM_PG0_SHIFT (0) /* Bits 0-31: Software control to power gate TCM Part0 memories */ +#define PWR_M7TCMPG0_TCM_PG0_MASK (0xFFFFFFFF << PWR_M7TCMPG0_TCM_PG0_SHIFT) + +/* PWR CM7 TCM Part1 Program register (PWR_M7TCMPG1) */ +#define PWR_M7TCMPG1_TCM_PG1_SHIFT (0) /* Bits 0-31: Software control to power gate TCM Part1 memories */ +#define PWR_M7TCMPG1_TCM_PG1_MASK (0xFFFFFFFF << PWR_M7TCMPG1_TCM_PG1_SHIFT) + +/* PWR CM7 TCM Part0 Retain 1 register (PWR_M7TCMRET1N0) */ +#define PWR_M7TCMRET1N0_TCM_RENT1N0_SHIFT (0) /* Bits 0-31: TCM Part0 Retain 1 mode select */ +#define PWR_M7TCMRET1N0_TCM_RENT1N0_MASK (0xFFFFFFFF << PWR_M7TCMRET1N0_TCM_RENT1N0_SHIFT) + +/* PWR CM7 TCM Part1 Retain 1 register (PWR_M7TCMRET1N1) */ +#define PWR_M7TCMRET1N1_TCM_RENT1N1_SHIFT (0) /* Bits 0-31: TCM Part1 Retain 1 mode select */ +#define PWR_M7TCMRET1N1_TCM_RENT1N1_MASK (0xFFFFFFFF << PWR_M7TCMRET1N1_TCM_RENT1N1_SHIFT) + +/* PWR CM7 TCM Part0 Retain 2 register (PWR_M7TCMRET2N0) */ +#define PWR_M7TCMRET2N0_TCM_RENT2N0_SHIFT (0) /* Bits 0-31: TCM Part0 Retain 2 mode select */ +#define PWR_M7TCMRET2N0_TCM_RENT2N0_MASK (0xFFFFFFFF << PWR_M7TCMRET2N0_TCM_RENT2N0_SHIFT) + +/* PWR CM7 TCM Part1 Retain 2 register (PWR_M7TCMRET2N1) */ +#define PWR_M7TCMRET2N1_TCM_RENT2N1_SHIFT (0) /* Bits 0-31: TCM Part1 Retain 2 mode select */ +#define PWR_M7TCMRET2N1_TCM_RENT2N1_MASK (0xFFFFFFFF << PWR_M7TCMRET2N1_TCM_RENT2N1_SHIFT) + +/* PWR CM7 TCM Part0 Power Ready register (PWR_M7TCMRDY0) */ +#define PWR_M7TCMRDY0_TCM_RDY0_SHIFT (0) /* Bits 0-31: TCM Part0 Power Ready flag */ +#define PWR_M7TCMRDY0_TCM_RDY0_MASK (0xFFFFFFFF << PWR_M7TCMRDY0_TCM_RDY0_SHIFT) + +/* PWR CM7 TCM Part1 Power Ready register (PWR_M7TCMRDY1) */ +#define PWR_M7TCMRDY1_TCM_RDY1_SHIFT (0) /* Bits 0-31: TCM Part1 Power Ready flag */ +#define PWR_M7TCMRDY1_TCM_RDY1_MASK (0xFFFFFFFF << PWR_M7TCMRDY1_TCM_RDY1_SHIFT) + +/* PWR CM4 Memory Low Power Control register (PWR_M4MEMLPCTRL) */ +#define PWR_M4MEMLPCTRL_MEM_PGCFG_SHIFT (2) /* Bits 2-3: Memory power gate sequence control */ +#define PWR_M4MEMLPCTRL_MEM_PGCFG_MASK (0x3 << PWR_M4MEMLPCTRL_MEM_PGCFG_SHIFT) +# define PWR_M4MEMLPCTRL_MEM_PGCFG_CM4ALL (0x0 << PWR_M4MEMLPCTRL_MEM_PGCFG_SHIFT) /* 00: All CM4 memories in one daisy chain */ +# define PWR_M4MEMLPCTRL_MEM_PGCFG_ALL_PARALLEL (0x1 << PWR_M4MEMLPCTRL_MEM_PGCFG_SHIFT) /* 01: All memory parallel */ +# define PWR_M4MEMLPCTRL_MEM_PGCFG_DITCM (0x2 << PWR_M4MEMLPCTRL_MEM_PGCFG_SHIFT) /* 10: D-cache -> I-cache, parallel within each group */ +# define PWR_M4MEMLPCTRL_MEM_PGCFG_ALL (0x3 << PWR_M4MEMLPCTRL_MEM_PGCFG_SHIFT) /* 11: All memory in one daisy chain */ + +#define PWR_M4MEMLPCTRL_MEM_RETSTP0EN_SHIFT (0) /* Bits 0-1: Memory retention mode select in STOP0 */ +#define PWR_M4MEMLPCTRL_MEM_RETSTP0EN_MASK (0x3 << PWR_M4MEMLPCTRL_MEM_RETSTP0EN_SHIFT) +# define PWR_M4MEMLPCTRL_MEM_RETSTP0EN_CHIP_DISABLE (0x0 << PWR_M4MEMLPCTRL_MEM_RETSTP0EN_SHIFT) /* 00: Chip disable mode */ +# define PWR_M4MEMLPCTRL_MEM_RETSTP0EN_PRECHARGE (0x1 << PWR_M4MEMLPCTRL_MEM_RETSTP0EN_SHIFT) /* 01: Precharge mode */ +# define PWR_M4MEMLPCTRL_MEM_RETSTP0EN_RETENTION1 (0x3 << PWR_M4MEMLPCTRL_MEM_RETSTP0EN_SHIFT) /* 11: Retention 1 mode */ + +#define PWR_M4MEMLPCTRL_MEM_PGSTP0EN_SHIFT (0) /* Bits 0-1: Memory power gate mode select in STOP0 */ +#define PWR_M4MEMLPCTRL_MEM_PGSTP0EN_MASK (0x3 << PWR_M4MEMLPCTRL_MEM_PGSTP0EN_SHIFT) +# define PWR_M4MEMLPCTRL_MEM_PGSTP0EN_CHIP_DISABLE (0x0 << PWR_M4MEMLPCTRL_MEM_PGSTP0EN_SHIFT) /* 00: Chip disable mode */ +# define PWR_M4MEMLPCTRL_MEM_PGSTP0EN_PRECHARGE (0x1 << PWR_M4MEMLPCTRL_MEM_PGSTP0EN_SHIFT) /* 01: Precharge mode */ +# define PWR_M4MEMLPCTRL_MEM_PGSTP0EN_RETENTION1 (0x3 << PWR_M4MEMLPCTRL_MEM_PGSTP0EN_SHIFT) /* 11: Retention 1 mode */ + +/* PWR System Memory Low Power Control register (PWR_SYSMEMLPCTRL) */ +#define PWR_SYSMEMLPCTRL_PRDY (1 << 31) /* Bit 31: All enabled system memory power ready flag */ +#define PWR_SYSMEMLPCTRL_AHBSRM5S2_RET2N (1 << 26) /* Bit 26: AHBSRM5S2 Retention 2 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM5S2_RET1N (1 << 25) /* Bit 25: AHBSRM5S2 Retention 1 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM5S1_RET2N (1 << 24) /* Bit 24: AHBSRM5S1 Retention 2 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM5S1_RET1N (1 << 23) /* Bit 23: AHBSRM5S1 Retention 1 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM4_RET2N (1 << 22) /* Bit 22: AHBSRM4 Retention 2 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM4_RET1N (1 << 21) /* Bit 21: AHBSRM4 Retention 1 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM3_RET2N (1 << 20) /* Bit 20: AHBSRM3 Retention 2 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM3_RET1N (1 << 19) /* Bit 19: AHBSRM3 Retention 1 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM2_RET2N (1 << 18) /* Bit 18: AHBSRM2 Retention 2 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM2_RET1N (1 << 17) /* Bit 17: AHBSRM2 Retention 1 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM1_RET2N (1 << 16) /* Bit 16: AHBSRM1 Retention 2 mode select */ +#define PWR_SYSMEMLPCTRL_AHBSRM1_RET1N (1 << 15) /* Bit 15: AHBSRM1 Retention 1 mode select */ +#define PWR_SYSMEMLPCTRL_AXISRM_RET2N (1 << 14) /* Bit 14: AXISRM Retention 2 mode select */ +#define PWR_SYSMEMLPCTRL_AXISRM_RET1N (1 << 13) /* Bit 13: AXISRM Retention 1 mode select */ + +#define PWR_SYSMEMLPCTRL_MEM_RETSTP0EN_SHIFT (8) /* Bits 8-9: Memory retention mode select in STOP0 */ +#define PWR_SYSMEMLPCTRL_MEM_RETSTP0EN_MASK (0x3 << PWR_SYSMEMLPCTRL_MEM_RETSTP0EN_SHIFT) +# define PWR_SYSMEMLPCTRL_MEM_RETSTP0EN_CHIP_DISABLE (0x0 << PWR_SYSMEMLPCTRL_MEM_RETSTP0EN_SHIFT) /* 00: Chip disable mode */ +# define PWR_SYSMEMLPCTRL_MEM_RETSTP0EN_PRECHARGE (0x1 << PWR_SYSMEMLPCTRL_MEM_RETSTP0EN_SHIFT) /* 01: Precharge mode */ +# define PWR_SYSMEMLPCTRL_MEM_RETSTP0EN_RETENTION1 (0x3 << PWR_SYSMEMLPCTRL_MEM_RETSTP0EN_SHIFT) /* 11: Retention 1 mode */ + +#define PWR_SYSMEMLPCTRL_MEM_PGSTP0EN_SHIFT (8) /* Bits 8-9: Memory power gate mode select in STOP0 */ +#define PWR_SYSMEMLPCTRL_MEM_PGSTP0EN_MASK (0x3 << PWR_SYSMEMLPCTRL_MEM_PGSTP0EN_SHIFT) +# define PWR_SYSMEMLPCTRL_MEM_PGSTP0EN_CHIP_DISABLE (0x0 << PWR_SYSMEMLPCTRL_MEM_PGSTP0EN_SHIFT) /* 00: Chip disable mode */ +# define PWR_SYSMEMLPCTRL_MEM_PGSTP0EN_PRECHARGE (0x1 << PWR_SYSMEMLPCTRL_MEM_PGSTP0EN_SHIFT) /* 01: Precharge mode */ +# define PWR_SYSMEMLPCTRL_MEM_PGSTP0EN_RETENTION1 (0x3 << PWR_SYSMEMLPCTRL_MEM_PGSTP0EN_SHIFT) /* 11: Retention 1 mode */ + +#define PWR_SYSMEMLPCTRL_AHBSRM5S2_PG (1 << 6) /* Bit 6: AHBSRM5S2 power gate enable */ +#define PWR_SYSMEMLPCTRL_AHBSRM5S1_PG (1 << 5) /* Bit 5: AHBSRM5S1 power gate enable */ +#define PWR_SYSMEMLPCTRL_AHBSRM4_PG (1 << 4) /* Bit 4: AHBSRM4 power gate enable */ +#define PWR_SYSMEMLPCTRL_AHBSRM3_PG (1 << 3) /* Bit 3: AHBSRM3 power gate enable */ +#define PWR_SYSMEMLPCTRL_AHBSRM2_PG (1 << 2) /* Bit 2: AHBSRM2 power gate enable */ +#define PWR_SYSMEMLPCTRL_AHBSRM1_PG (1 << 1) /* Bit 1: AHBSRM1 power gate enable */ +#define PWR_SYSMEMLPCTRL_AXISRM_PG (1 << 0) /* Bit 0: AXISRM power gate enable */ + +/* PWR System SHRTIM Power Control register (PWR_SHRTIMCTRL) */ +#define PWR_SHRTIMCTRL_SHRA_PSWACK1 (1 << 20) /* Bit 20: SHRTIM AFE power switch ACK1 */ +#define PWR_SHRTIMCTRL_SHRA_PWRRDY (1 << 19) /* Bit 19: SHRTIM AFE power domain ready flag */ +#define PWR_SHRTIMCTRL_SHRA_ISNEN (1 << 18) /* Bit 18: SHRTIM AFE power domain isolation signal */ +#define PWR_SHRTIMCTRL_SHRA_FUCEN (1 << 17) /* Bit 17: SHRTIM AFE function mode enable */ +#define PWR_SHRTIMCTRL_SHRA_PGEN (1 << 16) /* Bit 16: SHRTIM AFE power gate enable */ + +#define PWR_SHRTIMCTRL_SHR2_PSWACK1 (1 << 12) /* Bit 12: SHRTIM2 power switch ACK1 */ +#define PWR_SHRTIMCTRL_SHR2_PWRRDY (1 << 11) /* Bit 11: SHRTIM2 power domain ready flag */ +#define PWR_SHRTIMCTRL_SHR2_ISNEN (1 << 10) /* Bit 10: SHRTIM2 power domain isolation signal */ +#define PWR_SHRTIMCTRL_SHR2_FUCEN (1 << 9) /* Bit 9: SHRTIM2 function mode enable */ +#define PWR_SHRTIMCTRL_SHR2_PGEN (1 << 8) /* Bit 8: SHRTIM2 power gate enable */ + +#define PWR_SHRTIMCTRL_SHR1_PSWACK1 (1 << 4) /* Bit 4: SHRTIM1 power switch ACK1 */ +#define PWR_SHRTIMCTRL_SHR1_PWRRDY (1 << 3) /* Bit 3: SHRTIM1 power domain ready flag */ +#define PWR_SHRTIMCTRL_SHR1_ISNEN (1 << 2) /* Bit 2: SHRTIM1 power domain isolation signal */ +#define PWR_SHRTIMCTRL_SHR1_FUCEN (1 << 1) /* Bit 1: SHRTIM1 function mode enable */ +#define PWR_SHRTIMCTRL_SHR1_PGEN (1 << 0) /* Bit 0: SHRTIM1 power gate enable */ + +/* PWR System MDMA Power Control register (PWR_MDMACTRL) */ +#define PWR_MDMACTRL_MDMA_PSWACK1 (1 << 4) /* Bit 4: MDMA power switch ACK1 */ +#define PWR_MDMACTRL_MDMA_PWRRDY (1 << 3) /* Bit 3: MDMA power domain ready flag */ +#define PWR_MDMACTRL_MDMA_ISNEN (1 << 2) /* Bit 2: MDMA power domain isolation signal */ +#define PWR_MDMACTRL_MDMA_FUCEN (1 << 1) /* Bit 1: MDMA function mode enable */ +#define PWR_MDMACTRL_MDMA_PGEN (1 << 0) /* Bit 0: MDMA power gate enable */ + +/* PWR System ESC Power Control register (PWR_ESCCTRL) */ +#define PWR_ESCCTRL_ESC_PSWACK1 (1 << 4) /* Bit 4: ESC power switch ACK1 */ +#define PWR_ESCCTRL_ESC_PWRRDY (1 << 3) /* Bit 3: ESC power domain ready flag */ +#define PWR_ESCCTRL_ESC_ISNEN (1 << 2) /* Bit 2: ESC power domain isolation signal */ +#define PWR_ESCCTRL_ESC_FUCEN (1 << 1) /* Bit 1: ESC function mode enable */ +#define PWR_ESCCTRL_ESC_PGEN (1 << 0) /* Bit 0: ESC power gate enable */ + +/* PWR EMC RET Control Register 1 (PWR_EMCRETCTRL1) */ +#define PWR_EMCRETCTRL1_RETGB3DET (1 << 11) /* Bit 11: RET domain EMC GB3 detection enable */ +#define PWR_EMCRETCTRL1_RETGB2DET (1 << 10) /* Bit 10: RET domain EMC GB2 detection enable */ +#define PWR_EMCRETCTRL1_RETGB1DET (1 << 9) /* Bit 9: RET domain EMC GB1 detection enable */ +#define PWR_EMCRETCTRL1_RETGB0DET (1 << 8) /* Bit 8: RET domain EMC GB0 detection enable */ +#define PWR_EMCRETCTRL1_RETGBN3DET (1 << 7) /* Bit 7: RET domain EMC GBN3 detection enable */ +#define PWR_EMCRETCTRL1_RETGBN2DET (1 << 6) /* Bit 6: RET domain EMC GBN2 detection enable */ +#define PWR_EMCRETCTRL1_RETGBN1DET (1 << 5) /* Bit 5: RET domain EMC GBN1 detection enable */ +#define PWR_EMCRETCTRL1_RETGBN0DET (1 << 4) /* Bit 4: RET domain EMC GBN0 detection enable */ +#define PWR_EMCRETCTRL1_RETCLP3DET (1 << 3) /* Bit 3: RET domain EMC Clamp3 detection enable */ +#define PWR_EMCRETCTRL1_RETCLP2DET (1 << 2) /* Bit 2: RET domain EMC Clamp2 detection enable */ +#define PWR_EMCRETCTRL1_RETCLP1DET (1 << 1) /* Bit 1: RET domain EMC Clamp1 detection enable */ +#define PWR_EMCRETCTRL1_RETCLP0DET (1 << 0) /* Bit 0: RET domain EMC Clamp0 detection enable */ + +/* PWR EMC RET Status Register 1 (PWR_EMCRETSTS1) */ +#define PWR_EMCRETSTS1_EMCFCLR (1 << 24) /* Bit 24: Clear EMC Flag */ +#define PWR_EMCRETSTS1_GB3F (1 << 11) /* Bit 11: RET Domain EMC GB3 Flag */ +#define PWR_EMCRETSTS1_GB2F (1 << 10) /* Bit 10: RET Domain EMC GB2 Flag */ +#define PWR_EMCRETSTS1_GB1F (1 << 9) /* Bit 9: RET Domain EMC GB1 Flag */ +#define PWR_EMCRETSTS1_GB0F (1 << 8) /* Bit 8: RET Domain EMC GB0 Flag */ +#define PWR_EMCRETSTS1_GBN3F (1 << 7) /* Bit 7: RET Domain EMC GBN3 Flag */ +#define PWR_EMCRETSTS1_GBN2F (1 << 6) /* Bit 6: RET Domain EMC GBN2 Flag */ +#define PWR_EMCRETSTS1_GBN1F (1 << 5) /* Bit 5: RET Domain EMC GBN1 Flag */ +#define PWR_EMCRETSTS1_GBN0F (1 << 4) /* Bit 4: RET Domain EMC GBN0 Flag */ +#define PWR_EMCRETSTS1_CLP3F (1 << 3) /* Bit 3: RET Domain EMC Clamp3 Flag */ +#define PWR_EMCRETSTS1_CLP2F (1 << 2) /* Bit 2: RET Domain EMC Clamp2 Flag */ +#define PWR_EMCRETSTS1_CLP1F (1 << 1) /* Bit 1: RET Domain EMC Clamp1 Flag */ +#define PWR_EMCRETSTS1_CLP0F (1 << 0) /* Bit 0: RET Domain EMC Clamp0 Flag */ + +/* PWR EMC RET Control Register 2 (PWR_EMCRETCTRL2) */ +#define PWR_EMCRETCTRL2_RETGB7DET (1 << 11) /* Bit 11: RET domain EMC GB7 detection enable */ +#define PWR_EMCRETCTRL2_RETGB6DET (1 << 10) /* Bit 10: RET domain EMC GB6 detection enable */ +#define PWR_EMCRETCTRL2_RETGB5DET (1 << 9) /* Bit 9: RET domain EMC GB5 detection enable */ +#define PWR_EMCRETCTRL2_RETGB4DET (1 << 8) /* Bit 8: RET domain EMC GB4 detection enable */ +#define PWR_EMCRETCTRL2_RETGBN7DET (1 << 7) /* Bit 7: RET domain EMC GBN7 detection enable */ +#define PWR_EMCRETCTRL2_RETGBN6DET (1 << 6) /* Bit 6: RET domain EMC GBN6 detection enable */ +#define PWR_EMCRETCTRL2_RETGBN5DET (1 << 5) /* Bit 5: RET domain EMC GBN5 detection enable */ +#define PWR_EMCRETCTRL2_RETGBN4DET (1 << 4) /* Bit 4: RET domain EMC GBN4 detection enable */ +#define PWR_EMCRETCTRL2_RETCLP7DET (1 << 3) /* Bit 3: RET domain EMC Clamp7 detection enable */ +#define PWR_EMCRETCTRL2_RETCLP6DET (1 << 2) /* Bit 2: RET domain EMC Clamp6 detection enable */ +#define PWR_EMCRETCTRL2_RETCLP5DET (1 << 1) /* Bit 1: RET domain EMC Clamp5 detection enable */ +#define PWR_EMCRETCTRL2_RETCLP4DET (1 << 0) /* Bit 0: RET domain EMC Clamp4 detection enable */ + +/* PWR EMC RET Status Register 2 (PWR_EMCRETSTS2) */ +#define PWR_EMCRETSTS2_GB7F (1 << 11) /* Bit 11: RET Domain EMC GB7 Flag */ +#define PWR_EMCRETSTS2_GB6F (1 << 10) /* Bit 10: RET Domain EMC GB6 Flag */ +#define PWR_EMCRETSTS2_GB5F (1 << 9) /* Bit 9: RET Domain EMC GB5 Flag */ +#define PWR_EMCRETSTS2_GB4F (1 << 8) /* Bit 8: RET Domain EMC GB4 Flag */ +#define PWR_EMCRETSTS2_GBN7F (1 << 7) /* Bit 7: RET Domain EMC GBN7 Flag */ +#define PWR_EMCRETSTS2_GBN6F (1 << 6) /* Bit 6: RET Domain EMC GBN6 Flag */ +#define PWR_EMCRETSTS2_GBN5F (1 << 5) /* Bit 5: RET Domain EMC GBN5 Flag */ +#define PWR_EMCRETSTS2_GBN4F (1 << 4) /* Bit 4: RET Domain EMC GBN4 Flag */ +#define PWR_EMCRETSTS2_CLP7F (1 << 3) /* Bit 3: RET Domain EMC Clamp7 Flag */ +#define PWR_EMCRETSTS2_CLP6F (1 << 2) /* Bit 2: RET Domain EMC Clamp6 Flag */ +#define PWR_EMCRETSTS2_CLP5F (1 << 1) /* Bit 1: RET Domain EMC Clamp5 Flag */ +#define PWR_EMCRETSTS2_CLP4F (1 << 0) /* Bit 0: RET Domain EMC Clamp4 Flag */ + +/* PWR EMC RET Control Register 3 (PWR_EMCRETCTRL3) */ +#define PWR_EMCRETCTRL3_RETGB11DET (1 << 11) /* Bit 11: RET domain EMC GB11 detection enable */ +#define PWR_EMCRETCTRL3_RETGB10DET (1 << 10) /* Bit 10: RET domain EMC GB10 detection enable */ +#define PWR_EMCRETCTRL3_RETGB9DET (1 << 9) /* Bit 9: RET domain EMC GB9 detection enable */ +#define PWR_EMCRETCTRL3_RETGB8DET (1 << 8) /* Bit 8: RET domain EMC GB8 detection enable */ +#define PWR_EMCRETCTRL3_RETGBN11DET (1 << 7) /* Bit 7: RET domain EMC GBN11 detection enable */ +#define PWR_EMCRETCTRL3_RETGBN10DET (1 << 6) /* Bit 6: RET domain EMC GBN10 detection enable */ +#define PWR_EMCRETCTRL3_RETGBN9DET (1 << 5) /* Bit 5: RET domain EMC GBN9 detection enable */ +#define PWR_EMCRETCTRL3_RETGBN8DET (1 << 4) /* Bit 4: RET domain EMC GBN8 detection enable */ +#define PWR_EMCRETCTRL3_RETCLP11DET (1 << 3) /* Bit 3: RET domain EMC Clamp11 detection enable */ +#define PWR_EMCRETCTRL3_RETCLP10DET (1 << 2) /* Bit 2: RET domain EMC Clamp10 detection enable */ +#define PWR_EMCRETCTRL3_RETCLP9DET (1 << 1) /* Bit 1: RET domain EMC Clamp9 detection enable */ +#define PWR_EMCRETCTRL3_RETCLP8DET (1 << 0) /* Bit 0: RET domain EMC Clamp8 detection enable */ + +/* PWR EMC RET Status Register 3 (PWR_EMCRETSTS3) */ +#define PWR_EMCRETSTS3_GB11F (1 << 11) /* Bit 11: RET Domain EMC GB11 Flag */ +#define PWR_EMCRETSTS3_GB10F (1 << 10) /* Bit 10: RET Domain EMC GB10 Flag */ +#define PWR_EMCRETSTS3_GB9F (1 << 9) /* Bit 9: RET Domain EMC GB9 Flag */ +#define PWR_EMCRETSTS3_GB8F (1 << 8) /* Bit 8: RET Domain EMC GB8 Flag */ +#define PWR_EMCRETSTS3_GBN11F (1 << 7) /* Bit 7: RET Domain EMC GBN11 Flag */ +#define PWR_EMCRETSTS3_GBN10F (1 << 6) /* Bit 6: RET Domain EMC GBN10 Flag */ +#define PWR_EMCRETSTS3_GBN9F (1 << 5) /* Bit 5: RET Domain EMC GBN9 Flag */ +#define PWR_EMCRETSTS3_GBN8F (1 << 4) /* Bit 4: RET Domain EMC GBN8 Flag */ +#define PWR_EMCRETSTS3_CLP11F (1 << 3) /* Bit 3: RET Domain EMC Clamp11 Flag */ +#define PWR_EMCRETSTS3_CLP10F (1 << 2) /* Bit 2: RET Domain EMC Clamp10 Flag */ +#define PWR_EMCRETSTS3_CLP9F (1 << 1) /* Bit 1: RET Domain EMC Clamp9 Flag */ +#define PWR_EMCRETSTS3_CLP8F (1 << 0) /* Bit 0: RET Domain EMC Clamp8 Flag */ + +/* PWR EMC RET Control Register 4 (PWR_EMCRETCTRL4) */ +#define PWR_EMCRETCTRL4_RETGB14DET (1 << 10) /* Bit 10: RET domain EMC GB14 detection enable */ +#define PWR_EMCRETCTRL4_RETGB13DET (1 << 9) /* Bit 9: RET domain EMC GB13 detection enable */ +#define PWR_EMCRETCTRL4_RETGB12DET (1 << 8) /* Bit 8: RET domain EMC GB12 detection enable */ +#define PWR_EMCRETCTRL4_RETGBN14DET (1 << 6) /* Bit 6: RET domain EMC GBN14 detection enable */ +#define PWR_EMCRETCTRL4_RETGBN13DET (1 << 5) /* Bit 5: RET domain EMC GBN13 detection enable */ +#define PWR_EMCRETCTRL4_RETGBN12DET (1 << 4) /* Bit 4: RET domain EMC GBN12 detection enable */ +#define PWR_EMCRETCTRL4_RETCLP14DET (1 << 2) /* Bit 2: RET domain EMC Clamp14 detection enable */ +#define PWR_EMCRETCTRL4_RETCLP13DET (1 << 1) /* Bit 1: RET domain EMC Clamp13 detection enable */ +#define PWR_EMCRETCTRL4_RETCLP12DET (1 << 0) /* Bit 0: RET domain EMC Clamp12 detection enable */ + +/* PWR EMC RET Status Register 4 (PWR_EMCRETSTS4) */ +#define PWR_EMCRETSTS4_GB14F (1 << 10) /* Bit 10: RET Domain EMC GB14 Flag */ +#define PWR_EMCRETSTS4_GB13F (1 << 9) /* Bit 9: RET Domain EMC GB13 Flag */ +#define PWR_EMCRETSTS4_GB12F (1 << 8) /* Bit 8: RET Domain EMC GB12 Flag */ +#define PWR_EMCRETSTS4_GBN14F (1 << 6) /* Bit 6: RET Domain EMC GBN14 Flag */ +#define PWR_EMCRETSTS4_GBN13F (1 << 5) /* Bit 5: RET Domain EMC GBN13 Flag */ +#define PWR_EMCRETSTS4_GBN12F (1 << 4) /* Bit 4: RET Domain EMC GBN12 Flag */ +#define PWR_EMCRETSTS4_CLP14F (1 << 2) /* Bit 2: RET Domain EMC Clamp14 Flag */ +#define PWR_EMCRETSTS4_CLP13F (1 << 1) /* Bit 1: RET Domain EMC Clamp13 Flag */ +#define PWR_EMCRETSTS4_CLP12F (1 << 0) /* Bit 0: RET Domain EMC Clamp12 Flag */ + +/* PWR EMC BKP Control Register (PWR_EMCBKPCTRL) */ +#define PWR_EMCBKPCTRL_BKPGBDET (1 << 8) /* Bit 8: Backup domain EMC GB detection enable */ +#define PWR_EMCBKPCTRL_BKPGBNDET (1 << 4) /* Bit 4: Backup domain EMC GBN detection enable */ +#define PWR_EMCBKPCTRL_BKPCLPDET (1 << 0) /* Bit 0: Backup domain EMC Clamp detection enable */ + +/* PWR EMC BKP Status Register (PWR_EMCRETSTS) */ +#define PWR_EMCRETSTS_BKPGBF (1 << 8) /* Bit 8: Backup Domain EMC GB Flag */ +#define PWR_EMCRETSTS_BKPGBNF (1 << 4) /* Bit 4: Backup Domain EMC GBN Flag */ +#define PWR_EMCRETSTS_BKPCLPF (1 << 0) /* Bit 0: Backup Domain EMC Clamp Flag */ + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_PWR_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h76x_rcc.h b/arch/arm/src/n32h7/hardware/n32h76x_rcc.h new file mode 100644 index 0000000000000..492e3a0f089e7 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h76x_rcc.h @@ -0,0 +1,3415 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h76x_rcc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_RCC_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_RCC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" +#include "hardware/n32h7_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DWT_CR (*(volatile uint32_t *)0xE0001000U) +#define DWT_CYCCNT (*(volatile uint32_t *)0xE0001004U) +#define DEM_CR (*(volatile uint32_t *)0xE000EDFCU) +#define DEM_CR_TRCENA ((uint32_t)0x01000000U) +#define DWT_CR_CYCCNTENA ((uint32_t)0x00000001U) + +#define CPU_DELAY_INTI() do{ \ + /* Enable DWT*/ \ + DEM_CR |= DEM_CR_TRCENA; \ + /* Clear DWT CYCCNT*/ \ + DWT_CYCCNT = 0U; \ + /* Enable DWT CYCCNT*/ \ + DWT_CR |= DWT_CR_CYCCNTENA; \ + }while(0) + +#define CPU_DELAY_DISABLE() do{ \ + /* Disable DWT*/ \ + DEM_CR &= (uint32_t)(~(uint32_t)DEM_CR_TRCENA); \ + }while(0) + +#define __RCC_DELAY_US(usec)do{ \ + uint32_t delay_end; \ + CPU_DELAY_INTI(); \ + /* Delay*/ \ + delay_end = DWT_CYCCNT + (usec * (600000000/1000000)); \ + while(DWT_CYCCNT < delay_end){}; \ + CPU_DELAY_DISABLE(); \ + }while(0) + +#define __RCC_DELAY_MS(msec)do{ \ + uint32_t delay_end; \ + CPU_DELAY_INTI(); \ + /* Delay*/ \ + delay_end = DWT_CYCCNT + (msec * (600000000/1000)); \ + while(DWT_CYCCNT < delay_end){}; \ + CPU_DELAY_DISABLE(); \ + }while(0) + +/* Register Offsets *********************************************************/ + +#define N32_RCC_PLL1CTRL1_OFFSET 0x0000 /* PLL1 Control Register 1 */ +#define N32_RCC_PLL1CTRL2_OFFSET 0x0004 /* PLL1 Control Register 2 */ +#define N32_RCC_PLL2CTRL1_OFFSET 0x0010 /* PLL2 Control Register 1 */ +#define N32_RCC_PLL2CTRL2_OFFSET 0x0014 /* PLL2 Control Register 2 */ +#define N32_RCC_PLL3CTRL1_OFFSET 0x0020 /* PLL3 Control Register 1 */ +#define N32_RCC_PLL3CTRL2_OFFSET 0x0024 /* PLL3 Control Register 2 */ +#define N32_RCC_SRCCTRL1_OFFSET 0x0030 /* Source Control Register 1 */ +#define N32_RCC_PLL1DIV_OFFSET 0x0034 /* PLL1 Divider Register */ +#define N32_RCC_PLL2DIV_OFFSET 0x0038 /* PLL2 Divider Register */ +#define N32_RCC_PLL3DIV_OFFSET 0x003C /* PLL3 Divider Register */ +#define N32_RCC_SYSBUSDIV1_OFFSET 0x0040 /* System Bus Divider 1 */ +#define N32_RCC_SYSBUSDIV2_OFFSET 0x0044 /* System Bus Divider 2 */ +#define N32_RCC_BOOTMODE_OFFSET 0x0048 /* Boot Mode Register */ +#define N32_RCC_AHB1DIV1_OFFSET 0x004C /* AHB1 Divider 1 */ +#define N32_RCC_AHB1SEL1_OFFSET 0x0050 /* AHB1 Select 1 */ +#define N32_RCC_AHB1EN1_OFFSET 0x0054 /* AHB1 Enable 1 */ +#define N32_RCC_AHB1EN2_OFFSET 0x0058 /* AHB1 Enable 2 */ +#define N32_RCC_AHB1EN3_OFFSET 0x005C /* AHB1 Enable 3 */ +#define N32_RCC_AHB1EN4_OFFSET 0x0060 /* AHB1 Enable 4 */ +#define N32_RCC_AHB1RST1_OFFSET 0x0064 /* AHB1 Reset 1 */ +#define N32_RCC_AHB1RST2_OFFSET 0x0068 /* AHB1 Reset 2 */ +#define N32_RCC_AHB1RST3_OFFSET 0x006C /* AHB1 Reset 3 */ +#define N32_RCC_AHB1RST4_OFFSET 0x0070 /* AHB1 Reset 4 */ +#define N32_RCC_APB1DIV1_OFFSET 0x0074 /* APB1 Divider 1 */ +#define N32_RCC_APB1SEL1_OFFSET 0x0078 /* APB1 Select 1 */ +#define N32_RCC_APB1SEL2_OFFSET 0x007C /* APB1 Select 2 */ +#define N32_RCC_APB1EN1_OFFSET 0x0080 /* APB1 Enable 1 */ +#define N32_RCC_APB1EN2_OFFSET 0x0084 /* APB1 Enable 2 */ +#define N32_RCC_APB1EN3_OFFSET 0x0088 /* APB1 Enable 3 */ +#define N32_RCC_APB1EN4_OFFSET 0x008C /* APB1 Enable 4 */ +#define N32_RCC_APB1EN5_OFFSET 0x0090 /* APB1 Enable 5 */ +#define N32_RCC_APB1RST1_OFFSET 0x0094 /* APB1 Reset 1 */ +#define N32_RCC_APB1RST2_OFFSET 0x0098 /* APB1 Reset 2 */ +#define N32_RCC_APB1RST3_OFFSET 0x009C /* APB1 Reset 3 */ +#define N32_RCC_APB1RST4_OFFSET 0x00A0 /* APB1 Reset 4 */ +#define N32_RCC_APB1RST5_OFFSET 0x00A4 /* APB1 Reset 5 */ +#define N32_RCC_AHB2DIV1_OFFSET 0x00A8 /* AHB2 Divider 1 */ +#define N32_RCC_AHB2SEL1_OFFSET 0x00AC /* AHB2 Select 1 */ +#define N32_RCC_AHB2EN1_OFFSET 0x00B0 /* AHB2 Enable 1 */ +#define N32_RCC_AHB2RST1_OFFSET 0x00B4 /* AHB2 Reset 1 */ +#define N32_RCC_APB2DIV1_OFFSET 0x00B8 /* APB2 Divider 1 */ +#define N32_RCC_APB2SEL1_OFFSET 0x00BC /* APB2 Select 1 */ +#define N32_RCC_APB2SEL2_OFFSET 0x00C0 /* APB2 Select 2 */ +#define N32_RCC_APB2EN1_OFFSET 0x00C4 /* APB2 Enable 1 */ +#define N32_RCC_APB2EN2_OFFSET 0x00C8 /* APB2 Enable 2 */ +#define N32_RCC_APB2EN3_OFFSET 0x00CC /* APB2 Enable 3 */ +#define N32_RCC_APB2EN4_OFFSET 0x00D0 /* APB2 Enable 4 */ +#define N32_RCC_APB2RST1_OFFSET 0x00D4 /* APB2 Reset 1 */ +#define N32_RCC_APB2RST2_OFFSET 0x00D8 /* APB2 Reset 2 */ +#define N32_RCC_APB2RST3_OFFSET 0x00DC /* APB2 Reset 3 */ +#define N32_RCC_APB2RST4_OFFSET 0x00E0 /* APB2 Reset 4 */ +#define N32_RCC_AHB5EN1_OFFSET 0x00E4 /* AHB5 Enable 1 */ +#define N32_RCC_AHB5EN2_OFFSET 0x00E8 /* AHB5 Enable 2 */ +#define N32_RCC_AHB5RST1_OFFSET 0x00EC /* AHB5 Reset 1 */ +#define N32_RCC_AHB5RST2_OFFSET 0x00F0 /* AHB5 Reset 2 */ +#define N32_RCC_APB5DIV1_OFFSET 0x00F4 /* APB5 Divider 1 */ +#define N32_RCC_APB5SEL1_OFFSET 0x00F8 /* APB5 Select 1 */ +#define N32_RCC_APB5EN1_OFFSET 0x00FC /* APB5 Enable 1 */ +#define N32_RCC_APB5EN2_OFFSET 0x0100 /* APB5 Enable 2 */ +#define N32_RCC_APB5RST1_OFFSET 0x0104 /* APB5 Reset 1 */ +#define N32_RCC_APB5RST2_OFFSET 0x0108 /* APB5 Reset 2 */ +#define N32_RCC_RDDIV1_OFFSET 0x010C /* RD Divider 1 */ +#define N32_RCC_RDSEL1_OFFSET 0x0110 /* RD Select 1 */ +#define N32_RCC_RDEN1_OFFSET 0x0114 /* RD Enable 1 */ +#define N32_RCC_RDEN2_OFFSET 0x0118 /* RD Enable 2 */ +#define N32_RCC_RDRST1_OFFSET 0x011C /* RD Reset 1 */ +#define N32_RCC_RDRST2_OFFSET 0x0120 /* RD Reset 2 */ +#define N32_RCC_BDCTRL_OFFSET 0x0124 /* Backup Domain Control */ +#define N32_RCC_CTRLSTS_OFFSET 0x0128 /* Control and Status */ +#define N32_RCC_CLKINT1_OFFSET 0x012C /* Clock Interrupt 1 */ +#define N32_RCC_CLKINT2_OFFSET 0x0130 /* Clock Interrupt 2 */ +#define N32_RCC_CFG1_OFFSET 0x0134 /* Configuration 1 */ +#define N32_RCC_AXIDIV1_OFFSET 0x0138 /* AXI Divider 1 */ +#define N32_RCC_AXISEL1_OFFSET 0x013C /* AXI Select 1 */ +#define N32_RCC_AXIEN1_OFFSET 0x0140 /* AXI Enable 1 */ +#define N32_RCC_AXIEN2_OFFSET 0x0144 /* AXI Enable 2 */ +#define N32_RCC_AXIEN3_OFFSET 0x0148 /* AXI Enable 3 */ +#define N32_RCC_AXIEN4_OFFSET 0x014C /* AXI Enable 4 */ +#define N32_RCC_AXIRST1_OFFSET 0x0150 /* AXI Reset 1 */ +#define N32_RCC_AXIRST2_OFFSET 0x0154 /* AXI Reset 2 */ +#define N32_RCC_AXIRST3_OFFSET 0x0158 /* AXI Reset 3 */ +#define N32_RCC_AXIRST4_OFFSET 0x015C /* AXI Reset 4 */ +#define N32_RCC_CFG2_OFFSET 0x0160 /* Configuration 2 */ +#define N32_RCC_CFG3_OFFSET 0x0164 /* Configuration 3 */ +#define N32_RCC_CFG4_OFFSET 0x0168 /* Configuration 4 */ +#define N32_RCC_SRCCTRL2_OFFSET 0x016C /* Source Control 2 */ +#define N32_RCC_CFG5_OFFSET 0x0170 /* Configuration 5 */ +#define N32_RCC_M4RSTREL_OFFSET 0x0174 /* M4 Reset Release */ +#define N32_RCC_AXIDIV2_OFFSET 0x0178 /* AXI Divider 2 */ +#define N32_RCC_AXISEL2_OFFSET 0x017C /* AXI Select 2 */ +#define N32_RCC_SHRPLLCTRL1_OFFSET 0x018C /* Shared PLL Control 1 */ +#define N32_RCC_SHRPLLCTRL2_OFFSET 0x0190 /* Shared PLL Control 2 */ +#define N32_RCC_AHB1DIV2_OFFSET 0x0194 /* AHB1 Divider 2 */ +#define N32_RCC_LSERDDL_OFFSET 0x0198 /* LSE Ready Delay */ +#define N32_RCC_MSIRDDL_OFFSET 0x019C /* MSI Ready Delay */ +#define N32_RCC_HSERDDL_OFFSET 0x01A0 /* HSE Ready Delay */ +#define N32_RCC_PLLSFTLK_OFFSET 0x01A4 /* PLL Soft Lock */ +#define N32_RCC_RDCTRL1_OFFSET 0x01A8 /* RD Control 1 */ +#define N32_RCC_RDCTRL2_OFFSET 0x01AC /* RD Control 2 */ +#define N32_RCC_RDCTRL3_OFFSET 0x01B0 /* RD Control 3 */ +#define N32_RCC_AHB2EN2_OFFSET 0x01B4 /* AHB2 Enable 2 */ +#define N32_RCC_AHB9DIV1_OFFSET 0x01B8 /* AHB9 Divider 1 */ +#define N32_RCC_AHB9SEL1_OFFSET 0x01BC /* AHB9 Select 1 */ +#define N32_RCC_AHB9EN1_OFFSET 0x01C0 /* AHB9 Enable 1 */ +#define N32_RCC_AHB9RST1_OFFSET 0x01C4 /* AHB9 Reset 1 */ +#define N32_RCC_HSEOS_OFFSET 0x01C8 /* HSE Oscillator Status */ +#define N32_RCC_LSEOS_OFFSET 0x01CC /* LSE Oscillator Status */ +#define N32_RCC_HSECAL_OFFSET 0x01D0 /* HSE Calibration */ +#define N32_RCC_CLKINT3_OFFSET 0x01D4 /* Clock Interrupt 3 */ +#define N32_RCC_PLLFD_OFFSET 0x01D8 /* PLL Frequency Detect */ +#define N32_RCC_SRCCTRL3_OFFSET 0x01DC /* Source Control 3 */ +#define N32_RCC_LSICSSDL_OFFSET 0x01E0 /* LSI CSS Delay */ + +/* Register Addresses *******************************************************/ + +#define N32_RCC_PLL1CTRL1 (N32_RCC_BASE + N32_RCC_PLL1CTRL1_OFFSET) /* PLL1 Control Register 1 */ +#define N32_RCC_PLL1CTRL2 (N32_RCC_BASE + N32_RCC_PLL1CTRL2_OFFSET) /* PLL1 Control Register 2 */ +#define N32_RCC_PLL2CTRL1 (N32_RCC_BASE + N32_RCC_PLL2CTRL1_OFFSET) /* PLL2 Control Register 1 */ +#define N32_RCC_PLL2CTRL2 (N32_RCC_BASE + N32_RCC_PLL2CTRL2_OFFSET) /* PLL2 Control Register 2 */ +#define N32_RCC_PLL3CTRL1 (N32_RCC_BASE + N32_RCC_PLL3CTRL1_OFFSET) /* PLL3 Control Register 1 */ +#define N32_RCC_PLL3CTRL2 (N32_RCC_BASE + N32_RCC_PLL3CTRL2_OFFSET) /* PLL3 Control Register 2 */ +#define N32_RCC_SRCCTRL1 (N32_RCC_BASE + N32_RCC_SRCCTRL1_OFFSET) /* Source Control Register 1 */ +#define N32_RCC_PLL1DIV (N32_RCC_BASE + N32_RCC_PLL1DIV_OFFSET) /* PLL1 Divider Register */ +#define N32_RCC_PLL2DIV (N32_RCC_BASE + N32_RCC_PLL2DIV_OFFSET) /* PLL2 Divider Register */ +#define N32_RCC_PLL3DIV (N32_RCC_BASE + N32_RCC_PLL3DIV_OFFSET) /* PLL3 Divider Register */ +#define N32_RCC_SYSBUSDIV1 (N32_RCC_BASE + N32_RCC_SYSBUSDIV1_OFFSET) /* System Bus Divider 1 */ +#define N32_RCC_SYSBUSDIV2 (N32_RCC_BASE + N32_RCC_SYSBUSDIV2_OFFSET) /* System Bus Divider 2 */ +#define N32_RCC_BOOTMODE (N32_RCC_BASE + N32_RCC_BOOTMODE_OFFSET) /* Boot Mode Register */ +#define N32_RCC_AHB1DIV1 (N32_RCC_BASE + N32_RCC_AHB1DIV1_OFFSET) /* AHB1 Divider 1 */ +#define N32_RCC_AHB1SEL1 (N32_RCC_BASE + N32_RCC_AHB1SEL1_OFFSET) /* AHB1 Select 1 */ +#define N32_RCC_AHB1EN1 (N32_RCC_BASE + N32_RCC_AHB1EN1_OFFSET) /* AHB1 Enable 1 */ +#define N32_RCC_AHB1EN2 (N32_RCC_BASE + N32_RCC_AHB1EN2_OFFSET) /* AHB1 Enable 2 */ +#define N32_RCC_AHB1EN3 (N32_RCC_BASE + N32_RCC_AHB1EN3_OFFSET) /* AHB1 Enable 3 */ +#define N32_RCC_AHB1EN4 (N32_RCC_BASE + N32_RCC_AHB1EN4_OFFSET) /* AHB1 Enable 4 */ +#define N32_RCC_AHB1RST1 (N32_RCC_BASE + N32_RCC_AHB1RST1_OFFSET) /* AHB1 Reset 1 */ +#define N32_RCC_AHB1RST2 (N32_RCC_BASE + N32_RCC_AHB1RST2_OFFSET) /* AHB1 Reset 2 */ +#define N32_RCC_AHB1RST3 (N32_RCC_BASE + N32_RCC_AHB1RST3_OFFSET) /* AHB1 Reset 3 */ +#define N32_RCC_AHB1RST4 (N32_RCC_BASE + N32_RCC_AHB1RST4_OFFSET) /* AHB1 Reset 4 */ +#define N32_RCC_APB1DIV1 (N32_RCC_BASE + N32_RCC_APB1DIV1_OFFSET) /* APB1 Divider 1 */ +#define N32_RCC_APB1SEL1 (N32_RCC_BASE + N32_RCC_APB1SEL1_OFFSET) /* APB1 Select 1 */ +#define N32_RCC_APB1SEL2 (N32_RCC_BASE + N32_RCC_APB1SEL2_OFFSET) /* APB1 Select 2 */ +#define N32_RCC_APB1EN1 (N32_RCC_BASE + N32_RCC_APB1EN1_OFFSET) /* APB1 Enable 1 */ +#define N32_RCC_APB1EN2 (N32_RCC_BASE + N32_RCC_APB1EN2_OFFSET) /* APB1 Enable 2 */ +#define N32_RCC_APB1EN3 (N32_RCC_BASE + N32_RCC_APB1EN3_OFFSET) /* APB1 Enable 3 */ +#define N32_RCC_APB1EN4 (N32_RCC_BASE + N32_RCC_APB1EN4_OFFSET) /* APB1 Enable 4 */ +#define N32_RCC_APB1EN5 (N32_RCC_BASE + N32_RCC_APB1EN5_OFFSET) /* APB1 Enable 5 */ +#define N32_RCC_APB1RST1 (N32_RCC_BASE + N32_RCC_APB1RST1_OFFSET) /* APB1 Reset 1 */ +#define N32_RCC_APB1RST2 (N32_RCC_BASE + N32_RCC_APB1RST2_OFFSET) /* APB1 Reset 2 */ +#define N32_RCC_APB1RST3 (N32_RCC_BASE + N32_RCC_APB1RST3_OFFSET) /* APB1 Reset 3 */ +#define N32_RCC_APB1RST4 (N32_RCC_BASE + N32_RCC_APB1RST4_OFFSET) /* APB1 Reset 4 */ +#define N32_RCC_APB1RST5 (N32_RCC_BASE + N32_RCC_APB1RST5_OFFSET) /* APB1 Reset 5 */ +#define N32_RCC_AHB2DIV1 (N32_RCC_BASE + N32_RCC_AHB2DIV1_OFFSET) /* AHB2 Divider 1 */ +#define N32_RCC_AHB2SEL1 (N32_RCC_BASE + N32_RCC_AHB2SEL1_OFFSET) /* AHB2 Select 1 */ +#define N32_RCC_AHB2EN1 (N32_RCC_BASE + N32_RCC_AHB2EN1_OFFSET) /* AHB2 Enable 1 */ +#define N32_RCC_AHB2RST1 (N32_RCC_BASE + N32_RCC_AHB2RST1_OFFSET) /* AHB2 Reset 1 */ +#define N32_RCC_APB2DIV1 (N32_RCC_BASE + N32_RCC_APB2DIV1_OFFSET) /* APB2 Divider 1 */ +#define N32_RCC_APB2SEL1 (N32_RCC_BASE + N32_RCC_APB2SEL1_OFFSET) /* APB2 Select 1 */ +#define N32_RCC_APB2SEL2 (N32_RCC_BASE + N32_RCC_APB2SEL2_OFFSET) /* APB2 Select 2 */ +#define N32_RCC_APB2EN1 (N32_RCC_BASE + N32_RCC_APB2EN1_OFFSET) /* APB2 Enable 1 */ +#define N32_RCC_APB2EN2 (N32_RCC_BASE + N32_RCC_APB2EN2_OFFSET) /* APB2 Enable 2 */ +#define N32_RCC_APB2EN3 (N32_RCC_BASE + N32_RCC_APB2EN3_OFFSET) /* APB2 Enable 3 */ +#define N32_RCC_APB2EN4 (N32_RCC_BASE + N32_RCC_APB2EN4_OFFSET) /* APB2 Enable 4 */ +#define N32_RCC_APB2RST1 (N32_RCC_BASE + N32_RCC_APB2RST1_OFFSET) /* APB2 Reset 1 */ +#define N32_RCC_APB2RST2 (N32_RCC_BASE + N32_RCC_APB2RST2_OFFSET) /* APB2 Reset 2 */ +#define N32_RCC_APB2RST3 (N32_RCC_BASE + N32_RCC_APB2RST3_OFFSET) /* APB2 Reset 3 */ +#define N32_RCC_APB2RST4 (N32_RCC_BASE + N32_RCC_APB2RST4_OFFSET) /* APB2 Reset 4 */ +#define N32_RCC_AHB5EN1 (N32_RCC_BASE + N32_RCC_AHB5EN1_OFFSET) /* AHB5 Enable 1 */ +#define N32_RCC_AHB5EN2 (N32_RCC_BASE + N32_RCC_AHB5EN2_OFFSET) /* AHB5 Enable 2 */ +#define N32_RCC_AHB5RST1 (N32_RCC_BASE + N32_RCC_AHB5RST1_OFFSET) /* AHB5 Reset 1 */ +#define N32_RCC_AHB5RST2 (N32_RCC_BASE + N32_RCC_AHB5RST2_OFFSET) /* AHB5 Reset 2 */ +#define N32_RCC_APB5DIV1 (N32_RCC_BASE + N32_RCC_APB5DIV1_OFFSET) /* APB5 Divider 1 */ +#define N32_RCC_APB5SEL1 (N32_RCC_BASE + N32_RCC_APB5SEL1_OFFSET) /* APB5 Select 1 */ +#define N32_RCC_APB5EN1 (N32_RCC_BASE + N32_RCC_APB5EN1_OFFSET) /* APB5 Enable 1 */ +#define N32_RCC_APB5EN2 (N32_RCC_BASE + N32_RCC_APB5EN2_OFFSET) /* APB5 Enable 2 */ +#define N32_RCC_APB5RST1 (N32_RCC_BASE + N32_RCC_APB5RST1_OFFSET) /* APB5 Reset 1 */ +#define N32_RCC_APB5RST2 (N32_RCC_BASE + N32_RCC_APB5RST2_OFFSET) /* APB5 Reset 2 */ +#define N32_RCC_RDDIV1 (N32_RCC_BASE + N32_RCC_RDDIV1_OFFSET) /* RD Divider 1 */ +#define N32_RCC_RDSEL1 (N32_RCC_BASE + N32_RCC_RDSEL1_OFFSET) /* RD Select 1 */ +#define N32_RCC_RDEN1 (N32_RCC_BASE + N32_RCC_RDEN1_OFFSET) /* RD Enable 1 */ +#define N32_RCC_RDEN2 (N32_RCC_BASE + N32_RCC_RDEN2_OFFSET) /* RD Enable 2 */ +#define N32_RCC_RDRST1 (N32_RCC_BASE + N32_RCC_RDRST1_OFFSET) /* RD Reset 1 */ +#define N32_RCC_RDRST2 (N32_RCC_BASE + N32_RCC_RDRST2_OFFSET) /* RD Reset 2 */ +#define N32_RCC_BDCTRL (N32_RCC_BASE + N32_RCC_BDCTRL_OFFSET) /* Backup Domain Control */ +#define N32_RCC_CTRLSTS (N32_RCC_BASE + N32_RCC_CTRLSTS_OFFSET) /* Control and Status */ +#define N32_RCC_CLKINT1 (N32_RCC_BASE + N32_RCC_CLKINT1_OFFSET) /* Clock Interrupt 1 */ +#define N32_RCC_CLKINT2 (N32_RCC_BASE + N32_RCC_CLKINT2_OFFSET) /* Clock Interrupt 2 */ +#define N32_RCC_CFG1 (N32_RCC_BASE + N32_RCC_CFG1_OFFSET) /* Configuration 1 */ +#define N32_RCC_AXIDIV1 (N32_RCC_BASE + N32_RCC_AXIDIV1_OFFSET) /* AXI Divider 1 */ +#define N32_RCC_AXISEL1 (N32_RCC_BASE + N32_RCC_AXISEL1_OFFSET) /* AXI Select 1 */ +#define N32_RCC_AXIEN1 (N32_RCC_BASE + N32_RCC_AXIEN1_OFFSET) /* AXI Enable 1 */ +#define N32_RCC_AXIEN2 (N32_RCC_BASE + N32_RCC_AXIEN2_OFFSET) /* AXI Enable 2 */ +#define N32_RCC_AXIEN3 (N32_RCC_BASE + N32_RCC_AXIEN3_OFFSET) /* AXI Enable 3 */ +#define N32_RCC_AXIEN4 (N32_RCC_BASE + N32_RCC_AXIEN4_OFFSET) /* AXI Enable 4 */ +#define N32_RCC_AXIRST1 (N32_RCC_BASE + N32_RCC_AXIRST1_OFFSET) /* AXI Reset 1 */ +#define N32_RCC_AXIRST2 (N32_RCC_BASE + N32_RCC_AXIRST2_OFFSET) /* AXI Reset 2 */ +#define N32_RCC_AXIRST3 (N32_RCC_BASE + N32_RCC_AXIRST3_OFFSET) /* AXI Reset 3 */ +#define N32_RCC_AXIRST4 (N32_RCC_BASE + N32_RCC_AXIRST4_OFFSET) /* AXI Reset 4 */ +#define N32_RCC_CFG2 (N32_RCC_BASE + N32_RCC_CFG2_OFFSET) /* Configuration 2 */ +#define N32_RCC_CFG3 (N32_RCC_BASE + N32_RCC_CFG3_OFFSET) /* Configuration 3 */ +#define N32_RCC_CFG4 (N32_RCC_BASE + N32_RCC_CFG4_OFFSET) /* Configuration 4 */ +#define N32_RCC_SRCCTRL2 (N32_RCC_BASE + N32_RCC_SRCCTRL2_OFFSET) /* Source Control 2 */ +#define N32_RCC_CFG5 (N32_RCC_BASE + N32_RCC_CFG5_OFFSET) /* Configuration 5 */ +#define N32_RCC_M4RSTREL (N32_RCC_BASE + N32_RCC_M4RSTREL_OFFSET) /* M4 Reset Release */ +#define N32_RCC_AXIDIV2 (N32_RCC_BASE + N32_RCC_AXIDIV2_OFFSET) /* AXI Divider 2 */ +#define N32_RCC_AXISEL2 (N32_RCC_BASE + N32_RCC_AXISEL2_OFFSET) /* AXI Select 2 */ +#define N32_RCC_SHRPLLCTRL1 (N32_RCC_BASE + N32_RCC_SHRPLLCTRL1_OFFSET)/* Shared PLL Control 1 */ +#define N32_RCC_SHRPLLCTRL2 (N32_RCC_BASE + N32_RCC_SHRPLLCTRL2_OFFSET)/* Shared PLL Control 2 */ +#define N32_RCC_AHB1DIV2 (N32_RCC_BASE + N32_RCC_AHB1DIV2_OFFSET) /* AHB1 Divider 2 */ +#define N32_RCC_LSERDDL (N32_RCC_BASE + N32_RCC_LSERDDL_OFFSET) /* LSE Ready Delay */ +#define N32_RCC_MSIRDDL (N32_RCC_BASE + N32_RCC_MSIRDDL_OFFSET) /* MSI Ready Delay */ +#define N32_RCC_HSERDDL (N32_RCC_BASE + N32_RCC_HSERDDL_OFFSET) /* HSE Ready Delay */ +#define N32_RCC_PLLSFTLK (N32_RCC_BASE + N32_RCC_PLLSFTLK_OFFSET) /* PLL Soft Lock */ +#define N32_RCC_RDCTRL1 (N32_RCC_BASE + N32_RCC_RDCTRL1_OFFSET) /* RD Control 1 */ +#define N32_RCC_RDCTRL2 (N32_RCC_BASE + N32_RCC_RDCTRL2_OFFSET) /* RD Control 2 */ +#define N32_RCC_RDCTRL3 (N32_RCC_BASE + N32_RCC_RDCTRL3_OFFSET) /* RD Control 3 */ +#define N32_RCC_AHB2EN2 (N32_RCC_BASE + N32_RCC_AHB2EN2_OFFSET) /* AHB2 Enable 2 */ +#define N32_RCC_AHB9DIV1 (N32_RCC_BASE + N32_RCC_AHB9DIV1_OFFSET) /* AHB9 Divider 1 */ +#define N32_RCC_AHB9SEL1 (N32_RCC_BASE + N32_RCC_AHB9SEL1_OFFSET) /* AHB9 Select 1 */ +#define N32_RCC_AHB9EN1 (N32_RCC_BASE + N32_RCC_AHB9EN1_OFFSET) /* AHB9 Enable 1 */ +#define N32_RCC_AHB9RST1 (N32_RCC_BASE + N32_RCC_AHB9RST1_OFFSET) /* AHB9 Reset 1 */ +#define N32_RCC_HSEOS (N32_RCC_BASE + N32_RCC_HSEOS_OFFSET) /* HSE Oscillator Status */ +#define N32_RCC_LSEOS (N32_RCC_BASE + N32_RCC_LSEOS_OFFSET) /* LSE Oscillator Status */ +#define N32_RCC_HSECAL (N32_RCC_BASE + N32_RCC_HSECAL_OFFSET) /* HSE Calibration */ +#define N32_RCC_CLKINT3 (N32_RCC_BASE + N32_RCC_CLKINT3_OFFSET) /* Clock Interrupt 3 */ +#define N32_RCC_PLLFD (N32_RCC_BASE + N32_RCC_PLLFD_OFFSET) /* PLL Frequency Detect */ +#define N32_RCC_SRCCTRL3 (N32_RCC_BASE + N32_RCC_SRCCTRL3_OFFSET) /* Source Control 3 */ +#define N32_RCC_LSICSSDL (N32_RCC_BASE + N32_RCC_LSICSSDL_OFFSET) /* LSI CSS Delay */ + +/* Register Bitfield Definitions ********************************************/ + +/* Bit definition for RCC_PLL1CTRL1 register ********************************/ +#define RCC_PLL1CTRL1_PLL1SRC_SHIFT (28) /* Bits 28-29: PLL1 clock source selection */ +#define RCC_PLL1CTRL1_PLL1SRC_MASK (0x3 << RCC_PLL1CTRL1_PLL1SRC_SHIFT) +#define RCC_PLL1CTRL1_PLL1SRC_0 (1 << 28) /* Bit 28 */ +#define RCC_PLL1CTRL1_PLL1SRC_1 (1 << 29) /* Bit 29 */ + +#define RCC_PLL1CTRL1_PLL1SRC_HSI (0x0 << RCC_PLL1CTRL1_PLL1SRC_SHIFT) /* HSI Clock is the PLL source clock */ +#define RCC_PLL1CTRL1_PLL1SRC_NONE (0x1 << RCC_PLL1CTRL1_PLL1SRC_SHIFT) /* No clock */ +#define RCC_PLL1CTRL1_PLL1SRC_MSI (0x2 << RCC_PLL1CTRL1_PLL1SRC_SHIFT) /* MSI Clock is the PLL source clock */ +#define RCC_PLL1CTRL1_PLL1SRC_HSE (0x3 << RCC_PLL1CTRL1_PLL1SRC_SHIFT) /* HSE Clock is the PLL source clock */ + +#define RCC_PLL1CTRL1_PLL1PHLK (1 << 20) /* Bit 20: PLL1 PH lock */ +#define RCC_PLL1CTRL1_PLL1LDOEN (1 << 19) /* Bit 19: PLL1 LDO enable */ +#define RCC_PLL1CTRL1_PLL1EN (1 << 18) /* Bit 18: PLL1 enable */ +#define RCC_PLL1CTRL1_PLL1RST (1 << 17) /* Bit 17: PLL1 reset */ +#define RCC_PLL1CTRL1_PLL1PD (1 << 16) /* Bit 16: PLL1 power down */ + +#define RCC_PLL1CTRL1_PLL1BWAJ_SHIFT (0) /* Bits 0-11: PLL1 BWAJ value */ +#define RCC_PLL1CTRL1_PLL1BWAJ_MASK (0xFFF << RCC_PLL1CTRL1_PLL1BWAJ_SHIFT) +#define RCC_PLL1CTRL1_PLL1BWAJ_0 (1 << 0) /* Bit 0 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_1 (1 << 1) /* Bit 1 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_2 (1 << 2) /* Bit 2 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_3 (1 << 3) /* Bit 3 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_4 (1 << 4) /* Bit 4 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_5 (1 << 5) /* Bit 5 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_6 (1 << 6) /* Bit 6 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_7 (1 << 7) /* Bit 7 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_8 (1 << 8) /* Bit 8 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_9 (1 << 9) /* Bit 9 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_10 (1 << 10) /* Bit 10 */ +#define RCC_PLL1CTRL1_PLL1BWAJ_11 (1 << 11) /* Bit 11 */ + +#define RCC_PLL1CTRL1_PLL1BWAJ(n) ((n) << RCC_PLL1CTRL1_PLL1BWAJ_SHIFT) + +/* Bit definition for RCC_PLL1CTRL2 register ********************************/ +#define RCC_PLL1CTRL2_PLL1CLKR_SHIFT (26) /* Bits 26-31: PLL1 clock R divider */ +#define RCC_PLL1CTRL2_PLL1CLKR_MASK (0x3F << RCC_PLL1CTRL2_PLL1CLKR_SHIFT) +#define RCC_PLL1CTRL2_PLL1CLKR_0 (1 << 26) /* Bit 26 */ +#define RCC_PLL1CTRL2_PLL1CLKR_1 (1 << 27) /* Bit 27 */ +#define RCC_PLL1CTRL2_PLL1CLKR_2 (1 << 28) /* Bit 28 */ +#define RCC_PLL1CTRL2_PLL1CLKR_3 (1 << 29) /* Bit 29 */ +#define RCC_PLL1CTRL2_PLL1CLKR_4 (1 << 30) /* Bit 30 */ +#define RCC_PLL1CTRL2_PLL1CLKR_5 (1 << 31) /* Bit 31 */ + +#define RCC_PLL1CTRL2_PLL1CLKR(n) ((n) << RCC_PLL1CTRL2_PLL1CLKR_SHIFT) + +#define RCC_PLL1CTRL2_PLL1CLKF_SHIFT (0) /* Bits 0-25: PLL1 clock F multiplier */ +#define RCC_PLL1CTRL2_PLL1CLKF_MASK (0x3FFFFFF << RCC_PLL1CTRL2_PLL1CLKF_SHIFT) +#define RCC_PLL1CTRL2_PLL1CLKF_0 (1 << 0) /* Bit 0 */ +#define RCC_PLL1CTRL2_PLL1CLKF_1 (1 << 1) /* Bit 1 */ +#define RCC_PLL1CTRL2_PLL1CLKF_2 (1 << 2) /* Bit 2 */ +#define RCC_PLL1CTRL2_PLL1CLKF_3 (1 << 3) /* Bit 3 */ +#define RCC_PLL1CTRL2_PLL1CLKF_4 (1 << 4) /* Bit 4 */ +#define RCC_PLL1CTRL2_PLL1CLKF_5 (1 << 5) /* Bit 5 */ +#define RCC_PLL1CTRL2_PLL1CLKF_6 (1 << 6) /* Bit 6 */ +#define RCC_PLL1CTRL2_PLL1CLKF_7 (1 << 7) /* Bit 7 */ +#define RCC_PLL1CTRL2_PLL1CLKF_8 (1 << 8) /* Bit 8 */ +#define RCC_PLL1CTRL2_PLL1CLKF_9 (1 << 9) /* Bit 9 */ +#define RCC_PLL1CTRL2_PLL1CLKF_10 (1 << 10) /* Bit 10 */ +#define RCC_PLL1CTRL2_PLL1CLKF_11 (1 << 11) /* Bit 11 */ +#define RCC_PLL1CTRL2_PLL1CLKF_12 (1 << 12) /* Bit 12 */ +#define RCC_PLL1CTRL2_PLL1CLKF_13 (1 << 13) /* Bit 13 */ +#define RCC_PLL1CTRL2_PLL1CLKF_14 (1 << 14) /* Bit 14 */ +#define RCC_PLL1CTRL2_PLL1CLKF_15 (1 << 15) /* Bit 15 */ +#define RCC_PLL1CTRL2_PLL1CLKF_16 (1 << 16) /* Bit 16 */ +#define RCC_PLL1CTRL2_PLL1CLKF_17 (1 << 17) /* Bit 17 */ +#define RCC_PLL1CTRL2_PLL1CLKF_18 (1 << 18) /* Bit 18 */ +#define RCC_PLL1CTRL2_PLL1CLKF_19 (1 << 19) /* Bit 19 */ +#define RCC_PLL1CTRL2_PLL1CLKF_20 (1 << 20) /* Bit 20 */ +#define RCC_PLL1CTRL2_PLL1CLKF_21 (1 << 21) /* Bit 21 */ +#define RCC_PLL1CTRL2_PLL1CLKF_22 (1 << 22) /* Bit 22 */ +#define RCC_PLL1CTRL2_PLL1CLKF_23 (1 << 23) /* Bit 23 */ +#define RCC_PLL1CTRL2_PLL1CLKF_24 (1 << 24) /* Bit 24 */ +#define RCC_PLL1CTRL2_PLL1CLKF_25 (1 << 25) /* Bit 25 */ + +#define RCC_PLL1CTRL2_PLL1CLKF(n) ((n) << RCC_PLL1CTRL2_PLL1CLKF_SHIFT) + +/* Bit definition for RCC_PLL2CTRL1 register ********************************/ +#define RCC_PLL2CTRL1_PLL2SRC_SHIFT (28) /* Bits 28-29: PLL2 clock source selection */ +#define RCC_PLL2CTRL1_PLL2SRC_MASK (0x3 << RCC_PLL2CTRL1_PLL2SRC_SHIFT) +#define RCC_PLL2CTRL1_PLL2SRC_0 (1 << 28) /* Bit 28 */ +#define RCC_PLL2CTRL1_PLL2SRC_1 (1 << 29) /* Bit 29 */ + +#define RCC_PLL2CTRL1_PLL2SRC_HSI (0x0 << RCC_PLL2CTRL1_PLL2SRC_SHIFT) /* HSI Clock is the PLL source clock */ +#define RCC_PLL2CTRL1_PLL2SRC_NONE (0x1 << RCC_PLL2CTRL1_PLL2SRC_SHIFT) /* No clock */ +#define RCC_PLL2CTRL1_PLL2SRC_MSI (0x2 << RCC_PLL2CTRL1_PLL2SRC_SHIFT) /* MSI Clock is the PLL source clock */ +#define RCC_PLL2CTRL1_PLL2SRC_HSE (0x3 << RCC_PLL2CTRL1_PLL2SRC_SHIFT) /* HSE Clock is the PLL source clock */ + +#define RCC_PLL2CTRL1_PLL2PHLK (1 << 20) /* Bit 20: PLL2 PH lock */ +#define RCC_PLL2CTRL1_PLL2LDOEN (1 << 19) /* Bit 19: PLL2 LDO enable */ +#define RCC_PLL2CTRL1_PLL2EN (1 << 18) /* Bit 18: PLL2 enable */ +#define RCC_PLL2CTRL1_PLL2RST (1 << 17) /* Bit 17: PLL2 reset */ +#define RCC_PLL2CTRL1_PLL2PD (1 << 16) /* Bit 16: PLL2 power down */ + +#define RCC_PLL2CTRL1_PLL2BWAJ_SHIFT (0) /* Bits 0-11: PLL2 BWAJ value */ +#define RCC_PLL2CTRL1_PLL2BWAJ_MASK (0xFFF << RCC_PLL2CTRL1_PLL2BWAJ_SHIFT) +#define RCC_PLL2CTRL1_PLL2BWAJ_0 (1 << 0) /* Bit 0 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_1 (1 << 1) /* Bit 1 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_2 (1 << 2) /* Bit 2 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_3 (1 << 3) /* Bit 3 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_4 (1 << 4) /* Bit 4 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_5 (1 << 5) /* Bit 5 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_6 (1 << 6) /* Bit 6 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_7 (1 << 7) /* Bit 7 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_8 (1 << 8) /* Bit 8 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_9 (1 << 9) /* Bit 9 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_10 (1 << 10) /* Bit 10 */ +#define RCC_PLL2CTRL1_PLL2BWAJ_11 (1 << 11) /* Bit 11 */ + +#define RCC_PLL2CTRL1_PLL2BWAJ(n) ((n) << RCC_PLL2CTRL1_PLL2BWAJ_SHIFT) + +/* Bit definition for RCC_PLL2CTRL2 register ********************************/ +#define RCC_PLL2CTRL2_PLL2CLKR_SHIFT (26) /* Bits 26-31: PLL2 clock R divider */ +#define RCC_PLL2CTRL2_PLL2CLKR_MASK (0x3F << RCC_PLL2CTRL2_PLL2CLKR_SHIFT) +#define RCC_PLL2CTRL2_PLL2CLKR_0 (1 << 26) /* Bit 26 */ +#define RCC_PLL2CTRL2_PLL2CLKR_1 (1 << 27) /* Bit 27 */ +#define RCC_PLL2CTRL2_PLL2CLKR_2 (1 << 28) /* Bit 28 */ +#define RCC_PLL2CTRL2_PLL2CLKR_3 (1 << 29) /* Bit 29 */ +#define RCC_PLL2CTRL2_PLL2CLKR_4 (1 << 30) /* Bit 30 */ +#define RCC_PLL2CTRL2_PLL2CLKR_5 (1 << 31) /* Bit 31 */ + +#define RCC_PLL2CTRL2_PLL2CLKR(n) ((n) << RCC_PLL2CTRL2_PLL2CLKR_SHIFT) + +#define RCC_PLL2CTRL2_PLL2CLKF_SHIFT (0) /* Bits 0-25: PLL2 clock F multiplier */ +#define RCC_PLL2CTRL2_PLL2CLKF_MASK (0x3FFFFFF << RCC_PLL2CTRL2_PLL2CLKF_SHIFT) +#define RCC_PLL2CTRL2_PLL2CLKF_0 (1 << 0) /* Bit 0 */ +#define RCC_PLL2CTRL2_PLL2CLKF_1 (1 << 1) /* Bit 1 */ +#define RCC_PLL2CTRL2_PLL2CLKF_2 (1 << 2) /* Bit 2 */ +#define RCC_PLL2CTRL2_PLL2CLKF_3 (1 << 3) /* Bit 3 */ +#define RCC_PLL2CTRL2_PLL2CLKF_4 (1 << 4) /* Bit 4 */ +#define RCC_PLL2CTRL2_PLL2CLKF_5 (1 << 5) /* Bit 5 */ +#define RCC_PLL2CTRL2_PLL2CLKF_6 (1 << 6) /* Bit 6 */ +#define RCC_PLL2CTRL2_PLL2CLKF_7 (1 << 7) /* Bit 7 */ +#define RCC_PLL2CTRL2_PLL2CLKF_8 (1 << 8) /* Bit 8 */ +#define RCC_PLL2CTRL2_PLL2CLKF_9 (1 << 9) /* Bit 9 */ +#define RCC_PLL2CTRL2_PLL2CLKF_10 (1 << 10) /* Bit 10 */ +#define RCC_PLL2CTRL2_PLL2CLKF_11 (1 << 11) /* Bit 11 */ +#define RCC_PLL2CTRL2_PLL2CLKF_12 (1 << 12) /* Bit 12 */ +#define RCC_PLL2CTRL2_PLL2CLKF_13 (1 << 13) /* Bit 13 */ +#define RCC_PLL2CTRL2_PLL2CLKF_14 (1 << 14) /* Bit 14 */ +#define RCC_PLL2CTRL2_PLL2CLKF_15 (1 << 15) /* Bit 15 */ +#define RCC_PLL2CTRL2_PLL2CLKF_16 (1 << 16) /* Bit 16 */ +#define RCC_PLL2CTRL2_PLL2CLKF_17 (1 << 17) /* Bit 17 */ +#define RCC_PLL2CTRL2_PLL2CLKF_18 (1 << 18) /* Bit 18 */ +#define RCC_PLL2CTRL2_PLL2CLKF_19 (1 << 19) /* Bit 19 */ +#define RCC_PLL2CTRL2_PLL2CLKF_20 (1 << 20) /* Bit 20 */ +#define RCC_PLL2CTRL2_PLL2CLKF_21 (1 << 21) /* Bit 21 */ +#define RCC_PLL2CTRL2_PLL2CLKF_22 (1 << 22) /* Bit 22 */ +#define RCC_PLL2CTRL2_PLL2CLKF_23 (1 << 23) /* Bit 23 */ +#define RCC_PLL2CTRL2_PLL2CLKF_24 (1 << 24) /* Bit 24 */ +#define RCC_PLL2CTRL2_PLL2CLKF_25 (1 << 25) /* Bit 25 */ + +#define RCC_PLL2CTRL2_PLL2CLKF(n) ((n) << RCC_PLL2CTRL2_PLL2CLKF_SHIFT) + +/* Bit definition for RCC_PLL3CTRL1 register ********************************/ +#define RCC_PLL3CTRL1_PLL3SRC_SHIFT (28) /* Bits 28-29: PLL3 clock source selection */ +#define RCC_PLL3CTRL1_PLL3SRC_MASK (0x3 << RCC_PLL3CTRL1_PLL3SRC_SHIFT) +#define RCC_PLL3CTRL1_PLL3SRC_0 (1 << 28) /* Bit 28 */ +#define RCC_PLL3CTRL1_PLL3SRC_1 (1 << 29) /* Bit 29 */ + +#define RCC_PLL3CTRL1_PLL3SRC_HSI (0x0 << RCC_PLL3CTRL1_PLL3SRC_SHIFT) /* HSI Clock is the PLL source clock */ +#define RCC_PLL3CTRL1_PLL3SRC_NONE (0x1 << RCC_PLL3CTRL1_PLL3SRC_SHIFT) /* No clock */ +#define RCC_PLL3CTRL1_PLL3SRC_MSI (0x2 << RCC_PLL3CTRL1_PLL3SRC_SHIFT) /* MSI Clock is the PLL source clock */ +#define RCC_PLL3CTRL1_PLL3SRC_HSE (0x3 << RCC_PLL3CTRL1_PLL3SRC_SHIFT) /* HSE Clock is the PLL source clock */ + +#define RCC_PLL3CTRL1_PLL3PHLK (1 << 20) /* Bit 20: PLL3 PH lock */ +#define RCC_PLL3CTRL1_PLL3LDOEN (1 << 19) /* Bit 19: PLL3 LDO enable */ +#define RCC_PLL3CTRL1_PLL3EN (1 << 18) /* Bit 18: PLL3 enable */ +#define RCC_PLL3CTRL1_PLL3RST (1 << 17) /* Bit 17: PLL3 reset */ +#define RCC_PLL3CTRL1_PLL3PD (1 << 16) /* Bit 16: PLL3 power down */ + +#define RCC_PLL3CTRL1_PLL3BWAJ_SHIFT (0) /* Bits 0-11: PLL3 BWAJ value */ +#define RCC_PLL3CTRL1_PLL3BWAJ_MASK (0xFFF << RCC_PLL3CTRL1_PLL3BWAJ_SHIFT) +#define RCC_PLL3CTRL1_PLL3BWAJ_0 (1 << 0) /* Bit 0 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_1 (1 << 1) /* Bit 1 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_2 (1 << 2) /* Bit 2 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_3 (1 << 3) /* Bit 3 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_4 (1 << 4) /* Bit 4 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_5 (1 << 5) /* Bit 5 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_6 (1 << 6) /* Bit 6 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_7 (1 << 7) /* Bit 7 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_8 (1 << 8) /* Bit 8 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_9 (1 << 9) /* Bit 9 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_10 (1 << 10) /* Bit 10 */ +#define RCC_PLL3CTRL1_PLL3BWAJ_11 (1 << 11) /* Bit 11 */ + +#define RCC_PLL3CTRL1_PLL3BWAJ(n) ((n) << RCC_PLL3CTRL1_PLL3BWAJ_SHIFT) + +/* Bit definition for RCC_PLL3CTRL2 register ********************************/ +#define RCC_PLL3CTRL2_PLL3CLKR_SHIFT (26) /* Bits 26-31: PLL3 clock R divider */ +#define RCC_PLL3CTRL2_PLL3CLKR_MASK (0x3F << RCC_PLL3CTRL2_PLL3CLKR_SHIFT) +#define RCC_PLL3CTRL2_PLL3CLKR_0 (1 << 26) /* Bit 26 */ +#define RCC_PLL3CTRL2_PLL3CLKR_1 (1 << 27) /* Bit 27 */ +#define RCC_PLL3CTRL2_PLL3CLKR_2 (1 << 28) /* Bit 28 */ +#define RCC_PLL3CTRL2_PLL3CLKR_3 (1 << 29) /* Bit 29 */ +#define RCC_PLL3CTRL2_PLL3CLKR_4 (1 << 30) /* Bit 30 */ +#define RCC_PLL3CTRL2_PLL3CLKR_5 (1 << 31) /* Bit 31 */ + +#define RCC_PLL3CTRL2_PLL3CLKR(n) ((n) << RCC_PLL3CTRL2_PLL3CLKR_SHIFT) + +#define RCC_PLL3CTRL2_PLL3CLKF_SHIFT (0) /* Bits 0-25: PLL3 clock F multiplier */ +#define RCC_PLL3CTRL2_PLL3CLKF_MASK (0x3FFFFFF << RCC_PLL3CTRL2_PLL3CLKF_SHIFT) +#define RCC_PLL3CTRL2_PLL3CLKF_0 (1 << 0) /* Bit 0 */ +#define RCC_PLL3CTRL2_PLL3CLKF_1 (1 << 1) /* Bit 1 */ +#define RCC_PLL3CTRL2_PLL3CLKF_2 (1 << 2) /* Bit 2 */ +#define RCC_PLL3CTRL2_PLL3CLKF_3 (1 << 3) /* Bit 3 */ +#define RCC_PLL3CTRL2_PLL3CLKF_4 (1 << 4) /* Bit 4 */ +#define RCC_PLL3CTRL2_PLL3CLKF_5 (1 << 5) /* Bit 5 */ +#define RCC_PLL3CTRL2_PLL3CLKF_6 (1 << 6) /* Bit 6 */ +#define RCC_PLL3CTRL2_PLL3CLKF_7 (1 << 7) /* Bit 7 */ +#define RCC_PLL3CTRL2_PLL3CLKF_8 (1 << 8) /* Bit 8 */ +#define RCC_PLL3CTRL2_PLL3CLKF_9 (1 << 9) /* Bit 9 */ +#define RCC_PLL3CTRL2_PLL3CLKF_10 (1 << 10) /* Bit 10 */ +#define RCC_PLL3CTRL2_PLL3CLKF_11 (1 << 11) /* Bit 11 */ +#define RCC_PLL3CTRL2_PLL3CLKF_12 (1 << 12) /* Bit 12 */ +#define RCC_PLL3CTRL2_PLL3CLKF_13 (1 << 13) /* Bit 13 */ +#define RCC_PLL3CTRL2_PLL3CLKF_14 (1 << 14) /* Bit 14 */ +#define RCC_PLL3CTRL2_PLL3CLKF_15 (1 << 15) /* Bit 15 */ +#define RCC_PLL3CTRL2_PLL3CLKF_16 (1 << 16) /* Bit 16 */ +#define RCC_PLL3CTRL2_PLL3CLKF_17 (1 << 17) /* Bit 17 */ +#define RCC_PLL3CTRL2_PLL3CLKF_18 (1 << 18) /* Bit 18 */ +#define RCC_PLL3CTRL2_PLL3CLKF_19 (1 << 19) /* Bit 19 */ +#define RCC_PLL3CTRL2_PLL3CLKF_20 (1 << 20) /* Bit 20 */ +#define RCC_PLL3CTRL2_PLL3CLKF_21 (1 << 21) /* Bit 21 */ +#define RCC_PLL3CTRL2_PLL3CLKF_22 (1 << 22) /* Bit 22 */ +#define RCC_PLL3CTRL2_PLL3CLKF_23 (1 << 23) /* Bit 23 */ +#define RCC_PLL3CTRL2_PLL3CLKF_24 (1 << 24) /* Bit 24 */ +#define RCC_PLL3CTRL2_PLL3CLKF_25 (1 << 25) /* Bit 25 */ + +#define RCC_PLL3CTRL2_PLL3CLKF(n) ((n) << RCC_PLL3CTRL2_PLL3CLKF_SHIFT) + +/* Bit definition for RCC_SHRPLLCTRL1 register ******************************/ + +/* Bits 29:28 SHRPLL clock source selection */ +#define RCC_SHRPLLCTRL1_SHRPLLSRC_SHIFT (28) +#define RCC_SHRPLLCTRL1_SHRPLLSRC_MASK (0x3 << RCC_SHRPLLCTRL1_SHRPLLSRC_SHIFT) +#define RCC_SHRPLLCTRL1_SHRPLLSRC_0 (0x1 << 28) /* Bit 28 */ +#define RCC_SHRPLLCTRL1_SHRPLLSRC_1 (0x1 << 29) /* Bit 29 */ + +#define RCC_SHRPLLCTRL1_SHRPLLSRC_HSI (0x0 << RCC_SHRPLLCTRL1_SHRPLLSRC_SHIFT) /* HSI Clock is the PLL source clock */ +#define RCC_SHRPLLCTRL1_SHRPLLSRC_NONE (0x1 << RCC_SHRPLLCTRL1_SHRPLLSRC_SHIFT) /* No clock */ +#define RCC_SHRPLLCTRL1_SHRPLLSRC_MSI (0x2 << RCC_SHRPLLCTRL1_SHRPLLSRC_SHIFT) /* MSI Clock is the PLL source clock */ +#define RCC_SHRPLLCTRL1_SHRPLLSRC_HSE (0x3 << RCC_SHRPLLCTRL1_SHRPLLSRC_SHIFT) /* HSE Clock is the PLL source clock */ + +/* Bit 20 SHRPLL PH lock */ +#define RCC_SHRPLLCTRL1_SHRPLLPHLK (0x1 << 20) + +/* Bit 19 SHRPLL LDO enable */ +#define RCC_SHRPLLCTRL1_SHRPLLLDOEN (0x1 << 19) + +/* Bit 18 SHRPLL enable */ +#define RCC_SHRPLLCTRL1_SHRPLLEN (0x1 << 18) + +/* Bit 17 SHRPLL reset */ +#define RCC_SHRPLLCTRL1_SHRPLLRST (0x1 << 17) + +/* Bit 16 SHRPLL power down */ +#define RCC_SHRPLLCTRL1_SHRPLLPD (0x1 << 16) + +/* Bits 11:0 SHRPLL bandwidth adjustment */ +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_SHIFT (0) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_MASK (0xFFF << RCC_SHRPLLCTRL1_SHRPLLBWAJ_SHIFT) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_0 (0x1 << 0) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_1 (0x1 << 1) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_2 (0x1 << 2) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_3 (0x1 << 3) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_4 (0x1 << 4) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_5 (0x1 << 5) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_6 (0x1 << 6) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_7 (0x1 << 7) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_8 (0x1 << 8) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_9 (0x1 << 9) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_10 (0x1 << 10) +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ_11 (0x1 << 11) + +#define RCC_SHRPLLCTRL1_SHRPLLBWAJ(n) ((n) << RCC_SHRPLLCTRL1_SHRPLLBWAJ_SHIFT) + +/* Bit definition for RCC_SHRPLLCTRL2 register ******************************/ + +/* Bits 31:26 SHRPLL clock R divider */ +#define RCC_SHRPLLCTRL2_SHRPLLCLKR_SHIFT (26) +#define RCC_SHRPLLCTRL2_SHRPLLCLKR_MASK (0x3F << RCC_SHRPLLCTRL2_SHRPLLCLKR_SHIFT) +#define RCC_SHRPLLCTRL2_SHRPLLCLKR_0 (0x1 << 26) +#define RCC_SHRPLLCTRL2_SHRPLLCLKR_1 (0x1 << 27) +#define RCC_SHRPLLCTRL2_SHRPLLCLKR_2 (0x1 << 28) +#define RCC_SHRPLLCTRL2_SHRPLLCLKR_3 (0x1 << 29) +#define RCC_SHRPLLCTRL2_SHRPLLCLKR_4 (0x1 << 30) +#define RCC_SHRPLLCTRL2_SHRPLLCLKR_5 (0x1 << 31) + +#define RCC_SHRPLLCTRL2_SHRPLLCLKR(n) ((n) << RCC_SHRPLLCTRL2_SHRPLLCLKR_SHIFT) + +/* Bits 25:0 SHRPLL clock F multiplier */ +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_SHIFT (0) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_MASK (0x3FFFFFF << RCC_SHRPLLCTRL2_SHRPLLCLKF_SHIFT) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_0 (0x1 << 0) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_1 (0x1 << 1) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_2 (0x1 << 2) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_3 (0x1 << 3) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_4 (0x1 << 4) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_5 (0x1 << 5) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_6 (0x1 << 6) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_7 (0x1 << 7) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_8 (0x1 << 8) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_9 (0x1 << 9) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_10 (0x1 << 10) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_11 (0x1 << 11) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_12 (0x1 << 12) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_13 (0x1 << 13) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_14 (0x1 << 14) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_15 (0x1 << 15) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_16 (0x1 << 16) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_17 (0x1 << 17) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_18 (0x1 << 18) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_19 (0x1 << 19) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_20 (0x1 << 20) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_21 (0x1 << 21) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_22 (0x1 << 22) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_23 (0x1 << 23) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_24 (0x1 << 24) +#define RCC_SHRPLLCTRL2_SHRPLLCLKF_25 (0x1 << 25) + +#define RCC_SHRPLLCTRL2_SHRPLLCLKF(n) ((n) << RCC_SHRPLLCTRL2_SHRPLLCLKF_SHIFT) + +/* Bit definition for RCC_SRCCTRL1 register *********************************/ +#define RCC_SRCCTRL1_AFEMSIRDF (1 << 31) /* Bit 31: AFE MSI ready flag */ +#define RCC_SRCCTRL1_AFEHSIRDF (1 << 30) /* Bit 30: AFE HSI ready flag */ + +#define RCC_SRCCTRL1_SCLKSTS_SHIFT (26) /* Bits 26-27: System clock status */ +#define RCC_SRCCTRL1_SCLKSTS_MASK (0x3 << RCC_SRCCTRL1_SCLKSTS_SHIFT) +#define RCC_SRCCTRL1_SCLKSTS_HSI (0x0 << RCC_SRCCTRL1_SCLKSTS_SHIFT) +#define RCC_SRCCTRL1_SCLKSTS_MSI (0x1 << RCC_SRCCTRL1_SCLKSTS_SHIFT) +#define RCC_SRCCTRL1_SCLKSTS_HSE (0x2 << RCC_SRCCTRL1_SCLKSTS_SHIFT) +#define RCC_SRCCTRL1_SCLKSTS_PLL1A (0x3 << RCC_SRCCTRL1_SCLKSTS_SHIFT) + +#define RCC_SRCCTRL1_SCLKSW_SHIFT (24) /* Bits 24-25: System clock switch */ +#define RCC_SRCCTRL1_SCLKSW_MASK (0x3 << RCC_SRCCTRL1_SCLKSW_SHIFT) +#define RCC_SRCCTRL1_SCLKSW_HSI (0x0 << RCC_SRCCTRL1_SCLKSW_SHIFT) +#define RCC_SRCCTRL1_SCLKSW_MSI (0x1 << RCC_SRCCTRL1_SCLKSW_SHIFT) +#define RCC_SRCCTRL1_SCLKSW_HSE (0x2 << RCC_SRCCTRL1_SCLKSW_SHIFT) +#define RCC_SRCCTRL1_SCLKSW_PLL1A (0x3 << RCC_SRCCTRL1_SCLKSW_SHIFT) + +#define RCC_SRCCTRL1_HSERDCNTEN (1 << 8) /* Bit 8: HSE ready counter enable */ +#define RCC_SRCCTRL1_MSIRDF (1 << 7) /* Bit 7: MSI ready flag */ +#define RCC_SRCCTRL1_MSIEN (1 << 6) /* Bit 6: MSI enable */ +#define RCC_SRCCTRL1_HSECSSEN (1 << 5) /* Bit 5: HSE clock security system enable */ +#define RCC_SRCCTRL1_HSEBP (1 << 4) /* Bit 4: HSE bypass */ +#define RCC_SRCCTRL1_HSERDF (1 << 3) /* Bit 3: HSE ready flag */ +#define RCC_SRCCTRL1_HSEEN (1 << 2) /* Bit 2: HSE enable */ +#define RCC_SRCCTRL1_HSIRDF (1 << 1) /* Bit 1: HSI ready flag */ +#define RCC_SRCCTRL1_HSIEN (1 << 0) /* Bit 0: HSI enable */ + +/* Bit definition for RCC_SRCCTRL2 register *********************************/ +#define RCC_SRCCTRL2_BORF (0x1 << 30) /* Bit 30: Brown-out reset flag */ +#define RCC_SRCCTRL2_HSICALEF (0x1 << 29) /* Bit 29: HSI calibration error flag */ +#define RCC_SRCCTRL2_MSICALEF (0x1 << 28) /* Bit 28: MSI calibration error flag */ + +#define RCC_SRCCTRL2_M7HYPSEL_SHIFT (17) +#define RCC_SRCCTRL2_M7HYPSEL_MASK (0x1 << RCC_SRCCTRL2_M7HYPSEL_SHIFT) /* Bit 17: M7 hypervisor clock source selection */ +#define RCC_SRCCTRL2_M7HYPSEL_PLL1A (0x0 << RCC_SRCCTRL2_M7HYPSEL_SHIFT) /* Use PLL1A as M7 hypervisor clock source */ +#define RCC_SRCCTRL2_M7HYPSEL_PLL2A (0x1 << RCC_SRCCTRL2_M7HYPSEL_SHIFT) /* Use PLL2A as M7 hypervisor clock source */ + +#define RCC_SRCCTRL2_AXIHYPSEL_SHIFT (16) +#define RCC_SRCCTRL2_AXIHYPSEL_MASK (0x1 << RCC_SRCCTRL2_AXIHYPSEL_SHIFT) /* Bit 16: AXI hypervisor clock source selection */ +#define RCC_SRCCTRL2_AXIHYPSEL_PLL1A (0x0 << RCC_SRCCTRL2_AXIHYPSEL_SHIFT) /* Use PLL1A as AXI hypervisor clock source */ +#define RCC_SRCCTRL2_AXIHYPSEL_PLL2A (0x1 << RCC_SRCCTRL2_AXIHYPSEL_SHIFT) /* Use PLL2A as AXI hypervisor clock source */ + +/* Bits 12:8 MSI calibration value */ +#define RCC_SRCCTRL2_MSICAL_SHIFT (8) +#define RCC_SRCCTRL2_MSICAL_MASK (0x1F << RCC_SRCCTRL2_MSICAL_SHIFT) +#define RCC_SRCCTRL2_MSICAL_0 (0x1 << (RCC_SRCCTRL2_MSICAL_SHIFT + 0)) /* Bit 8 */ +#define RCC_SRCCTRL2_MSICAL_1 (0x1 << (RCC_SRCCTRL2_MSICAL_SHIFT + 1)) /* Bit 9 */ +#define RCC_SRCCTRL2_MSICAL_2 (0x1 << (RCC_SRCCTRL2_MSICAL_SHIFT + 2)) /* Bit 10 */ +#define RCC_SRCCTRL2_MSICAL_3 (0x1 << (RCC_SRCCTRL2_MSICAL_SHIFT + 3)) /* Bit 11 */ +#define RCC_SRCCTRL2_MSICAL_4 (0x1 << (RCC_SRCCTRL2_MSICAL_SHIFT + 4)) /* Bit 12 */ + +/* Bits 4:0 MSI trim value */ +#define RCC_SRCCTRL2_MSITRIM_SHIFT (0) +#define RCC_SRCCTRL2_MSITRIM_MASK (0x1F << RCC_SRCCTRL2_MSITRIM_SHIFT) +#define RCC_SRCCTRL2_MSITRIM_0 (0x1 << (RCC_SRCCTRL2_MSITRIM_SHIFT + 0)) /* Bit 0 */ +#define RCC_SRCCTRL2_MSITRIM_1 (0x1 << (RCC_SRCCTRL2_MSITRIM_SHIFT + 1)) /* Bit 1 */ +#define RCC_SRCCTRL2_MSITRIM_2 (0x1 << (RCC_SRCCTRL2_MSITRIM_SHIFT + 2)) /* Bit 2 */ +#define RCC_SRCCTRL2_MSITRIM_3 (0x1 << (RCC_SRCCTRL2_MSITRIM_SHIFT + 3)) /* Bit 3 */ +#define RCC_SRCCTRL2_MSITRIM_4 (0x1 << (RCC_SRCCTRL2_MSITRIM_SHIFT + 4)) /* Bit 4 */ + +/* Bit definition for RCC_SRCCTRL3 register *********************************/ + +/* Bits 24:16 HSI calibration value */ +#define RCC_SRCCTRL3_HSICAL_SHIFT (16) +#define RCC_SRCCTRL3_HSICAL_MASK (0x1FF << RCC_SRCCTRL3_HSICAL_SHIFT) +#define RCC_SRCCTRL3_HSICAL_0 (0x1 << (RCC_SRCCTRL3_HSICAL_SHIFT + 0)) /* Bit 16 */ +#define RCC_SRCCTRL3_HSICAL_1 (0x1 << (RCC_SRCCTRL3_HSICAL_SHIFT + 1)) /* Bit 17 */ +#define RCC_SRCCTRL3_HSICAL_2 (0x1 << (RCC_SRCCTRL3_HSICAL_SHIFT + 2)) /* Bit 18 */ +#define RCC_SRCCTRL3_HSICAL_3 (0x1 << (RCC_SRCCTRL3_HSICAL_SHIFT + 3)) /* Bit 19 */ +#define RCC_SRCCTRL3_HSICAL_4 (0x1 << (RCC_SRCCTRL3_HSICAL_SHIFT + 4)) /* Bit 20 */ +#define RCC_SRCCTRL3_HSICAL_5 (0x1 << (RCC_SRCCTRL3_HSICAL_SHIFT + 5)) /* Bit 21 */ +#define RCC_SRCCTRL3_HSICAL_6 (0x1 << (RCC_SRCCTRL3_HSICAL_SHIFT + 6)) /* Bit 22 */ +#define RCC_SRCCTRL3_HSICAL_7 (0x1 << (RCC_SRCCTRL3_HSICAL_SHIFT + 7)) /* Bit 23 */ +#define RCC_SRCCTRL3_HSICAL_8 (0x1 << (RCC_SRCCTRL3_HSICAL_SHIFT + 8)) /* Bit 24 */ + +/* Bits 8:0 HSI trim value */ +#define RCC_SRCCTRL3_HSITRIM_SHIFT (0) +#define RCC_SRCCTRL3_HSITRIM_MASK (0x1FF << RCC_SRCCTRL3_HSITRIM_SHIFT) +#define RCC_SRCCTRL3_HSITRIM_0 (0x1 << (RCC_SRCCTRL3_HSITRIM_SHIFT + 0)) /* Bit 0 */ +#define RCC_SRCCTRL3_HSITRIM_1 (0x1 << (RCC_SRCCTRL3_HSITRIM_SHIFT + 1)) /* Bit 1 */ +#define RCC_SRCCTRL3_HSITRIM_2 (0x1 << (RCC_SRCCTRL3_HSITRIM_SHIFT + 2)) /* Bit 2 */ +#define RCC_SRCCTRL3_HSITRIM_3 (0x1 << (RCC_SRCCTRL3_HSITRIM_SHIFT + 3)) /* Bit 3 */ +#define RCC_SRCCTRL3_HSITRIM_4 (0x1 << (RCC_SRCCTRL3_HSITRIM_SHIFT + 4)) /* Bit 4 */ +#define RCC_SRCCTRL3_HSITRIM_5 (0x1 << (RCC_SRCCTRL3_HSITRIM_SHIFT + 5)) /* Bit 5 */ +#define RCC_SRCCTRL3_HSITRIM_6 (0x1 << (RCC_SRCCTRL3_HSITRIM_SHIFT + 6)) /* Bit 6 */ +#define RCC_SRCCTRL3_HSITRIM_7 (0x1 << (RCC_SRCCTRL3_HSITRIM_SHIFT + 7)) /* Bit 7 */ +#define RCC_SRCCTRL3_HSITRIM_8 (0x1 << (RCC_SRCCTRL3_HSITRIM_SHIFT + 8)) /* Bit 8 */ + +/* Bit definition for RCC_PLL1DIV register **********************************/ + +/* Bit[21:16] PLL1CDIV */ +#define RCC_PLL1DIV_PLL1CDIV_SHIFT (16) +#define RCC_PLL1DIV_PLL1CDIV_MASK (0x3F << RCC_PLL1DIV_PLL1CDIV_SHIFT) +#define RCC_PLL1DIV_PLL1CDIV_0 (0x1 << (RCC_PLL1DIV_PLL1CDIV_SHIFT + 0)) /* Bit16 */ + +/* Bit definition for RCC_HSECAL register ***********************************/ + +/* [31:18] Reserved */ + +/* [17] HSE Calibration Count Enable */ +#define RCC_PLL1DIV_PLL1CDIV_1 (0x1 << (RCC_PLL1DIV_PLL1CDIV_SHIFT + 1)) /* Bit17 */ +#define RCC_PLL1DIV_PLL1CDIV_2 (0x1 << (RCC_PLL1DIV_PLL1CDIV_SHIFT + 2)) /* Bit18 */ +#define RCC_PLL1DIV_PLL1CDIV_3 (0x1 << (RCC_PLL1DIV_PLL1CDIV_SHIFT + 3)) /* Bit19 */ +#define RCC_PLL1DIV_PLL1CDIV_4 (0x1 << (RCC_PLL1DIV_PLL1CDIV_SHIFT + 4)) /* Bit20 */ +#define RCC_PLL1DIV_PLL1CDIV_5 (0x1 << (RCC_PLL1DIV_PLL1CDIV_SHIFT + 5)) /* Bit21 */ + +#define RCC_PLL1DIV_PLL1CDIV_DIV(n) ((n) << RCC_PLL1DIV_PLL1CDIV_SHIFT) + +/* Bit[13:8] PLL1BDIV */ +#define RCC_PLL1DIV_PLL1BDIV_SHIFT (8) +#define RCC_PLL1DIV_PLL1BDIV_MASK (0x3F << RCC_PLL1DIV_PLL1BDIV_SHIFT) +#define RCC_PLL1DIV_PLL1BDIV_0 (0x1 << (RCC_PLL1DIV_PLL1BDIV_SHIFT + 0)) /* Bit8 */ +#define RCC_PLL1DIV_PLL1BDIV_1 (0x1 << (RCC_PLL1DIV_PLL1BDIV_SHIFT + 1)) /* Bit9 */ +#define RCC_PLL1DIV_PLL1BDIV_2 (0x1 << (RCC_PLL1DIV_PLL1BDIV_SHIFT + 2)) /* Bit10 */ +#define RCC_PLL1DIV_PLL1BDIV_3 (0x1 << (RCC_PLL1DIV_PLL1BDIV_SHIFT + 3)) /* Bit11 */ +#define RCC_PLL1DIV_PLL1BDIV_4 (0x1 << (RCC_PLL1DIV_PLL1BDIV_SHIFT + 4)) /* Bit12 */ +#define RCC_PLL1DIV_PLL1BDIV_5 (0x1 << (RCC_PLL1DIV_PLL1BDIV_SHIFT + 5)) /* Bit13 */ + +#define RCC_PLL1DIV_PLL1BDIV_DIV(n) ((n) << RCC_PLL1DIV_PLL1BDIV_SHIFT) + +/* Bit definition for RCC_PLL1DIV register **********************************/ + +/* Bit[5:0] PLL1ADIV */ +#define RCC_PLL1DIV_PLL1ADIV_SHIFT (0) +#define RCC_PLL1DIV_PLL1ADIV_MASK (0x3F << RCC_PLL1DIV_PLL1ADIV_SHIFT) +#define RCC_PLL1DIV_PLL1ADIV_0 (0x1 << (RCC_PLL1DIV_PLL1ADIV_SHIFT + 0)) /* Bit0 */ +#define RCC_PLL1DIV_PLL1ADIV_1 (0x1 << (RCC_PLL1DIV_PLL1ADIV_SHIFT + 1)) /* Bit1 */ +#define RCC_PLL1DIV_PLL1ADIV_2 (0x1 << (RCC_PLL1DIV_PLL1ADIV_SHIFT + 2)) /* Bit2 */ +#define RCC_PLL1DIV_PLL1ADIV_3 (0x1 << (RCC_PLL1DIV_PLL1ADIV_SHIFT + 3)) /* Bit3 */ +#define RCC_PLL1DIV_PLL1ADIV_4 (0x1 << (RCC_PLL1DIV_PLL1ADIV_SHIFT + 4)) /* Bit4 */ +#define RCC_PLL1DIV_PLL1ADIV_5 (0x1 << (RCC_PLL1DIV_PLL1ADIV_SHIFT + 5)) /* Bit5 */ + +#define RCC_PLL1DIV_PLL1ADIV_DIV(n) ((n) << RCC_PLL1DIV_PLL1ADIV_SHIFT) + +/* Bit definition for RCC_PLL2DIV register **********************************/ + +/* Bit[21:16] PLL2CDIV */ +#define RCC_PLL2DIV_PLL2CDIV_SHIFT (16) +#define RCC_PLL2DIV_PLL2CDIV_MASK (0x3F << RCC_PLL2DIV_PLL2CDIV_SHIFT) +#define RCC_PLL2DIV_PLL2CDIV_0 (0x1 << (RCC_PLL2DIV_PLL2CDIV_SHIFT + 0)) /* Bit16 */ +#define RCC_PLL2DIV_PLL2CDIV_1 (0x1 << (RCC_PLL2DIV_PLL2CDIV_SHIFT + 1)) /* Bit17 */ +#define RCC_PLL2DIV_PLL2CDIV_2 (0x1 << (RCC_PLL2DIV_PLL2CDIV_SHIFT + 2)) /* Bit18 */ +#define RCC_PLL2DIV_PLL2CDIV_3 (0x1 << (RCC_PLL2DIV_PLL2CDIV_SHIFT + 3)) /* Bit19 */ +#define RCC_PLL2DIV_PLL2CDIV_4 (0x1 << (RCC_PLL2DIV_PLL2CDIV_SHIFT + 4)) /* Bit20 */ +#define RCC_PLL2DIV_PLL2CDIV_5 (0x1 << (RCC_PLL2DIV_PLL2CDIV_SHIFT + 5)) /* Bit21 */ + +#define RCC_PLL2DIV_PLL2CDIV_DIV(n) ((n) << RCC_PLL2DIV_PLL2CDIV_SHIFT) + +/* Bit[13:8] PLL2BDIV */ +#define RCC_PLL2DIV_PLL2BDIV_SHIFT (8) +#define RCC_PLL2DIV_PLL2BDIV_MASK (0x3F << RCC_PLL2DIV_PLL2BDIV_SHIFT) +#define RCC_PLL2DIV_PLL2BDIV_0 (0x1 << (RCC_PLL2DIV_PLL2BDIV_SHIFT + 0)) /* Bit8 */ +#define RCC_PLL2DIV_PLL2BDIV_1 (0x1 << (RCC_PLL2DIV_PLL2BDIV_SHIFT + 1)) /* Bit9 */ +#define RCC_PLL2DIV_PLL2BDIV_2 (0x1 << (RCC_PLL2DIV_PLL2BDIV_SHIFT + 2)) /* Bit10 */ +#define RCC_PLL2DIV_PLL2BDIV_3 (0x1 << (RCC_PLL2DIV_PLL2BDIV_SHIFT + 3)) /* Bit11 */ +#define RCC_PLL2DIV_PLL2BDIV_4 (0x1 << (RCC_PLL2DIV_PLL2BDIV_SHIFT + 4)) /* Bit12 */ +#define RCC_PLL2DIV_PLL2BDIV_5 (0x1 << (RCC_PLL2DIV_PLL2BDIV_SHIFT + 5)) /* Bit13 */ + +#define RCC_PLL2DIV_PLL2BDIV_DIV(n) ((n) << RCC_PLL2DIV_PLL2BDIV_SHIFT) + +/* Bit definition for RCC_PLL2DIV register **********************************/ +#define RCC_PLL2DIV_PLL2ADIV_SHIFT (0) +#define RCC_PLL2DIV_PLL2ADIV_MASK (0x3F << RCC_PLL2DIV_PLL2ADIV_SHIFT) +#define RCC_PLL2DIV_PLL2ADIV_0 (0x1 << (RCC_PLL2DIV_PLL2ADIV_SHIFT + 0)) /* Bit0 */ +#define RCC_PLL2DIV_PLL2ADIV_1 (0x1 << (RCC_PLL2DIV_PLL2ADIV_SHIFT + 1)) /* Bit1 */ +#define RCC_PLL2DIV_PLL2ADIV_2 (0x1 << (RCC_PLL2DIV_PLL2ADIV_SHIFT + 2)) /* Bit2 */ +#define RCC_PLL2DIV_PLL2ADIV_3 (0x1 << (RCC_PLL2DIV_PLL2ADIV_SHIFT + 3)) /* Bit3 */ +#define RCC_PLL2DIV_PLL2ADIV_4 (0x1 << (RCC_PLL2DIV_PLL2ADIV_SHIFT + 4)) /* Bit4 */ +#define RCC_PLL2DIV_PLL2ADIV_5 (0x1 << (RCC_PLL2DIV_PLL2ADIV_SHIFT + 5)) /* Bit5 */ + +#define RCC_PLL2DIV_PLL2ADIV_DIV(n) ((n) << RCC_PLL2DIV_PLL2ADIV_SHIFT) + +/* Bit definition for RCC_PLL3DIV register **********************************/ + +/* Bit[21:16] PLL3CDIV */ +#define RCC_PLL3DIV_PLL3CDIV_SHIFT (16) +#define RCC_PLL3DIV_PLL3CDIV_MASK (0x3F << RCC_PLL3DIV_PLL3CDIV_SHIFT) +#define RCC_PLL3DIV_PLL3CDIV_0 (0x1 << (RCC_PLL3DIV_PLL3CDIV_SHIFT + 0)) /* Bit16 */ +#define RCC_PLL3DIV_PLL3CDIV_1 (0x1 << (RCC_PLL3DIV_PLL3CDIV_SHIFT + 1)) /* Bit17 */ +#define RCC_PLL3DIV_PLL3CDIV_2 (0x1 << (RCC_PLL3DIV_PLL3CDIV_SHIFT + 2)) /* Bit18 */ +#define RCC_PLL3DIV_PLL3CDIV_3 (0x1 << (RCC_PLL3DIV_PLL3CDIV_SHIFT + 3)) /* Bit19 */ +#define RCC_PLL3DIV_PLL3CDIV_4 (0x1 << (RCC_PLL3DIV_PLL3CDIV_SHIFT + 4)) /* Bit20 */ +#define RCC_PLL3DIV_PLL3CDIV_5 (0x1 << (RCC_PLL3DIV_PLL3CDIV_SHIFT + 5)) /* Bit21 */ + +#define RCC_PLL3DIV_PLL3CDIV_DIV(n) ((n) << RCC_PLL3DIV_PLL3CDIV_SHIFT) + +/* Bit[13:8] PLL3BDIV */ +#define RCC_PLL3DIV_PLL3BDIV_SHIFT (8) +#define RCC_PLL3DIV_PLL3BDIV_MASK (0x3F << RCC_PLL3DIV_PLL3BDIV_SHIFT) +#define RCC_PLL3DIV_PLL3BDIV_0 (0x1 << (RCC_PLL3DIV_PLL3BDIV_SHIFT + 0)) /* Bit8 */ +#define RCC_PLL3DIV_PLL3BDIV_1 (0x1 << (RCC_PLL3DIV_PLL3BDIV_SHIFT + 1)) /* Bit9 */ +#define RCC_PLL3DIV_PLL3BDIV_2 (0x1 << (RCC_PLL3DIV_PLL3BDIV_SHIFT + 2)) /* Bit10 */ +#define RCC_PLL3DIV_PLL3BDIV_3 (0x1 << (RCC_PLL3DIV_PLL3BDIV_SHIFT + 3)) /* Bit11 */ +#define RCC_PLL3DIV_PLL3BDIV_4 (0x1 << (RCC_PLL3DIV_PLL3BDIV_SHIFT + 4)) /* Bit12 */ +#define RCC_PLL3DIV_PLL3BDIV_5 (0x1 << (RCC_PLL3DIV_PLL3BDIV_SHIFT + 5)) /* Bit13 */ + +#define RCC_PLL3DIV_PLL3BDIV_DIV(n) ((n) << RCC_PLL3DIV_PLL3BDIV_SHIFT) + +/* Bit definition for RCC_PLL3DIV register **********************************/ +#define RCC_PLL3DIV_PLL3ADIV_SHIFT (0) +#define RCC_PLL3DIV_PLL3ADIV_MASK (0x3F << RCC_PLL3DIV_PLL3ADIV_SHIFT) +#define RCC_PLL3DIV_PLL3ADIV_0 (0x1 << (RCC_PLL3DIV_PLL3ADIV_SHIFT + 0)) /* Bit0 */ +#define RCC_PLL3DIV_PLL3ADIV_1 (0x1 << (RCC_PLL3DIV_PLL3ADIV_SHIFT + 1)) /* Bit1 */ +#define RCC_PLL3DIV_PLL3ADIV_2 (0x1 << (RCC_PLL3DIV_PLL3ADIV_SHIFT + 2)) /* Bit2 */ +#define RCC_PLL3DIV_PLL3ADIV_3 (0x1 << (RCC_PLL3DIV_PLL3ADIV_SHIFT + 3)) /* Bit3 */ +#define RCC_PLL3DIV_PLL3ADIV_4 (0x1 << (RCC_PLL3DIV_PLL3ADIV_SHIFT + 4)) /* Bit4 */ +#define RCC_PLL3DIV_PLL3ADIV_5 (0x1 << (RCC_PLL3DIV_PLL3ADIV_SHIFT + 5)) /* Bit5 */ + +#define RCC_PLL3DIV_PLL3ADIV_DIV(n) ((n) << RCC_PLL3DIV_PLL3ADIV_SHIFT) + +/* Bit definition for RCC_SYSBUSDIV1 register *******************************/ + +/* Bit[27:24] AXIHYPDIV */ +#define RCC_SYSBUSDIV1_AXIHYPDIV_SHIFT (24) +#define RCC_SYSBUSDIV1_AXIHYPDIV_MASK (0x0F << RCC_SYSBUSDIV1_AXIHYPDIV_SHIFT) +#define RCC_SYSBUSDIV1_AXIHYPDIV_0 (0x01 << RCC_SYSBUSDIV1_AXIHYPDIV_SHIFT) /* Bit24 */ +#define RCC_SYSBUSDIV1_AXIHYPDIV_1 (0x02 << RCC_SYSBUSDIV1_AXIHYPDIV_SHIFT) /* Bit25 */ +#define RCC_SYSBUSDIV1_AXIHYPDIV_2 (0x04 << RCC_SYSBUSDIV1_AXIHYPDIV_SHIFT) /* Bit26 */ +#define RCC_SYSBUSDIV1_AXIHYPDIV_3 (0x08 << RCC_SYSBUSDIV1_AXIHYPDIV_SHIFT) /* Bit27 */ +#define RCC_SYSBUSDIV1_AXIHYPDIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << 24 : \ + (n) == 2 ? 0x00000001U << 24 : \ + (n) == 4 ? 0x00000002U << 24 : \ + (n) == 8 ? 0x00000004U << 24 : \ + (n) == 16 ? 0x00000007U << 24 : \ + (n) == 32 ? 0x00000008U << 24 : \ + (n) == 64 ? 0x00000009U << 24 : \ + (n) == 128 ? 0x0000000AU << 24 : \ + (n) == 256 ? 0x0000000BU << 24 : \ + (n) == 512 ? 0x0000000CU << 24 : \ + 0x00000000U << 24 ) + +/* Bit[23:20] HSIDIV */ +#define RCC_SYSBUSDIV1_HSIDIV_SHIFT (20) +#define RCC_SYSBUSDIV1_HSIDIV_MASK (0x0F << RCC_SYSBUSDIV1_HSIDIV_SHIFT) +#define RCC_SYSBUSDIV1_HSIDIV_0 (0x01 << RCC_SYSBUSDIV1_HSIDIV_SHIFT) /* Bit20 */ +#define RCC_SYSBUSDIV1_HSIDIV_1 (0x02 << RCC_SYSBUSDIV1_HSIDIV_SHIFT) /* Bit21 */ +#define RCC_SYSBUSDIV1_HSIDIV_2 (0x04 << RCC_SYSBUSDIV1_HSIDIV_SHIFT) /* Bit22 */ +#define RCC_SYSBUSDIV1_HSIDIV_3 (0x08 << RCC_SYSBUSDIV1_HSIDIV_SHIFT) /* Bit23 */ +#define RCC_SYSBUSDIV1_HSIDIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << 20 : \ + (n) == 2 ? 0x00000001U << 20 : \ + (n) == 4 ? 0x00000002U << 20 : \ + (n) == 8 ? 0x00000004U << 20 : \ + (n) == 16 ? 0x00000007U << 20 : \ + (n) == 32 ? 0x00000008U << 20 : \ + (n) == 64 ? 0x00000009U << 20 : \ + (n) == 128 ? 0x0000000AU << 20 : \ + (n) == 256 ? 0x0000000BU << 20 : \ + (n) == 512 ? 0x0000000CU << 20 : \ + 0x00000000U << 20 ) + +/* Bit[19:16] M7HYPDIV */ +#define RCC_SYSBUSDIV1_M7HYPDIV_SHIFT (16) +#define RCC_SYSBUSDIV1_M7HYPDIV_MASK (0x0F << RCC_SYSBUSDIV1_M7HYPDIV_SHIFT) +#define RCC_SYSBUSDIV1_M7HYPDIV_0 (0x01 << RCC_SYSBUSDIV1_M7HYPDIV_SHIFT) /* Bit16 */ +#define RCC_SYSBUSDIV1_M7HYPDIV_1 (0x02 << RCC_SYSBUSDIV1_M7HYPDIV_SHIFT) /* Bit17 */ +#define RCC_SYSBUSDIV1_M7HYPDIV_2 (0x04 << RCC_SYSBUSDIV1_M7HYPDIV_SHIFT) /* Bit18 */ +#define RCC_SYSBUSDIV1_M7HYPDIV_3 (0x08 << RCC_SYSBUSDIV1_M7HYPDIV_SHIFT) /* Bit19 */ +#define RCC_SYSBUSDIV1_M7HYPDIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << 16 : \ + (n) == 2 ? 0x00000001U << 16 : \ + (n) == 4 ? 0x00000002U << 16 : \ + (n) == 8 ? 0x00000004U << 16 : \ + (n) == 16 ? 0x00000007U << 16 : \ + (n) == 32 ? 0x00000008U << 16 : \ + (n) == 64 ? 0x00000009U << 16 : \ + (n) == 128 ? 0x0000000AU << 16 : \ + (n) == 256 ? 0x0000000BU << 16 : \ + (n) == 512 ? 0x0000000CU << 16 : \ + 0x00000000U << 16 ) + +/* Bit[15:12] AXIDIV */ +#define RCC_SYSBUSDIV1_AXIDIV_SHIFT (12) +#define RCC_SYSBUSDIV1_AXIDIV_MASK (0x0F << RCC_SYSBUSDIV1_AXIDIV_SHIFT) +#define RCC_SYSBUSDIV1_AXIDIV_0 (0x01 << RCC_SYSBUSDIV1_AXIDIV_SHIFT) /* Bit12 */ +#define RCC_SYSBUSDIV1_AXIDIV_1 (0x02 << RCC_SYSBUSDIV1_AXIDIV_SHIFT) /* Bit13 */ +#define RCC_SYSBUSDIV1_AXIDIV_2 (0x04 << RCC_SYSBUSDIV1_AXIDIV_SHIFT) /* Bit14 */ +#define RCC_SYSBUSDIV1_AXIDIV_3 (0x08 << RCC_SYSBUSDIV1_AXIDIV_SHIFT) /* Bit15 */ +#define RCC_SYSBUSDIV1_AXIDIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << 12 : \ + (n) == 2 ? 0x00000001U << 12 : \ + (n) == 4 ? 0x00000002U << 12 : \ + (n) == 8 ? 0x00000004U << 12 : \ + (n) == 16 ? 0x00000007U << 12 : \ + (n) == 32 ? 0x00000008U << 12 : \ + (n) == 64 ? 0x00000009U << 12 : \ + (n) == 128 ? 0x0000000AU << 12 : \ + (n) == 256 ? 0x0000000BU << 12 : \ + (n) == 512 ? 0x0000000CU << 12 : \ + 0x00000000U << 12 ) + +/* Bit[11:8] BUSDIV */ +#define RCC_SYSBUSDIV1_BUSDIV_SHIFT (8) +#define RCC_SYSBUSDIV1_BUSDIV_MASK (0x0F << RCC_SYSBUSDIV1_BUSDIV_SHIFT) +#define RCC_SYSBUSDIV1_BUSDIV_0 (0x01 << RCC_SYSBUSDIV1_BUSDIV_SHIFT) /* Bit8 */ +#define RCC_SYSBUSDIV1_BUSDIV_1 (0x02 << RCC_SYSBUSDIV1_BUSDIV_SHIFT) /* Bit9 */ +#define RCC_SYSBUSDIV1_BUSDIV_2 (0x04 << RCC_SYSBUSDIV1_BUSDIV_SHIFT) /* Bit10 */ +#define RCC_SYSBUSDIV1_BUSDIV_3 (0x08 << RCC_SYSBUSDIV1_BUSDIV_SHIFT) /* Bit11 */ +#define RCC_SYSBUSDIV1_BUSDIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << 8 : \ + (n) == 2 ? 0x00000001U << 8 : \ + (n) == 4 ? 0x00000002U << 8 : \ + (n) == 8 ? 0x00000004U << 8 : \ + (n) == 16 ? 0x00000007U << 8 : \ + (n) == 32 ? 0x00000008U << 8 : \ + (n) == 64 ? 0x00000009U << 8 : \ + (n) == 128 ? 0x0000000AU << 8 : \ + (n) == 256 ? 0x0000000BU << 8 : \ + (n) == 512 ? 0x0000000CU << 8 : \ + 0x00000000U << 8 ) + +/* Bit[7:4] MSIDIV */ +#define RCC_SYSBUSDIV1_MSIDIV_SHIFT (4) +#define RCC_SYSBUSDIV1_MSIDIV_MASK (0x0F << RCC_SYSBUSDIV1_MSIDIV_SHIFT) +#define RCC_SYSBUSDIV1_MSIDIV_0 (0x01 << RCC_SYSBUSDIV1_MSIDIV_SHIFT) /* Bit4 */ +#define RCC_SYSBUSDIV1_MSIDIV_1 (0x02 << RCC_SYSBUSDIV1_MSIDIV_SHIFT) /* Bit5 */ +#define RCC_SYSBUSDIV1_MSIDIV_2 (0x04 << RCC_SYSBUSDIV1_MSIDIV_SHIFT) /* Bit6 */ +#define RCC_SYSBUSDIV1_MSIDIV_3 (0x08 << RCC_SYSBUSDIV1_MSIDIV_SHIFT) /* Bit7 */ +#define RCC_SYSBUSDIV1_MSIDIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << 4 : \ + (n) == 2 ? 0x00000001U << 4 : \ + (n) == 4 ? 0x00000002U << 4 : \ + (n) == 8 ? 0x00000004U << 4 : \ + (n) == 16 ? 0x00000007U << 4 : \ + (n) == 32 ? 0x00000008U << 4 : \ + (n) == 64 ? 0x00000009U << 4 : \ + (n) == 128 ? 0x0000000AU << 4 : \ + (n) == 256 ? 0x0000000BU << 4 : \ + (n) == 512 ? 0x0000000CU << 4 : \ + 0x00000000U << 4 ) + +/* Bit[3:0] SYSCLKDIV */ +#define RCC_SYSBUSDIV1_SYSCLKDIV_SHIFT (0) +#define RCC_SYSBUSDIV1_SYSCLKDIV_MASK (0x0F << RCC_SYSBUSDIV1_SYSCLKDIV_SHIFT) +#define RCC_SYSBUSDIV1_SYSCLKDIV_0 (0x01 << RCC_SYSBUSDIV1_SYSCLKDIV_SHIFT) /* Bit0 */ +#define RCC_SYSBUSDIV1_SYSCLKDIV_1 (0x02 << RCC_SYSBUSDIV1_SYSCLKDIV_SHIFT) /* Bit1 */ +#define RCC_SYSBUSDIV1_SYSCLKDIV_2 (0x04 << RCC_SYSBUSDIV1_SYSCLKDIV_SHIFT) /* Bit2 */ +#define RCC_SYSBUSDIV1_SYSCLKDIV_3 (0x08 << RCC_SYSBUSDIV1_SYSCLKDIV_SHIFT) /* Bit3 */ +#define RCC_SYSBUSDIV1_SYSCLKDIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U : \ + (n) == 2 ? 0x00000001U : \ + (n) == 4 ? 0x00000002U : \ + (n) == 8 ? 0x00000004U : \ + (n) == 16 ? 0x00000007U : \ + (n) == 32 ? 0x00000008U : \ + (n) == 64 ? 0x00000009U : \ + (n) == 128 ? 0x0000000AU : \ + (n) == 256 ? 0x0000000BU : \ + (n) == 512 ? 0x0000000CU : \ + 0x00000000U ) + +/* Bit definition for RCC_SYSBUSDIV2 register *******************************/ + +/* Bit[26:24] APB6DIV */ +#define RCC_SYSBUSDIV2_APB6DIV_SHIFT (24) +#define RCC_SYSBUSDIV2_APB6DIV_MASK (0x07 << RCC_SYSBUSDIV2_APB6DIV_SHIFT) +#define RCC_SYSBUSDIV2_APB6DIV_0 (0x01 << RCC_SYSBUSDIV2_APB6DIV_SHIFT) /* Bit24 */ +#define RCC_SYSBUSDIV2_APB6DIV_1 (0x02 << RCC_SYSBUSDIV2_APB6DIV_SHIFT) /* Bit25 */ +#define RCC_SYSBUSDIV2_APB6DIV_2 (0x04 << RCC_SYSBUSDIV2_APB6DIV_SHIFT) /* Bit26 */ +#define RCC_SYSBUSDIV2_APB6DIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << RCC_SYSBUSDIV2_APB6DIV_SHIFT : \ + (n) == 2 ? 0x00000004U << RCC_SYSBUSDIV2_APB6DIV_SHIFT : \ + (n) == 4 ? 0x00000005U << RCC_SYSBUSDIV2_APB6DIV_SHIFT : \ + (n) == 8 ? 0x00000006U << RCC_SYSBUSDIV2_APB6DIV_SHIFT : \ + (n) == 16 ? 0x00000007U << RCC_SYSBUSDIV2_APB6DIV_SHIFT : \ + 0x00000000U << RCC_SYSBUSDIV2_APB6DIV_SHIFT ) + +/* Bit[18:16] APB5DIV */ +#define RCC_SYSBUSDIV2_APB5DIV_SHIFT (16) +#define RCC_SYSBUSDIV2_APB5DIV_MASK (0x07 << RCC_SYSBUSDIV2_APB5DIV_SHIFT) +#define RCC_SYSBUSDIV2_APB5DIV_0 (0x01 << RCC_SYSBUSDIV2_APB5DIV_SHIFT) /* Bit16 */ +#define RCC_SYSBUSDIV2_APB5DIV_1 (0x02 << RCC_SYSBUSDIV2_APB5DIV_SHIFT) /* Bit17 */ +#define RCC_SYSBUSDIV2_APB5DIV_2 (0x04 << RCC_SYSBUSDIV2_APB5DIV_SHIFT) /* Bit18 */ +#define RCC_SYSBUSDIV2_APB5DIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << RCC_SYSBUSDIV2_APB5DIV_SHIFT : \ + (n) == 2 ? 0x00000004U << RCC_SYSBUSDIV2_APB5DIV_SHIFT : \ + (n) == 4 ? 0x00000005U << RCC_SYSBUSDIV2_APB5DIV_SHIFT : \ + (n) == 8 ? 0x00000006U << RCC_SYSBUSDIV2_APB5DIV_SHIFT : \ + (n) == 16 ? 0x00000007U << RCC_SYSBUSDIV2_APB5DIV_SHIFT : \ + 0x00000000U << RCC_SYSBUSDIV2_APB5DIV_SHIFT ) + +/* Bit[10:8] APB2DIV */ +#define RCC_SYSBUSDIV2_APB2DIV_SHIFT (8) +#define RCC_SYSBUSDIV2_APB2DIV_MASK (0x07 << RCC_SYSBUSDIV2_APB2DIV_SHIFT) +#define RCC_SYSBUSDIV2_APB2DIV_0 (0x01 << RCC_SYSBUSDIV2_APB2DIV_SHIFT) /* Bit8 */ +#define RCC_SYSBUSDIV2_APB2DIV_1 (0x02 << RCC_SYSBUSDIV2_APB2DIV_SHIFT) /* Bit9 */ +#define RCC_SYSBUSDIV2_APB2DIV_2 (0x04 << RCC_SYSBUSDIV2_APB2DIV_SHIFT) /* Bit10 */ +#define RCC_SYSBUSDIV2_APB2DIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << RCC_SYSBUSDIV2_APB2DIV_SHIFT : \ + (n) == 2 ? 0x00000004U << RCC_SYSBUSDIV2_APB2DIV_SHIFT : \ + (n) == 4 ? 0x00000005U << RCC_SYSBUSDIV2_APB2DIV_SHIFT : \ + (n) == 8 ? 0x00000006U << RCC_SYSBUSDIV2_APB2DIV_SHIFT : \ + (n) == 16 ? 0x00000007U << RCC_SYSBUSDIV2_APB2DIV_SHIFT : \ + 0x00000000U << RCC_SYSBUSDIV2_APB2DIV_SHIFT ) + +/* Bit[2:0] APB1DIV */ +#define RCC_SYSBUSDIV2_APB1DIV_SHIFT (0) +#define RCC_SYSBUSDIV2_APB1DIV_MASK (0x07 << RCC_SYSBUSDIV2_APB1DIV_SHIFT) +#define RCC_SYSBUSDIV2_APB1DIV_0 (0x01 << RCC_SYSBUSDIV2_APB1DIV_SHIFT) /* Bit0 */ +#define RCC_SYSBUSDIV2_APB1DIV_1 (0x02 << RCC_SYSBUSDIV2_APB1DIV_SHIFT) /* Bit1 */ +#define RCC_SYSBUSDIV2_APB1DIV_2 (0x04 << RCC_SYSBUSDIV2_APB1DIV_SHIFT) /* Bit2 */ +#define RCC_SYSBUSDIV2_APB1DIV_DIV(n) \ + ( (n) == 1 ? 0x00000000U << RCC_SYSBUSDIV2_APB1DIV_SHIFT : \ + (n) == 2 ? 0x00000004U << RCC_SYSBUSDIV2_APB1DIV_SHIFT : \ + (n) == 4 ? 0x00000005U << RCC_SYSBUSDIV2_APB1DIV_SHIFT : \ + (n) == 8 ? 0x00000006U << RCC_SYSBUSDIV2_APB1DIV_SHIFT : \ + (n) == 16 ? 0x00000007U << RCC_SYSBUSDIV2_APB1DIV_SHIFT : \ + 0x00000000U << RCC_SYSBUSDIV2_APB1DIV_SHIFT ) + +/* Bit definition for RCC_BOOTMODE register *********************************/ + +#define RCC_BOOTMODE_BOOTMODE_SHIFT (0) +#define RCC_BOOTMODE_BOOTMODE_MASK (0xFFFFFFFF << RCC_BOOTMODE_BOOTMODE_SHIFT) +#define RCC_BOOTMODE_BOOTMODE(n) ((n) << RCC_BOOTMODE_BOOTMODE_SHIFT) + +/* Bit definition for RCC_AHB1DIV1 register *********************************/ + +/* Bit[31:28] ETH2SYSDIV */ +#define RCC_AHB1DIV1_ETH2SYSDIV_SHIFT (28) +#define RCC_AHB1DIV1_ETH2SYSDIV_MASK (0x0F << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV1 (0x00000000U << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV2 (0x00000001U << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV4 (0x00000002U << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV8 (0x00000004U << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV16 (0x00000007U << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV32 (0x00000008U << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV64 (0x00000009U << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV128 (0x0000000AU << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV256 (0x0000000BU << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_ETH2SYSDIV_DIV512 (0x0000000CU << RCC_AHB1DIV1_ETH2SYSDIV_SHIFT) + +/* Bit[27:24] SDMMC2SYSDIV */ +#define RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT (24) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_MASK (0x0F << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV1 (0x00000000U << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV2 (0x00000001U << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV4 (0x00000002U << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV8 (0x00000004U << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV16 (0x00000007U << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV32 (0x00000008U << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV64 (0x00000009U << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV128 (0x0000000AU << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV256 (0x0000000BU << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) +#define RCC_AHB1DIV1_SDMMC2SYSDIV_DIV512 (0x0000000CU << RCC_AHB1DIV1_SDMMC2SYSDIV_SHIFT) + +/* Bit definition for RCC_AHB1DIV2 register *********************************/ + +/* Bit[21:16] ADC3SYSDIV */ +#define RCC_AHB1DIV2_ADC3SYSDIV_SHIFT (16) +#define RCC_AHB1DIV2_ADC3SYSDIV_MASK (0x3F << RCC_AHB1DIV2_ADC3SYSDIV_SHIFT) +#define RCC_AHB1DIV2_ADC3SYSDIV_DIV(n) ((n >= 1 && n <= 63) ? (n << RCC_AHB1DIV2_ADC3SYSDIV_SHIFT) : 0) + +/* Bit[13:8] ADC2SYSDIV */ +#define RCC_AHB1DIV2_ADC2SYSDIV_SHIFT (8) +#define RCC_AHB1DIV2_ADC2SYSDIV_MASK (0x3F << RCC_AHB1DIV2_ADC2SYSDIV_SHIFT) +#define RCC_AHB1DIV2_ADC2SYSDIV_DIV(n) ((n >= 1 && n <= 63) ? (n << RCC_AHB1DIV2_ADC2SYSDIV_SHIFT) : 0) + +/* Bit[5:0] ADC1SYSDIV */ +#define RCC_AHB1DIV2_ADC1SYSDIV_SHIFT (0) +#define RCC_AHB1DIV2_ADC1SYSDIV_MASK (0x3F << RCC_AHB1DIV2_ADC1SYSDIV_SHIFT) +#define RCC_AHB1DIV2_ADC1SYSDIV_DIV(n) ((n >= 1 && n <= 63) ? (n << RCC_AHB1DIV2_ADC1SYSDIV_SHIFT) : 0) + +/* Bit definition for RCC_AHB1SEL1 register *********************************/ + +/* Bit[21:20] ETH2PTPSEL */ +#define RCC_AHB1SEL1_ETH2PTPSEL_SHIFT (20) +#define RCC_AHB1SEL1_ETH2PTPSEL_MASK (0x03 << RCC_AHB1SEL1_ETH2PTPSEL_SHIFT) +#define RCC_AHB1SEL1_ETH2PTPSEL_SYSCLK (0x00000000U << RCC_AHB1SEL1_ETH2PTPSEL_SHIFT) + +#define RCC_AHB1SEL1_ETH2PTPSEL_PERIPH (0x00000001U << RCC_AHB1SEL1_ETH2PTPSEL_SHIFT) +#define RCC_AHB1SEL1_ETH2PTPSEL_PLL2C (0x00000002U << RCC_AHB1SEL1_ETH2PTPSEL_SHIFT) +#define RCC_AHB1SEL1_ETH2PTPSEL_PLL3A (0x00000003U << RCC_AHB1SEL1_ETH2PTPSEL_SHIFT) + +/* Bit[14:12] SDMMC2KERSEL */ +#define RCC_AHB1SEL1_SDMMC2KERSEL_SHIFT (12) +#define RCC_AHB1SEL1_SDMMC2KERSEL_MASK (0x07 << RCC_AHB1SEL1_SDMMC2KERSEL_SHIFT) +#define RCC_AHB1SEL1_SDMMC2KERSEL_SYSCLK (0x00000000U << RCC_AHB1SEL1_SDMMC2KERSEL_SHIFT) +#define RCC_AHB1SEL1_SDMMC2KERSEL_PERIPH (0x00000001U << RCC_AHB1SEL1_SDMMC2KERSEL_SHIFT) +#define RCC_AHB1SEL1_SDMMC2KERSEL_PLL2A (0x00000002U << RCC_AHB1SEL1_SDMMC2KERSEL_SHIFT) +#define RCC_AHB1SEL1_SDMMC2KERSEL_PLL3A (0x00000003U << RCC_AHB1SEL1_SDMMC2KERSEL_SHIFT) +#define RCC_AHB1SEL1_SDMMC2KERSEL_PLL1B (0x00000004U << RCC_AHB1SEL1_SDMMC2KERSEL_SHIFT) + +/* Bit[9:8] ADC3PLLSEL */ +#define RCC_AHB1SEL1_ADC3PLLSEL_SHIFT (8) +#define RCC_AHB1SEL1_ADC3PLLSEL_MASK (0x03 << RCC_AHB1SEL1_ADC3PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC3PLLSEL_PLL2B (0x00000000U << RCC_AHB1SEL1_ADC3PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC3PLLSEL_PLL1B (0x00000001U << RCC_AHB1SEL1_ADC3PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC3PLLSEL_PLL3B (0x00000002U << RCC_AHB1SEL1_ADC3PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC3PLLSEL_PLL3C (0x00000003U << RCC_AHB1SEL1_ADC3PLLSEL_SHIFT) + +/* Bit[5:4] ADC2PLLSEL */ +#define RCC_AHB1SEL1_ADC2PLLSEL_SHIFT (4) +#define RCC_AHB1SEL1_ADC2PLLSEL_MASK (0x03 << RCC_AHB1SEL1_ADC2PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC2PLLSEL_PLL2B (0x00000000U << RCC_AHB1SEL1_ADC2PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC2PLLSEL_PLL1B (0x00000001U << RCC_AHB1SEL1_ADC2PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC2PLLSEL_PLL3B (0x00000002U << RCC_AHB1SEL1_ADC2PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC2PLLSEL_PLL3C (0x00000003U << RCC_AHB1SEL1_ADC2PLLSEL_SHIFT) + +/* Bit[1:0] ADC1PLLSEL */ +#define RCC_AHB1SEL1_ADC1PLLSEL_SHIFT (0) +#define RCC_AHB1SEL1_ADC1PLLSEL_MASK (0x03 << RCC_AHB1SEL1_ADC1PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC1PLLSEL_PLL2B (0x00000000U << RCC_AHB1SEL1_ADC1PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC1PLLSEL_PLL1B (0x00000001U << RCC_AHB1SEL1_ADC1PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC1PLLSEL_PLL3B (0x00000002U << RCC_AHB1SEL1_ADC1PLLSEL_SHIFT) +#define RCC_AHB1SEL1_ADC1PLLSEL_PLL3C (0x00000003U << RCC_AHB1SEL1_ADC1PLLSEL_SHIFT) + +/* Bit definition for RCC_AHB1EN1 register **********************************/ + +#define RCC_AHB1EN1_M7SDMMC2EN (1U << 31) /* Bit[31] */ +#define RCC_AHB1EN1_M4SDMMC2EN (1U << 30) /* Bit[30] */ +#define RCC_AHB1EN1_M7SDMMC2LPEN (1U << 29) /* Bit[29] */ +#define RCC_AHB1EN1_M4SDMMC2LPEN (1U << 28) /* Bit[28] */ +#define RCC_AHB1EN1_M7USB2EN (1U << 23) /* Bit[23] */ +#define RCC_AHB1EN1_M4USB2EN (1U << 22) /* Bit[22] */ +#define RCC_AHB1EN1_M7USB2LPEN (1U << 21) /* Bit[21] */ +#define RCC_AHB1EN1_M4USB2LPEN (1U << 20) /* Bit[20] */ +#define RCC_AHB1EN1_M7DMAMUX1EN (1U << 19) /* Bit[19] */ +#define RCC_AHB1EN1_M4DMAMUX1EN (1U << 18) /* Bit[18] */ +#define RCC_AHB1EN1_M7DMAMUX1LPEN (1U << 17) /* Bit[17] */ +#define RCC_AHB1EN1_M4DMAMUX1LPEN (1U << 16) /* Bit[16] */ +#define RCC_AHB1EN1_M7ADC1PLLEN (1U << 15) /* Bit[15] */ +#define RCC_AHB1EN1_M4ADC1PLLEN (1U << 14) /* Bit[14] */ +#define RCC_AHB1EN1_M7ADC1PLLLPEN (1U << 13) /* Bit[13] */ +#define RCC_AHB1EN1_M4ADC1PLLLPEN (1U << 12) /* Bit[12] */ +#define RCC_AHB1EN1_M7ADC1SYSEN (1U << 11) /* Bit[11] */ +#define RCC_AHB1EN1_M4ADC1SYSEN (1U << 10) /* Bit[10] */ +#define RCC_AHB1EN1_M7ADC1SYSLPEN (1U << 9) /* Bit[9] */ +#define RCC_AHB1EN1_M4ADC1SYSLPEN (1U << 8) /* Bit[8] */ +#define RCC_AHB1EN1_M7ADC1BUSEN (1U << 3) /* Bit[3] */ +#define RCC_AHB1EN1_M4ADC1BUSEN (1U << 2) /* Bit[2] */ +#define RCC_AHB1EN1_M7ADC1BUSLPEN (1U << 1) /* Bit[1] */ +#define RCC_AHB1EN1_M4ADC1BUSLPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB1EN2 register **********************************/ + +#define RCC_AHB1EN2_M7ETH2TXEN (1U << 11) /* Bit[11] */ +#define RCC_AHB1EN2_M4ETH2TXEN (1U << 10) /* Bit[10] */ +#define RCC_AHB1EN2_M7ETH2TXLPEN (1U << 9) /* Bit[9] */ +#define RCC_AHB1EN2_M4ETH2TXLPEN (1U << 8) /* Bit[8] */ +#define RCC_AHB1EN2_M7ETH2RXEN (1U << 7) /* Bit[7] */ +#define RCC_AHB1EN2_M4ETH2RXEN (1U << 6) /* Bit[6] */ +#define RCC_AHB1EN2_M7ETH2RXLPEN (1U << 5) /* Bit[5] */ +#define RCC_AHB1EN2_M4ETH2RXLPEN (1U << 4) /* Bit[4] */ +#define RCC_AHB1EN2_M7ETH2MACEN (1U << 3) /* Bit[3] */ +#define RCC_AHB1EN2_M4ETH2MACEN (1U << 2) /* Bit[2] */ +#define RCC_AHB1EN2_M7ETH2MACLPEN (1U << 1) /* Bit[1] */ +#define RCC_AHB1EN2_M4ETH2MACLPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB1EN3 register **********************************/ + +#define RCC_AHB1EN3_M7ECCMACEN (1U << 27) /* Bit[27] */ +#define RCC_AHB1EN3_M4ECCMACEN (1U << 26) /* Bit[26] */ +#define RCC_AHB1EN3_M7ECCMACLPEN (1U << 25) /* Bit[25] */ +#define RCC_AHB1EN3_M4ECCMACLPEN (1U << 24) /* Bit[24] */ +#define RCC_AHB1EN3_M7DMA1EN (1U << 19) /* Bit[19] */ +#define RCC_AHB1EN3_M4DMA1EN (1U << 18) /* Bit[18] */ +#define RCC_AHB1EN3_M7DMA1LPEN (1U << 17) /* Bit[17] */ +#define RCC_AHB1EN3_M4DMA1LPEN (1U << 16) /* Bit[16] */ +#define RCC_AHB1EN3_M7DMA2EN (1U << 11) /* Bit[11] */ +#define RCC_AHB1EN3_M4DMA2EN (1U << 10) /* Bit[10] */ +#define RCC_AHB1EN3_M7DMA2LPEN (1U << 9) /* Bit[9] */ +#define RCC_AHB1EN3_M4DMA2LPEN (1U << 8) /* Bit[8] */ +#define RCC_AHB1EN3_M7DMA3EN (1U << 3) /* Bit[3] */ +#define RCC_AHB1EN3_M4DMA3EN (1U << 2) /* Bit[2] */ +#define RCC_AHB1EN3_M7DMA3LPEN (1U << 1) /* Bit[1] */ +#define RCC_AHB1EN3_M4DMA3LPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB1EN4 register **********************************/ + +#define RCC_AHB1EN4_M7ADC2PLLEN (1U << 31) /* Bit[31] */ +#define RCC_AHB1EN4_M4ADC2PLLEN (1U << 30) /* Bit[30] */ +#define RCC_AHB1EN4_M7ADC2PLLLPEN (1U << 29) /* Bit[29] */ +#define RCC_AHB1EN4_M4ADC2PLLLPEN (1U << 28) /* Bit[28] */ +#define RCC_AHB1EN4_M7ADC2SYSEN (1U << 27) /* Bit[27] */ +#define RCC_AHB1EN4_M4ADC2SYSEN (1U << 26) /* Bit[26] */ +#define RCC_AHB1EN4_M7ADC2SYSLPEN (1U << 25) /* Bit[25] */ +#define RCC_AHB1EN4_M4ADC2SYSLPEN (1U << 24) /* Bit[24] */ +#define RCC_AHB1EN4_M7ADC2BUSEN (1U << 19) /* Bit[19] */ +#define RCC_AHB1EN4_M4ADC2BUSEN (1U << 18) /* Bit[18] */ +#define RCC_AHB1EN4_M7ADC2BUSLPEN (1U << 17) /* Bit[17] */ +#define RCC_AHB1EN4_M4ADC2BUSLPEN (1U << 16) /* Bit[16] */ +#define RCC_AHB1EN4_M7ADC3PLLEN (1U << 15) /* Bit[15] */ +#define RCC_AHB1EN4_M4ADC3PLLEN (1U << 14) /* Bit[14] */ +#define RCC_AHB1EN4_M7ADC3PLLLPEN (1U << 13) /* Bit[13] */ +#define RCC_AHB1EN4_M4ADC3PLLLPEN (1U << 12) /* Bit[12] */ +#define RCC_AHB1EN4_M7ADC3SYSEN (1U << 11) /* Bit[11] */ +#define RCC_AHB1EN4_M4ADC3SYSEN (1U << 10) /* Bit[10] */ +#define RCC_AHB1EN4_M7ADC3SYSLPEN (1U << 9) /* Bit[9] */ +#define RCC_AHB1EN4_M4ADC3SYSLPEN (1U << 8) /* Bit[8] */ +#define RCC_AHB1EN4_M7ADC3BUSEN (1U << 3) /* Bit[3] */ +#define RCC_AHB1EN4_M4ADC3BUSEN (1U << 2) /* Bit[2] */ +#define RCC_AHB1EN4_M7ADC3BUSLPEN (1U << 1) /* Bit[1] */ +#define RCC_AHB1EN4_M4ADC3BUSLPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB1RST1 register *********************************/ + +#define RCC_AHB1RST1_SDMMC2RST (1U << 29) /* Bit[29] */ +#define RCC_AHB1RST1_SDHOST2RST (1U << 28) /* Bit[28] */ +#define RCC_AHB1RST1_USB2WRAPRST (1U << 22) /* Bit[22] */ +#define RCC_AHB1RST1_USB2PORRST (1U << 21) /* Bit[21] */ +#define RCC_AHB1RST1_USB2RST (1U << 20) /* Bit[20] */ +#define RCC_AHB1RST1_DMAMUX1RST (1U << 16) /* Bit[16] */ +#define RCC_AHB1RST1_ADC1RST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB1RST2 register *********************************/ + +#define RCC_AHB1RST2_ETH2RST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB1RST3 register *********************************/ + +#define RCC_AHB1RST3_ECCMACRST (1U << 24) /* Bit[24] */ +#define RCC_AHB1RST3_DMA1RST (1U << 16) /* Bit[16] */ +#define RCC_AHB1RST3_DMA2RST (1U << 8) /* Bit[8] */ +#define RCC_AHB1RST3_DMA3RST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB1RST4 register *********************************/ + +#define RCC_AHB1RST4_ADC2RST (1U << 16) /* Bit[16] */ +#define RCC_AHB1RST4_ADC3RST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB1DIV1 register *********************************/ + +/* Bit[30:28] APB1USARTDIV */ +#define RCC_APB1DIV1_APB1USARTDIV_SHIFT (28) +#define RCC_APB1DIV1_APB1USARTDIV_MASK (0x07 << RCC_APB1DIV1_APB1USARTDIV_SHIFT) +#define RCC_APB1DIV1_APB1USARTDIV_DIV1 (0x00000000U << RCC_APB1DIV1_APB1USARTDIV_SHIFT) +#define RCC_APB1DIV1_APB1USARTDIV_DIV2 (0x00000004U << RCC_APB1DIV1_APB1USARTDIV_SHIFT) +#define RCC_APB1DIV1_APB1USARTDIV_DIV4 (0x00000005U << RCC_APB1DIV1_APB1USARTDIV_SHIFT) +#define RCC_APB1DIV1_APB1USARTDIV_DIV8 (0x00000006U << RCC_APB1DIV1_APB1USARTDIV_SHIFT) +#define RCC_APB1DIV1_APB1USARTDIV_DIV16 (0x00000007U << RCC_APB1DIV1_APB1USARTDIV_SHIFT) + +/* Bit[26:24] APB1BTIMDIV */ +#define RCC_APB1DIV1_APB1BTIMDIV_SHIFT (24) +#define RCC_APB1DIV1_APB1BTIMDIV_MASK (0x07 << RCC_APB1DIV1_APB1BTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1BTIMDIV_DIV1 (0x00000000U << RCC_APB1DIV1_APB1BTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1BTIMDIV_DIV2 (0x00000004U << RCC_APB1DIV1_APB1BTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1BTIMDIV_DIV4 (0x00000005U << RCC_APB1DIV1_APB1BTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1BTIMDIV_DIV8 (0x00000006U << RCC_APB1DIV1_APB1BTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1BTIMDIV_DIV16 (0x00000007U << RCC_APB1DIV1_APB1BTIMDIV_SHIFT) + +/* Bit[18:16] APB1GTIMDIV */ +#define RCC_APB1DIV1_APB1GTIMDIV_SHIFT (16) +#define RCC_APB1DIV1_APB1GTIMDIV_MASK (0x07 << RCC_APB1DIV1_APB1GTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1GTIMDIV_DIV1 (0x00000000U << RCC_APB1DIV1_APB1GTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1GTIMDIV_DIV2 (0x00000004U << RCC_APB1DIV1_APB1GTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1GTIMDIV_DIV4 (0x00000005U << RCC_APB1DIV1_APB1GTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1GTIMDIV_DIV8 (0x00000006U << RCC_APB1DIV1_APB1GTIMDIV_SHIFT) +#define RCC_APB1DIV1_APB1GTIMDIV_DIV16 (0x00000007U << RCC_APB1DIV1_APB1GTIMDIV_SHIFT) + +/* Bit[10:8] APB1I2SDIV */ +#define RCC_APB1DIV1_APB1I2SDIV_SHIFT (8) +#define RCC_APB1DIV1_APB1I2SDIV_MASK (0x07 << RCC_APB1DIV1_APB1I2SDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2SDIV_DIV1 (0x00000000U << RCC_APB1DIV1_APB1I2SDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2SDIV_DIV2 (0x00000004U << RCC_APB1DIV1_APB1I2SDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2SDIV_DIV4 (0x00000005U << RCC_APB1DIV1_APB1I2SDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2SDIV_DIV8 (0x00000006U << RCC_APB1DIV1_APB1I2SDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2SDIV_DIV16 (0x00000007U << RCC_APB1DIV1_APB1I2SDIV_SHIFT) + +/* Bit[6:4] APB1FDCANDIV */ +#define RCC_APB1DIV1_APB1FDCANDIV_SHIFT (4) +#define RCC_APB1DIV1_APB1FDCANDIV_MASK (0x07 << RCC_APB1DIV1_APB1FDCANDIV_SHIFT) +#define RCC_APB1DIV1_APB1FDCANDIV_DIV1 (0x00000000U << RCC_APB1DIV1_APB1FDCANDIV_SHIFT) +#define RCC_APB1DIV1_APB1FDCANDIV_DIV2 (0x00000004U << RCC_APB1DIV1_APB1FDCANDIV_SHIFT) +#define RCC_APB1DIV1_APB1FDCANDIV_DIV4 (0x00000005U << RCC_APB1DIV1_APB1FDCANDIV_SHIFT) +#define RCC_APB1DIV1_APB1FDCANDIV_DIV8 (0x00000006U << RCC_APB1DIV1_APB1FDCANDIV_SHIFT) +#define RCC_APB1DIV1_APB1FDCANDIV_DIV16 (0x00000007U << RCC_APB1DIV1_APB1FDCANDIV_SHIFT) + +/* Bit[2:0] APB1I2CDIV */ +#define RCC_APB1DIV1_APB1I2CDIV_SHIFT (0) +#define RCC_APB1DIV1_APB1I2CDIV_MASK (0x07 << RCC_APB1DIV1_APB1I2CDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2CDIV_DIV1 (0x00000000U << RCC_APB1DIV1_APB1I2CDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2CDIV_DIV2 (0x00000004U << RCC_APB1DIV1_APB1I2CDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2CDIV_DIV4 (0x00000005U << RCC_APB1DIV1_APB1I2CDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2CDIV_DIV8 (0x00000006U << RCC_APB1DIV1_APB1I2CDIV_SHIFT) +#define RCC_APB1DIV1_APB1I2CDIV_DIV16 (0x00000007U << RCC_APB1DIV1_APB1I2CDIV_SHIFT) + +/* Bit definition for RCC_APB1SEL1 register *********************************/ + +/* Bit[30:28] I2C1KERSEL */ +#define RCC_APB1SEL1_I2C1KERSEL_SHIFT (28) +#define RCC_APB1SEL1_I2C1KERSEL_MASK (0x07 << RCC_APB1SEL1_I2C1KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C1KERSEL_SYSDIV (0x00000000U << RCC_APB1SEL1_I2C1KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C1KERSEL_PLL3C (0x00000001U << RCC_APB1SEL1_I2C1KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C1KERSEL_HSI (0x00000002U << RCC_APB1SEL1_I2C1KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C1KERSEL_MSI (0x00000003U << RCC_APB1SEL1_I2C1KERSEL_SHIFT) + +/* Bit[26:24] I2C2KERSEL */ +#define RCC_APB1SEL1_I2C2KERSEL_SHIFT (24) +#define RCC_APB1SEL1_I2C2KERSEL_MASK (0x07 << RCC_APB1SEL1_I2C2KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C2KERSEL_SYSDIV (0x00000000U << RCC_APB1SEL1_I2C2KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C2KERSEL_PLL3C (0x00000001U << RCC_APB1SEL1_I2C2KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C2KERSEL_HSI (0x00000002U << RCC_APB1SEL1_I2C2KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C2KERSEL_MSI (0x00000003U << RCC_APB1SEL1_I2C2KERSEL_SHIFT) + +/* Bit[22:20] I2C3KERSEL */ +#define RCC_APB1SEL1_I2C3KERSEL_SHIFT (20) +#define RCC_APB1SEL1_I2C3KERSEL_MASK (0x07 << RCC_APB1SEL1_I2C3KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C3KERSEL_SYSDIV (0x00000000U << RCC_APB1SEL1_I2C3KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C3KERSEL_PLL3C (0x00000001U << RCC_APB1SEL1_I2C3KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C3KERSEL_HSI (0x00000002U << RCC_APB1SEL1_I2C3KERSEL_SHIFT) +#define RCC_APB1SEL1_I2C3KERSEL_MSI (0x00000003U << RCC_APB1SEL1_I2C3KERSEL_SHIFT) + +/* Bit[18:16] FDCAN1KERSEL */ +#define RCC_APB1SEL1_FDCAN1KERSEL_SHIFT (16) +#define RCC_APB1SEL1_FDCAN1KERSEL_MASK (0x07 << RCC_APB1SEL1_FDCAN1KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN1KERSEL_SYSDIV (0x00000000U << RCC_APB1SEL1_FDCAN1KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN1KERSEL_PLL1C (0x00000001U << RCC_APB1SEL1_FDCAN1KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN1KERSEL_PLL2C (0x00000002U << RCC_APB1SEL1_FDCAN1KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN1KERSEL_PLL3B (0x00000003U << RCC_APB1SEL1_FDCAN1KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN1KERSEL_PERIPH (0x00000004U << RCC_APB1SEL1_FDCAN1KERSEL_SHIFT) + +/* Bit[10:8] FDCAN2KERSEL */ +#define RCC_APB1SEL1_FDCAN2KERSEL_SHIFT (8) +#define RCC_APB1SEL1_FDCAN2KERSEL_MASK (0x07 << RCC_APB1SEL1_FDCAN2KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN2KERSEL_SYSDIV (0x00000000U << RCC_APB1SEL1_FDCAN2KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN2KERSEL_PLL1C (0x00000001U << RCC_APB1SEL1_FDCAN2KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN2KERSEL_PLL2C (0x00000002U << RCC_APB1SEL1_FDCAN2KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN2KERSEL_PLL3B (0x00000003U << RCC_APB1SEL1_FDCAN2KERSEL_SHIFT) +#define RCC_APB1SEL1_FDCAN2KERSEL_PERIPH (0x00000004U << RCC_APB1SEL1_FDCAN2KERSEL_SHIFT) + +/* Bit[3:2] I2S4KERSEL */ +#define RCC_APB1SEL1_I2S4KERSEL_SHIFT (2) +#define RCC_APB1SEL1_I2S4KERSEL_MASK (0x03 << RCC_APB1SEL1_I2S4KERSEL_SHIFT) +#define RCC_APB1SEL1_I2S4KERSEL_SYSDIV (0x00000000U << RCC_APB1SEL1_I2S4KERSEL_SHIFT) +#define RCC_APB1SEL1_I2S4KERSEL_PLL3B (0x00000001U << RCC_APB1SEL1_I2S4KERSEL_SHIFT) +#define RCC_APB1SEL1_I2S4KERSEL_HSI (0x00000002U << RCC_APB1SEL1_I2S4KERSEL_SHIFT) +#define RCC_APB1SEL1_I2S4KERSEL_I2S4CKIN (0x00000003U << RCC_APB1SEL1_I2S4KERSEL_SHIFT) + +/* Bit[1:0] I2S3KERSEL */ +#define RCC_APB1SEL1_I2S3KERSEL_SHIFT (0) +#define RCC_APB1SEL1_I2S3KERSEL_MASK (0x03 << RCC_APB1SEL1_I2S3KERSEL_SHIFT) +#define RCC_APB1SEL1_I2S3KERSEL_SYSDIV (0x00000000U << RCC_APB1SEL1_I2S3KERSEL_SHIFT) +#define RCC_APB1SEL1_I2S3KERSEL_PLL3B (0x00000001U << RCC_APB1SEL1_I2S3KERSEL_SHIFT) +#define RCC_APB1SEL1_I2S3KERSEL_HSI (0x00000002U << RCC_APB1SEL1_I2S3KERSEL_SHIFT) +#define RCC_APB1SEL1_I2S3KERSEL_I2S4CKIN (0x00000003U << RCC_APB1SEL1_I2S3KERSEL_SHIFT) + +/* Bit definition for RCC_APB1SEL2 register *********************************/ + +/* Bit[30:28] FDCAN5KERSEL */ +#define RCC_APB1SEL2_FDCAN5KERSEL_SHIFT (28) +#define RCC_APB1SEL2_FDCAN5KERSEL_MASK (0x07 << RCC_APB1SEL2_FDCAN5KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN5KERSEL_SYSDIV (0x00000000U << RCC_APB1SEL2_FDCAN5KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN5KERSEL_PLL1C (0x00000001U << RCC_APB1SEL2_FDCAN5KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN5KERSEL_PLL2C (0x00000002U << RCC_APB1SEL2_FDCAN5KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN5KERSEL_PLL3B (0x00000003U << RCC_APB1SEL2_FDCAN5KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN5KERSEL_PERIPH (0x00000004U << RCC_APB1SEL2_FDCAN5KERSEL_SHIFT) + +/* Bit[22:20] FDCAN6KERSEL */ +#define RCC_APB1SEL2_FDCAN6KERSEL_SHIFT (20) +#define RCC_APB1SEL2_FDCAN6KERSEL_MASK (0x07 << RCC_APB1SEL2_FDCAN6KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN6KERSEL_SYSDIV (0x00000000U << RCC_APB1SEL2_FDCAN6KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN6KERSEL_PLL1C (0x00000001U << RCC_APB1SEL2_FDCAN6KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN6KERSEL_PLL2C (0x00000002U << RCC_APB1SEL2_FDCAN6KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN6KERSEL_PLL3B (0x00000003U << RCC_APB1SEL2_FDCAN6KERSEL_SHIFT) +#define RCC_APB1SEL2_FDCAN6KERSEL_PERIPH (0x00000004U << RCC_APB1SEL2_FDCAN6KERSEL_SHIFT) + +/* Bit definition for RCC_APB1EN1 register **********************************/ + +#define RCC_APB1EN1_M7BTIM1EN (1U << 31) /* Bit[31] */ +#define RCC_APB1EN1_M4BTIM1EN (1U << 30) /* Bit[30] */ +#define RCC_APB1EN1_M7BTIM1LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB1EN1_M4BTIM1LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB1EN1_M7BTIM2EN (1U << 27) /* Bit[27] */ +#define RCC_APB1EN1_M4BTIM2EN (1U << 26) /* Bit[26] */ +#define RCC_APB1EN1_M7BTIM2LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB1EN1_M4BTIM2LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB1EN1_M7BTIM3EN (1U << 23) /* Bit[23] */ +#define RCC_APB1EN1_M4BTIM3EN (1U << 22) /* Bit[22] */ +#define RCC_APB1EN1_M7BTIM3LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB1EN1_M4BTIM3LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB1EN1_M7BTIM4EN (1U << 19) /* Bit[19] */ +#define RCC_APB1EN1_M4BTIM4EN (1U << 18) /* Bit[18] */ +#define RCC_APB1EN1_M7BTIM4LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB1EN1_M4BTIM4LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB1EN1_M7GTIMB1EN (1U << 15) /* Bit[15] */ +#define RCC_APB1EN1_M4GTIMB1EN (1U << 14) /* Bit[14] */ +#define RCC_APB1EN1_M7GTIMB1LPEN (1U << 13) /* Bit[13] */ +#define RCC_APB1EN1_M4GTIMB1LPEN (1U << 12) /* Bit[12] */ +#define RCC_APB1EN1_M7GTIMB2EN (1U << 11) /* Bit[11] */ +#define RCC_APB1EN1_M4GTIMB2EN (1U << 10) /* Bit[10] */ +#define RCC_APB1EN1_M7GTIMB2LPEN (1U << 9) /* Bit[9] */ +#define RCC_APB1EN1_M4GTIMB2LPEN (1U << 8) /* Bit[8] */ +#define RCC_APB1EN1_M7GTIMB3EN (1U << 7) /* Bit[7] */ +#define RCC_APB1EN1_M4GTIMB3EN (1U << 6) /* Bit[6] */ +#define RCC_APB1EN1_M7GTIMB3LPEN (1U << 5) /* Bit[5] */ +#define RCC_APB1EN1_M4GTIMB3LPEN (1U << 4) /* Bit[4] */ +#define RCC_APB1EN1_M7GTIMA4EN (1U << 3) /* Bit[3] */ +#define RCC_APB1EN1_M4GTIMA4EN (1U << 2) /* Bit[2] */ +#define RCC_APB1EN1_M7GTIMA4LPEN (1U << 1) /* Bit[1] */ +#define RCC_APB1EN1_M4GTIMA4LPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB1EN2 register **********************************/ + +#define RCC_APB1EN2_M7GTIMA5EN (1U << 31) /* Bit[31] */ +#define RCC_APB1EN2_M4GTIMA5EN (1U << 30) /* Bit[30] */ +#define RCC_APB1EN2_M7GTIMA5LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB1EN2_M4GTIMA5LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB1EN2_M7GTIMA6EN (1U << 27) /* Bit[27] */ +#define RCC_APB1EN2_M4GTIMA6EN (1U << 26) /* Bit[26] */ +#define RCC_APB1EN2_M7GTIMA6LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB1EN2_M4GTIMA6LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB1EN2_M7GTIMA7EN (1U << 23) /* Bit[23] */ +#define RCC_APB1EN2_M4GTIMA7EN (1U << 22) /* Bit[22] */ +#define RCC_APB1EN2_M7GTIMA7LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB1EN2_M4GTIMA7LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB1EN2_M7SPI3EN (1U << 19) /* Bit[19] */ +#define RCC_APB1EN2_M4SPI3EN (1U << 18) /* Bit[18] */ +#define RCC_APB1EN2_M7SPI3LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB1EN2_M4SPI3LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB1EN2_M7DAC12EN (1U << 15) /* Bit[15] */ +#define RCC_APB1EN2_M4DAC12EN (1U << 14) /* Bit[14] */ +#define RCC_APB1EN2_M7DAC12LPEN (1U << 13) /* Bit[13] */ +#define RCC_APB1EN2_M4DAC12LPEN (1U << 12) /* Bit[12] */ +#define RCC_APB1EN2_M7WWDG2EN (1U << 7) /* Bit[7] */ +#define RCC_APB1EN2_M4WWDG2EN (1U << 6) /* Bit[6] */ +#define RCC_APB1EN2_M7WWDG2LPEN (1U << 5) /* Bit[5] */ +#define RCC_APB1EN2_M4WWDG2LPEN (1U << 4) /* Bit[4] */ + +/* Bit definition for RCC_APB1EN3 register **********************************/ + +#define RCC_APB1EN3_M7USART1EN (1U << 31) /* Bit[31] */ +#define RCC_APB1EN3_M4USART1EN (1U << 30) /* Bit[30] */ +#define RCC_APB1EN3_M7USART1LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB1EN3_M4USART1LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB1EN3_M7USART2EN (1U << 27) /* Bit[27] */ +#define RCC_APB1EN3_M4USART2EN (1U << 26) /* Bit[26] */ +#define RCC_APB1EN3_M7USART2LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB1EN3_M4USART2LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB1EN3_M7USART3EN (1U << 23) /* Bit[23] */ +#define RCC_APB1EN3_M4USART3EN (1U << 22) /* Bit[22] */ +#define RCC_APB1EN3_M7USART3LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB1EN3_M4USART3LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB1EN3_M7USART4EN (1U << 19) /* Bit[19] */ +#define RCC_APB1EN3_M4USART4EN (1U << 18) /* Bit[18] */ +#define RCC_APB1EN3_M7USART4LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB1EN3_M4USART4LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB1EN3_M7UART9EN (1U << 15) /* Bit[15] */ +#define RCC_APB1EN3_M4UART9EN (1U << 14) /* Bit[14] */ +#define RCC_APB1EN3_M7UART9LPEN (1U << 13) /* Bit[13] */ +#define RCC_APB1EN3_M4UART9LPEN (1U << 12) /* Bit[12] */ +#define RCC_APB1EN3_M7UART10EN (1U << 11) /* Bit[11] */ +#define RCC_APB1EN3_M4UART10EN (1U << 10) /* Bit[10] */ +#define RCC_APB1EN3_M7UART10LPEN (1U << 9) /* Bit[9] */ +#define RCC_APB1EN3_M4UART10LPEN (1U << 8) /* Bit[8] */ +#define RCC_APB1EN3_M7UART11EN (1U << 7) /* Bit[7] */ +#define RCC_APB1EN3_M4UART11EN (1U << 6) /* Bit[6] */ +#define RCC_APB1EN3_M7UART11LPEN (1U << 5) /* Bit[5] */ +#define RCC_APB1EN3_M4UART11LPEN (1U << 4) /* Bit[4] */ +#define RCC_APB1EN3_M7UART12EN (1U << 3) /* Bit[3] */ +#define RCC_APB1EN3_M4UART12EN (1U << 2) /* Bit[2] */ +#define RCC_APB1EN3_M7UART12LPEN (1U << 1) /* Bit[1] */ +#define RCC_APB1EN3_M4UART12LPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB1EN4 register **********************************/ + +#define RCC_APB1EN4_M7I2S3EN (1U << 31) /* Bit[31] */ +#define RCC_APB1EN4_M4I2S3EN (1U << 30) /* Bit[30] */ +#define RCC_APB1EN4_M7I2S3LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB1EN4_M4I2S3LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB1EN4_M7I2S4EN (1U << 27) /* Bit[27] */ +#define RCC_APB1EN4_M4I2S4EN (1U << 26) /* Bit[26] */ +#define RCC_APB1EN4_M7I2S4LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB1EN4_M4I2S4LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB1EN4_M7I2C1EN (1U << 23) /* Bit[23] */ +#define RCC_APB1EN4_M4I2C1EN (1U << 22) /* Bit[22] */ +#define RCC_APB1EN4_M7I2C1LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB1EN4_M4I2C1LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB1EN4_M7I2C2EN (1U << 19) /* Bit[19] */ +#define RCC_APB1EN4_M4I2C2EN (1U << 18) /* Bit[18] */ +#define RCC_APB1EN4_M7I2C2LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB1EN4_M4I2C2LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB1EN4_M7I2C3EN (1U << 15) /* Bit[15] */ +#define RCC_APB1EN4_M4I2C3EN (1U << 14) /* Bit[14] */ +#define RCC_APB1EN4_M7I2C3LPEN (1U << 13) /* Bit[13] */ +#define RCC_APB1EN4_M4I2C3LPEN (1U << 12) /* Bit[12] */ + +/* Bit definition for RCC_APB1EN5 register **********************************/ + +#define RCC_APB1EN5_M7FDCAN1EN (1U << 31) /* Bit[31] */ +#define RCC_APB1EN5_M4FDCAN1EN (1U << 30) /* Bit[30] */ +#define RCC_APB1EN5_M7FDCAN1LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB1EN5_M4FDCAN1LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB1EN5_M7FDCAN2EN (1U << 27) /* Bit[27] */ +#define RCC_APB1EN5_M4FDCAN2EN (1U << 26) /* Bit[26] */ +#define RCC_APB1EN5_M7FDCAN2LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB1EN5_M4FDCAN2LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB1EN5_M7FDCAN5EN (1U << 23) /* Bit[23] */ +#define RCC_APB1EN5_M4FDCAN5EN (1U << 22) /* Bit[22] */ +#define RCC_APB1EN5_M7FDCAN5LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB1EN5_M4FDCAN5LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB1EN5_M7FDCAN6EN (1U << 19) /* Bit[19] */ +#define RCC_APB1EN5_M4FDCAN6EN (1U << 18) /* Bit[18] */ +#define RCC_APB1EN5_M7FDCAN6LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB1EN5_M4FDCAN6LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB1EN5_FDCAN1STPREQ (1U << 15) /* Bit[15] */ +#define RCC_APB1EN5_FDCAN1STPACK (1U << 14) /* Bit[14] */ +#define RCC_APB1EN5_FDCAN2STPREQ (1U << 11) /* Bit[11] */ +#define RCC_APB1EN5_FDCAN2STPACK (1U << 10) /* Bit[10] */ +#define RCC_APB1EN5_FDCAN5STPREQ (1U << 7) /* Bit[7] */ +#define RCC_APB1EN5_FDCAN5STPACK (1U << 6) /* Bit[6] */ +#define RCC_APB1EN5_FDCAN6STPREQ (1U << 3) /* Bit[3] */ +#define RCC_APB1EN5_FDCAN6STPACK (1U << 2) /* Bit[2] */ + +/* Bit definition for RCC_APB1RST1 register *********************************/ + +#define RCC_APB1RST1_BTIM1RST (1U << 28) /* Bit[28] */ +#define RCC_APB1RST1_BTIM2RST (1U << 24) /* Bit[24] */ +#define RCC_APB1RST1_BTIM3RST (1U << 20) /* Bit[20] */ +#define RCC_APB1RST1_BTIM4RST (1U << 16) /* Bit[16] */ +#define RCC_APB1RST1_GTIMB1RST (1U << 12) /* Bit[12] */ +#define RCC_APB1RST1_GTIMB2RST (1U << 8) /* Bit[8] */ +#define RCC_APB1RST1_GTIMB3RST (1U << 4) /* Bit[4] */ +#define RCC_APB1RST1_GTIMA4RST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB1RST2 register *********************************/ + +#define RCC_APB1RST2_GTIMA5RST (1U << 28) /* Bit[28] */ +#define RCC_APB1RST2_GTIMA6RST (1U << 24) /* Bit[24] */ +#define RCC_APB1RST2_GTIMA7RST (1U << 20) /* Bit[20] */ +#define RCC_APB1RST2_SPI3RST (1U << 16) /* Bit[16] */ +#define RCC_APB1RST2_DAC12RST (1U << 12) /* Bit[12] */ +#define RCC_APB1RST2_WWDG2RST (1U << 4) /* Bit[4] */ + +/* Bit definition for RCC_APB1RST3 register *********************************/ + +#define RCC_APB1RST3_USART1RST (1U << 28) /* Bit[28] */ +#define RCC_APB1RST3_USART2RST (1U << 24) /* Bit[24] */ +#define RCC_APB1RST3_USART3RST (1U << 20) /* Bit[20] */ +#define RCC_APB1RST3_USART4RST (1U << 16) /* Bit[16] */ +#define RCC_APB1RST3_UART9RST (1U << 12) /* Bit[12] */ +#define RCC_APB1RST3_UART10RST (1U << 8) /* Bit[8] */ +#define RCC_APB1RST3_UART11RST (1U << 4) /* Bit[4] */ +#define RCC_APB1RST3_UART12RST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB1RST4 register *********************************/ + +#define RCC_APB1RST4_I2S3RST (1U << 28) /* Bit[28] */ +#define RCC_APB1RST4_I2S4RST (1U << 24) /* Bit[24] */ +#define RCC_APB1RST4_I2C1RST (1U << 20) /* Bit[20] */ +#define RCC_APB1RST4_I2C2RST (1U << 16) /* Bit[16] */ +#define RCC_APB1RST4_I2C3RST (1U << 12) /* Bit[12] */ + +/* Bit definition for RCC_APB1RST5 register *********************************/ + +#define RCC_APB1RST5_FDCAN1RST (1U << 28) /* Bit[28] */ +#define RCC_APB1RST5_FDCAN2RST (1U << 24) /* Bit[24] */ +#define RCC_APB1RST5_FDCAN5RST (1U << 20) /* Bit[20] */ +#define RCC_APB1RST5_FDCAN6RST (1U << 16) /* Bit[16] */ +#define RCC_APB1RST5_CAHIRST (1U << 4) /* Bit[4] */ +#define RCC_APB1RST5_CAHDRST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB2DIV1 register *********************************/ + +/* Bit[31:28] ETH1SYSDIV */ +#define RCC_AHB2DIV1_ETH1SYSDIV_SHIFT (28) +#define RCC_AHB2DIV1_ETH1SYSDIV_MASK (0x0F << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV1 (0x00000000U << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV2 (0x00000001U << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV4 (0x00000002U << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV8 (0x00000004U << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV16 (0x00000007U << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV32 (0x00000008U << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV64 (0x00000009U << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV128 (0x0000000AU << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV256 (0x0000000BU << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) +#define RCC_AHB2DIV1_ETH1SYSDIV_DIV512 (0x0000000CU << RCC_AHB2DIV1_ETH1SYSDIV_SHIFT) + +/* Bit[27:24] USBHSEDIV */ +#define RCC_AHB2DIV1_USBHSEDIV_SHIFT (24) +#define RCC_AHB2DIV1_USBHSEDIV_MASK (0x0F << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV1 (0x00000000U << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV2 (0x00000001U << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV4 (0x00000002U << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV8 (0x00000004U << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV16 (0x00000007U << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV32 (0x00000008U << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV64 (0x00000009U << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV128 (0x0000000AU << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV256 (0x0000000BU << RCC_AHB2DIV1_USBHSEDIV_SHIFT) +#define RCC_AHB2DIV1_USBHSEDIV_DIV512 (0x0000000CU << RCC_AHB2DIV1_USBHSEDIV_SHIFT) + +/* Bit definition for RCC_AHB2SEL1 register *********************************/ + +/* Bit[21:20] ETH1PTPSEL */ +#define RCC_AHB2SEL1_ETH1PTPSEL_SHIFT (20) +#define RCC_AHB2SEL1_ETH1PTPSEL_MASK (0x03 << RCC_AHB2SEL1_ETH1PTPSEL_SHIFT) +#define RCC_AHB2SEL1_ETH1PTPSEL_SYSCLK (0x00000000U << RCC_AHB2SEL1_ETH1PTPSEL_SHIFT) +#define RCC_AHB2SEL1_ETH1PTPSEL_PERIPH (0x00000001U << RCC_AHB2SEL1_ETH1PTPSEL_SHIFT) +#define RCC_AHB2SEL1_ETH1PTPSEL_PLL2C (0x00000002U << RCC_AHB2SEL1_ETH1PTPSEL_SHIFT) +#define RCC_AHB2SEL1_ETH1PTPSEL_PLL3A (0x00000003U << RCC_AHB2SEL1_ETH1PTPSEL_SHIFT) + +/* Bit[18:16] ETH1GMIITXSEL */ +#define RCC_AHB2SEL1_ETH1GMIITXSEL_SHIFT (16) +#define RCC_AHB2SEL1_ETH1GMIITXSEL_MASK (0x07 << RCC_AHB2SEL1_ETH1GMIITXSEL_SHIFT) +#define RCC_AHB2SEL1_ETH1GMIITXSEL_PLL3A (0x00000000U << RCC_AHB2SEL1_ETH1GMIITXSEL_SHIFT) +#define RCC_AHB2SEL1_ETH1GMIITXSEL_PLL2B (0x00000001U << RCC_AHB2SEL1_ETH1GMIITXSEL_SHIFT) +#define RCC_AHB2SEL1_ETH1GMIITXSEL_PAD (0x00000002U << RCC_AHB2SEL1_ETH1GMIITXSEL_SHIFT) +#define RCC_AHB2SEL1_ETH1GMIITXSEL_PLL1C (0x00000003U << RCC_AHB2SEL1_ETH1GMIITXSEL_SHIFT) + +/* Bit definition for RCC_AHB2EN1 register **********************************/ + +#define RCC_AHB2EN1_M7USB1EN (1U << 23) /* Bit[23] */ +#define RCC_AHB2EN1_M4USB1EN (1U << 22) /* Bit[22] */ +#define RCC_AHB2EN1_M7USB1LPEN (1U << 21) /* Bit[21] */ +#define RCC_AHB2EN1_M4USB1LPEN (1U << 20) /* Bit[20] */ +#define RCC_AHB2EN1_M7ECCM2EN (1U << 15) /* Bit[15] */ +#define RCC_AHB2EN1_M4ECCM2EN (1U << 14) /* Bit[14] */ +#define RCC_AHB2EN1_M7ECCM2LPEN (1U << 13) /* Bit[13] */ +#define RCC_AHB2EN1_M4ECCM2LPEN (1U << 12) /* Bit[12] */ +#define RCC_AHB2EN1_M7CORDICEN (1U << 11) /* Bit[11] */ +#define RCC_AHB2EN1_M4CORDICEN (1U << 10) /* Bit[10] */ +#define RCC_AHB2EN1_M7CORDICLPEN (1U << 9) /* Bit[9] */ +#define RCC_AHB2EN1_M4CORDICLPEN (1U << 8) /* Bit[8] */ +#define RCC_AHB2EN1_M7SDPUEN (1U << 7) /* Bit[7] */ +#define RCC_AHB2EN1_M4SDPUEN (1U << 6) /* Bit[6] */ +#define RCC_AHB2EN1_M7SDPULPEN (1U << 5) /* Bit[5] */ +#define RCC_AHB2EN1_M4SDPULPEN (1U << 4) /* Bit[4] */ +#define RCC_AHB2EN1_M7FMACEN (1U << 3) /* Bit[3] */ +#define RCC_AHB2EN1_M4FMACEN (1U << 2) /* Bit[2] */ +#define RCC_AHB2EN1_M7FMACLPEN (1U << 1) /* Bit[1] */ +#define RCC_AHB2EN1_M4FMACLPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB2EN2 register **********************************/ + +#define RCC_AHB2EN2_M7DAC56EN (1U << 23) /* Bit[23] */ +#define RCC_AHB2EN2_M4DAC56EN (1U << 22) /* Bit[22] */ +#define RCC_AHB2EN2_M7DAC56LPEN (1U << 21) /* Bit[21] */ +#define RCC_AHB2EN2_M4DAC56LPEN (1U << 20) /* Bit[20] */ +#define RCC_AHB2EN2_M7DAC34EN (1U << 19) /* Bit[19] */ +#define RCC_AHB2EN2_M4DAC34EN (1U << 18) /* Bit[18] */ +#define RCC_AHB2EN2_M7DAC34LPEN (1U << 17) /* Bit[17] */ +#define RCC_AHB2EN2_M4DAC34LPEN (1U << 16) /* Bit[16] */ +#define RCC_AHB2EN2_M7ETH1TEN (1U << 11) /* Bit[11] */ +#define RCC_AHB2EN2_M4ETH1TEN (1U << 10) /* Bit[10] */ +#define RCC_AHB2EN2_M7ETH1TLPEN (1U << 9) /* Bit[9] */ +#define RCC_AHB2EN2_M4ETH1TLPEN (1U << 8) /* Bit[8] */ +#define RCC_AHB2EN2_M7ETH1REN (1U << 7) /* Bit[7] */ +#define RCC_AHB2EN2_M4ETH1REN (1U << 6) /* Bit[6] */ +#define RCC_AHB2EN2_M7ETH1RLPEN (1U << 5) /* Bit[5] */ +#define RCC_AHB2EN2_M4ETH1RLPEN (1U << 4) /* Bit[4] */ +#define RCC_AHB2EN2_M7ETH1MEN (1U << 3) /* Bit[3] */ +#define RCC_AHB2EN2_M4ETH1MEN (1U << 2) /* Bit[2] */ +#define RCC_AHB2EN2_M7ETH1MLPEN (1U << 1) /* Bit[1] */ +#define RCC_AHB2EN2_M4ETH1MLPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB2RST1 register *********************************/ + +#define RCC_AHB2RST1_DAC56RST (1U << 25) /* Bit[25] */ +#define RCC_AHB2RST1_DAC34RST (1U << 24) /* Bit[24] */ +#define RCC_AHB2RST1_USB1WRAPRST (1U << 22) /* Bit[22] */ +#define RCC_AHB2RST1_USB1PORRST (1U << 21) /* Bit[21] */ +#define RCC_AHB2RST1_USB1RST (1U << 20) /* Bit[20] */ +#define RCC_AHB2RST1_ECCM2RST (1U << 12) /* Bit[12] */ +#define RCC_AHB2RST1_CORDICRST (1U << 8) /* Bit[8] */ +#define RCC_AHB2RST1_SDPURST (1U << 4) /* Bit[4] */ +#define RCC_AHB2RST1_FMACRST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB2DIV1 register *********************************/ + +/* Bit[31:28] APB2ATIMDIV */ +#define RCC_APB2DIV1_APB2ATIMDIV_SHIFT (28) +#define RCC_APB2DIV1_APB2ATIMDIV_MASK (0x0F << RCC_APB2DIV1_APB2ATIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2ATIMDIV_DIV1 (0x00000000U << RCC_APB2DIV1_APB2ATIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2ATIMDIV_DIV2 (0x00000004U << RCC_APB2DIV1_APB2ATIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2ATIMDIV_DIV4 (0x00000005U << RCC_APB2DIV1_APB2ATIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2ATIMDIV_DIV8 (0x00000006U << RCC_APB2DIV1_APB2ATIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2ATIMDIV_DIV16 (0x00000007U << RCC_APB2DIV1_APB2ATIMDIV_SHIFT) + +/* Bit[26:24] APB2GTIMDIV */ +#define RCC_APB2DIV1_APB2GTIMDIV_SHIFT (24) +#define RCC_APB2DIV1_APB2GTIMDIV_MASK (0x07 << RCC_APB2DIV1_APB2GTIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2GTIMDIV_DIV1 (0x00000000U << RCC_APB2DIV1_APB2GTIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2GTIMDIV_DIV2 (0x00000004U << RCC_APB2DIV1_APB2GTIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2GTIMDIV_DIV4 (0x00000005U << RCC_APB2DIV1_APB2GTIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2GTIMDIV_DIV8 (0x00000006U << RCC_APB2DIV1_APB2GTIMDIV_SHIFT) +#define RCC_APB2DIV1_APB2GTIMDIV_DIV16 (0x00000007U << RCC_APB2DIV1_APB2GTIMDIV_SHIFT) + +/* Bit[18:16] APB2I2SDIV */ +#define RCC_APB2DIV1_APB2I2SDIV_SHIFT (16) +#define RCC_APB2DIV1_APB2I2SDIV_MASK (0x07 << RCC_APB2DIV1_APB2I2SDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2SDIV_DIV1 (0x00000000U << RCC_APB2DIV1_APB2I2SDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2SDIV_DIV2 (0x00000004U << RCC_APB2DIV1_APB2I2SDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2SDIV_DIV4 (0x00000005U << RCC_APB2DIV1_APB2I2SDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2SDIV_DIV8 (0x00000006U << RCC_APB2DIV1_APB2I2SDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2SDIV_DIV16 (0x00000007U << RCC_APB2DIV1_APB2I2SDIV_SHIFT) + +/* Bit[14:12] APB2DSMUDIV */ +#define RCC_APB2DIV1_APB2DSMUDIV_SHIFT (12) +#define RCC_APB2DIV1_APB2DSMUDIV_MASK (0x07 << RCC_APB2DIV1_APB2DSMUDIV_SHIFT) +#define RCC_APB2DIV1_APB2DSMUDIV_DIV1 (0x00000000U << RCC_APB2DIV1_APB2DSMUDIV_SHIFT) +#define RCC_APB2DIV1_APB2DSMUDIV_DIV2 (0x00000004U << RCC_APB2DIV1_APB2DSMUDIV_SHIFT) +#define RCC_APB2DIV1_APB2DSMUDIV_DIV4 (0x00000005U << RCC_APB2DIV1_APB2DSMUDIV_SHIFT) +#define RCC_APB2DIV1_APB2DSMUDIV_DIV8 (0x00000006U << RCC_APB2DIV1_APB2DSMUDIV_SHIFT) +#define RCC_APB2DIV1_APB2DSMUDIV_DIV16 (0x00000007U << RCC_APB2DIV1_APB2DSMUDIV_SHIFT) + +/* Bit[10:8] APB2I2CDIV */ +#define RCC_APB2DIV1_APB2I2CDIV_SHIFT (8) +#define RCC_APB2DIV1_APB2I2CDIV_MASK (0x07 << RCC_APB2DIV1_APB2I2CDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2CDIV_DIV1 (0x00000000U << RCC_APB2DIV1_APB2I2CDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2CDIV_DIV2 (0x00000004U << RCC_APB2DIV1_APB2I2CDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2CDIV_DIV4 (0x00000005U << RCC_APB2DIV1_APB2I2CDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2CDIV_DIV8 (0x00000006U << RCC_APB2DIV1_APB2I2CDIV_SHIFT) +#define RCC_APB2DIV1_APB2I2CDIV_DIV16 (0x00000007U << RCC_APB2DIV1_APB2I2CDIV_SHIFT) + +/* Bit[6:4] APB2FDCANDIV */ +#define RCC_APB2DIV1_APB2FDCANDIV_SHIFT (4) +#define RCC_APB2DIV1_APB2FDCANDIV_MASK (0x07 << RCC_APB2DIV1_APB2FDCANDIV_SHIFT) +#define RCC_APB2DIV1_APB2FDCANDIV_DIV1 (0x00000000U << RCC_APB2DIV1_APB2FDCANDIV_SHIFT) +#define RCC_APB2DIV1_APB2FDCANDIV_DIV2 (0x00000004U << RCC_APB2DIV1_APB2FDCANDIV_SHIFT) +#define RCC_APB2DIV1_APB2FDCANDIV_DIV4 (0x00000005U << RCC_APB2DIV1_APB2FDCANDIV_SHIFT) +#define RCC_APB2DIV1_APB2FDCANDIV_DIV8 (0x00000006U << RCC_APB2DIV1_APB2FDCANDIV_SHIFT) +#define RCC_APB2DIV1_APB2FDCANDIV_DIV16 (0x00000007U << RCC_APB2DIV1_APB2FDCANDIV_SHIFT) + +/* Bit definition for RCC_APB2SEL1 register *********************************/ + +/* Bit[20:18] DSMUKERASEL */ +#define RCC_APB2SEL1_DSMUKERASEL_SHIFT (18) +#define RCC_APB2SEL1_DSMUKERASEL_MASK (0x07 << RCC_APB2SEL1_DSMUKERASEL_SHIFT) +#define RCC_APB2SEL1_DSMUKERASEL_SYSCLK (0x00000000U << RCC_APB2SEL1_DSMUKERASEL_SHIFT) +#define RCC_APB2SEL1_DSMUKERASEL_PLL1B (0x00000001U << RCC_APB2SEL1_DSMUKERASEL_SHIFT) +#define RCC_APB2SEL1_DSMUKERASEL_PLL2B (0x00000002U << RCC_APB2SEL1_DSMUKERASEL_SHIFT) +#define RCC_APB2SEL1_DSMUKERASEL_PLL3A (0x00000003U << RCC_APB2SEL1_DSMUKERASEL_SHIFT) +#define RCC_APB2SEL1_DSMUKERASEL_I2SCKIN (0x00000004U << RCC_APB2SEL1_DSMUKERASEL_SHIFT) +#define RCC_APB2SEL1_DSMUKERASEL_PERIPH (0x00000005U << RCC_APB2SEL1_DSMUKERASEL_SHIFT) + +/* Bit[14:12] I2C4KERSEL */ +#define RCC_APB2SEL1_I2C4KERSEL_SHIFT (12) +#define RCC_APB2SEL1_I2C4KERSEL_MASK (0x07 << RCC_APB2SEL1_I2C4KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C4KERSEL_SYSCLK (0x00000000U << RCC_APB2SEL1_I2C4KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C4KERSEL_PLL3C (0x00000001U << RCC_APB2SEL1_I2C4KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C4KERSEL_HSI (0x00000002U << RCC_APB2SEL1_I2C4KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C4KERSEL_MSI (0x00000003U << RCC_APB2SEL1_I2C4KERSEL_SHIFT) + +/* Bit[10:8] I2C5KERSEL */ +#define RCC_APB2SEL1_I2C5KERSEL_SHIFT (8) +#define RCC_APB2SEL1_I2C5KERSEL_MASK (0x07 << RCC_APB2SEL1_I2C5KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C5KERSEL_SYSCLK (0x00000000U << RCC_APB2SEL1_I2C5KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C5KERSEL_PLL3C (0x00000001U << RCC_APB2SEL1_I2C5KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C5KERSEL_HSI (0x00000002U << RCC_APB2SEL1_I2C5KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C5KERSEL_MSI (0x00000003U << RCC_APB2SEL1_I2C5KERSEL_SHIFT) + +/* Bit[6:4] I2C6KERSEL */ +#define RCC_APB2SEL1_I2C6KERSEL_SHIFT (4) +#define RCC_APB2SEL1_I2C6KERSEL_MASK (0x07 << RCC_APB2SEL1_I2C6KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C6KERSEL_SYSCLK (0x00000000U << RCC_APB2SEL1_I2C6KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C6KERSEL_PLL3C (0x00000001U << RCC_APB2SEL1_I2C6KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C6KERSEL_HSI (0x00000002U << RCC_APB2SEL1_I2C6KERSEL_SHIFT) +#define RCC_APB2SEL1_I2C6KERSEL_MSI (0x00000003U << RCC_APB2SEL1_I2C6KERSEL_SHIFT) + +/* Bit[2:0] I2S2KERSEL */ +#define RCC_APB2SEL1_I2S2KERSEL_SHIFT (0) +#define RCC_APB2SEL1_I2S2KERSEL_MASK (0x03 << RCC_APB2SEL1_I2S2KERSEL_SHIFT) +#define RCC_APB2SEL1_I2S2KERSEL_SYSCLK (0x00000000U << RCC_APB2SEL1_I2S2KERSEL_SHIFT) +#define RCC_APB2SEL1_I2S2KERSEL_PLL3B (0x00000001U << RCC_APB2SEL1_I2S2KERSEL_SHIFT) +#define RCC_APB2SEL1_I2S2KERSEL_HSI (0x00000002U << RCC_APB2SEL1_I2S2KERSEL_SHIFT) +#define RCC_APB2SEL1_I2S2KERSEL_I2S2CKIN (0x00000003U << RCC_APB2SEL1_I2S2KERSEL_SHIFT) + +/* Bit definition for RCC_APB2SEL2 register *********************************/ + +/* Bit[28:26] FDCAN3KERSEL */ +#define RCC_APB2SEL2_FDCAN3KERSEL_SHIFT (26) +#define RCC_APB2SEL2_FDCAN3KERSEL_MASK (0x07 << RCC_APB2SEL2_FDCAN3KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN3KERSEL_SYSCLK (0x00000000U << RCC_APB2SEL2_FDCAN3KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN3KERSEL_PLL1C (0x00000001U << RCC_APB2SEL2_FDCAN3KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN3KERSEL_PLL2C (0x00000002U << RCC_APB2SEL2_FDCAN3KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN3KERSEL_PLL3B (0x00000003U << RCC_APB2SEL2_FDCAN3KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN3KERSEL_PERIPH (0x00000004U << RCC_APB2SEL2_FDCAN3KERSEL_SHIFT) + +/* Bit[22:20] FDCAN4KERSEL */ +#define RCC_APB2SEL2_FDCAN4KERSEL_SHIFT (20) +#define RCC_APB2SEL2_FDCAN4KERSEL_MASK (0x07 << RCC_APB2SEL2_FDCAN4KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN4KERSEL_SYSCLK (0x00000000U << RCC_APB2SEL2_FDCAN4KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN4KERSEL_PLL1C (0x00000001U << RCC_APB2SEL2_FDCAN4KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN4KERSEL_PLL2C (0x00000002U << RCC_APB2SEL2_FDCAN4KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN4KERSEL_PLL3B (0x00000003U << RCC_APB2SEL2_FDCAN4KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN4KERSEL_PERIPH (0x00000004U << RCC_APB2SEL2_FDCAN4KERSEL_SHIFT) + +/* Bit[14:12] FDCAN7KERSEL */ +#define RCC_APB2SEL2_FDCAN7KERSEL_SHIFT (12) +#define RCC_APB2SEL2_FDCAN7KERSEL_MASK (0x07 << RCC_APB2SEL2_FDCAN7KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN7KERSEL_SYSCLK (0x00000000U << RCC_APB2SEL2_FDCAN7KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN7KERSEL_PLL1C (0x00000001U << RCC_APB2SEL2_FDCAN7KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN7KERSEL_PLL2C (0x00000002U << RCC_APB2SEL2_FDCAN7KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN7KERSEL_PLL3B (0x00000003U << RCC_APB2SEL2_FDCAN7KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN7KERSEL_PERIPH (0x00000004U << RCC_APB2SEL2_FDCAN7KERSEL_SHIFT) + +/* Bit[6:4] FDCAN8KERSEL */ +#define RCC_APB2SEL2_FDCAN8KERSEL_SHIFT (4) +#define RCC_APB2SEL2_FDCAN8KERSEL_MASK (0x07 << RCC_APB2SEL2_FDCAN8KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN8KERSEL_SYSCLK (0x00000000U << RCC_APB2SEL2_FDCAN8KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN8KERSEL_PLL1C (0x00000001U << RCC_APB2SEL2_FDCAN8KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN8KERSEL_PLL2C (0x00000002U << RCC_APB2SEL2_FDCAN8KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN8KERSEL_PLL3B (0x00000003U << RCC_APB2SEL2_FDCAN8KERSEL_SHIFT) +#define RCC_APB2SEL2_FDCAN8KERSEL_PERIPH (0x00000004U << RCC_APB2SEL2_FDCAN8KERSEL_SHIFT) + +/* Bit definition for RCC_APB2EN1 register **********************************/ + +#define RCC_APB2EN1_M7ATIM1EN (1U << 31) /* Bit[31] */ +#define RCC_APB2EN1_M4ATIM1EN (1U << 30) /* Bit[30] */ +#define RCC_APB2EN1_M7ATIM1LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB2EN1_M4ATIM1LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB2EN1_M7ATIM2EN (1U << 27) /* Bit[27] */ +#define RCC_APB2EN1_M4ATIM2EN (1U << 26) /* Bit[26] */ +#define RCC_APB2EN1_M7ATIM2LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB2EN1_M4ATIM2LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB2EN1_M7GTIMA1EN (1U << 23) /* Bit[23] */ +#define RCC_APB2EN1_M4GTIMA1EN (1U << 22) /* Bit[22] */ +#define RCC_APB2EN1_M7GTIMA1LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB2EN1_M4GTIMA1LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB2EN1_M7GTIMA2EN (1U << 19) /* Bit[19] */ +#define RCC_APB2EN1_M4GTIMA2EN (1U << 18) /* Bit[18] */ +#define RCC_APB2EN1_M7GTIMA2LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB2EN1_M4GTIMA2LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB2EN1_M7GTIMA3EN (1U << 15) /* Bit[15] */ +#define RCC_APB2EN1_M4GTIMA3EN (1U << 14) /* Bit[14] */ +#define RCC_APB2EN1_M7GTIMA3LPEN (1U << 13) /* Bit[13] */ +#define RCC_APB2EN1_M4GTIMA3LPEN (1U << 12) /* Bit[12] */ +#define RCC_APB2EN1_M7SHRTIM1EN (1U << 11) /* Bit[11] */ +#define RCC_APB2EN1_M4SHRTIM1EN (1U << 10) /* Bit[10] */ +#define RCC_APB2EN1_M7SHRTIM1LPEN (1U << 9) /* Bit[9] */ +#define RCC_APB2EN1_M4SHRTIM1LPEN (1U << 8) /* Bit[8] */ +#define RCC_APB2EN1_M7SHRTIM2EN (1U << 7) /* Bit[7] */ +#define RCC_APB2EN1_M4SHRTIM2EN (1U << 6) /* Bit[6] */ +#define RCC_APB2EN1_M7SHRTIM2LPEN (1U << 5) /* Bit[5] */ +#define RCC_APB2EN1_M4SHRTIM2LPEN (1U << 4) /* Bit[4] */ + +/* Bit definition for RCC_APB2EN2 register **********************************/ + +#define RCC_APB2EN2_M7I2S1EN (1U << 31) /* Bit[31] */ +#define RCC_APB2EN2_M4I2S1EN (1U << 30) /* Bit[30] */ +#define RCC_APB2EN2_M7I2S1LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB2EN2_M4I2S1LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB2EN2_M7I2S2EN (1U << 27) /* Bit[27] */ +#define RCC_APB2EN2_M4I2S2EN (1U << 26) /* Bit[26] */ +#define RCC_APB2EN2_M7I2S2LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB2EN2_M4I2S2LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB2EN2_M7SPI1EN (1U << 23) /* Bit[23] */ +#define RCC_APB2EN2_M4SPI1EN (1U << 22) /* Bit[22] */ +#define RCC_APB2EN2_M7SPI1LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB2EN2_M4SPI1LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB2EN2_M7SPI2EN (1U << 19) /* Bit[19] */ +#define RCC_APB2EN2_M4SPI2EN (1U << 18) /* Bit[18] */ +#define RCC_APB2EN2_M7SPI2LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB2EN2_M4SPI2LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB2EN2_M7DSMUEN (1U << 15) /* Bit[15] */ +#define RCC_APB2EN2_M4DSMUEN (1U << 14) /* Bit[14] */ +#define RCC_APB2EN2_M7DSMULPEN (1U << 13) /* Bit[13] */ +#define RCC_APB2EN2_M4DSMULPEN (1U << 12) /* Bit[12] */ +#define RCC_APB2EN2_M7I2C4EN (1U << 11) /* Bit[11] */ +#define RCC_APB2EN2_M4I2C4EN (1U << 10) /* Bit[10] */ +#define RCC_APB2EN2_M7I2C4LPEN (1U << 9) /* Bit[9] */ +#define RCC_APB2EN2_M4I2C4LPEN (1U << 8) /* Bit[8] */ +#define RCC_APB2EN2_M7I2C5EN (1U << 7) /* Bit[7] */ +#define RCC_APB2EN2_M4I2C5EN (1U << 6) /* Bit[6] */ +#define RCC_APB2EN2_M7I2C5LPEN (1U << 5) /* Bit[5] */ +#define RCC_APB2EN2_M4I2C5LPEN (1U << 4) /* Bit[4] */ +#define RCC_APB2EN2_M7I2C6EN (1U << 3) /* Bit[3] */ +#define RCC_APB2EN2_M4I2C6EN (1U << 2) /* Bit[2] */ +#define RCC_APB2EN2_M7I2C6LPEN (1U << 1) /* Bit[1] */ +#define RCC_APB2EN2_M4I2C6LPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB2EN3 register **********************************/ + +#define RCC_APB2EN3_M7USART5EN (1U << 31) /* Bit[31] */ +#define RCC_APB2EN3_M4USART5EN (1U << 30) /* Bit[30] */ +#define RCC_APB2EN3_M7USART5LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB2EN3_M4USART5LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB2EN3_M7USART6EN (1U << 27) /* Bit[27] */ +#define RCC_APB2EN3_M4USART6EN (1U << 26) /* Bit[26] */ +#define RCC_APB2EN3_M7USART6LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB2EN3_M4USART6LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB2EN3_M7USART7EN (1U << 23) /* Bit[23] */ +#define RCC_APB2EN3_M4USART7EN (1U << 22) /* Bit[22] */ +#define RCC_APB2EN3_M7USART7LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB2EN3_M4USART7LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB2EN3_M7USART8EN (1U << 19) /* Bit[19] */ +#define RCC_APB2EN3_M4USART8EN (1U << 18) /* Bit[18] */ +#define RCC_APB2EN3_M7USART8LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB2EN3_M4USART8LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB2EN3_M7UART13EN (1U << 15) /* Bit[15] */ +#define RCC_APB2EN3_M4UART13EN (1U << 14) /* Bit[14] */ +#define RCC_APB2EN3_M7UART13LPEN (1U << 13) /* Bit[13] */ +#define RCC_APB2EN3_M4UART13LPEN (1U << 12) /* Bit[12] */ +#define RCC_APB2EN3_M7UART14EN (1U << 11) /* Bit[11] */ +#define RCC_APB2EN3_M4UART14EN (1U << 10) /* Bit[10] */ +#define RCC_APB2EN3_M7UART14LPEN (1U << 9) /* Bit[9] */ +#define RCC_APB2EN3_M4UART14LPEN (1U << 8) /* Bit[8] */ +#define RCC_APB2EN3_M7UART15EN (1U << 7) /* Bit[7] */ +#define RCC_APB2EN3_M4UART15EN (1U << 6) /* Bit[6] */ +#define RCC_APB2EN3_M7UART15LPEN (1U << 5) /* Bit[5] */ +#define RCC_APB2EN3_M4UART15LPEN (1U << 4) /* Bit[4] */ + +/* Bit definition for RCC_APB2EN4 register **********************************/ + +#define RCC_APB2EN4_M7FDCAN3EN (1U << 31) /* Bit[31] */ +#define RCC_APB2EN4_M4FDCAN3EN (1U << 30) /* Bit[30] */ +#define RCC_APB2EN4_M7FDCAN3LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB2EN4_M4FDCAN3LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB2EN4_M7FDCAN4EN (1U << 27) /* Bit[27] */ +#define RCC_APB2EN4_M4FDCAN4EN (1U << 26) /* Bit[26] */ +#define RCC_APB2EN4_M7FDCAN4LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB2EN4_M4FDCAN4LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB2EN4_M7FDCAN7EN (1U << 23) /* Bit[23] */ +#define RCC_APB2EN4_M4FDCAN7EN (1U << 22) /* Bit[22] */ +#define RCC_APB2EN4_M7FDCAN7LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB2EN4_M4FDCAN7LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB2EN4_M7FDCAN8EN (1U << 19) /* Bit[19] */ +#define RCC_APB2EN4_M4FDCAN8EN (1U << 18) /* Bit[18] */ +#define RCC_APB2EN4_M7FDCAN8LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB2EN4_M4FDCAN8LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB2EN4_FDCAN3STPREQ (1U << 15) /* Bit[15] */ +#define RCC_APB2EN4_FDCAN3STPACK (1U << 14) /* Bit[14] */ +#define RCC_APB2EN4_FDCAN4STPREQ (1U << 11) /* Bit[11] */ +#define RCC_APB2EN4_FDCAN4STPACK (1U << 10) /* Bit[10] */ +#define RCC_APB2EN4_FDCAN7STPREQ (1U << 7) /* Bit[7] */ +#define RCC_APB2EN4_FDCAN7STPACK (1U << 6) /* Bit[6] */ +#define RCC_APB2EN4_FDCAN8STPREQ (1U << 3) /* Bit[3] */ +#define RCC_APB2EN4_FDCAN8STPACK (1U << 2) /* Bit[2] */ + +/* Bit definition for RCC_APB2RST1 register *********************************/ + +#define RCC_APB2RST1_ATIM1RST (1U << 28) /* Bit[28] */ +#define RCC_APB2RST1_ATIM2RST (1U << 24) /* Bit[24] */ +#define RCC_APB2RST1_GTIMA1RST (1U << 20) /* Bit[20] */ +#define RCC_APB2RST1_GTIMA2RST (1U << 16) /* Bit[16] */ +#define RCC_APB2RST1_GTIMA3RST (1U << 12) /* Bit[12] */ +#define RCC_APB2RST1_SHRTIM1RST (1U << 8) /* Bit[8] */ +#define RCC_APB2RST1_SHRTIM2RST (1U << 4) /* Bit[4] */ + +/* Bit definition for RCC_APB2RST2 register *********************************/ + +#define RCC_APB2RST2_I2S1RST (1U << 28) /* Bit[28] */ +#define RCC_APB2RST2_I2S2RST (1U << 24) /* Bit[24] */ +#define RCC_APB2RST2_SPI1RST (1U << 20) /* Bit[20] */ +#define RCC_APB2RST2_SPI2RST (1U << 16) /* Bit[16] */ +#define RCC_APB2RST2_DSMURST (1U << 12) /* Bit[12] */ +#define RCC_APB2RST2_I2C4RST (1U << 8) /* Bit[8] */ +#define RCC_APB2RST2_I2C5RST (1U << 4) /* Bit[4] */ +#define RCC_APB2RST2_I2C6RST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB2RST3 register *********************************/ + +#define RCC_APB2RST3_USART5RST (1U << 28) /* Bit[28] */ +#define RCC_APB2RST3_USART6RST (1U << 24) /* Bit[24] */ +#define RCC_APB2RST3_USART7RST (1U << 20) /* Bit[20] */ +#define RCC_APB2RST3_USART8RST (1U << 16) /* Bit[16] */ +#define RCC_APB2RST3_UART13RST (1U << 12) /* Bit[12] */ +#define RCC_APB2RST3_UART14RST (1U << 8) /* Bit[8] */ +#define RCC_APB2RST3_UART15RST (1U << 4) /* Bit[4] */ + +/* Bit definition for RCC_APB2RST4 register *********************************/ + +#define RCC_APB2RST4_FDCAN3RST (1U << 28) /* Bit[28] */ +#define RCC_APB2RST4_FDCAN4RST (1U << 24) /* Bit[24] */ +#define RCC_APB2RST4_FDCAN7RST (1U << 20) /* Bit[20] */ +#define RCC_APB2RST4_FDCAN8RST (1U << 16) /* Bit[16] */ + +/* Bit definition for RCC_AHB5EN1 register **********************************/ + +#define RCC_AHB5EN1_M7GPIOAEN (1U << 31) /* Bit[31] */ +#define RCC_AHB5EN1_M4GPIOAEN (1U << 30) /* Bit[30] */ +#define RCC_AHB5EN1_M7GPIOALPEN (1U << 29) /* Bit[29] */ +#define RCC_AHB5EN1_M4GPIOALPEN (1U << 28) /* Bit[28] */ +#define RCC_AHB5EN1_M7GPIOBEN (1U << 27) /* Bit[27] */ +#define RCC_AHB5EN1_M4GPIOBEN (1U << 26) /* Bit[26] */ +#define RCC_AHB5EN1_M7GPIOBLPEN (1U << 25) /* Bit[25] */ +#define RCC_AHB5EN1_M4GPIOBLPEN (1U << 24) /* Bit[24] */ +#define RCC_AHB5EN1_M7GPIOCEN (1U << 23) /* Bit[23] */ +#define RCC_AHB5EN1_M4GPIOCEN (1U << 22) /* Bit[22] */ +#define RCC_AHB5EN1_M7GPIOCLPEN (1U << 21) /* Bit[21] */ +#define RCC_AHB5EN1_M4GPIOCLPEN (1U << 20) /* Bit[20] */ +#define RCC_AHB5EN1_M7GPIODEN (1U << 19) /* Bit[19] */ +#define RCC_AHB5EN1_M4GPIODEN (1U << 18) /* Bit[18] */ +#define RCC_AHB5EN1_M7GPIODLPEN (1U << 17) /* Bit[17] */ +#define RCC_AHB5EN1_M4GPIODLPEN (1U << 16) /* Bit[16] */ +#define RCC_AHB5EN1_M7GPIOEEN (1U << 15) /* Bit[15] */ +#define RCC_AHB5EN1_M4GPIOEEN (1U << 14) /* Bit[14] */ +#define RCC_AHB5EN1_M7GPIOELPEN (1U << 13) /* Bit[13] */ +#define RCC_AHB5EN1_M4GPIOELPEN (1U << 12) /* Bit[12] */ +#define RCC_AHB5EN1_M7GPIOFEN (1U << 11) /* Bit[11] */ +#define RCC_AHB5EN1_M4GPIOFEN (1U << 10) /* Bit[10] */ +#define RCC_AHB5EN1_M7GPIOFLPEN (1U << 9) /* Bit[9] */ +#define RCC_AHB5EN1_M4GPIOFLPEN (1U << 8) /* Bit[8] */ +#define RCC_AHB5EN1_M7GPIOGEN (1U << 7) /* Bit[7] */ +#define RCC_AHB5EN1_M4GPIOGEN (1U << 6) /* Bit[6] */ +#define RCC_AHB5EN1_M7GPIOGLPEN (1U << 5) /* Bit[5] */ +#define RCC_AHB5EN1_M4GPIOGLPEN (1U << 4) /* Bit[4] */ +#define RCC_AHB5EN1_M7GPIOHEN (1U << 3) /* Bit[3] */ +#define RCC_AHB5EN1_M4GPIOHEN (1U << 2) /* Bit[2] */ +#define RCC_AHB5EN1_M7GPIOHLPEN (1U << 1) /* Bit[1] */ +#define RCC_AHB5EN1_M4GPIOHLPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB5EN2 register **********************************/ + +#define RCC_AHB5EN2_M7GPIOIEN (1U << 31) /* Bit[31] */ +#define RCC_AHB5EN2_M4GPIOIEN (1U << 30) /* Bit[30] */ +#define RCC_AHB5EN2_M7GPIOILPEN (1U << 29) /* Bit[29] */ +#define RCC_AHB5EN2_M4GPIOILPEN (1U << 28) /* Bit[28] */ +#define RCC_AHB5EN2_M7GPIOJEN (1U << 27) /* Bit[27] */ +#define RCC_AHB5EN2_M4GPIOJEN (1U << 26) /* Bit[26] */ +#define RCC_AHB5EN2_M7GPIOJLPEN (1U << 25) /* Bit[25] */ +#define RCC_AHB5EN2_M4GPIOJLPEN (1U << 24) /* Bit[24] */ +#define RCC_AHB5EN2_M7GPIOKEN (1U << 23) /* Bit[23] */ +#define RCC_AHB5EN2_M4GPIOKEN (1U << 22) /* Bit[22] */ +#define RCC_AHB5EN2_M7GPIOKLPEN (1U << 21) /* Bit[21] */ +#define RCC_AHB5EN2_M4GPIOKLPEN (1U << 20) /* Bit[20] */ +#define RCC_AHB5EN2_M7ECCM3EN (1U << 19) /* Bit[19] */ +#define RCC_AHB5EN2_M4ECCM3EN (1U << 18) /* Bit[18] */ +#define RCC_AHB5EN2_M7ECCM3LPEN (1U << 17) /* Bit[17] */ +#define RCC_AHB5EN2_M4ECCM3LPEN (1U << 16) /* Bit[16] */ +#define RCC_AHB5EN2_PWREN (1U << 15) /* Bit[15] */ +#define RCC_AHB5EN2_M7CRCEN (1U << 11) /* Bit[11] */ +#define RCC_AHB5EN2_M4CRCEN (1U << 10) /* Bit[10] */ +#define RCC_AHB5EN2_M7CRCLPEN (1U << 9) /* Bit[9] */ +#define RCC_AHB5EN2_M4CRCLPEN (1U << 8) /* Bit[8] */ +#define RCC_AHB5EN2_M7SEMA4EN (1U << 7) /* Bit[7] */ +#define RCC_AHB5EN2_M4SEMA4EN (1U << 6) /* Bit[6] */ +#define RCC_AHB5EN2_M7SEMA4LPEN (1U << 5) /* Bit[5] */ +#define RCC_AHB5EN2_M4SEMA4LPEN (1U << 4) /* Bit[4] */ +#define RCC_AHB5EN2_M7AFIOEN (1U << 3) /* Bit[3] */ +#define RCC_AHB5EN2_M4AFIOEN (1U << 2) /* Bit[2] */ +#define RCC_AHB5EN2_M7AFIOLPEN (1U << 1) /* Bit[1] */ +#define RCC_AHB5EN2_M4AFIOLPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB5RST1 register *********************************/ + +#define RCC_AHB5RST1_GPIOARST (1U << 28) /* Bit[28] */ +#define RCC_AHB5RST1_GPIOBRST (1U << 24) /* Bit[24] */ +#define RCC_AHB5RST1_GPIOCRST (1U << 20) /* Bit[20] */ +#define RCC_AHB5RST1_GPIODRST (1U << 16) /* Bit[16] */ +#define RCC_AHB5RST1_GPIOERST (1U << 12) /* Bit[12] */ +#define RCC_AHB5RST1_GPIOFRST (1U << 8) /* Bit[8] */ +#define RCC_AHB5RST1_GPIOGRST (1U << 4) /* Bit[4] */ +#define RCC_AHB5RST1_GPIOHRST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB5RST2 register *********************************/ + +#define RCC_AHB5RST2_GPIOIRST (1U << 28) /* Bit[28] */ +#define RCC_AHB5RST2_GPIOJRST (1U << 24) /* Bit[24] */ +#define RCC_AHB5RST2_GPIOKRST (1U << 20) /* Bit[20] */ +#define RCC_AHB5RST2_ECCM3RST (1U << 16) /* Bit[16] */ +#define RCC_AHB5RST2_PWRRST (1U << 12) /* Bit[12] */ +#define RCC_AHB5RST2_CRCRST (1U << 8) /* Bit[8] */ +#define RCC_AHB5RST2_SEMA4RST (1U << 4) /* Bit[4] */ +#define RCC_AHB5RST2_AFIORST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB5DIV1 register *********************************/ + +/* Bit[30:28] APB5ATIMDIV */ +#define RCC_APB5DIV1_APB5ATIMDIV_SHIFT (28) +#define RCC_APB5DIV1_APB5ATIMDIV_MASK (0x07 << RCC_APB5DIV1_APB5ATIMDIV_SHIFT) +#define RCC_APB5DIV1_APB5ATIMDIV_DIV1 (0x00000000U << RCC_APB5DIV1_APB5ATIMDIV_SHIFT) +#define RCC_APB5DIV1_APB5ATIMDIV_DIV2 (0x00000004U << RCC_APB5DIV1_APB5ATIMDIV_SHIFT) +#define RCC_APB5DIV1_APB5ATIMDIV_DIV4 (0x00000005U << RCC_APB5DIV1_APB5ATIMDIV_SHIFT) +#define RCC_APB5DIV1_APB5ATIMDIV_DIV8 (0x00000006U << RCC_APB5DIV1_APB5ATIMDIV_SHIFT) +#define RCC_APB5DIV1_APB5ATIMDIV_DIV16 (0x00000007U << RCC_APB5DIV1_APB5ATIMDIV_SHIFT) + +/* Bit[26:24] APB5I2CDIV */ +#define RCC_APB5DIV1_APB5I2CDIV_SHIFT (24) +#define RCC_APB5DIV1_APB5I2CDIV_MASK (0x07 << RCC_APB5DIV1_APB5I2CDIV_SHIFT) +#define RCC_APB5DIV1_APB5I2CDIV_DIV1 (0x00000000U << RCC_APB5DIV1_APB5I2CDIV_SHIFT) +#define RCC_APB5DIV1_APB5I2CDIV_DIV2 (0x00000004U << RCC_APB5DIV1_APB5I2CDIV_SHIFT) +#define RCC_APB5DIV1_APB5I2CDIV_DIV4 (0x00000005U << RCC_APB5DIV1_APB5I2CDIV_SHIFT) +#define RCC_APB5DIV1_APB5I2CDIV_DIV8 (0x00000006U << RCC_APB5DIV1_APB5I2CDIV_SHIFT) +#define RCC_APB5DIV1_APB5I2CDIV_DIV16 (0x00000007U << RCC_APB5DIV1_APB5I2CDIV_SHIFT) + +/* Bit[22:20] APB5EXTIDIV */ +#define RCC_APB5DIV1_APB5EXTIDIV_SHIFT (20) +#define RCC_APB5DIV1_APB5EXTIDIV_MASK (0x07 << RCC_APB5DIV1_APB5EXTIDIV_SHIFT) +#define RCC_APB5DIV1_APB5EXTIDIV_DIV1 (0x00000000U << RCC_APB5DIV1_APB5EXTIDIV_SHIFT) +#define RCC_APB5DIV1_APB5EXTIDIV_DIV2 (0x00000004U << RCC_APB5DIV1_APB5EXTIDIV_SHIFT) +#define RCC_APB5DIV1_APB5EXTIDIV_DIV4 (0x00000005U << RCC_APB5DIV1_APB5EXTIDIV_SHIFT) +#define RCC_APB5DIV1_APB5EXTIDIV_DIV8 (0x00000006U << RCC_APB5DIV1_APB5EXTIDIV_SHIFT) +#define RCC_APB5DIV1_APB5EXTIDIV_DIV16 (0x00000007U << RCC_APB5DIV1_APB5EXTIDIV_SHIFT) + +/* Bit definition for RCC_APB5SEL1 register *********************************/ + +/* Bit[30:28] I2C7KERSEL */ +#define RCC_APB5SEL1_I2C7KERSEL_SHIFT (28) +#define RCC_APB5SEL1_I2C7KERSEL_MASK (0x07 << RCC_APB5SEL1_I2C7KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C7KERSEL_SYSCLK (0x00000000U << RCC_APB5SEL1_I2C7KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C7KERSEL_PLL3C (0x00000001U << RCC_APB5SEL1_I2C7KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C7KERSEL_HSI (0x00000002U << RCC_APB5SEL1_I2C7KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C7KERSEL_MSI (0x00000003U << RCC_APB5SEL1_I2C7KERSEL_SHIFT) + +/* Bit[26:24] I2C8KERSEL */ +#define RCC_APB5SEL1_I2C8KERSEL_SHIFT (24) +#define RCC_APB5SEL1_I2C8KERSEL_MASK (0x07 << RCC_APB5SEL1_I2C8KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C8KERSEL_SYSCLK (0x00000000U << RCC_APB5SEL1_I2C8KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C8KERSEL_PLL3C (0x00000001U << RCC_APB5SEL1_I2C8KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C8KERSEL_HSI (0x00000002U << RCC_APB5SEL1_I2C8KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C8KERSEL_MSI (0x00000003U << RCC_APB5SEL1_I2C8KERSEL_SHIFT) + +/* Bit[22:20] I2C9KERSEL */ +#define RCC_APB5SEL1_I2C9KERSEL_SHIFT (20) +#define RCC_APB5SEL1_I2C9KERSEL_MASK (0x07 << RCC_APB5SEL1_I2C9KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C9KERSEL_SYSCLK (0x00000000U << RCC_APB5SEL1_I2C9KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C9KERSEL_PLL3C (0x00000001U << RCC_APB5SEL1_I2C9KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C9KERSEL_HSI (0x00000002U << RCC_APB5SEL1_I2C9KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C9KERSEL_MSI (0x00000003U << RCC_APB5SEL1_I2C9KERSEL_SHIFT) + +/* Bit[18:16] I2C10KERSEL */ +#define RCC_APB5SEL1_I2C10KERSEL_SHIFT (16) +#define RCC_APB5SEL1_I2C10KERSEL_MASK (0x07 << RCC_APB5SEL1_I2C10KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C10KERSEL_SYSCLK (0x00000000U << RCC_APB5SEL1_I2C10KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C10KERSEL_PLL3C (0x00000001U << RCC_APB5SEL1_I2C10KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C10KERSEL_HSI (0x00000002U << RCC_APB5SEL1_I2C10KERSEL_SHIFT) +#define RCC_APB5SEL1_I2C10KERSEL_MSI (0x00000003U << RCC_APB5SEL1_I2C10KERSEL_SHIFT) + +/* Bit definition for RCC_APB5EN1 register **********************************/ + +#define RCC_APB5EN1_M7ATIM3EN (1U << 31) /* Bit[31] */ +#define RCC_APB5EN1_M4ATIM3EN (1U << 30) /* Bit[30] */ +#define RCC_APB5EN1_M7ATIM3LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB5EN1_M4ATIM3LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB5EN1_M7ATIM4EN (1U << 27) /* Bit[27] */ +#define RCC_APB5EN1_M4ATIM4EN (1U << 26) /* Bit[26] */ +#define RCC_APB5EN1_M7ATIM4LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB5EN1_M4ATIM4LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB5EN1_M7AFECEN (1U << 23) /* Bit[23] */ +#define RCC_APB5EN1_M4AFECEN (1U << 22) /* Bit[22] */ +#define RCC_APB5EN1_M7AFECLPEN (1U << 21) /* Bit[21] */ +#define RCC_APB5EN1_M4AFECLPEN (1U << 20) /* Bit[20] */ +#define RCC_APB5EN1_M7SPI4EN (1U << 15) /* Bit[15] */ +#define RCC_APB5EN1_M4SPI4EN (1U << 14) /* Bit[14] */ +#define RCC_APB5EN1_M7SPI4LPEN (1U << 13) /* Bit[13] */ +#define RCC_APB5EN1_M4SPI4LPEN (1U << 12) /* Bit[12] */ +#define RCC_APB5EN1_M7SPI5EN (1U << 11) /* Bit[11] */ +#define RCC_APB5EN1_M4SPI5EN (1U << 10) /* Bit[10] */ +#define RCC_APB5EN1_M7SPI5LPEN (1U << 9) /* Bit[9] */ +#define RCC_APB5EN1_M4SPI5LPEN (1U << 8) /* Bit[8] */ +#define RCC_APB5EN1_M7SPI6EN (1U << 7) /* Bit[7] */ +#define RCC_APB5EN1_M4SPI6EN (1U << 6) /* Bit[6] */ +#define RCC_APB5EN1_M7SPI6LPEN (1U << 5) /* Bit[5] */ +#define RCC_APB5EN1_M4SPI6LPEN (1U << 4) /* Bit[4] */ +#define RCC_APB5EN1_M7SPI7EN (1U << 3) /* Bit[3] */ +#define RCC_APB5EN1_M4SPI7EN (1U << 2) /* Bit[2] */ +#define RCC_APB5EN1_M7SPI7LPEN (1U << 1) /* Bit[1] */ +#define RCC_APB5EN1_M4SPI7LPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB5EN2 register **********************************/ + +#define RCC_APB5EN2_M7I2C7EN (1U << 31) /* Bit[31] */ +#define RCC_APB5EN2_M4I2C7EN (1U << 30) /* Bit[30] */ +#define RCC_APB5EN2_M7I2C7LPEN (1U << 29) /* Bit[29] */ +#define RCC_APB5EN2_M4I2C7LPEN (1U << 28) /* Bit[28] */ +#define RCC_APB5EN2_M7I2C8EN (1U << 27) /* Bit[27] */ +#define RCC_APB5EN2_M4I2C8EN (1U << 26) /* Bit[26] */ +#define RCC_APB5EN2_M7I2C8LPEN (1U << 25) /* Bit[25] */ +#define RCC_APB5EN2_M4I2C8LPEN (1U << 24) /* Bit[24] */ +#define RCC_APB5EN2_M7I2C9EN (1U << 23) /* Bit[23] */ +#define RCC_APB5EN2_M4I2C9EN (1U << 22) /* Bit[22] */ +#define RCC_APB5EN2_M7I2C9LPEN (1U << 21) /* Bit[21] */ +#define RCC_APB5EN2_M4I2C9LPEN (1U << 20) /* Bit[20] */ +#define RCC_APB5EN2_M7I2C10EN (1U << 19) /* Bit[19] */ +#define RCC_APB5EN2_M4I2C10EN (1U << 18) /* Bit[18] */ +#define RCC_APB5EN2_M7I2C10LPEN (1U << 17) /* Bit[17] */ +#define RCC_APB5EN2_M4I2C10LPEN (1U << 16) /* Bit[16] */ +#define RCC_APB5EN2_EXTIEN (1U << 15) /* Bit[15] */ +#define RCC_APB5EN2_M7RTCPCLKEN (1U << 11) /* Bit[11] */ +#define RCC_APB5EN2_M4RTCPCLKEN (1U << 10) /* Bit[10] */ +#define RCC_APB5EN2_M7RTCPCLKLPEN (1U << 9) /* Bit[9] */ +#define RCC_APB5EN2_M4RTCPCLKLPEN (1U << 8) /* Bit[8] */ +#define RCC_APB5EN2_IWDG1PCLKEN (1U << 7) /* Bit[7] */ +#define RCC_APB5EN2_IWDG1PCLKLPEN (1U << 5) /* Bit[5] */ +#define RCC_APB5EN2_IWDG2PCLKEN (1U << 3) /* Bit[3] */ +#define RCC_APB5EN2_IWDG2PCLKLPEN (1U << 1) /* Bit[1] */ + +/* Bit definition for RCC_APB5RST1 register *********************************/ + +#define RCC_APB5RST1_ATIM3RST (1U << 28) /* Bit[28] */ +#define RCC_APB5RST1_ATIM4RST (1U << 24) /* Bit[24] */ +#define RCC_APB5RST1_SPI4RST (1U << 12) /* Bit[12] */ +#define RCC_APB5RST1_SPI5RST (1U << 8) /* Bit[8] */ +#define RCC_APB5RST1_SPI6RST (1U << 4) /* Bit[4] */ +#define RCC_APB5RST1_SPI7RST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_APB5RST2 register *********************************/ + +#define RCC_APB5RST2_I2C7RST (1U << 28) /* Bit[28] */ +#define RCC_APB5RST2_I2C8RST (1U << 24) /* Bit[24] */ +#define RCC_APB5RST2_I2C9RST (1U << 20) /* Bit[20] */ +#define RCC_APB5RST2_I2C10RST (1U << 16) /* Bit[16] */ + +/* Bit definition for RCC_AHB9DIV1 register *********************************/ + +/* Bit[3:0] ESCSYSDIV */ +#define RCC_AHB9DIV1_ESCSYSDIV_SHIFT (0) +#define RCC_AHB9DIV1_ESCSYSDIV_MASK (0x0F << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV1 (0x00000000U << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV2 (0x00000001U << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV4 (0x00000002U << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV8 (0x00000004U << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV16 (0x00000007U << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV32 (0x00000008U << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV64 (0x00000009U << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV128 (0x0000000AU << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV256 (0x0000000BU << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) +#define RCC_AHB9DIV1_ESCSYSDIV_DIV512 (0x0000000CU << RCC_AHB9DIV1_ESCSYSDIV_SHIFT) + +/* Bit definition for RCC_AHB9SEL1 register *********************************/ + +/* Bit[2:0] ESCKERSEL */ +#define RCC_AHB9SEL1_ESCKERSEL_SHIFT (0) +#define RCC_AHB9SEL1_ESCKERSEL_MASK (0x07 << RCC_AHB9SEL1_ESCKERSEL_SHIFT) +#define RCC_AHB9SEL1_ESCKERSEL_SYSCLK (0x00000000U << RCC_AHB9SEL1_ESCKERSEL_SHIFT) +#define RCC_AHB9SEL1_ESCKERSEL_PLL2B (0x00000001U << RCC_AHB9SEL1_ESCKERSEL_SHIFT) +#define RCC_AHB9SEL1_ESCKERSEL_PLL3A (0x00000002U << RCC_AHB9SEL1_ESCKERSEL_SHIFT) +#define RCC_AHB9SEL1_ESCKERSEL_PLL3C (0x00000003U << RCC_AHB9SEL1_ESCKERSEL_SHIFT) +#define RCC_AHB9SEL1_ESCKERSEL_PLL1B (0x00000004U << RCC_AHB9SEL1_ESCKERSEL_SHIFT) + +/* Bit definition for RCC_AHB9EN1 register **********************************/ + +#define RCC_AHB9EN1_M7ESCEN (1U << 3) /* Bit[3] */ +#define RCC_AHB9EN1_M4ESCEN (1U << 2) /* Bit[2] */ +#define RCC_AHB9EN1_M7ESCLPEN (1U << 1) /* Bit[1] */ +#define RCC_AHB9EN1_M4ESCLPEN (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_AHB9RST1 register *********************************/ + +#define RCC_AHB9RST1_ESCRST (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_RDDIV1 register ***********************************/ + +/* Bit[30:28] COMPDIV */ +#define RCC_RDDIV1_COMPDIV_SHIFT (28) +#define RCC_RDDIV1_COMPDIV_MASK (0x07 << RCC_RDDIV1_COMPDIV_SHIFT) +#define RCC_RDDIV1_COMPDIV_DIV1 (0x00000000U << RCC_RDDIV1_COMPDIV_SHIFT) +#define RCC_RDDIV1_COMPDIV_DIV2 (0x00000001U << RCC_RDDIV1_COMPDIV_SHIFT) +#define RCC_RDDIV1_COMPDIV_DIV4 (0x00000002U << RCC_RDDIV1_COMPDIV_SHIFT) +#define RCC_RDDIV1_COMPDIV_DIV8 (0x00000004U << RCC_RDDIV1_COMPDIV_SHIFT) +#define RCC_RDDIV1_COMPDIV_DIV16 (0x00000007U << RCC_RDDIV1_COMPDIV_SHIFT) + +/* Bit[26:24] LPUARTDIV */ +#define RCC_RDDIV1_LPUARTDIV_SHIFT (24) +#define RCC_RDDIV1_LPUARTDIV_MASK (0x07 << RCC_RDDIV1_LPUARTDIV_SHIFT) +#define RCC_RDDIV1_LPUARTDIV_DIV1 (0x00000000U << RCC_RDDIV1_LPUARTDIV_SHIFT) +#define RCC_RDDIV1_LPUARTDIV_DIV2 (0x00000001U << RCC_RDDIV1_LPUARTDIV_SHIFT) +#define RCC_RDDIV1_LPUARTDIV_DIV4 (0x00000002U << RCC_RDDIV1_LPUARTDIV_SHIFT) +#define RCC_RDDIV1_LPUARTDIV_DIV8 (0x00000004U << RCC_RDDIV1_LPUARTDIV_SHIFT) +#define RCC_RDDIV1_LPUARTDIV_DIV16 (0x00000007U << RCC_RDDIV1_LPUARTDIV_SHIFT) + +/* Bit definition for RCC_RDSEL1 register ***********************************/ + +/* Bit[31:28] LPTIM1SEL */ +#define RCC_RDSEL1_LPTIM1SEL_SHIFT (28) +#define RCC_RDSEL1_LPTIM1SEL_MASK (0x0F << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_APB5 (0x00000000U << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_LSI (0x00000001U << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_LSE (0x00000002U << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_HSE (0x00000003U << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_HIS (0x00000004U << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_MSI (0x00000005U << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_COMP1 (0x00000008U << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_COMP2 (0x00000009U << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_COMP3 (0x0000000AU << RCC_RDSEL1_LPTIM1SEL_SHIFT) +#define RCC_RDSEL1_LPTIM1SEL_COMP4 (0x0000000BU << RCC_RDSEL1_LPTIM1SEL_SHIFT) + +/* Bit[27:24] LPTIM2SEL */ +#define RCC_RDSEL1_LPTIM2SEL_SHIFT (24) +#define RCC_RDSEL1_LPTIM2SEL_MASK (0x0F << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_APB5 (0x00000000U << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_LSI (0x00000001U << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_LSE (0x00000002U << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_HSE (0x00000003U << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_HIS (0x00000004U << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_MSI (0x00000005U << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_COMP1 (0x00000008U << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_COMP2 (0x00000009U << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_COMP3 (0x0000000AU << RCC_RDSEL1_LPTIM2SEL_SHIFT) +#define RCC_RDSEL1_LPTIM2SEL_COMP4 (0x0000000BU << RCC_RDSEL1_LPTIM2SEL_SHIFT) + +/* Bit[23:20] LPTIM3SEL */ +#define RCC_RDSEL1_LPTIM3SEL_SHIFT (20) +#define RCC_RDSEL1_LPTIM3SEL_MASK (0x0F << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_APB5 (0x00000000U << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_LSI (0x00000001U << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_LSE (0x00000002U << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_HSE (0x00000003U << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_HIS (0x00000004U << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_MSI (0x00000005U << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_COMP1 (0x00000008U << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_COMP2 (0x00000009U << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_COMP3 (0x0000000AU << RCC_RDSEL1_LPTIM3SEL_SHIFT) +#define RCC_RDSEL1_LPTIM3SEL_COMP4 (0x0000000BU << RCC_RDSEL1_LPTIM3SEL_SHIFT) + +/* Bit[19:16] LPTIM4SEL */ +#define RCC_RDSEL1_LPTIM4SEL_SHIFT (16) +#define RCC_RDSEL1_LPTIM4SEL_MASK (0x0F << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_APB5 (0x00000000U << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_LSI (0x00000001U << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_LSE (0x00000002U << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_HSE (0x00000003U << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_HIS (0x00000004U << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_MSI (0x00000005U << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_COMP1 (0x00000008U << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_COMP2 (0x00000009U << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_COMP3 (0x0000000AU << RCC_RDSEL1_LPTIM4SEL_SHIFT) +#define RCC_RDSEL1_LPTIM4SEL_COMP4 (0x0000000BU << RCC_RDSEL1_LPTIM4SEL_SHIFT) + +/* Bit[15:12] LPTIM5SEL */ +#define RCC_RDSEL1_LPTIM5SEL_SHIFT (12) +#define RCC_RDSEL1_LPTIM5SEL_MASK (0x0F << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_APB5 (0x00000000U << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_LSI (0x00000001U << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_LSE (0x00000002U << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_HSE (0x00000003U << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_HIS (0x00000004U << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_MSI (0x00000005U << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_COMP1 (0x00000008U << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_COMP2 (0x00000009U << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_COMP3 (0x0000000AU << RCC_RDSEL1_LPTIM5SEL_SHIFT) +#define RCC_RDSEL1_LPTIM5SEL_COMP4 (0x0000000BU << RCC_RDSEL1_LPTIM5SEL_SHIFT) + +/* Bit[10:8] LPUART1SEL */ +#define RCC_RDSEL1_LPUART1SEL_SHIFT (8) +#define RCC_RDSEL1_LPUART1SEL_MASK (0x07 << RCC_RDSEL1_LPUART1SEL_SHIFT) +#define RCC_RDSEL1_LPUART1SEL_SYSCLK (0x00000000U << RCC_RDSEL1_LPUART1SEL_SHIFT) +#define RCC_RDSEL1_LPUART1SEL_HSI (0x00000001U << RCC_RDSEL1_LPUART1SEL_SHIFT) +#define RCC_RDSEL1_LPUART1SEL_LSE (0x00000002U << RCC_RDSEL1_LPUART1SEL_SHIFT) +#define RCC_RDSEL1_LPUART1SEL_HSE (0x00000003U << RCC_RDSEL1_LPUART1SEL_SHIFT) +#define RCC_RDSEL1_LPUART1SEL_MSI (0x00000004U << RCC_RDSEL1_LPUART1SEL_SHIFT) + +/* Bit[6:4] LPUART2SEL */ +#define RCC_RDSEL1_LPUART2SEL_SHIFT (4) +#define RCC_RDSEL1_LPUART2SEL_MASK (0x07 << RCC_RDSEL1_LPUART2SEL_SHIFT) +#define RCC_RDSEL1_LPUART2SEL_SYSCLK (0x00000000U << RCC_RDSEL1_LPUART2SEL_SHIFT) +#define RCC_RDSEL1_LPUART2SEL_HSI (0x00000001U << RCC_RDSEL1_LPUART2SEL_SHIFT) +#define RCC_RDSEL1_LPUART2SEL_LSE (0x00000002U << RCC_RDSEL1_LPUART2SEL_SHIFT) +#define RCC_RDSEL1_LPUART2SEL_HSE (0x00000003U << RCC_RDSEL1_LPUART2SEL_SHIFT) +#define RCC_RDSEL1_LPUART2SEL_MSI (0x00000004U << RCC_RDSEL1_LPUART2SEL_SHIFT) + +/* Bit[0] COMPSEL */ +#define RCC_RDSEL1_COMPSEL (1U << 0) /* Bit[0] */ + +/* Bit definition for RCC_RDCTRL1 register **********************************/ + +#define RCC_RDCTRL1_LPTIM2FLTEN (1U << 29) +#define RCC_RDCTRL1_LPTIM2FLTSEL (1U << 28) +#define RCC_RDCTRL1_LPTIM2COMP4EN (1U << 27) +#define RCC_RDCTRL1_LPTIM2COMP3EN (1U << 26) +#define RCC_RDCTRL1_LPTIM2COMP2EN (1U << 25) +#define RCC_RDCTRL1_LPTIM2COMP1EN (1U << 24) +#define RCC_RDCTRL1_LPTIM2FLTDFC_SHIFT (16) +#define RCC_RDCTRL1_LPTIM2FLTDFC_MASK (0x1F << RCC_RDCTRL1_LPTIM2FLTDFC_SHIFT) +#define RCC_RDCTRL1_LPTIM1FLTEN (1U << 13) +#define RCC_RDCTRL1_LPTIM1FLTSEL (1U << 12) +#define RCC_RDCTRL1_LPTIM1COMP4EN (1U << 11) +#define RCC_RDCTRL1_LPTIM1COMP3EN (1U << 10) +#define RCC_RDCTRL1_LPTIM1COMP2EN (1U << 9) +#define RCC_RDCTRL1_LPTIM1COMP1EN (1U << 8) +#define RCC_RDCTRL1_LPTIM1FLTDFC_SHIFT (0) +#define RCC_RDCTRL1_LPTIM1FLTDFC_MASK (0x1F << RCC_RDCTRL1_LPTIM1FLTDFC_SHIFT) + +/* Bit definition for RCC_RDCTRL2 register **********************************/ + +#define RCC_RDCTRL2_LPTIM4FLTEN (1U << 29) +#define RCC_RDCTRL2_LPTIM4FLTSEL (1U << 28) +#define RCC_RDCTRL2_LPTIM4COMP4EN (1U << 27) +#define RCC_RDCTRL2_LPTIM4COMP3EN (1U << 26) +#define RCC_RDCTRL2_LPTIM4COMP2EN (1U << 25) +#define RCC_RDCTRL2_LPTIM4COMP1EN (1U << 24) +#define RCC_RDCTRL2_LPTIM4FLTDFC_SHIFT (16) +#define RCC_RDCTRL2_LPTIM4FLTDFC_MASK (0x1F << RCC_RDCTRL2_LPTIM4FLTDFC_SHIFT) +#define RCC_RDCTRL2_LPTIM3FLTEN (1U << 13) +#define RCC_RDCTRL2_LPTIM3FLTSEL (1U << 12) +#define RCC_RDCTRL2_LPTIM3COMP4EN (1U << 11) +#define RCC_RDCTRL2_LPTIM3COMP3EN (1U << 10) +#define RCC_RDCTRL2_LPTIM3COMP2EN (1U << 9) +#define RCC_RDCTRL2_LPTIM3COMP1EN (1U << 8) +#define RCC_RDCTRL2_LPTIM3FLTDFC_SHIFT (0) +#define RCC_RDCTRL2_LPTIM3FLTDFC_MASK (0x1F << RCC_RDCTRL2_LPTIM3FLTDFC_SHIFT) + +/* Bit definition for RCC_RDCTRL3 register **********************************/ + +#define RCC_RDCTRL3_LPTIM5FLTEN (1U << 13) +#define RCC_RDCTRL3_LPTIM5FLTSEL (1U << 12) +#define RCC_RDCTRL3_LPTIM5COMP4EN (1U << 11) +#define RCC_RDCTRL3_LPTIM5COMP3EN (1U << 10) +#define RCC_RDCTRL3_LPTIM5COMP2EN (1U << 9) +#define RCC_RDCTRL3_LPTIM5COMP1EN (1U << 8) +#define RCC_RDCTRL3_LPTIM5FLTDFC_SHIFT (0) +#define RCC_RDCTRL3_LPTIM5FLTDFC_MASK (0x1F << RCC_RDCTRL3_LPTIM5FLTDFC_SHIFT) + +/* Bit definition for RCC_RDEN1 register ************************************/ + +#define RCC_RDEN1_M7LPTIM1EN (1U << 31) +#define RCC_RDEN1_M4LPTIM1EN (1U << 30) +#define RCC_RDEN1_M7LPTIM1LPEN (1U << 29) +#define RCC_RDEN1_M4LPTIM1LPEN (1U << 28) +#define RCC_RDEN1_M7LPTIM2EN (1U << 27) +#define RCC_RDEN1_M4LPTIM2EN (1U << 26) +#define RCC_RDEN1_M7LPTIM2LPEN (1U << 25) +#define RCC_RDEN1_M4LPTIM2LPEN (1U << 24) +#define RCC_RDEN1_M7LPTIM3EN (1U << 23) +#define RCC_RDEN1_M4LPTIM3EN (1U << 22) +#define RCC_RDEN1_M7LPTIM3LPEN (1U << 21) +#define RCC_RDEN1_M4LPTIM3LPEN (1U << 20) +#define RCC_RDEN1_M7LPTIM4EN (1U << 19) +#define RCC_RDEN1_M4LPTIM4EN (1U << 18) +#define RCC_RDEN1_M7LPTIM4LPEN (1U << 17) +#define RCC_RDEN1_M4LPTIM4LPEN (1U << 16) +#define RCC_RDEN1_M7LPTIM5EN (1U << 15) +#define RCC_RDEN1_M4LPTIM5EN (1U << 14) +#define RCC_RDEN1_M7LPTIM5LPEN (1U << 13) +#define RCC_RDEN1_M4LPTIM5LPEN (1U << 12) +#define RCC_RDEN1_M7LPUART1EN (1U << 11) +#define RCC_RDEN1_M4LPUART1EN (1U << 10) +#define RCC_RDEN1_M7LPUART1LPEN (1U << 9) +#define RCC_RDEN1_M4LPUART1LPEN (1U << 8) +#define RCC_RDEN1_M7LPUART2EN (1U << 7) +#define RCC_RDEN1_M4LPUART2EN (1U << 6) +#define RCC_RDEN1_M7LPUART2LPEN (1U << 5) +#define RCC_RDEN1_M4LPUART2LPEN (1U << 4) + +/* Bit definition for RCC_RDEN2 register ************************************/ + +#define RCC_RDEN2_M7COMPEN (1U << 31) +#define RCC_RDEN2_M4COMPEN (1U << 30) +#define RCC_RDEN2_M7COMPLPEN (1U << 29) +#define RCC_RDEN2_M4COMPLPEN (1U << 28) + +/* Bit definition for RCC_RDRST1 register ***********************************/ + +#define RCC_RDRST1_LPTIM1RST (1U << 28) +#define RCC_RDRST1_LPTIM2RST (1U << 24) +#define RCC_RDRST1_LPTIM3RST (1U << 20) +#define RCC_RDRST1_LPTIM4RST (1U << 16) +#define RCC_RDRST1_LPTIM5RST (1U << 12) +#define RCC_RDRST1_LPUART1RST (1U << 8) +#define RCC_RDRST1_LPUART2RST (1U << 4) + +/* Bit definition for RCC_RDRST2 register ***********************************/ + +#define RCC_RDRST2_COMPRST (1U << 28) + +/* Bit definition for RCC_BDCTRL register ***********************************/ + +#define RCC_BDCTRL_AFELSERDF (1U << 31) +#define RCC_BDCTRL_AFELSIRDF (1U << 30) +#define RCC_BDCTRL_LSELDOEN (1U << 28) +#define RCC_BDCTRL_LSIOVREN (1U << 27) +#define RCC_BDCTRL_LSIPFACK (1U << 26) +#define RCC_BDCTRL_LSIPFF (1U << 25) +#define RCC_BDCTRL_LSICSSEN (1U << 24) +#define RCC_BDCTRL_LSERDCNTEN (1U << 22) +#define RCC_BDCTRL_RTCLSFSW (1U << 21) +#define RCC_BDCTRL_RTCHSFSW (1U << 20) +#define RCC_BDCTRL_LSISECRDF (1U << 19) +#define RCC_BDCTRL_RTCEN (1U << 18) + +/* RTCSEL[1:0] */ +#define RCC_BDCTRL_RTCSEL_SHIFT (16) +#define RCC_BDCTRL_RTCSEL_MASK (0x03 << RCC_BDCTRL_RTCSEL_SHIFT) +#define RCC_BDCTRL_RTCSEL_NONE (0x00 << RCC_BDCTRL_RTCSEL_SHIFT) +#define RCC_BDCTRL_RTCSEL_LSE (0x01 << RCC_BDCTRL_RTCSEL_SHIFT) +#define RCC_BDCTRL_RTCSEL_LSI (0x02 << RCC_BDCTRL_RTCSEL_SHIFT) +#define RCC_BDCTRL_RTCSEL_HSE_DIV (0x03 << RCC_BDCTRL_RTCSEL_SHIFT) + +#define RCC_BDCTRL_BORRSTEN (1U << 15) +#define RCC_BDCTRL_C1LPRSTEN (1U << 14) +#define RCC_BDCTRL_C2LPRSTEN (1U << 13) +#define RCC_BDCTRL_BDRST (1U << 12) +#define RCC_BDCTRL_BKPEMC_RSTEN (1U << 11) +#define RCC_BDCTRL_RETEMC_RSTEN (1U << 10) +#define RCC_BDCTRL_LSECSSF (1U << 9) +#define RCC_BDCTRL_LSECSSEN (1U << 8) +#define RCC_BDCTRL_LSERDEN (1U << 7) +#define RCC_BDCTRL_LSEBP (1U << 6) +#define RCC_BDCTRL_LSERDF (1U << 5) +#define RCC_BDCTRL_LSEEN (1U << 4) +#define RCC_BDCTRL_LSIRDEN (1U << 3) +#define RCC_BDCTRL_LSISECEN (1U << 2) +#define RCC_BDCTRL_LSIRDF (1U << 1) +#define RCC_BDCTRL_LSIEN (1U << 0) + +/* Bit definition for RCC_LSICSSDL register *********************************/ + +/* Bit[31:0] DELAY */ +#define RCC_LSICSSDL_DELAY_SHIFT (0) +#define RCC_LSICSSDL_DELAY_MASK (0xFFFFFFFFU << RCC_LSICSSDL_DELAY_SHIFT) + +/* Bit definition for RCC_CTRLSTS register **********************************/ + +#define RCC_CTRLSTS_RMRSTF (1U << 31) +#define RCC_CTRLSTS_C1LPRSTF (1U << 15) +#define RCC_CTRLSTS_C2LPRSTF (1U << 14) +#define RCC_CTRLSTS_RETEMCRSTF (1U << 13) +#define RCC_CTRLSTS_BKPEMCRSTF (1U << 12) +#define RCC_CTRLSTS_BORRSTF (1U << 11) +#define RCC_CTRLSTS_MMURSTF (1U << 9) +#define RCC_CTRLSTS_WWDG1RSTF (1U << 7) +#define RCC_CTRLSTS_WWDG2RSTF (1U << 6) +#define RCC_CTRLSTS_IWDG1RSTF (1U << 5) +#define RCC_CTRLSTS_IWDG2RSTF (1U << 4) +#define RCC_CTRLSTS_CM4SFTRSTF (1U << 3) +#define RCC_CTRLSTS_CM7SFTRSTF (1U << 2) +#define RCC_CTRLSTS_PORRSTF (1U << 1) +#define RCC_CTRLSTS_PINRSTF (1U << 0) + +/* Bit definition for RCC_CLKINT1 register **********************************/ + +#define RCC_CLKINT1_LSECSSIE (1U << 30) +#define RCC_CLKINT1_LSECSSIF (1U << 29) +#define RCC_CLKINT1_LSECSSIC (1U << 28) +#define RCC_CLKINT1_HSECSSIF (1U << 25) +#define RCC_CLKINT1_HSECSSIC (1U << 24) +#define RCC_CLKINT1_BORIE (1U << 22) +#define RCC_CLKINT1_BORIF (1U << 21) +#define RCC_CLKINT1_BORIC (1U << 20) +#define RCC_CLKINT1_PLL1RDIE (1U << 18) +#define RCC_CLKINT1_PLL1RDIF (1U << 17) +#define RCC_CLKINT1_PLL1RDIC (1U << 16) +#define RCC_CLKINT1_PLL2RDIE (1U << 14) +#define RCC_CLKINT1_PLL2RDIF (1U << 13) +#define RCC_CLKINT1_PLL2RDIC (1U << 12) +#define RCC_CLKINT1_PLL3RDIE (1U << 10) +#define RCC_CLKINT1_PLL3RDIF (1U << 9) +#define RCC_CLKINT1_PLL3RDIC (1U << 8) +#define RCC_CLKINT1_SHRPLLRDIE (1U << 6) +#define RCC_CLKINT1_SHRPLLRDIF (1U << 5) +#define RCC_CLKINT1_SHRPLLRDIC (1U << 4) + +/* Bit definition for RCC_CLKINT2 register **********************************/ + +#define RCC_CLKINT2_HSERDIE (1U << 30) +#define RCC_CLKINT2_HSERDIF (1U << 29) +#define RCC_CLKINT2_HSERDIC (1U << 28) +#define RCC_CLKINT2_HSIRDIE (1U << 26) +#define RCC_CLKINT2_HSIRDIF (1U << 25) +#define RCC_CLKINT2_HSIRDIC (1U << 24) +#define RCC_CLKINT2_MSIRDIE (1U << 22) +#define RCC_CLKINT2_MSIRDIF (1U << 21) +#define RCC_CLKINT2_MSIRDIC (1U << 20) +#define RCC_CLKINT2_LSERDIE (1U << 18) +#define RCC_CLKINT2_LSERDIF (1U << 17) +#define RCC_CLKINT2_LSERDIC (1U << 16) +#define RCC_CLKINT2_LSIRDIE (1U << 14) +#define RCC_CLKINT2_LSIRDIF (1U << 13) +#define RCC_CLKINT2_LSIRDIC (1U << 12) +#define RCC_CLKINT2_HSICALEIE (1U << 10) +#define RCC_CLKINT2_HSICALEIF (1U << 9) +#define RCC_CLKINT2_HSICALEIC (1U << 8) +#define RCC_CLKINT2_MSICALEIE (1U << 6) +#define RCC_CLKINT2_MSICALEIF (1U << 5) +#define RCC_CLKINT2_MSICALEIC (1U << 4) + +/* Bit definition for RCC_CLKINT3 register **********************************/ + +#define RCC_CLKINT3_PLL1LKFIEN (1U << 18) +#define RCC_CLKINT3_PLL1LKFIF (1U << 17) +#define RCC_CLKINT3_PLL1LKFIC (1U << 16) +#define RCC_CLKINT3_PLL2LKFIEN (1U << 14) +#define RCC_CLKINT3_PLL2LKFIF (1U << 13) +#define RCC_CLKINT3_PLL2LKFIC (1U << 12) +#define RCC_CLKINT3_PLL3LKFIEN (1U << 10) +#define RCC_CLKINT3_PLL3LKFIF (1U << 9) +#define RCC_CLKINT3_PLL3LKFIC (1U << 8) +#define RCC_CLKINT3_SHRPLLLKFIE (1U << 6) +#define RCC_CLKINT3_SHRPLLLKFIF (1U << 5) +#define RCC_CLKINT3_SHRPLLLKFIC (1U << 4) +#define RCC_CLKINT3_LSIFIE (1U << 2) +#define RCC_CLKINT3_LSIFIF (1U << 1) +#define RCC_CLKINT3_LSIFIC (1U << 0) + +/* Bit definition for RCC_CFG1 register *************************************/ + +#define RCC_CFG1_WWDG2RSTDLCNT_SHIFT (24) /* WWDG2 reset delay counter shift */ +#define RCC_CFG1_WWDG2RSTDLCNT_MASK (0x0F << RCC_CFG1_WWDG2RSTDLCNT_SHIFT) + +#define RCC_CFG1_WWDG1RSTDLCNT_SHIFT (20) /* WWDG1 reset delay counter shift */ +#define RCC_CFG1_WWDG1RSTDLCNT_MASK (0x0F << RCC_CFG1_WWDG1RSTDLCNT_SHIFT) + +#define RCC_CFG1_WWDG2RSTEN (1U << 19) /* WWDG2 reset enable */ +#define RCC_CFG1_WWDG1RSTEN (1U << 18) /* WWDG1 reset enable */ + +#define RCC_CFG1_M7TRACEDIV_SHIFT (12) /* M7 trace clock divider shift */ +#define RCC_CFG1_M7TRACEDIV_MASK (0x0F << RCC_CFG1_M7TRACEDIV_SHIFT) +#define RCC_CFG1_M7TRACEDIV1 (0U << RCC_CFG1_M7TRACEDIV_SHIFT) +#define RCC_CFG1_M7TRACEDIV2 (1U << RCC_CFG1_M7TRACEDIV_SHIFT) +#define RCC_CFG1_M7TRACEDIV4 (2U << RCC_CFG1_M7TRACEDIV_SHIFT) +#define RCC_CFG1_M7TRACEDIV8 (4U << RCC_CFG1_M7TRACEDIV_SHIFT) +/* Bit definition for RCC_HSECAL register ***********************************/ + +/* [31:18] Reserved */ + +/* [17] HSE Calibration Count Enable */ +#define RCC_CFG1_M7TRACEDIV16 (7U << RCC_CFG1_M7TRACEDIV_SHIFT) +#define RCC_CFG1_M7TRACEDIV32 (8U << RCC_CFG1_M7TRACEDIV_SHIFT) +#define RCC_CFG1_M7TRACEDIV64 (9U << RCC_CFG1_M7TRACEDIV_SHIFT) +#define RCC_CFG1_M7TRACEDIV128 (10U << RCC_CFG1_M7TRACEDIV_SHIFT) +#define RCC_CFG1_M7TRACEDIV256 (11U << RCC_CFG1_M7TRACEDIV_SHIFT) +#define RCC_CFG1_M7TRACEDIV512 (12U << RCC_CFG1_M7TRACEDIV_SHIFT) + +#define RCC_CFG1_M4TRACEDIV_SHIFT (8) /* M4 trace clock divider shift */ +#define RCC_CFG1_M4TRACEDIV_MASK (0x0F << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV1 (0U << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV2 (1U << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV4 (2U << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV8 (4U << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV16 (7U << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV32 (8U << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV64 (9U << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV128 (10U << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV256 (11U << RCC_CFG1_M4TRACEDIV_SHIFT) +#define RCC_CFG1_M4TRACEDIV512 (12U << RCC_CFG1_M4TRACEDIV_SHIFT) + +/* Bit definition for RCC_AXIDIV1 register **********************************/ + +#define RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT (24) /* SDMMC1 AXI clock divider shift position */ +#define RCC_AXIDIV1_SDMMC1AXIDIV_MASK (0x0F << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV1 (0U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV2 (1U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV4 (2U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV8 (4U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV16 (7U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV32 (8U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV64 (9U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV128 (10U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV256 (11U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) +#define RCC_AXIDIV1_SDMMC1AXIDIV512 (12U << RCC_AXIDIV1_SDMMC1AXIDIV_SHIFT) + +#define RCC_AXIDIV1_DSIREFDIV_SHIFT (16) /* DSI reference clock divider shift position */ +#define RCC_AXIDIV1_DSIREFDIV_MASK (0x0F << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV1 (0U << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV2 (1U << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV4 (2U << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV8 (4U << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV16 (7U << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV32 (8U << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV64 (9U << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV128 (10U << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV256 (11U << RCC_AXIDIV1_DSIREFDIV_SHIFT) +#define RCC_AXIDIV1_DSIREFDIV512 (12U << RCC_AXIDIV1_DSIREFDIV_SHIFT) + +#define RCC_AXIDIV1_LCDAXIDIV_SHIFT (12) /* LCD AXI clock divider shift position */ +#define RCC_AXIDIV1_LCDAXIDIV_MASK (0x0F << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV1 (0U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV2 (1U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV4 (2U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV8 (4U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV16 (7U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV32 (8U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV64 (9U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV128 (10U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV256 (11U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) +#define RCC_AXIDIV1_LCDAXIDIV512 (12U << RCC_AXIDIV1_LCDAXIDIV_SHIFT) + +#define RCC_AXIDIV1_DVPMAXIDIV_SHIFT (8) /* DVP AXI clock divider shift position */ +#define RCC_AXIDIV1_DVPMAXIDIV_MASK (0x0F << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV1 (0U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV2 (1U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV4 (2U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV8 (4U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV16 (7U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV32 (8U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV64 (9U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV128 (10U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV256 (11U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) +#define RCC_AXIDIV1_DVPMAXIDIV512 (12U << RCC_AXIDIV1_DVPMAXIDIV_SHIFT) + +/* Bit definition for RCC_AXIDIV2 register **********************************/ + +#define RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT (24) /* DSI AXI PP clock divider position */ +#define RCC_AXIDIV2_DSIAXIPPIDIV_MASK (0x0F << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV1 (0U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV2 (1U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV4 (2U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV8 (4U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV16 (7U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV32 (8U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV64 (9U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV128 (10U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV256 (11U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) +#define RCC_AXIDIV2_DSIAXIPPIDIV512 (12U << RCC_AXIDIV2_DSIAXIPPIDIV_SHIFT) + +#define RCC_AXIDIV2_DSIREFULPSDIV_SHIFT (16) /* DSI reference ULPS clock divider position */ +#define RCC_AXIDIV2_DSIREFULPSDIV_MASK (0x0F << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV1 (0U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV2 (1U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV4 (2U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV8 (4U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV16 (7U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV32 (8U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV64 (9U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV128 (10U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV256 (11U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) +#define RCC_AXIDIV2_DSIREFULPSDIV512 (12U << RCC_AXIDIV2_DSIREFULPSDIV_SHIFT) + +#define RCC_AXIDIV2_SDRAMMEMDIV_SHIFT (8) /* SDRAM memory clock divider position */ +#define RCC_AXIDIV2_SDRAMMEMDIV_MASK (0x0F << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV1 (0U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV2 (1U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV4 (2U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV8 (4U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV16 (7U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV32 (8U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV64 (9U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV128 (10U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV256 (11U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) +#define RCC_AXIDIV2_SDRAMMEMDIV512 (12U << RCC_AXIDIV2_SDRAMMEMDIV_SHIFT) + +#define RCC_AXIDIV2_FEMCM1AXIDIV_SHIFT (4) /* FEMC M1 AXI clock divider position */ +#define RCC_AXIDIV2_FEMCM1AXIDIV_MASK (0x0F << RCC_AXIDIV2_FEMCM1AXIDIV_SHIFT) + +#define RCC_AXIDIV2_FEMCM0AXIDIV_SHIFT (0) /* FEMC M0 AXI clock divider position */ +#define RCC_AXIDIV2_FEMCM0AXIDIV_MASK (0x0F << RCC_AXIDIV2_FEMCM0AXIDIV_SHIFT) + +/* Bit definition for RCC_AXISEL1 register **********************************/ + +/* DSI ULPS Clock Source Selection */ +#define RCC_AXISEL1_DSIULPSSEL_SHIFT (26) +#define RCC_AXISEL1_DSIULPSSEL_MASK (0x03 << RCC_AXISEL1_DSIULPSSEL_SHIFT) +#define RCC_AXISEL1_DSIULPSSEL_DSIREF (0x00 << RCC_AXISEL1_DSIULPSSEL_SHIFT) +#define RCC_AXISEL1_DSIULPSSEL_PLL3C (0x01 << RCC_AXISEL1_DSIULPSSEL_SHIFT) + +/* DSI Kernel Clock Source Selection */ +#define RCC_AXISEL1_DSIKERSEL_SHIFT (24) +#define RCC_AXISEL1_DSIKERSEL_MASK (0x03 << RCC_AXISEL1_DSIKERSEL_SHIFT) +#define RCC_AXISEL1_DSIKERSEL_DSIREF (0x00 << RCC_AXISEL1_DSIKERSEL_SHIFT) +#define RCC_AXISEL1_DSIKERSEL_PLL3C (0x01 << RCC_AXISEL1_DSIKERSEL_SHIFT) + +/* SDMMC1 Kernel Clock Source Selection */ +#define RCC_AXISEL1_SDMMC1KERSEL_SHIFT (20) +#define RCC_AXISEL1_SDMMC1KERSEL_MASK (0x07 << RCC_AXISEL1_SDMMC1KERSEL_SHIFT) +#define RCC_AXISEL1_SDMMC1KERSEL_AXIDIV (0x00 << RCC_AXISEL1_SDMMC1KERSEL_SHIFT) +#define RCC_AXISEL1_SDMMC1KERSEL_PERIPH (0x01 << RCC_AXISEL1_SDMMC1KERSEL_SHIFT) +#define RCC_AXISEL1_SDMMC1KERSEL_PLL2A (0x02 << RCC_AXISEL1_SDMMC1KERSEL_SHIFT) +#define RCC_AXISEL1_SDMMC1KERSEL_PLL3A (0x03 << RCC_AXISEL1_SDMMC1KERSEL_SHIFT) +#define RCC_AXISEL1_SDMMC1KERSEL_PLL1B (0x04 << RCC_AXISEL1_SDMMC1KERSEL_SHIFT) + +/* DSI PPI TX Clock Source Selection */ +#define RCC_AXISEL1_DSIPPITXSEL_SHIFT (16) +#define RCC_AXISEL1_DSIPPITXSEL_MASK (0x03 << RCC_AXISEL1_DSIPPITXSEL_SHIFT) +#define RCC_AXISEL1_DSIPPITXSEL_DSIDIV (0x00 << RCC_AXISEL1_DSIPPITXSEL_SHIFT) +#define RCC_AXISEL1_DSIPPITXSEL_PLL2B (0x01 << RCC_AXISEL1_DSIPPITXSEL_SHIFT) +#define RCC_AXISEL1_DSIPPITXSEL_PERIPH (0x02 << RCC_AXISEL1_DSIPPITXSEL_SHIFT) +#define RCC_AXISEL1_DSIPPITXSEL_AXIDIV (0x03 << RCC_AXISEL1_DSIPPITXSEL_SHIFT) + +/* LCD Kernel Clock Source Selection */ +#define RCC_AXISEL1_LCDKERSEL_SHIFT (12) +#define RCC_AXISEL1_LCDKERSEL_MASK (0x03 << RCC_AXISEL1_LCDKERSEL_SHIFT) +#define RCC_AXISEL1_LCDKERSEL_AXIDIV (0x00 << RCC_AXISEL1_LCDKERSEL_SHIFT) +#define RCC_AXISEL1_LCDKERSEL_PERIPH (0x01 << RCC_AXISEL1_LCDKERSEL_SHIFT) +#define RCC_AXISEL1_LCDKERSEL_PLL2C (0x02 << RCC_AXISEL1_LCDKERSEL_SHIFT) +#define RCC_AXISEL1_LCDKERSEL_PLL3B (0x03 << RCC_AXISEL1_LCDKERSEL_SHIFT) + +/* DVP1 Memory Clock Source Selection */ +#define RCC_AXISEL1_DVP1MSEL_SHIFT (10) +#define RCC_AXISEL1_DVP1MSEL_MASK (0x03 << RCC_AXISEL1_DVP1MSEL_SHIFT) +#define RCC_AXISEL1_DVP1MSEL_AXIDIV (0x00 << RCC_AXISEL1_DVP1MSEL_SHIFT) +#define RCC_AXISEL1_DVP1MSEL_PERIPH (0x01 << RCC_AXISEL1_DVP1MSEL_SHIFT) +#define RCC_AXISEL1_DVP1MSEL_PLL2C (0x02 << RCC_AXISEL1_DVP1MSEL_SHIFT) +#define RCC_AXISEL1_DVP1MSEL_PLL3A (0x03 << RCC_AXISEL1_DVP1MSEL_SHIFT) + +/* DVP2 Memory Clock Source Selection */ +#define RCC_AXISEL1_DVP2MSEL_SHIFT (8) +#define RCC_AXISEL1_DVP2MSEL_MASK (0x03 << RCC_AXISEL1_DVP2MSEL_SHIFT) +#define RCC_AXISEL1_DVP2MSEL_AXIDIV (0x00 << RCC_AXISEL1_DVP2MSEL_SHIFT) +#define RCC_AXISEL1_DVP2MSEL_PERIPH (0x01 << RCC_AXISEL1_DVP2MSEL_SHIFT) +#define RCC_AXISEL1_DVP2MSEL_PLL2C (0x02 << RCC_AXISEL1_DVP2MSEL_SHIFT) +#define RCC_AXISEL1_DVP2MSEL_PLL3A (0x03 << RCC_AXISEL1_DVP2MSEL_SHIFT) + +/* XSPI1 SSI Clock Source Selection */ +#define RCC_AXISEL1_XSPI1SSISEL_SHIFT (4) +#define RCC_AXISEL1_XSPI1SSISEL_MASK (0x07 << RCC_AXISEL1_XSPI1SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI1SSISEL_AXI (0x00 << RCC_AXISEL1_XSPI1SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI1SSISEL_PLL3C (0x01 << RCC_AXISEL1_XSPI1SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI1SSISEL_PLL1B (0x02 << RCC_AXISEL1_XSPI1SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI1SSISEL_PLL2A (0x03 << RCC_AXISEL1_XSPI1SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI1SSISEL_PLL2C (0x04 << RCC_AXISEL1_XSPI1SSISEL_SHIFT) + +/* XSPI2 SSI Clock Source Selection */ +#define RCC_AXISEL1_XSPI2SSISEL_SHIFT (0) +#define RCC_AXISEL1_XSPI2SSISEL_MASK (0x07 << RCC_AXISEL1_XSPI2SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI2SSISEL_AXI (0x00 << RCC_AXISEL1_XSPI2SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI2SSISEL_PLL3C (0x01 << RCC_AXISEL1_XSPI2SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI2SSISEL_PLL1B (0x02 << RCC_AXISEL1_XSPI2SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI2SSISEL_PLL2A (0x03 << RCC_AXISEL1_XSPI2SSISEL_SHIFT) +#define RCC_AXISEL1_XSPI2SSISEL_PLL2C (0x04 << RCC_AXISEL1_XSPI2SSISEL_SHIFT) + +/* Bit definition for RCC_AXISEL2 register **********************************/ + +/* Bit[10:8] SDRAMMEMSEL */ +#define RCC_AXISEL2_SDRAMMEMSEL_SHIFT (8) +#define RCC_AXISEL2_SDRAMMEMSEL_MASK (0x07 << RCC_AXISEL2_SDRAMMEMSEL_SHIFT) +#define RCC_AXISEL2_SDRAMMEMSEL_AXIDIV (0x00 << RCC_AXISEL2_SDRAMMEMSEL_SHIFT) +#define RCC_AXISEL2_SDRAMMEMSEL_PERIPH (0x01 << RCC_AXISEL2_SDRAMMEMSEL_SHIFT) +#define RCC_AXISEL2_SDRAMMEMSEL_PLL2A (0x02 << RCC_AXISEL2_SDRAMMEMSEL_SHIFT) +#define RCC_AXISEL2_SDRAMMEMSEL_PLL3A (0x03 << RCC_AXISEL2_SDRAMMEMSEL_SHIFT) +#define RCC_AXISEL2_SDRAMMEMSEL_PLL1B (0x04 << RCC_AXISEL2_SDRAMMEMSEL_SHIFT) + +/* Bit[6:4] FEMCM1SEL */ +#define RCC_AXISEL2_FEMCM1SEL_SHIFT (4) +#define RCC_AXISEL2_FEMCM1SEL_MASK (0x07 << RCC_AXISEL2_FEMCM1SEL_SHIFT) +#define RCC_AXISEL2_FEMCM1SEL_AXIDIV (0x00 << RCC_AXISEL2_FEMCM1SEL_SHIFT) +#define RCC_AXISEL2_FEMCM1SEL_PERIPH (0x01 << RCC_AXISEL2_FEMCM1SEL_SHIFT) +#define RCC_AXISEL2_FEMCM1SEL_PLL2C (0x02 << RCC_AXISEL2_FEMCM1SEL_SHIFT) +#define RCC_AXISEL2_FEMCM1SEL_PLL3B (0x03 << RCC_AXISEL2_FEMCM1SEL_SHIFT) +#define RCC_AXISEL2_FEMCM1SEL_PLL1B (0x04 << RCC_AXISEL2_FEMCM1SEL_SHIFT) + +/* Bit[2:0] FEMCM0SEL */ +#define RCC_AXISEL2_FEMCM0SEL_SHIFT (0) +#define RCC_AXISEL2_FEMCM0SEL_MASK (0x07 << RCC_AXISEL2_FEMCM0SEL_SHIFT) +#define RCC_AXISEL2_FEMCM0SEL_AXIDIV (0x00 << RCC_AXISEL2_FEMCM0SEL_SHIFT) +#define RCC_AXISEL2_FEMCM0SEL_PERIPH (0x01 << RCC_AXISEL2_FEMCM0SEL_SHIFT) +#define RCC_AXISEL2_FEMCM0SEL_PLL2C (0x02 << RCC_AXISEL2_FEMCM0SEL_SHIFT) +#define RCC_AXISEL2_FEMCM0SEL_PLL3B (0x03 << RCC_AXISEL2_FEMCM0SEL_SHIFT) +#define RCC_AXISEL2_FEMCM0SEL_PLL1B (0x04 << RCC_AXISEL2_FEMCM0SEL_SHIFT) + +/* Bit definition for RCC_AXIEN1 register ***********************************/ + +#define RCC_AXIEN1_M7JPEGDEN (1U << 31) +#define RCC_AXIEN1_M4JPEGDEN (1U << 30) +#define RCC_AXIEN1_M7JPEGDLPEN (1U << 29) +#define RCC_AXIEN1_M4JPEGDLPEN (1U << 28) +#define RCC_AXIEN1_M7JPEGEEN (1U << 23) +#define RCC_AXIEN1_M4JPEGEEN (1U << 22) +#define RCC_AXIEN1_M7JPEGELPEN (1U << 21) +#define RCC_AXIEN1_M4JPEGELPEN (1U << 20) +#define RCC_AXIEN1_M7DMAMUX2EN (1U << 19) +#define RCC_AXIEN1_M4DMAMUX2EN (1U << 18) +#define RCC_AXIEN1_M7DMAMUX2LPEN (1U << 17) +#define RCC_AXIEN1_M4DMAMUX2LPEN (1U << 16) +#define RCC_AXIEN1_M7MDMAEN (1U << 15) +#define RCC_AXIEN1_M4MDMAEN (1U << 14) +#define RCC_AXIEN1_M7MDMALPEN (1U << 13) +#define RCC_AXIEN1_M4MDMALPEN (1U << 12) +#define RCC_AXIEN1_M7SDMMC1EN (1U << 11) +#define RCC_AXIEN1_M4SDMMC1EN (1U << 10) +#define RCC_AXIEN1_M7SDMMC1LPEN (1U << 9) +#define RCC_AXIEN1_M4SDMMC1LPEN (1U << 8) +#define RCC_AXIEN1_M7ECCM1EN (1U << 7) +#define RCC_AXIEN1_M4ECCM1EN (1U << 6) +#define RCC_AXIEN1_M7ECCM1LPEN (1U << 5) +#define RCC_AXIEN1_M4ECCM1LPEN (1U << 4) +#define RCC_AXIEN1_M7OTPCEN (1U << 3) +#define RCC_AXIEN1_M4OTPCEN (1U << 2) +#define RCC_AXIEN1_M7OTPCLPEN (1U << 1) +#define RCC_AXIEN1_M4OTPCLPEN (1U << 0) + +/* Bit definition for RCC_AXIEN2 register ***********************************/ + +#define RCC_AXIEN2_M7DSIEN (1U << 31) +#define RCC_AXIEN2_M4DSIEN (1U << 30) +#define RCC_AXIEN2_M7DSILPEN (1U << 29) +#define RCC_AXIEN2_M4DSILPEN (1U << 28) +#define RCC_AXIEN2_M7LCDEN (1U << 27) +#define RCC_AXIEN2_M4LCDEN (1U << 26) +#define RCC_AXIEN2_M7LCDLPEN (1U << 25) +#define RCC_AXIEN2_M4LCDLPEN (1U << 24) +#define RCC_AXIEN2_M7LCDAPBEN (1U << 23) +#define RCC_AXIEN2_M4LCDAPBEN (1U << 22) +#define RCC_AXIEN2_M7LCDAPBLPEN (1U << 21) +#define RCC_AXIEN2_M4LCDAPBLPEN (1U << 20) +#define RCC_AXIEN2_M7DVP1EN (1U << 19) +#define RCC_AXIEN2_M4DVP1EN (1U << 18) +#define RCC_AXIEN2_M7DVP1LPEN (1U << 17) +#define RCC_AXIEN2_M4DVP1LPEN (1U << 16) +#define RCC_AXIEN2_M7DVP1APBEN (1U << 15) +#define RCC_AXIEN2_M4DVP1APBEN (1U << 14) +#define RCC_AXIEN2_M7DVP1APBLPEN (1U << 13) +#define RCC_AXIEN2_M4DVP1APBLPEN (1U << 12) +#define RCC_AXIEN2_M7DVP2EN (1U << 11) +#define RCC_AXIEN2_M4DVP2EN (1U << 10) +#define RCC_AXIEN2_M7DVP2LPEN (1U << 9) +#define RCC_AXIEN2_M4DVP2LPEN (1U << 8) +#define RCC_AXIEN2_M7DVP2APBEN (1U << 7) +#define RCC_AXIEN2_M4DVP2APBEN (1U << 6) +#define RCC_AXIEN2_M7DVP2APBLPEN (1U << 5) +#define RCC_AXIEN2_M4DVP2APBLPEN (1U << 4) +#define RCC_AXIEN2_M7WWDG1EN (1U << 3) +#define RCC_AXIEN2_M4WWDG1EN (1U << 2) +#define RCC_AXIEN2_M7WWDG1LPEN (1U << 1) +#define RCC_AXIEN2_M4WWDG1LPEN (1U << 0) + +/* Bit definition for RCC_AXIEN3 register ***********************************/ + +#define RCC_AXIEN3_M7TASRAM2EN (1U << 31) +#define RCC_AXIEN3_M4TASRAM2EN (1U << 30) +#define RCC_AXIEN3_M7TASRAM2LPEN (1U << 29) +#define RCC_AXIEN3_M4TASRAM2LPEN (1U << 28) +#define RCC_AXIEN3_M7TASRAM3EN (1U << 27) +#define RCC_AXIEN3_M4TASRAM3EN (1U << 26) +#define RCC_AXIEN3_M7TASRAM3LPEN (1U << 25) +#define RCC_AXIEN3_M4TASRAM3LPEN (1U << 24) +#define RCC_AXIEN3_M7TCMEN (1U << 23) +#define RCC_AXIEN3_M4TCMEN (1U << 22) +#define RCC_AXIEN3_M7TCMLPEN (1U << 21) +#define RCC_AXIEN3_M4TCMLPEN (1U << 20) +#define RCC_AXIEN3_M7TCMAXIEN (1U << 19) +#define RCC_AXIEN3_M4TCMAXIEN (1U << 18) +#define RCC_AXIEN3_M7TCMAXILPEN (1U << 17) +#define RCC_AXIEN3_M4TCMAXILPEN (1U << 16) +#define RCC_AXIEN3_M7TCMAPBEN (1U << 15) +#define RCC_AXIEN3_M4TCMAPBEN (1U << 14) +#define RCC_AXIEN3_M7TCMAPBLPEN (1U << 13) +#define RCC_AXIEN3_M4TCMAPBLPEN (1U << 12) +#define RCC_AXIEN3_M7ASRAM1EN (1U << 11) +#define RCC_AXIEN3_M4ASRAM1EN (1U << 10) +#define RCC_AXIEN3_M7ASRAM1LPEN (1U << 9) +#define RCC_AXIEN3_M4ASRAM1LPEN (1U << 8) +#define RCC_AXIEN3_M7AXIROMEN (1U << 7) +#define RCC_AXIEN3_M4AXIROMEN (1U << 6) +#define RCC_AXIEN3_M7AXIROMLPEN (1U << 5) +#define RCC_AXIEN3_M4AXIROMLPEN (1U << 4) +#define RCC_AXIEN3_M7GPUEN (1U << 3) +#define RCC_AXIEN3_M4GPUEN (1U << 2) +#define RCC_AXIEN3_M7GPULPEN (1U << 1) +#define RCC_AXIEN3_M4GPULPEN (1U << 0) + +/* Bit definition for RCC_AXIEN4 register ***********************************/ + +#define RCC_AXIEN4_M7XSPI1EN (1U << 31) +#define RCC_AXIEN4_M4XSPI1EN (1U << 30) +#define RCC_AXIEN4_M7XSPI1LPEN (1U << 29) +#define RCC_AXIEN4_M4XSPI1LPEN (1U << 28) +#define RCC_AXIEN4_M7XSPI2EN (1U << 27) +#define RCC_AXIEN4_M4XSPI2EN (1U << 26) +#define RCC_AXIEN4_M7XSPI2LPEN (1U << 25) +#define RCC_AXIEN4_M4XSPI2LPEN (1U << 24) +#define RCC_AXIEN4_M7FEMCEN (1U << 23) +#define RCC_AXIEN4_M4FEMCEN (1U << 22) +#define RCC_AXIEN4_M7FEMCLPEN (1U << 21) +#define RCC_AXIEN4_M4FEMCLPEN (1U << 20) +#define RCC_AXIEN4_M7SDRAMEN (1U << 19) +#define RCC_AXIEN4_M4SDRAMEN (1U << 18) +#define RCC_AXIEN4_M7SDRAMLPEN (1U << 17) +#define RCC_AXIEN4_M4SDRAMLPEN (1U << 16) +#define RCC_AXIEN4_M7DSIULPSEN (1U << 3) +#define RCC_AXIEN4_M4DSIULPSEN (1U << 2) +#define RCC_AXIEN4_M7DSIULPSLPEN (1U << 1) +#define RCC_AXIEN4_M4DSIULPSLPEN (1U << 0) + +/* Bit definition for RCC_AXIRST1 register **********************************/ + +#define RCC_AXIRST1_JPEGDRST (1U << 28) +#define RCC_AXIRST1_JPEGERST (1U << 20) +#define RCC_AXIRST1_DMAMUX2RST (1U << 16) +#define RCC_AXIRST1_MDMARST (1U << 12) +#define RCC_AXIRST1_SDMMC1RST (1U << 9) +#define RCC_AXIRST1_SDHOST1RST (1U << 8) +#define RCC_AXIRST1_ECCM1RST (1U << 4) +#define RCC_AXIRST1_OTPCRST (1U << 0) + +/* Bit definition for RCC_AXIRST2 register **********************************/ + +#define RCC_AXIRST2_DSICFGRST (1U << 29) +#define RCC_AXIRST2_DSIRST (1U << 28) +#define RCC_AXIRST2_LCDRST (1U << 24) +#define RCC_AXIRST2_DVP1RST (1U << 16) +#define RCC_AXIRST2_DVP2RST (1U << 8) +#define RCC_AXIRST2_WWDG1RST (1U << 0) + +/* Bit definition for RCC_AXIRST3 register **********************************/ + +#define RCC_AXIRST3_GPURST (1U << 0) + +/* Bit definition for RCC_AXIRST4 register **********************************/ + +#define RCC_AXIRST4_XSPI1RST (1U << 28) +#define RCC_AXIRST4_XSPI2RST (1U << 24) +#define RCC_AXIRST4_FEMCCFGRST (1U << 21) +#define RCC_AXIRST4_FEMCRST (1U << 20) +#define RCC_AXIRST4_SDRAMRST (1U << 16) + +/* Bit definition for RCC_CFG2 register *************************************/ + +/* Cache & MMU */ +#define RCC_CFG2_M4CAHIEN (1U << 30) +#define RCC_CFG2_M4CAHIPCLKEN (1U << 28) +#define RCC_CFG2_M4CAHDEN (1U << 26) +#define RCC_CFG2_M4CAHDPCLKEN (1U << 24) + +#define RCC_CFG2_M7MMUEN (1U << 23) +#define RCC_CFG2_M7MMULPEN (1U << 22) +#define RCC_CFG2_M4MMUEN (1U << 21) +#define RCC_CFG2_M4MMULPEN (1U << 20) + +/* BKP SRAM */ +#define RCC_CFG2_M7SRAMBKPEN (1U << 19) +#define RCC_CFG2_M4SRAMBKPEN (1U << 18) +#define RCC_CFG2_M7SRAMBKPLPEN (1U << 17) +#define RCC_CFG2_M4SRAMBKPLPEN (1U << 16) + +/* SRAM1~4 */ +#define RCC_CFG2_M7SRAM1EN (1U << 15) +#define RCC_CFG2_M4SRAM1EN (1U << 14) +#define RCC_CFG2_M7SRAM1LPEN (1U << 13) +#define RCC_CFG2_M4SRAM1LPEN (1U << 12) + +#define RCC_CFG2_M7SRAM2EN (1U << 11) +#define RCC_CFG2_M4SRAM2EN (1U << 10) +#define RCC_CFG2_M7SRAM2LPEN (1U << 9) +#define RCC_CFG2_M4SRAM2LPEN (1U << 8) + +#define RCC_CFG2_M7SRAM3EN (1U << 7) +#define RCC_CFG2_M4SRAM3EN (1U << 6) +#define RCC_CFG2_M7SRAM3LPEN (1U << 5) +#define RCC_CFG2_M4SRAM3LPEN (1U << 4) + +#define RCC_CFG2_M7SRAM4EN (1U << 3) +#define RCC_CFG2_M4SRAM4EN (1U << 2) +#define RCC_CFG2_M7SRAM4LPEN (1U << 1) +#define RCC_CFG2_M4SRAM4LPEN (1U << 0) + +/* Bit definition for RCC_CFG3 register *************************************/ + +/* MCO1 */ +#define RCC_CFG3_MCO1SEL_SHIFT (28) +#define RCC_CFG3_MCO1SEL_MASK (0x0F << RCC_CFG3_MCO1SEL_SHIFT) +#define RCC_CFG3_MCO1SEL_LSI (0x08 << RCC_CFG3_MCO1SEL_SHIFT) +#define RCC_CFG3_MCO1SEL_HSI (0x09 << RCC_CFG3_MCO1SEL_SHIFT) +#define RCC_CFG3_MCO1SEL_MSI (0x0A << RCC_CFG3_MCO1SEL_SHIFT) +#define RCC_CFG3_MCO1SEL_LSE (0x0B << RCC_CFG3_MCO1SEL_SHIFT) +#define RCC_CFG3_MCO1SEL_HSE (0x0C << RCC_CFG3_MCO1SEL_SHIFT) +#define RCC_CFG3_MCO1SEL_PLL3B (0x0D << RCC_CFG3_MCO1SEL_SHIFT) + +#define RCC_CFG3_MCO1DIV_SHIFT (24) +#define RCC_CFG3_MCO1DIV_MASK (0x0F << RCC_CFG3_MCO1DIV_SHIFT) +#define RCC_CFG3_MCO1DIV_DIV1 (0x00 << RCC_CFG3_MCO1DIV_SHIFT) +#define RCC_CFG3_MCO1DIV_DIV2 (0x01 << RCC_CFG3_MCO1DIV_SHIFT) +#define RCC_CFG3_MCO1DIV_DIV4 (0x02 << RCC_CFG3_MCO1DIV_SHIFT) +#define RCC_CFG3_MCO1DIV_DIV8 (0x04 << RCC_CFG3_MCO1DIV_SHIFT) +#define RCC_CFG3_MCO1DIV_DIV16 (0x07 << RCC_CFG3_MCO1DIV_SHIFT) +#define RCC_CFG3_MCO1DIV_DIV32 (0x08 << RCC_CFG3_MCO1DIV_SHIFT) +#define RCC_CFG3_MCO1DIV_DIV64 (0x09 << RCC_CFG3_MCO1DIV_SHIFT) +#define RCC_CFG3_MCO1DIV_DIV128 (0x0A << RCC_CFG3_MCO1DIV_SHIFT) + +/* MCO2 */ +#define RCC_CFG3_MCO2SEL_SHIFT (20) +#define RCC_CFG3_MCO2SEL_MASK (0x0F << RCC_CFG3_MCO2SEL_SHIFT) +#define RCC_CFG3_MCO2SEL_SYSCLK (0x08 << RCC_CFG3_MCO2SEL_SHIFT) +#define RCC_CFG3_MCO2SEL_PLL1A (0x09 << RCC_CFG3_MCO2SEL_SHIFT) +#define RCC_CFG3_MCO2SEL_PLL2A (0x0A << RCC_CFG3_MCO2SEL_SHIFT) +#define RCC_CFG3_MCO2SEL_PLL3A (0x0B << RCC_CFG3_MCO2SEL_SHIFT) +#define RCC_CFG3_MCO2SEL_SHRPLL (0x0C << RCC_CFG3_MCO2SEL_SHIFT) +#define RCC_CFG3_MCO2SEL_LSE (0x0D << RCC_CFG3_MCO2SEL_SHIFT) + +#define RCC_CFG3_MCO2DIV_SHIFT (16) +#define RCC_CFG3_MCO2DIV_MASK (0x0F << RCC_CFG3_MCO2DIV_SHIFT) +#define RCC_CFG3_MCO2DIV_DIV1 (0x00 << RCC_CFG3_MCO2DIV_SHIFT) +#define RCC_CFG3_MCO2DIV_DIV2 (0x01 << RCC_CFG3_MCO2DIV_SHIFT) +#define RCC_CFG3_MCO2DIV_DIV4 (0x02 << RCC_CFG3_MCO2DIV_SHIFT) +#define RCC_CFG3_MCO2DIV_DIV8 (0x04 << RCC_CFG3_MCO2DIV_SHIFT) +#define RCC_CFG3_MCO2DIV_DIV16 (0x07 << RCC_CFG3_MCO2DIV_SHIFT) +#define RCC_CFG3_MCO2DIV_DIV32 (0x08 << RCC_CFG3_MCO2DIV_SHIFT) +#define RCC_CFG3_MCO2DIV_DIV64 (0x09 << RCC_CFG3_MCO2DIV_SHIFT) +#define RCC_CFG3_MCO2DIV_DIV128 (0x0A << RCC_CFG3_MCO2DIV_SHIFT) + +/* I2S CKIN 选择 */ +#define RCC_CFG3_I2SSEL_SHIFT (14) +#define RCC_CFG3_I2SSEL_MASK (0x03 << RCC_CFG3_I2SSEL_SHIFT) +#define RCC_CFG3_I2SSEL_I2S1 (0x00 << RCC_CFG3_I2SSEL_SHIFT) +#define RCC_CFG3_I2SSEL_I2S2 (0x01 << RCC_CFG3_I2SSEL_SHIFT) +#define RCC_CFG3_I2SSEL_I2S3 (0x02 << RCC_CFG3_I2SSEL_SHIFT) +#define RCC_CFG3_I2SSEL_I2S4 (0x03 << RCC_CFG3_I2SSEL_SHIFT) + +/* 外设时钟选择 */ +#define RCC_CFG3_PERSW_SHIFT (12) +#define RCC_CFG3_PERSW_MASK (0x03 << RCC_CFG3_PERSW_SHIFT) +#define RCC_CFG3_PERSW_HSI (0x00 << RCC_CFG3_PERSW_SHIFT) +#define RCC_CFG3_PERSW_MSI (0x02 << RCC_CFG3_PERSW_SHIFT) +#define RCC_CFG3_PERSW_HSE (0x03 << RCC_CFG3_PERSW_SHIFT) + +/* M7/M4 SysTick 分频器 */ +#define RCC_CFG3_M7STCLKDIV_SHIFT (4) +#define RCC_CFG3_M7STCLKDIV_MASK (0x0F << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV1 (0x00 << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV2 (0x01 << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV4 (0x02 << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV8 (0x04 << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV16 (0x07 << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV32 (0x08 << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV64 (0x09 << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV128 (0x0A << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV256 (0x0B << RCC_CFG3_M7STCLKDIV_SHIFT) +#define RCC_CFG3_M7STCLKDIV_DIV512 (0x0C << RCC_CFG3_M7STCLKDIV_SHIFT) + +#define RCC_CFG3_M4STCLKDIV_SHIFT (0) +#define RCC_CFG3_M4STCLKDIV_MASK (0x0F << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV1 (0x00 << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV2 (0x01 << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV4 (0x02 << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV8 (0x04 << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV16 (0x07 << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV32 (0x08 << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV64 (0x09 << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV128 (0x0A << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV256 (0x0B << RCC_CFG3_M4STCLKDIV_SHIFT) +#define RCC_CFG3_M4STCLKDIV_DIV512 (0x0C << RCC_CFG3_M4STCLKDIV_SHIFT) + +/* Bit definition for RCC_CFG4 register *************************************/ + +/* 总线时钟使能位 */ +#define RCC_CFG4_AHB1CLKEN (1U << 31) +#define RCC_CFG4_AHB2CLKEN (1U << 30) +#define RCC_CFG4_AHB3CLKEN (1U << 29) +#define RCC_CFG4_AHB5CLKEN (1U << 27) +#define RCC_CFG4_AHB6CLKEN (1U << 26) +#define RCC_CFG4_AXICLKEN (1U << 23) +#define RCC_CFG4_APB1CLKEN (1U << 22) +#define RCC_CFG4_APB2CLKEN (1U << 21) +#define RCC_CFG4_APB5CLKEN (1U << 20) +#define RCC_CFG4_APB6CLKEN (1U << 19) +#define RCC_CFG4_AHB9CLKEN (1U << 18) + +/* AXI 总线矩阵 */ +#define RCC_CFG4_AXIMM7GCLKEN (1U << 17) +#define RCC_CFG4_AXIMM4GCLKEN (1U << 16) + +/* 时钟源使能位 */ +#define RCC_CFG4_HSICGEN (1U << 15) +#define RCC_CFG4_HSIKERCGEN (1U << 14) +#define RCC_CFG4_HSECGEN (1U << 13) +#define RCC_CFG4_HSEKERCGEN (1U << 12) +#define RCC_CFG4_MSICGEN (1U << 11) +#define RCC_CFG4_MSIKERCGEN (1U << 10) + +#define RCC_CFG4_RSVD (1U << 9) + +/* 子系统时钟 */ +#define RCC_CFG4_AXIMM7CLKEN (1U << 8) +#define RCC_CFG4_AXIGCLKEN (1U << 7) +#define RCC_CFG4_AXIMM4CLKEN (1U << 6) +#define RCC_CFG4_DCMUM7CLKEN (1U << 5) +#define RCC_CFG4_DCMUM4CLKEN (1U << 4) +#define RCC_CFG4_AHBM1CLKEN (1U << 3) +#define RCC_CFG4_AHBM2CLKEN (1U << 2) +#define RCC_CFG4_AHBM3CLKEN (1U << 1) +#define RCC_CFG4_DCMURST (1U << 0) + +/* Bit definition for RCC_CFG5 register *************************************/ + +/* RTC HSE 分频 */ +#define RCC_CFG5_RTCHSEDIV_SHIFT (24) +#define RCC_CFG5_RTCHSEDIV_MASK (0x3F << RCC_CFG5_RTCHSEDIV_SHIFT) +#define RCC_CFG5_RTCHSEDIV(n) ((n) << RCC_CFG5_RTCHSEDIV_SHIFT) + +/* SRAM5 */ +#define RCC_CFG5_M7SRAM5EN (1U << 23) +#define RCC_CFG5_M4SRAM5EN (1U << 22) +#define RCC_CFG5_M7SRAM5LPEN (1U << 21) +#define RCC_CFG5_M4SRAM5LPEN (1U << 20) + +/* DCD 时钟 */ +#define RCC_CFG5_DCDCLKEN (1U << 16) + +/* TRNG 配置 */ +#define RCC_CFG5_TRNGEN (1U << 13) +#define RCC_CFG5_TRNGSEL (1U << 12) + +#define RCC_CFG5_TRNGDIV_SHIFT (8) +#define RCC_CFG5_TRNGDIV_MASK (0x0F << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV1 (0x00 << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV2 (0x01 << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV4 (0x02 << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV8 (0x04 << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV16 (0x07 << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV32 (0x08 << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV64 (0x09 << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV128 (0x0A << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV256 (0x0B << RCC_CFG5_TRNGDIV_SHIFT) +#define RCC_CFG5_TRNGDIV_DIV512 (0x0C << RCC_CFG5_TRNGDIV_SHIFT) + +/* DSI HSE 分频 */ +#define RCC_CFG5_DSIHSEDIV_SHIFT (4) +#define RCC_CFG5_DSIHSEDIV_MASK (0x0F << RCC_CFG5_DSIHSEDIV_SHIFT) +#define RCC_CFG5_DSIHSEDIV1 (0x00 << RCC_CFG5_DSIHSEDIV_SHIFT) +#define RCC_CFG5_DSIHSEDIV2 (0x01 << RCC_CFG5_DSIHSEDIV_SHIFT) + +/* RTC HSI 分频 */ +#define RCC_CFG5_RTCHSIDIV_SHIFT (0) +#define RCC_CFG5_RTCHSIDIV_MASK (0x0F << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV1 (0x00 << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV2 (0x01 << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV4 (0x02 << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV8 (0x04 << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV16 (0x07 << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV32 (0x08 << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV64 (0x09 << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV128 (0x0A << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV256 (0x0B << RCC_CFG5_RTCHSIDIV_SHIFT) +#define RCC_CFG5_RTCHSIDIV_DIV512 (0x0C << RCC_CFG5_RTCHSIDIV_SHIFT) + +/* Bit definition for RCC_M4RSTREL register *********************************/ + +/* 0: CM4 in reset state;1: Release CM4 reset */ +#define RCC_M4RSTREL_EN (1U << 0) + +/* Bit definition for RCC_LSERDDL register **********************************/ + +/* 32-bit delay counter */ +#define RCC_LSERDDL_DELAY_SHIFT (0) +#define RCC_LSERDDL_DELAY_MASK (0xFFFFFFFFU << RCC_LSERDDL_DELAY_SHIFT) + +/* Bit definition for RCC_MSIRDDL register **********************************/ + +/* 32-bit delay counter */ +#define RCC_MSIRDDL_DELAY_SHIFT (0) +#define RCC_MSIRDDL_DELAY_MASK (0xFFFFFFFFU << RCC_MSIRDDL_DELAY_SHIFT) + +/* Bit definition for RCC_HSERDDL register **********************************/ + +/* 32-bit delay counter */ +#define RCC_HSERDDL_DELAY_SHIFT (0) +#define RCC_HSERDDL_DELAY_MASK (0xFFFFFFFFU << RCC_HSERDDL_DELAY_SHIFT) + +/* Bit definition for RCC_PLLSFTLK register *********************************/ + +/* [31:29] Reserved */ + +/* [28:25] SDRAM Delay Chain Select */ +#define RCC_PLLSFTLK_SDRAMDLSEL_SHIFT (25) +#define RCC_PLLSFTLK_SDRAMDLSEL_MASK (0x0F << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) + +#define RCC_PLLSFTLK_SDRAMDLSEL_0P2NS (0x0 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_0P4NS (0x1 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_0P6NS (0x2 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_0P8NS (0x3 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_1P0NS (0x4 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_1P2NS (0x5 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_1P4NS (0x6 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_1P6NS (0x7 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_1P8NS (0x8 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_2P0NS (0x9 << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_2P2NS (0xA << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_2P4NS (0xB << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_2P6NS (0xC << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_2P8NS (0xD << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_3P0NS (0xE << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) +#define RCC_PLLSFTLK_SDRAMDLSEL_3P2NS (0xF << RCC_PLLSFTLK_SDRAMDLSEL_SHIFT) + +/* [24] SDRAM Delay Chain Enable */ +#define RCC_PLLSFTLK_SDRAMDLEN (1U << 24) +/* [23:6] Reserved */ + +/* [5] SHRTIM AFE Soft Reset */ +#define RCC_PLLSFTLK_SHRTIMAFERST (1U << 5) +/* [4] Reserved */ + +/* [3] SHRPLL Software Lock */ +#define RCC_PLLSFTLK_SHRPLLSFTLK (1U << 3) +/* [2] PLL3 Software Lock */ +#define RCC_PLLSFTLK_PLL3SFTLK (1U << 2) +/* [1] PLL2 Software Lock */ +#define RCC_PLLSFTLK_PLL2SFTLK (1U << 1) +/* [0] PLL1 Software Lock */ +#define RCC_PLLSFTLK_PLL1SFTLK (1U << 0) + +/* Bit definition for RCC_HSEOS register ************************************/ + +/* [31:24] HSE Max Positive Deviation Threshold */ +#define RCC_HSEOS_HSEMAXPDTHR_SHIFT (24) +#define RCC_HSEOS_HSEMAXPDTHR_MASK (0xFFUL << RCC_HSEOS_HSEMAXPDTHR_SHIFT) + +/* [23:16] HSE Min Negative Deviation Threshold */ +#define RCC_HSEOS_HSEMINNDTHR_SHIFT (16) +#define RCC_HSEOS_HSEMINNDTHR_MASK (0xFFUL << RCC_HSEOS_HSEMINNDTHR_SHIFT) + +/* [15:8] HSE Offset Threshold for 5% Detection */ +#define RCC_HSEOS_HSEOSTHR_SHIFT (8) +#define RCC_HSEOS_HSEOSTHR_MASK (0xFFUL << RCC_HSEOS_HSEOSTHR_SHIFT) + +/* Single Frequency */ +#define RCC_HSEOS_HSEOSTHR_4MHZ (0x20UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_5MHZ (0x1AUL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_6MHZ (0x16UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_7MHZ (0x12UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_8MHZ (0x10UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_9MHZ (0x0EUL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_10MHZ (0x0DUL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_11MHZ (0x0CUL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_12MHZ (0x0BUL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_13MHZ (0x0AUL << RCC_HSEOS_HSEOSTHR_SHIFT) + +/* Range Frequency */ +#define RCC_HSEOS_HSEOSTHR_14_15MHZ (0x09UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_16_17MHZ (0x08UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_18_19MHZ (0x07UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_20_24MHZ (0x06UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_25_30MHZ (0x05UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_31_39MHZ (0x04UL << RCC_HSEOS_HSEOSTHR_SHIFT) +#define RCC_HSEOS_HSEOSTHR_40_50MHZ (0x03UL << RCC_HSEOS_HSEOSTHR_SHIFT) + +/* [7] Reserved */ + +/* [6] HSE Max Positive Deviation Flag (rc_w1) */ +#define RCC_HSEOS_HSEMAXPDF (1U << 6) +/* [5] HSE Min Negative Deviation Flag (rc_w1) */ +#define RCC_HSEOS_HSEMINNDF (1U << 5) +/* [4] HSE Offset Flag ≥5% (rc_w1) */ +#define RCC_HSEOS_HSEOSF (1U << 4) +/* [3] Reserved */ + +/* [2] HSE Max Positive Deviation Detect Enable */ +#define RCC_HSEOS_HSEMAXPDEN (1U << 2) +/* [1] HSE Min Negative Deviation Detect Enable */ +#define RCC_HSEOS_HSEMINNDEN (1U << 1) +/* [0] HSE Offset Detect Enable */ +#define RCC_HSEOS_HSEOSEN (1U << 0) + +/* Bit definition for RCC_HSECAL register ***********************************/ + +/* [31:18] Reserved */ + +/* [17] HSE Calibration Count Enable */ +#define RCC_HSECAL_HSECALCNTEN (1U << 17) + +/* [16] HSE Calibration Count Ready Flag (read-only) */ +#define RCC_HSECAL_HSECALCNTF (1U << 16) + +/* [15:0] HSE Calibration Count Value (read-only) */ +#define RCC_HSECAL_HSECALCNT_SHIFT (0) + +#define RCC_HSECAL_HSECALCNT_MASK (0xFFFFU << RCC_HSECAL_HSECALCNT_SHIFT) + +/* Bit definition for RCC_LSEOS register ************************************/ + +/* [31:26] Reserved */ + +/* [25] LSE Calibration Count Enable */ +#define RCC_LSEOS_LSECALCNTEN (1U << 25) +/* [24] LSE Calibration Count Ready Flag (read-only) */ +#define RCC_LSEOS_LSECALCNTF (1U << 24) + +/* [23:16] LSE Calibration Count Value (read-only) */ +#define RCC_LSEOS_LSECALCNT_SHIFT (16) +#define RCC_LSEOS_LSECALCNT_MASK (0xFFUL << RCC_LSEOS_LSECALCNT_SHIFT) + +/* [15:10] Reserved */ + +/* [9] LSE Offset Flag ≥10% (rc_w1) */ +#define RCC_LSEOS_LSEOSF (1U << 9) + +/* [8] LSE Offset Detect Enable */ +#define RCC_LSEOS_LSEOSEN (1U << 8) + +/* [7:0] LSE Offset Threshold for 10% Detection */ +#define RCC_LSEOS_LSEOSTHR_SHIFT (0) +#define RCC_LSEOS_LSEOSTHR_MASK (0xFFUL << RCC_LSEOS_LSEOSTHR_SHIFT) + +/* Bit definition for RCC_PLLFD register ************************************/ + +/* [31:12] Reserved */ + +/* [11] SHRPLL Clock Gate Status (read-only) */ +#define RCC_PLLFD_SHRPLLGF (1U << 11) + +/* [10] PLL3 Clock Gate Status (read-only) */ +#define RCC_PLLFD_PLL3GF (1U << 10) + +/* [9] PLL2 Clock Gate Status (read-only) */ +#define RCC_PLLFD_PLL2GF (1U << 9) + +/* [8] PLL1 Clock Gate Status (read-only) */ +#define RCC_PLLFD_PLL1GF (1U << 8) + +/* [7] SHRPLL Fail Flag (read-only) */ +#define RCC_PLLFD_SHRPLLFF (1U << 7) + +/* [6] PLL3 Fail Flag (read-only) */ +#define RCC_PLLFD_PLL3FF (1U << 6) + +/* [5] PLL2 Fail Flag (read-only) */ +#define RCC_PLLFD_PLL2FF (1U << 5) + +/* [4] PLL1 Fail Flag (read-only) */ +#define RCC_PLLFD_PLL1FF (1U << 4) + +/* [3] SHRPLL Fail Detect Enable */ +#define RCC_PLLFD_SHRPLLFEN (1U << 3) + +/* [2] PLL3 Fail Detect Enable */ +#define RCC_PLLFD_PLL3FEN (1U << 2) + +/* [1] PLL2 Fail Detect Enable */ +#define RCC_PLLFD_PLL2FEN (1U << 1) + +/* [0] PLL1 Fail Detect Enable */ +#define RCC_PLLFD_PLL1FEN (1U << 0) + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_RCC_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h76x_uart.h b/arch/arm/src/n32h7/hardware/n32h76x_uart.h new file mode 100644 index 0000000000000..7b9eb6a328888 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h76x_uart.h @@ -0,0 +1,415 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h76x_uart.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_UART_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" +#include "hardware/n32h7_memorymap.h" + +#if defined(CONFIG_N32H7_N32H76X) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define N32_USART_CTRL1_OFFSET 0x0000 /* Control register 1 */ +#define N32_USART_CTRL2_OFFSET 0x0004 /* Control register 2 */ +#define N32_USART_CTRL3_OFFSET 0x0008 /* Control register 3 */ +#define N32_USART_STS_OFFSET 0x000C /* Status register */ +#define N32_USART_DAT_OFFSET 0x0010 /* Data register */ +#define N32_USART_BRCF_OFFSET 0x0014 /* Baud Rate Configuration register */ +#define N32_USART_GTP_OFFSET 0x0018 /* Guard Time and Prescaler register */ +#define N32_USART_FIFO_OFFSET 0x001C /* FIFO Configuration register */ +#define N32_USART_IFW_OFFSET 0x0020 /* Idle Frame Width register */ +#define N32_USART_RTO_OFFSET 0x0024 /* Receiver Timeout register */ + +/* Register Addresses *******************************************************/ + +#if N32H7_NUSART > 0 +# define N32_USART1_CTRL1 (N32_USART1_BASE + N32_USART_CTRL1_OFFSET) +# define N32_USART1_CTRL2 (N32_USART1_BASE + N32_USART_CTRL2_OFFSET) +# define N32_USART1_CTRL3 (N32_USART1_BASE + N32_USART_CTRL3_OFFSET) +# define N32_USART1_STS (N32_USART1_BASE + N32_USART_STS_OFFSET) +# define N32_USART1_DAT (N32_USART1_BASE + N32_USART_DAT_OFFSET) +# define N32_USART1_BRCF (N32_USART1_BASE + N32_USART_BRCF_OFFSET) +# define N32_USART1_GTP (N32_USART1_BASE + N32_USART_GTP_OFFSET) +# define N32_USART1_FIFO (N32_USART1_BASE + N32_USART_FIFO_OFFSET) +# define N32_USART1_IFW (N32_USART1_BASE + N32_USART_IFW_OFFSET) +# define N32_USART1_RTO (N32_USART1_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUSART > 1 +# define N32_USART2_CTRL1 (N32_USART2_BASE + N32_USART_CTRL1_OFFSET) +# define N32_USART2_CTRL2 (N32_USART2_BASE + N32_USART_CTRL2_OFFSET) +# define N32_USART2_CTRL3 (N32_USART2_BASE + N32_USART_CTRL3_OFFSET) +# define N32_USART2_STS (N32_USART2_BASE + N32_USART_STS_OFFSET) +# define N32_USART2_DAT (N32_USART2_BASE + N32_USART_DAT_OFFSET) +# define N32_USART2_BRCF (N32_USART2_BASE + N32_USART_BRCF_OFFSET) +# define N32_USART2_GTP (N32_USART2_BASE + N32_USART_GTP_OFFSET) +# define N32_USART2_FIFO (N32_USART2_BASE + N32_USART_FIFO_OFFSET) +# define N32_USART2_IFW (N32_USART2_BASE + N32_USART_IFW_OFFSET) +# define N32_USART2_RTO (N32_USART2_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUSART > 2 +# define N32_USART3_CTRL1 (N32_USART3_BASE + N32_USART_CTRL1_OFFSET) +# define N32_USART3_CTRL2 (N32_USART3_BASE + N32_USART_CTRL2_OFFSET) +# define N32_USART3_CTRL3 (N32_USART3_BASE + N32_USART_CTRL3_OFFSET) +# define N32_USART3_STS (N32_USART3_BASE + N32_USART_STS_OFFSET) +# define N32_USART3_DAT (N32_USART3_BASE + N32_USART_DAT_OFFSET) +# define N32_USART3_BRCF (N32_USART3_BASE + N32_USART_BRCF_OFFSET) +# define N32_USART3_GTP (N32_USART3_BASE + N32_USART_GTP_OFFSET) +# define N32_USART3_FIFO (N32_USART3_BASE + N32_USART_FIFO_OFFSET) +# define N32_USART3_IFW (N32_USART3_BASE + N32_USART_IFW_OFFSET) +# define N32_USART3_RTO (N32_USART3_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUSART > 3 +# define N32_USART4_CTRL1 (N32_USART4_BASE + N32_USART_CTRL1_OFFSET) +# define N32_USART4_CTRL2 (N32_USART4_BASE + N32_USART_CTRL2_OFFSET) +# define N32_USART4_CTRL3 (N32_USART4_BASE + N32_USART_CTRL3_OFFSET) +# define N32_USART4_STS (N32_USART4_BASE + N32_USART_STS_OFFSET) +# define N32_USART4_DAT (N32_USART4_BASE + N32_USART_DAT_OFFSET) +# define N32_USART4_BRCF (N32_USART4_BASE + N32_USART_BRCF_OFFSET) +# define N32_USART4_GTP (N32_USART4_BASE + N32_USART_GTP_OFFSET) +# define N32_USART4_FIFO (N32_USART4_BASE + N32_USART_FIFO_OFFSET) +# define N32_USART4_IFW (N32_USART4_BASE + N32_USART_IFW_OFFSET) +# define N32_USART4_RTO (N32_USART4_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUSART > 4 +# define N32_USART5_CTRL1 (N32_USART5_BASE + N32_USART_CTRL1_OFFSET) +# define N32_USART5_CTRL2 (N32_USART5_BASE + N32_USART_CTRL2_OFFSET) +# define N32_USART5_CTRL3 (N32_USART5_BASE + N32_USART_CTRL3_OFFSET) +# define N32_USART5_STS (N32_USART5_BASE + N32_USART_STS_OFFSET) +# define N32_USART5_DAT (N32_USART5_BASE + N32_USART_DAT_OFFSET) +# define N32_USART5_BRCF (N32_USART5_BASE + N32_USART_BRCF_OFFSET) +# define N32_USART5_GTP (N32_USART5_BASE + N32_USART_GTP_OFFSET) +# define N32_USART5_FIFO (N32_USART5_BASE + N32_USART_FIFO_OFFSET) +# define N32_USART5_IFW (N32_USART5_BASE + N32_USART_IFW_OFFSET) +# define N32_USART5_RTO (N32_USART5_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUSART > 5 +# define N32_USART6_CTRL1 (N32_USART6_BASE + N32_USART_CTRL1_OFFSET) +# define N32_USART6_CTRL2 (N32_USART6_BASE + N32_USART_CTRL2_OFFSET) +# define N32_USART6_CTRL3 (N32_USART6_BASE + N32_USART_CTRL3_OFFSET) +# define N32_USART6_STS (N32_USART6_BASE + N32_USART_STS_OFFSET) +# define N32_USART6_DAT (N32_USART6_BASE + N32_USART_DAT_OFFSET) +# define N32_USART6_BRCF (N32_USART6_BASE + N32_USART_BRCF_OFFSET) +# define N32_USART6_GTP (N32_USART6_BASE + N32_USART_GTP_OFFSET) +# define N32_USART6_FIFO (N32_USART6_BASE + N32_USART_FIFO_OFFSET) +# define N32_USART6_IFW (N32_USART6_BASE + N32_USART_IFW_OFFSET) +# define N32_USART6_RTO (N32_USART6_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUSART > 6 +# define N32_USART7_CTRL1 (N32_USART7_BASE + N32_USART_CTRL1_OFFSET) +# define N32_USART7_CTRL2 (N32_USART7_BASE + N32_USART_CTRL2_OFFSET) +# define N32_USART7_CTRL3 (N32_USART7_BASE + N32_USART_CTRL3_OFFSET) +# define N32_USART7_STS (N32_USART7_BASE + N32_USART_STS_OFFSET) +# define N32_USART7_DAT (N32_USART7_BASE + N32_USART_DAT_OFFSET) +# define N32_USART7_BRCF (N32_USART7_BASE + N32_USART_BRCF_OFFSET) +# define N32_USART7_GTP (N32_USART7_BASE + N32_USART_GTP_OFFSET) +# define N32_USART7_FIFO (N32_USART7_BASE + N32_USART_FIFO_OFFSET) +# define N32_USART7_IFW (N32_USART7_BASE + N32_USART_IFW_OFFSET) +# define N32_USART7_RTO (N32_USART7_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUSART > 7 +# define N32_USART8_CTRL1 (N32_USART8_BASE + N32_USART_CTRL1_OFFSET) +# define N32_USART8_CTRL2 (N32_USART8_BASE + N32_USART_CTRL2_OFFSET) +# define N32_USART8_CTRL3 (N32_USART8_BASE + N32_USART_CTRL3_OFFSET) +# define N32_USART8_STS (N32_USART8_BASE + N32_USART_STS_OFFSET) +# define N32_USART8_DAT (N32_USART8_BASE + N32_USART_DAT_OFFSET) +# define N32_USART8_BRCF (N32_USART8_BASE + N32_USART_BRCF_OFFSET) +# define N32_USART8_GTP (N32_USART8_BASE + N32_USART_GTP_OFFSET) +# define N32_USART8_FIFO (N32_USART8_BASE + N32_USART_FIFO_OFFSET) +# define N32_USART8_IFW (N32_USART8_BASE + N32_USART_IFW_OFFSET) +# define N32_USART8_RTO (N32_USART8_BASE + N32_USART_RTO_OFFSET) +#endif + +/* UART Modules (e.g., UART9, UART10) */ + +#if N32H7_NUART > 0 +# define N32_UART9_CTRL1 (N32_UART9_BASE + N32_USART_CTRL1_OFFSET) +# define N32_UART9_CTRL2 (N32_UART9_BASE + N32_USART_CTRL2_OFFSET) +# define N32_UART9_CTRL3 (N32_UART9_BASE + N32_USART_CTRL3_OFFSET) +# define N32_UART9_STS (N32_UART9_BASE + N32_USART_STS_OFFSET) +# define N32_UART9_DAT (N32_UART9_BASE + N32_USART_DAT_OFFSET) +# define N32_UART9_BRCF (N32_UART9_BASE + N32_USART_BRCF_OFFSET) +# define N32_UART9_GTP (N32_UART9_BASE + N32_USART_GTP_OFFSET) +# define N32_UART9_FIFO (N32_UART9_BASE + N32_USART_FIFO_OFFSET) +# define N32_UART9_IFW (N32_UART9_BASE + N32_USART_IFW_OFFSET) +# define N32_UART9_RTO (N32_UART9_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUART > 1 +# define N32_UART10_CTRL1 (N32_UART10_BASE + N32_USART_CTRL1_OFFSET) +# define N32_UART10_CTRL2 (N32_UART10_BASE + N32_USART_CTRL2_OFFSET) +# define N32_UART10_CTRL3 (N32_UART10_BASE + N32_USART_CTRL3_OFFSET) +# define N32_UART10_STS (N32_UART10_BASE + N32_USART_STS_OFFSET) +# define N32_UART10_DAT (N32_UART10_BASE + N32_USART_DAT_OFFSET) +# define N32_UART10_BRCF (N32_UART10_BASE + N32_USART_BRCF_OFFSET) +# define N32_UART10_GTP (N32_UART10_BASE + N32_USART_GTP_OFFSET) +# define N32_UART10_FIFO (N32_UART10_BASE + N32_USART_FIFO_OFFSET) +# define N32_UART10_IFW (N32_UART10_BASE + N32_USART_IFW_OFFSET) +# define N32_UART10_RTO (N32_UART10_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUART > 2 +# define N32_UART11_CTRL1 (N32_UART11_BASE + N32_USART_CTRL1_OFFSET) +# define N32_UART11_CTRL2 (N32_UART11_BASE + N32_USART_CTRL2_OFFSET) +# define N32_UART11_CTRL3 (N32_UART11_BASE + N32_USART_CTRL3_OFFSET) +# define N32_UART11_STS (N32_UART11_BASE + N32_USART_STS_OFFSET) +# define N32_UART11_DAT (N32_UART11_BASE + N32_USART_DAT_OFFSET) +# define N32_UART11_BRCF (N32_UART11_BASE + N32_USART_BRCF_OFFSET) +# define N32_UART11_GTP (N32_UART11_BASE + N32_USART_GTP_OFFSET) +# define N32_UART11_FIFO (N32_UART11_BASE + N32_USART_FIFO_OFFSET) +# define N32_UART11_IFW (N32_UART11_BASE + N32_USART_IFW_OFFSET) +# define N32_UART11_RTO (N32_UART11_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUART > 3 +# define N32_UART12_CTRL1 (N32_UART12_BASE + N32_USART_CTRL1_OFFSET) +# define N32_UART12_CTRL2 (N32_UART12_BASE + N32_USART_CTRL2_OFFSET) +# define N32_UART12_CTRL3 (N32_UART12_BASE + N32_USART_CTRL3_OFFSET) +# define N32_UART12_STS (N32_UART12_BASE + N32_USART_STS_OFFSET) +# define N32_UART12_DAT (N32_UART12_BASE + N32_USART_DAT_OFFSET) +# define N32_UART12_BRCF (N32_UART12_BASE + N32_USART_BRCF_OFFSET) +# define N32_UART12_GTP (N32_UART12_BASE + N32_USART_GTP_OFFSET) +# define N32_UART12_FIFO (N32_UART12_BASE + N32_USART_FIFO_OFFSET) +# define N32_UART12_IFW (N32_UART12_BASE + N32_USART_IFW_OFFSET) +# define N32_UART12_RTO (N32_UART12_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUART > 4 +# define N32_UART13_CTRL1 (N32_UART13_BASE + N32_USART_CTRL1_OFFSET) +# define N32_UART13_CTRL2 (N32_UART13_BASE + N32_USART_CTRL2_OFFSET) +# define N32_UART13_CTRL3 (N32_UART13_BASE + N32_USART_CTRL3_OFFSET) +# define N32_UART13_STS (N32_UART13_BASE + N32_USART_STS_OFFSET) +# define N32_UART13_DAT (N32_UART13_BASE + N32_USART_DAT_OFFSET) +# define N32_UART13_BRCF (N32_UART13_BASE + N32_USART_BRCF_OFFSET) +# define N32_UART13_GTP (N32_UART13_BASE + N32_USART_GTP_OFFSET) +# define N32_UART13_FIFO (N32_UART13_BASE + N32_USART_FIFO_OFFSET) +# define N32_UART13_IFW (N32_UART13_BASE + N32_USART_IFW_OFFSET) +# define N32_UART13_RTO (N32_UART13_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUART > 5 +# define N32_UART14_CTRL1 (N32_UART14_BASE + N32_USART_CTRL1_OFFSET) +# define N32_UART14_CTRL2 (N32_UART14_BASE + N32_USART_CTRL2_OFFSET) +# define N32_UART14_CTRL3 (N32_UART14_BASE + N32_USART_CTRL3_OFFSET) +# define N32_UART14_STS (N32_UART14_BASE + N32_USART_STS_OFFSET) +# define N32_UART14_DAT (N32_UART14_BASE + N32_USART_DAT_OFFSET) +# define N32_UART14_BRCF (N32_UART14_BASE + N32_USART_BRCF_OFFSET) +# define N32_UART14_GTP (N32_UART14_BASE + N32_USART_GTP_OFFSET) +# define N32_UART14_FIFO (N32_UART14_BASE + N32_USART_FIFO_OFFSET) +# define N32_UART14_IFW (N32_UART14_BASE + N32_USART_IFW_OFFSET) +# define N32_UART14_RTO (N32_UART14_BASE + N32_USART_RTO_OFFSET) +#endif + +#if N32H7_NUART > 6 +# define N32_UART15_CTRL1 (N32_UART15_BASE + N32_USART_CTRL1_OFFSET) +# define N32_UART15_CTRL2 (N32_UART15_BASE + N32_USART_CTRL2_OFFSET) +# define N32_UART15_CTRL3 (N32_UART15_BASE + N32_USART_CTRL3_OFFSET) +# define N32_UART15_STS (N32_UART15_BASE + N32_USART_STS_OFFSET) +# define N32_UART15_DAT (N32_UART15_BASE + N32_USART_DAT_OFFSET) +# define N32_UART15_BRCF (N32_UART15_BASE + N32_USART_BRCF_OFFSET) +# define N32_UART15_GTP (N32_UART15_BASE + N32_USART_GTP_OFFSET) +# define N32_UART15_FIFO (N32_UART15_BASE + N32_USART_FIFO_OFFSET) +# define N32_UART15_IFW (N32_UART15_BASE + N32_USART_IFW_OFFSET) +# define N32_UART15_RTO (N32_UART15_BASE + N32_USART_RTO_OFFSET) +#endif + +/* Register Bitfield Definitions ********************************************/ + +/* USART Control Register 1 (USART_CTRL1) */ +#define USART_CTRL1_UEN (1 << 0) /* Bit 0: USART enable */ +#define USART_CTRL1_RXEN (1 << 1) /* Bit 1: Receiver enable */ +#define USART_CTRL1_TXEN (1 << 2) /* Bit 2: Transmitter enable */ +#define USART_CTRL1_PSEL (1 << 3) /* Bit 3: Parity selection */ +#define USART_CTRL1_PCEN (1 << 4) /* Bit 4: Parity control enable */ +#define USART_CTRL1_WL (1 << 5) /* Bit 5: Word length */ +#define USART_CTRL1_RCVWU (1 << 6) /* Bit 6: Receiver wakeup control */ +#define USART_CTRL1_WUM (1 << 7) /* Bit 7: Wakeup mode */ +#define USART_CTRL1_IDLEIEN (1 << 8) /* Bit 8: IDLE interrupt enable */ +#define USART_CTRL1_RXDNEIEN (1 << 9) /* Bit 9: RXDNE interrupt enable */ +#define USART_CTRL1_TXDEIEN (1 << 10) /* Bit 10: TXDE interrupt enable */ +#define USART_CTRL1_TXCIEN (1 << 11) /* Bit 11: TXC interrupt enable */ +#define USART_CTRL1_PEIEN (1 << 12) /* Bit 12: PE interrupt enable */ +#define USART_CTRL1_SDBRK (1 << 13) /* Bit 13: Send break character */ +#define USART_CTRL1_DEM (1 << 14) /* Bit 14: Driver enable mode */ +#define USART_CTRL1_DEP (1 << 15) /* Bit 15: Driver enable polarity */ +#define USART_CTRL1_DEDT_SHIFT (16) /* Bits 16-20: Driver deassertion time */ +#define USART_CTRL1_DEDT_MASK (0x1F << USART_CTRL1_DEDT_SHIFT) +#define USART_CTRL1_DEDT(n) ((n) << USART_CTRL1_DEDT_SHIFT) + +#define USART_CTRL1_ALLINTS (USART_CTRL1_IDLEIEN|USART_CTRL1_RXDNEIEN| \ + USART_CTRL1_TXDEIEN|USART_CTRL1_TXCIEN| \ + USART_CTRL1_PEIEN) + +#define USART_CTRL1_DEAT_SHIFT (21) /* Bits 21-25: Driver assertion time */ +#define USART_CTRL1_DEAT_MASK (0x1F << USART_CTRL1_DEAT_SHIFT) +#define USART_CTRL1_DEAT(n) ((n) << USART_CTRL1_DEAT_SHIFT) + +#define USART_CTRL1_OSPM (1 << 26) /* Bit 26: Oversampling mode */ +#define USART_CTRL1_SWAP (1 << 27) /* Bit 27: TX/RX pins swap */ +#define USART_CTRL1_IFCEN (1 << 28) /* Bit 28: Idle frame controllable */ + +/* USART Control Register 2 (USART_CTRL2) */ +#define USART_CTRL2_ADDR_SHIFT (0) /* Bits 0-3: USART address */ +#define USART_CTRL2_ADDR_MASK (0xF << USART_CTRL2_ADDR_SHIFT) +#define USART_CTRL2_ADDR(n) ((n) << USART_CTRL2_ADDR_SHIFT) + +#define USART_CTRL2_STPB_SHIFT (5) /* Bits 5-6: STOP bits */ +#define USART_CTRL2_STPB_MASK (0x3 << USART_CTRL2_STPB_SHIFT) +#define USART_CTRL2_STPB(n) ((n) << USART_CTRL2_STPB_SHIFT) + +#define USART_CTRL2_CLKEN (1 << 8) /* Bit 8: Clock enable */ +#define USART_CTRL2_CLKPOL (1 << 9) /* Bit 9: Clock polarity */ +#define USART_CTRL2_CLKPHA (1 << 10) /* Bit 10: Clock phase */ +#define USART_CTRL2_LBCLK (1 << 11) /* Bit 11: Last bit clock pulse */ +#define USART_CTRL2_LINMEN (1 << 12) /* Bit 12: LIN mode enable */ +#define USART_CTRL2_LINBDIEN (1 << 13) /* Bit 13: LIN break detect intr */ +#define USART_CTRL2_LINBDL (1 << 14) /* Bit 14: LIN break detect len */ +#define USART_CTRL2_RTOEN (1 << 15) /* Bit 15: Receiver timeout en */ +#define USART_CTRL2_RTOCF (1 << 16) /* Bit 16: Receiver timeout clear */ +#define USART_CTRL2_RTOIEN (1 << 17) /* Bit 17: RTO interrupt enable */ +#define USART_CTRL2_PEFLOSE (1 << 18) /* Bit 18: PEF discard enable */ +#define USART_CTRL2_NEFLOSE (1 << 19) /* Bit 19: NEF discard enable */ +#define USART_CTRL2_FEFLOSE (1 << 20) /* Bit 20: FEF discard enable */ + +#define USART_CTRL2_ALLINTS (USART_CTRL2_RTOIEN) + +/* USART Control Register 3 (USART_CTRL3) */ +#define USART_CTRL3_CTSEN (1 << 0) /* Bit 0: CTS enable */ +#define USART_CTRL3_CTSIEN (1 << 1) /* Bit 1: CTS interrupt enable */ +#define USART_CTRL3_RTSEN (1 << 2) /* Bit 2: RTS enable */ +#define USART_CTRL3_HDMEN (1 << 3) /* Bit 3: Half-duplex mode en */ +#define USART_CTRL3_DMATXEN (1 << 4) /* Bit 4: DMA transmitter en */ +#define USART_CTRL3_DMARXEN (1 << 5) /* Bit 5: DMA receiver enable */ +#define USART_CTRL3_ERRIEN (1 << 6) /* Bit 6: Error interrupt en */ +#define USART_CTRL3_IRDAMEN (1 << 7) /* Bit 7: IrDA mode enable */ +#define USART_CTRL3_IRDALP (1 << 8) /* Bit 8: IrDA low-power mode */ +#define USART_CTRL3_SCMEN (1 << 9) /* Bit 9: Smartcard mode en */ +#define USART_CTRL3_SCNACK (1 << 10) /* Bit 10: Smartcard NACK en */ + +#define USART_CTRL3_ALLINTS (USART_CTRL3_CTSIEN|USART_CTRL3_ERRIEN) + +/* USART Status Register (USART_STS) */ +#define USART_STS_TXFF (1 << 0) /* Bit 0: TX FIFO full */ +#define USART_STS_RXFF (1 << 1) /* Bit 1: RX FIFO full */ +#define USART_STS_TXFE (1 << 2) /* Bit 2: TX FIFO empty */ +#define USART_STS_RXFE (1 << 3) /* Bit 3: RX FIFO empty */ +#define USART_STS_RXFT (1 << 4) /* Bit 4: RX FIFO threshold */ +#define USART_STS_TXFT (1 << 5) /* Bit 5: TX FIFO threshold */ +#define USART_STS_IDLEF (1 << 6) /* Bit 6: IDLE line detected */ +#define USART_STS_TXDE (1 << 7) /* Bit 7: TX data empty */ +#define USART_STS_TXC (1 << 8) /* Bit 8: Transmission complete */ +#define USART_STS_RXDNE (1 << 9) /* Bit 9: RX data not empty */ +#define USART_STS_CTSF (1 << 10) /* Bit 10: CTS flag */ +#define USART_STS_LINBDF (1 << 11) /* Bit 11: LIN break detect */ +#define USART_STS_PEF (1 << 12) /* Bit 12: Parity error */ +#define USART_STS_OREF (1 << 13) /* Bit 13: Overrun error */ +#define USART_STS_NEF (1 << 14) /* Bit 14: Noise error */ +#define USART_STS_FEF (1 << 15) /* Bit 15: Framing error */ +#define USART_STS_RTOF (1 << 16) /* Bit 16: Receiver timeout */ +#define USART_STS_PELOSEF (1 << 17) /* Bit 17: PE discard flag */ +#define USART_STS_NEELOSEF (1 << 18) /* Bit 18: NE discard flag */ +#define USART_STS_FEELOSEF (1 << 19) /* Bit 19: FE discard flag */ + +/* USART Data Register (USART_DAT) */ +#define USART_DAT_DATV_SHIFT (0) /* Bits 0-8: Data value */ +#define USART_DAT_DATV_MASK (0x1FF << USART_DAT_DATV_SHIFT) + +/* USART Baud Rate Register (USART_BRCF) */ +#define USART_BRCF_DIVDEC_SHIFT (0) /* Bits 0-3: Fractional divider */ +#define USART_BRCF_DIVDEC_MASK (0xF << USART_BRCF_DIVDEC_SHIFT) +#define USART_BRCF_DIVDEC(n) ((n) << USART_BRCF_DIVDEC_SHIFT) +#define USART_BRCF_DIVINT_SHIFT (4) /* Bits 4-15: Integer divider */ +#define USART_BRCF_DIVINT_MASK (0xFFF << USART_BRCF_DIVINT_SHIFT) +#define USART_BRCF_DIVINT(n) ((n) << USART_BRCF_DIVINT_SHIFT) + +/* USART Guard Time Register (USART_GTP) */ +#define USART_GTP_PSCV_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTP_PSCV_MASK (0xFF << USART_GTP_PSCV_SHIFT) +#define USART_GTP_PSCV(n) ((n) << USART_GTP_PSCV_SHIFT) +#define USART_GTP_GTV_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTP_GTV_MASK (0xFF << USART_GTP_GTV_SHIFT) +#define USART_GTP_GTV(n) ((n) << USART_GTP_GTV_SHIFT) + +/* USART FIFO Register (USART_FIFO) */ +#define USART_FIFO_EN (1 << 0) /* Bit 0: FIFO enable */ +#define USART_FIFO_CLR (1 << 1) /* Bit 1: FIFO clear */ + +#define USART_FIFO_TXFTCFG_SHIFT (2) /* Bits 2-4: TX FIFO threshold */ +#define USART_FIFO_TXFTCFG_MASK (0x7 << USART_FIFO_TXFTCFG_SHIFT) +#define USART_FIFO_TXFT_1_8 (0x0 << USART_FIFO_TXFTCFG_SHIFT) /* 000: 1/8 full */ +#define USART_FIFO_TXFT_2_8 (0x1 << USART_FIFO_TXFTCFG_SHIFT) /* 001: 2/8 full */ +#define USART_FIFO_TXFT_4_8 (0x2 << USART_FIFO_TXFTCFG_SHIFT) /* 010: 4/8 full */ +#define USART_FIFO_TXFT_6_8 (0x3 << USART_FIFO_TXFTCFG_SHIFT) /* 011: 6/8 full */ +#define USART_FIFO_TXFT_7_8 (0x4 << USART_FIFO_TXFTCFG_SHIFT) /* 100: 7/8 full */ +#define USART_FIFO_TXFT_FULL (0x5 << USART_FIFO_TXFTCFG_SHIFT) /* 101: Full */ + +#define USART_FIFO_RXFTCFG_SHIFT (5) /* Bits 5-7: RX FIFO threshold */ +#define USART_FIFO_RXFTCFG_MASK (0x7 << USART_FIFO_RXFTCFG_SHIFT) +#define USART_FIFO_RXFT_1_8 (0x0 << USART_FIFO_RXFTCFG_SHIFT) /* 000: 1/8 full */ +#define USART_FIFO_RXFT_2_8 (0x1 << USART_FIFO_RXFTCFG_SHIFT) /* 001: 2/8 full */ +#define USART_FIFO_RXFT_4_8 (0x2 << USART_FIFO_RXFTCFG_SHIFT) /* 010: 4/8 full */ +#define USART_FIFO_RXFT_6_8 (0x3 << USART_FIFO_RXFTCFG_SHIFT) /* 011: 6/8 full */ +#define USART_FIFO_RXFT_7_8 (0x4 << USART_FIFO_RXFTCFG_SHIFT) /* 100: 7/8 full */ +#define USART_FIFO_RXFT_FULL (0x5 << USART_FIFO_RXFTCFG_SHIFT) /* 101: Full */ + +#define USART_FIFO_TXFFIEN (1 << 8) /* Bit 8: TX FIFO full intr en */ +#define USART_FIFO_RXFFIEN (1 << 9) /* Bit 9: RX FIFO full intr en */ +#define USART_FIFO_TXFEIEN (1 << 10) /* Bit 10: TX FIFO empty intr en */ +#define USART_FIFO_RXFEIEN (1 << 11) /* Bit 11: RX FIFO empty intr en */ +#define USART_FIFO_RXFTIEN (1 << 12) /* Bit 12: RX FIFO thres intr en */ +#define USART_FIFO_TXFTIEN (1 << 13) /* Bit 13: TX FIFO thres intr en */ + +#define USART_FIFO_RXCNT_SHIFT (14) /* Bits 14-17: RX FIFO count */ +#define USART_FIFO_RXCNT_MASK (0xF << USART_FIFO_RXCNT_SHIFT) +#define USART_FIFO_GET_RXCNT(n) ((n) >> USART_FIFO_RXCNT_SHIFT) + +#define USART_FIFO_TXCNT_SHIFT (18) /* Bits 18-21: TX FIFO count */ +#define USART_FIFO_TXCNT_MASK (0xF << USART_FIFO_TXCNT_SHIFT) +#define USART_FIFO_GET_TXCNT(n) ((n) >> USART_FIFO_TXCNT_SHIFT) + +/* USART Idle Frame Width Register (USART_IFW) */ +#define USART_IFW_WIDTH_SHIFT (0) /* Bits 0-15: Idle frame width */ +#define USART_IFW_WIDTH_MASK (0xFFFF << USART_IFW_WIDTH_SHIFT) + +/* USART Timeout Register (USART_RTO) */ +#define USART_RTO_TIME_SHIFT (0) /* Bits 0-27: Timeout value */ +#define USART_RTO_TIME_MASK (0xFFFFFFF << USART_RTO_TIME_SHIFT) + +#endif /* CONFIG_N32H7_N32H76X */ +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H76X_UART_H */ \ No newline at end of file diff --git a/arch/arm/src/n32h7/hardware/n32h7_afio.h b/arch/arm/src/n32h7/hardware/n32h7_afio.h new file mode 100644 index 0000000000000..aaa18538df355 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_afio.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_afio.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32_AFIO_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32_AFIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_N32H7_N32H76X) +# include "hardware/n32h76x_afio.h" +#else +# error "Unsupported N32 H7 part" +#endif + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32_AFIO_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_cordic.h b/arch/arm/src/n32h7/hardware/n32h7_cordic.h new file mode 100644 index 0000000000000..d8da28cae4b38 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_cordic.h @@ -0,0 +1,85 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_cordic.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_CORDIC_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_CORDIC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define N32_CORDIC_CTRLSTS_OFFSET 0x0000 /* Control/status register */ +#define N32_CORDIC_WDATA_OFFSET 0x0004 /* Write data register */ +#define N32_CORDIC_RDATA_OFFSET 0x0008 /* Read data register */ + +/* Register Addresses (assuming N32_CORDIC_BASE defined in chip.h) **********/ + +#define N32_CORDIC_CTRLSTS (N32_CORDIC_BASE + N32_CORDIC_CTRLSTS_OFFSET) +#define N32_CORDIC_WDATA (N32_CORDIC_BASE + N32_CORDIC_WDATA_OFFSET) +#define N32_CORDIC_RDATA (N32_CORDIC_BASE + N32_CORDIC_RDATA_OFFSET) + +/* CTRLSTS Bitfield Definitions *********************************************/ + +#define CORDIC_CTRLSTS_FUNC_SHIFT 0 +#define CORDIC_CTRLSTS_FUNC_MASK (0xf << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_COS (0 << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_SIN (1 << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_PHASE (2 << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_MODULUS (3 << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_ARCTAN (4 << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_HB_COS (5 << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_HB_SIN (6 << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_HB_ARCT (7 << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_NATL (8 << CORDIC_CTRLSTS_FUNC_SHIFT) +# define CORDIC_CTRLSTS_FUNC_SQRT (9 << CORDIC_CTRLSTS_FUNC_SHIFT) + +#define CORDIC_CTRLSTS_PRECISION_SHIFT 4 +#define CORDIC_CTRLSTS_PRECISION_MASK (0xf << CORDIC_CTRLSTS_PRECISION_SHIFT) + +#define CORDIC_CTRLSTS_SCALE_SHIFT 8 +#define CORDIC_CTRLSTS_SCALE_MASK (0x7 << CORDIC_CTRLSTS_SCALE_SHIFT) + +#define CORDIC_CTRLSTS_INTEN (1 << 16) /* Interrupt enable */ +#define CORDIC_CTRLSTS_DMAREN (1 << 17) /* DMA read enable */ +#define CORDIC_CTRLSTS_DMAWEN (1 << 18) /* DMA write enable */ +#define CORDIC_CTRLSTS_NUMREAD (1 << 19) /* Number of results (1 = two, 0 = one) */ +#define CORDIC_CTRLSTS_NUMWRITE (1 << 20) /* Number of arguments (1 = two, 0 = one) */ +#define CORDIC_CTRLSTS_OUTSIZE (1 << 21) /* Output width: 0=32bit, 1=16bit */ +#define CORDIC_CTRLSTS_INSIZE (1 << 22) /* Input width: 0=32bit, 1=16bit */ +#define CORDIC_CTRLSTS_FLOATIN (1 << 23) /* Float input enable */ +#define CORDIC_CTRLSTS_FLOATOUT (1 << 24) /* Float output enable */ +#define CORDIC_CTRLSTS_PHASELIMIT (1 << 25) /* Phase limit enable */ +#define CORDIC_CTRLSTS_CODINLIMIT (1 << 26) /* Coordinate limit enable */ +#define CORDIC_CTRLSTS_INOVINTEN (1 << 27) /* Input overflow interrupt enable */ +#define CORDIC_CTRLSTS_INOVF (1 << 30) /* Input overflow flag (write 1 to clear) */ +#define CORDIC_CTRLSTS_RRF (1 << 31) /* Result ready flag */ + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_CORDIC_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_dma.h b/arch/arm/src/n32h7/hardware/n32h7_dma.h new file mode 100644 index 0000000000000..dafe25966bc08 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_dma.h @@ -0,0 +1,512 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_dma.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_DMA_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_DMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#include "n32h7_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* 3 DMA controllers + 1 MDMA */ + +#define MDMA (0) +#define DMA1 (1) +#define DMA2 (2) +#define DMA3 (3) + +/* 8 DMA channels for standard DMA */ + +#define DMA_CH0 (0) +#define DMA_CH1 (1) +#define DMA_CH2 (2) +#define DMA_CH3 (3) +#define DMA_CH4 (4) +#define DMA_CH5 (5) +#define DMA_CH6 (6) +#define DMA_CH7 (7) + +/* ========================================================================== + * Channel Register Offset(Each channel 0x58 bytes per channel) + * ========================================================================== + */ +#define N32_DMA_CH_OFFSET(n) (0x58U * (n)) + +#define N32_DMA_CH_SA_OFFSET 0x0000U /* Source Address */ +#define N32_DMA_CH_DA_OFFSET 0x0008U /* Destination Address */ +#define N32_DMA_CH_LLP_OFFSET 0x0010U /* Linked List Pointer */ +#define N32_DMA_CH_CTRL_OFFSET 0x0018U /* Control Register */ +#define N32_DMA_CH_CFG_OFFSET 0x0040U /* Configuration Register */ +#define N32_DMA_CH_SG_OFFSET 0x0048U /* Source Gather */ +#define N32_DMA_CH_DS_OFFSET 0x0050U /* Destination Scatter */ + +/* ========================================================================== + * Global Interrupt Register Offset + * ========================================================================== + */ +#define N32_DMA_RAWTCINTSTS_OFFSET 0x02C0U +#define N32_DMA_RAWBTCINTSTS_OFFSET 0x02C8U +#define N32_DMA_RAWSTCINTSTS_OFFSET 0x02D0U +#define N32_DMA_RAWDTCINTSTS_OFFSET 0x02D8U +#define N32_DMA_RAWERRINTSTS_OFFSET 0x02E0U + +#define N32_DMA_TCINTSTS_OFFSET 0x02E8U +#define N32_DMA_BTCINTSTS_OFFSET 0x02F0U +#define N32_DMA_STCINTSTS_OFFSET 0x02F8U +#define N32_DMA_DTCINTSTS_OFFSET 0x0300U +#define N32_DMA_ERRINTSTS_OFFSET 0x0308U + +#define N32_DMA_TCINTMSK_OFFSET 0x0310U +#define N32_DMA_BTCINTMSK_OFFSET 0x0318U +#define N32_DMA_STCINTMSK_OFFSET 0x0320U +#define N32_DMA_DTCINTMSK_OFFSET 0x0328U +#define N32_DMA_ERRINTMSK_OFFSET 0x0330U + +#define N32_DMA_TCINTCLR_OFFSET 0x0338U +#define N32_DMA_BTCINTCLR_OFFSET 0x0340U +#define N32_DMA_STCINTCLR_OFFSET 0x0348U +#define N32_DMA_DTCINTCLR_OFFSET 0x0350U +#define N32_DMA_ERRINTCLR_OFFSET 0x0358U + +#define N32_DMA_INTCBESTS_OFFSET 0x0360U + +/* ========================================================================== + * Software Handshake Register Offset + * ========================================================================== + */ +#define N32_DMA_SRCSWTREQ_OFFSET 0x0368U +#define N32_DMA_DSTSWTREQ_OFFSET 0x0370U +#define N32_DMA_SRCSGTREQ_OFFSET 0x0378U +#define N32_DMA_DSTSGTREQ_OFFSET 0x0380U +#define N32_DMA_SRCLTREQ_OFFSET 0x0388U +#define N32_DMA_DSTLTREQ_OFFSET 0x0390U + +/* ========================================================================== + * DMA Miscellaneous Register Offset + * ========================================================================== + */ +#define N32_DMA_CFG_OFFSET 0x0398U /* DMA Configuration Register */ +#define N32_DMA_CHEN_OFFSET 0x03A0U /* DMA Channel Enable Register */ +#define N32_DMA_ID_OFFSET 0x03A8U /* DMA ID Register */ +#define N32_DMA_TEST_OFFSET 0x03B0U /* DMA Test Register */ +#define N32_DMA_LPTIMEOUT_OFFSET 0x03B8U /* DMA Low Power Timeout Register */ +#define N32_DMA_COMPID_OFFSET 0x03F8U /* DMA Component ID Register */ + +/* ========================================================================== + * Channel Register Address Macro Definitions + * ========================================================================== + */ +#define N32_DMA1_CH_SA(n) (N32_DMA1_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_SA_OFFSET) +#define N32_DMA1_CH_DA(n) (N32_DMA1_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_DA_OFFSET) +#define N32_DMA1_CH_LLP(n) (N32_DMA1_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_LLP_OFFSET) +#define N32_DMA1_CH_CTRL(n) (N32_DMA1_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_CTRL_OFFSET) +#define N32_DMA1_CH_CFG(n) (N32_DMA1_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_CFG_OFFSET) +#define N32_DMA1_CH_SG(n) (N32_DMA1_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_SG_OFFSET) +#define N32_DMA1_CH_DS(n) (N32_DMA1_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_DS_OFFSET) + +#define N32_DMA2_CH_SA(n) (N32_DMA2_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_SA_OFFSET) +#define N32_DMA2_CH_DA(n) (N32_DMA2_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_DA_OFFSET) +#define N32_DMA2_CH_LLP(n) (N32_DMA2_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_LLP_OFFSET) +#define N32_DMA2_CH_CTRL(n) (N32_DMA2_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_CTRL_OFFSET) +#define N32_DMA2_CH_CFG(n) (N32_DMA2_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_CFG_OFFSET) +#define N32_DMA2_CH_SG(n) (N32_DMA2_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_SG_OFFSET) +#define N32_DMA2_CH_DS(n) (N32_DMA2_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_DS_OFFSET) + +#define N32_DMA3_CH_SA(n) (N32_DMA3_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_SA_OFFSET) +#define N32_DMA3_CH_DA(n) (N32_DMA3_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_DA_OFFSET) +#define N32_DMA3_CH_LLP(n) (N32_DMA3_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_LLP_OFFSET) +#define N32_DMA3_CH_CTRL(n) (N32_DMA3_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_CTRL_OFFSET) +#define N32_DMA3_CH_CFG(n) (N32_DMA3_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_CFG_OFFSET) +#define N32_DMA3_CH_SG(n) (N32_DMA3_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_SG_OFFSET) +#define N32_DMA3_CH_DS(n) (N32_DMA3_BASE + N32_DMA_CH_OFFSET(n) + N32_DMA_CH_DS_OFFSET) + +/* ========================================================================== + * Global Interrupt Register Offset + * ========================================================================== + */ +#define N32_DMA1_RAWTCINTSTS (N32_DMA1_BASE + N32_DMA_RAWTCINTSTS_OFFSET) +#define N32_DMA1_TCINTSTS (N32_DMA1_BASE + N32_DMA_TCINTSTS_OFFSET) +#define N32_DMA1_TCINTMSK (N32_DMA1_BASE + N32_DMA_TCINTMSK_OFFSET) +#define N32_DMA1_TCINTCLR (N32_DMA1_BASE + N32_DMA_TCINTCLR_OFFSET) + +#define N32_DMA2_RAWTCINTSTS (N32_DMA2_BASE + N32_DMA_RAWTCINTSTS_OFFSET) +#define N32_DMA2_TCINTSTS (N32_DMA2_BASE + N32_DMA_TCINTSTS_OFFSET) +#define N32_DMA2_TCINTMSK (N32_DMA2_BASE + N32_DMA_TCINTMSK_OFFSET) +#define N32_DMA2_TCINTCLR (N32_DMA2_BASE + N32_DMA_TCINTCLR_OFFSET) + +#define N32_DMA3_RAWTCINTSTS (N32_DMA3_BASE + N32_DMA_RAWTCINTSTS_OFFSET) +#define N32_DMA3_TCINTSTS (N32_DMA3_BASE + N32_DMA_TCINTSTS_OFFSET) +#define N32_DMA3_TCINTMSK (N32_DMA3_BASE + N32_DMA_TCINTMSK_OFFSET) +#define N32_DMA3_TCINTCLR (N32_DMA3_BASE + N32_DMA_TCINTCLR_OFFSET) + +#define N32_DMA1_RAWBTCINTSTS (N32_DMA1_BASE + N32_DMA_RAWBTCINTSTS_OFFSET) +#define N32_DMA1_BTCINTSTS (N32_DMA1_BASE + N32_DMA_BTCINTSTS_OFFSET) +#define N32_DMA1_BTCINTMSK (N32_DMA1_BASE + N32_DMA_BTCINTMSK_OFFSET) +#define N32_DMA1_BTCINTCLR (N32_DMA1_BASE + N32_DMA_BTCINTCLR_OFFSET) + +#define N32_DMA2_RAWBTCINTSTS (N32_DMA2_BASE + N32_DMA_RAWBTCINTSTS_OFFSET) +#define N32_DMA2_BTCINTSTS (N32_DMA2_BASE + N32_DMA_BTCINTSTS_OFFSET) +#define N32_DMA2_BTCINTMSK (N32_DMA2_BASE + N32_DMA_BTCINTMSK_OFFSET) +#define N32_DMA2_BTCINTCLR (N32_DMA2_BASE + N32_DMA_BTCINTCLR_OFFSET) + +#define N32_DMA3_RAWBTCINTSTS (N32_DMA3_BASE + N32_DMA_RAWBTCINTSTS_OFFSET) +#define N32_DMA3_BTCINTSTS (N32_DMA3_BASE + N32_DMA_BTCINTSTS_OFFSET) +#define N32_DMA3_BTCINTMSK (N32_DMA3_BASE + N32_DMA_BTCINTMSK_OFFSET) +#define N32_DMA3_BTCINTCLR (N32_DMA3_BASE + N32_DMA_BTCINTCLR_OFFSET) + +#define N32_DMA1_RAWSTCINTSTS (N32_DMA1_BASE + N32_DMA_RAWSTCINTSTS_OFFSET) +#define N32_DMA1_STCINTSTS (N32_DMA1_BASE + N32_DMA_STCINTSTS_OFFSET) +#define N32_DMA1_STCINTMSK (N32_DMA1_BASE + N32_DMA_STCINTMSK_OFFSET) +#define N32_DMA1_STCINTCLR (N32_DMA1_BASE + N32_DMA_STCINTCLR_OFFSET) + +#define N32_DMA2_RAWSTCINTSTS (N32_DMA2_BASE + N32_DMA_RAWSTCINTSTS_OFFSET) +#define N32_DMA2_STCINTSTS (N32_DMA2_BASE + N32_DMA_STCINTSTS_OFFSET) +#define N32_DMA2_STCINTMSK (N32_DMA2_BASE + N32_DMA_STCINTMSK_OFFSET) +#define N32_DMA2_STCINTCLR (N32_DMA2_BASE + N32_DMA_STCINTCLR_OFFSET) + +#define N32_DMA3_RAWSTCINTSTS (N32_DMA3_BASE + N32_DMA_RAWSTCINTSTS_OFFSET) +#define N32_DMA3_STCINTSTS (N32_DMA3_BASE + N32_DMA_STCINTSTS_OFFSET) +#define N32_DMA3_STCINTMSK (N32_DMA3_BASE + N32_DMA_STCINTMSK_OFFSET) +#define N32_DMA3_STCINTCLR (N32_DMA3_BASE + N32_DMA_STCINTCLR_OFFSET) + +#define N32_DMA1_RAWDTCINTSTS (N32_DMA1_BASE + N32_DMA_RAWDTCINTSTS_OFFSET) +#define N32_DMA1_DTCINTSTS (N32_DMA1_BASE + N32_DMA_DTCINTSTS_OFFSET) +#define N32_DMA1_DTCINTMSK (N32_DMA1_BASE + N32_DMA_DTCINTMSK_OFFSET) +#define N32_DMA1_DTCINTCLR (N32_DMA1_BASE + N32_DMA_DTCINTCLR_OFFSET) + +#define N32_DMA2_RAWDTCINTSTS (N32_DMA2_BASE + N32_DMA_RAWDTCINTSTS_OFFSET) +#define N32_DMA2_DTCINTSTS (N32_DMA2_BASE + N32_DMA_DTCINTSTS_OFFSET) +#define N32_DMA2_DTCINTMSK (N32_DMA2_BASE + N32_DMA_DTCINTMSK_OFFSET) +#define N32_DMA2_DTCINTCLR (N32_DMA2_BASE + N32_DMA_DTCINTCLR_OFFSET) + +#define N32_DMA3_RAWDTCINTSTS (N32_DMA3_BASE + N32_DMA_RAWDTCINTSTS_OFFSET) +#define N32_DMA3_DTCINTSTS (N32_DMA3_BASE + N32_DMA_DTCINTSTS_OFFSET) +#define N32_DMA3_DTCINTMSK (N32_DMA3_BASE + N32_DMA_DTCINTMSK_OFFSET) +#define N32_DMA3_DTCINTCLR (N32_DMA3_BASE + N32_DMA_DTCINTCLR_OFFSET) + +#define N32_DMA1_RAWERRINTSTS (N32_DMA1_BASE + N32_DMA_RAWERRINTSTS_OFFSET) +#define N32_DMA1_ERRINTSTS (N32_DMA1_BASE + N32_DMA_ERRINTSTS_OFFSET) +#define N32_DMA1_ERRINTMSK (N32_DMA1_BASE + N32_DMA_ERRINTMSK_OFFSET) +#define N32_DMA1_ERRINTCLR (N32_DMA1_BASE + N32_DMA_ERRINTCLR_OFFSET) + +#define N32_DMA2_RAWERRINTSTS (N32_DMA2_BASE + N32_DMA_RAWERRINTSTS_OFFSET) +#define N32_DMA2_ERRINTSTS (N32_DMA2_BASE + N32_DMA_ERRINTSTS_OFFSET) +#define N32_DMA2_ERRINTMSK (N32_DMA2_BASE + N32_DMA_ERRINTMSK_OFFSET) +#define N32_DMA2_ERRINTCLR (N32_DMA2_BASE + N32_DMA_ERRINTCLR_OFFSET) + +#define N32_DMA3_RAWERRINTSTS (N32_DMA3_BASE + N32_DMA_RAWERRINTSTS_OFFSET) +#define N32_DMA3_ERRINTSTS (N32_DMA3_BASE + N32_DMA_ERRINTSTS_OFFSET) +#define N32_DMA3_ERRINTMSK (N32_DMA3_BASE + N32_DMA_ERRINTMSK_OFFSET) +#define N32_DMA3_ERRINTCLR (N32_DMA3_BASE + N32_DMA_ERRINTCLR_OFFSET) + +#define N32_DMA1_INTCBESTS (N32_DMA1_BASE + N32_DMA_INTCBESTS_OFFSET) + +#define N32_DMA2_INTCBESTS (N32_DMA2_BASE + N32_DMA_INTCBESTS_OFFSET) + +#define N32_DMA3_INTCBESTS (N32_DMA3_BASE + N32_DMA_INTCBESTS_OFFSET) + +/* ========================================================================== + * Software Handshake Register Offset + * ========================================================================== + */ +#define N32_DMA1_SRCSWTREQ (N32_DMA1_BASE + N32_DMA_SRCSWTREQ_OFFSET) +#define N32_DMA1_DSTSWTREQ (N32_DMA1_BASE + N32_DMA_DSTSWTREQ_OFFSET) +#define N32_DMA1_SRCSGTREQ (N32_DMA1_BASE + N32_DMA_SRCSGTREQ_OFFSET) +#define N32_DMA1_DSTSGTREQ (N32_DMA1_BASE + N32_DMA_DSTSGTREQ_OFFSET) +#define N32_DMA1_SRCLTREQ (N32_DMA1_BASE + N32_DMA_SRCLTREQ_OFFSET) +#define N32_DMA1_DSTLTREQ (N32_DMA1_BASE + N32_DMA_DSTLTREQ_OFFSET) + +#define N32_DMA2_SRCSWTREQ (N32_DMA2_BASE + N32_DMA_SRCSWTREQ_OFFSET) +#define N32_DMA2_DSTSWTREQ (N32_DMA2_BASE + N32_DMA_DSTSWTREQ_OFFSET) +#define N32_DMA2_SRCSGTREQ (N32_DMA2_BASE + N32_DMA_SRCSGTREQ_OFFSET) +#define N32_DMA2_DSTSGTREQ (N32_DMA2_BASE + N32_DMA_DSTSGTREQ_OFFSET) +#define N32_DMA2_SRCLTREQ (N32_DMA2_BASE + N32_DMA_SRCLTREQ_OFFSET) +#define N32_DMA2_DSTLTREQ (N32_DMA2_BASE + N32_DMA_DSTLTREQ_OFFSET) + +#define N32_DMA3_SRCSWTREQ (N32_DMA3_BASE + N32_DMA_SRCSWTREQ_OFFSET) +#define N32_DMA3_DSTSWTREQ (N32_DMA3_BASE + N32_DMA_DSTSWTREQ_OFFSET) +#define N32_DMA3_SRCSGTREQ (N32_DMA3_BASE + N32_DMA_SRCSGTREQ_OFFSET) +#define N32_DMA3_DSTSGTREQ (N32_DMA3_BASE + N32_DMA_DSTSGTREQ_OFFSET) +#define N32_DMA3_SRCLTREQ (N32_DMA3_BASE + N32_DMA_SRCLTREQ_OFFSET) +#define N32_DMA3_DSTLTREQ (N32_DMA3_BASE + N32_DMA_DSTLTREQ_OFFSET) + +/* ========================================================================== + * DMA Miscellaneous Register Offset + * ========================================================================== + */ +#define N32_DMA1_CFG (N32_DMA1_BASE + N32_DMA_CFG_OFFSET) +#define N32_DMA1_CHEN (N32_DMA1_BASE + N32_DMA_CHEN_OFFSET) +#define N32_DMA1_ID (N32_DMA1_BASE + N32_DMA_ID_OFFSET) +#define N32_DMA1_TEST (N32_DMA1_BASE + N32_DMA_TEST_OFFSET) +#define N32_DMA1_LPTIMEOUT (N32_DMA1_BASE + N32_DMA_LPTIMEOUT_OFFSET) +#define N32_DMA1_COMPID (N32_DMA1_BASE + N32_DMA_COMPID_OFFSET) + +#define N32_DMA2_CFG (N32_DMA2_BASE + N32_DMA_CFG_OFFSET) +#define N32_DMA2_CHEN (N32_DMA2_BASE + N32_DMA_CHEN_OFFSET) +#define N32_DMA2_ID (N32_DMA2_BASE + N32_DMA_ID_OFFSET) +#define N32_DMA2_TEST (N32_DMA2_BASE + N32_DMA_TEST_OFFSET) +#define N32_DMA2_LPTIMEOUT (N32_DMA2_BASE + N32_DMA_LPTIMEOUT_OFFSET) +#define N32_DMA2_COMPID (N32_DMA2_BASE + N32_DMA_COMPID_OFFSET) + +#define N32_DMA3_CFG (N32_DMA3_BASE + N32_DMA_CFG_OFFSET) +#define N32_DMA3_CHEN (N32_DMA3_BASE + N32_DMA_CHEN_OFFSET) +#define N32_DMA3_ID (N32_DMA3_BASE + N32_DMA_ID_OFFSET) +#define N32_DMA3_TEST (N32_DMA3_BASE + N32_DMA_TEST_OFFSET) +#define N32_DMA3_LPTIMEOUT (N32_DMA3_BASE + N32_DMA_LPTIMEOUT_OFFSET) +#define N32_DMA3_COMPID (N32_DMA3_BASE + N32_DMA_COMPID_OFFSET) + +/* ========================================================================== + * Interrupt Bit Definitions (Channel Number n = 0~7) + * ========================================================================== + */ +#define DMA_INT_CH(n) (1U << (n)) +#define DMA_INT_CH_MASK 0xFFU + +/**************************************************************************** + * 64-bit CH_CTRL / DMA_CHnCTRL Bit Definitions + * Address:channel_base + 0x18 + * Reset Value:0x00000002_00304801 + ****************************************************************************/ + +/* ===== High 32 Bits (Bits 63:32) ===== */ +#define DMA_CHCTRL_DONE (1ULL << 44) /* 44: Done bit (status write-back) */ + +#define DMA_CHCTRL_BTS_SHIFT 32 /* 43:32: Block Transfer Size (12-bit) */ +#define DMA_CHCTRL_BTS_MASK (0xFFFULL << DMA_CHCTRL_BTS_SHIFT) +#define DMA_CHCTRL_BTS(n) ((n) << DMA_CHCTRL_BTS_SHIFT) + +/* ===== Low 32 Bits (Bits 31:0) ===== */ + +/* LLP Control Bits */ +#define DMA_CHCTRL_LLPSRCEN (1ULL << 28) /* 28: Source List Enable */ +#define DMA_CHCTRL_LLPDSTEN (1ULL << 27) /* 27: Destination List Enable */ + +/* AHB Master Port Select */ +#define DMA_CHCTRL_SMS_SHIFT 25 /* 26:25: Source Master Port */ +#define DMA_CHCTRL_SMS_MASK (0x3ULL << DMA_CHCTRL_SMS_SHIFT) +#define DMA_CHCTRL_SMS(n) ((n) << DMA_CHCTRL_SMS_SHIFT) + +#define DMA_CHCTRL_DMS_SHIFT 23 /* 24:23: Destination Master Port */ +#define DMA_CHCTRL_DMS_MASK (0x3ULL << DMA_CHCTRL_DMS_SHIFT) +#define DMA_CHCTRL_DMS(n) ((n) << DMA_CHCTRL_DMS_SHIFT) + +/* Transfer Type & Flow Control */ +#define DMA_CHCTRL_TTFC_SHIFT 20 /* 22:20: Transfer Type & Flow Control */ +#define DMA_CHCTRL_TTFC_MASK (0x7ULL << DMA_CHCTRL_TTFC_SHIFT) +#define DMA_CHCTRL_TTFC(n) ((n) << DMA_CHCTRL_TTFC_SHIFT) + +/* Function Enable Bits */ +#define DMA_CHCTRL_DSTSCAEN (1ULL << 18) /* 18: Destination Scatter Enable */ +#define DMA_CHCTRL_SRCGATEN (1ULL << 17) /* 17: Source Gather Enable */ + +/* Burst Length */ +#define DMA_CHCTRL_SRCMSIZE_SHIFT 14 /* 16:14: Source Burst Length (Encoded Value) */ +#define DMA_CHCTRL_SRCMSIZE_MASK (0x7ULL << DMA_CHCTRL_SRCMSIZE_SHIFT) +#define DMA_CHCTRL_SRCMSIZE(n) ((n) << DMA_CHCTRL_SRCMSIZE_SHIFT) + +#define DMA_CHCTRL_DSTMSIZE_SHIFT 11 /* 13:11: Destination Burst Length (Encoded Value) */ +#define DMA_CHCTRL_DSTMSIZE_MASK (0x7ULL << DMA_CHCTRL_DSTMSIZE_SHIFT) +#define DMA_CHCTRL_DSTMSIZE(n) ((n) << DMA_CHCTRL_DSTMSIZE_SHIFT) + +/* Address Increment Direction */ +#define DMA_CHCTRL_SINC_SHIFT 9 /* 10:9: Source Address Control */ +#define DMA_CHCTRL_SINC_MASK (0x3ULL << DMA_CHCTRL_SINC_SHIFT) +#define DMA_CHCTRL_SINC(n) ((n) << DMA_CHCTRL_SINC_SHIFT) + +#define DMA_CHCTRL_DINC_SHIFT 7 /* 8:7: Destination Address Control */ +#define DMA_CHCTRL_DINC_MASK (0x3ULL << DMA_CHCTRL_DINC_SHIFT) +#define DMA_CHCTRL_DINC(n) ((n) << DMA_CHCTRL_DINC_SHIFT) + +/* Transfer Width */ +#define DMA_CHCTRL_STW_SHIFT 4 /* 6:4: Source Width */ +#define DMA_CHCTRL_STW_MASK (0x7ULL << DMA_CHCTRL_STW_SHIFT) +#define DMA_CHCTRL_STW(n) ((n) << DMA_CHCTRL_STW_SHIFT) + +#define DMA_CHCTRL_DTW_SHIFT 1 /* 3:1: Destination Width */ +#define DMA_CHCTRL_DTW_MASK (0x7ULL << DMA_CHCTRL_DTW_SHIFT) +#define DMA_CHCTRL_DTW(n) ((n) << DMA_CHCTRL_DTW_SHIFT) + +/* Global Interrupt Enable Bit */ +#define DMA_CHCTRL_INTEN (1ULL << 0) /* 0: Interrupt Enable */ + +/* TTFC Enumeration */ +#define DMA_TTFC_MEM_TO_MEM_DMA (0ULL) +#define DMA_TTFC_MEM_TO_PER_DMA (1ULL) +#define DMA_TTFC_PER_TO_MEM_DMA (2ULL) +#define DMA_TTFC_PER_TO_PER_DMA (3ULL) +#define DMA_TTFC_PER_TO_MEM_PER (4ULL) +#define DMA_TTFC_PER_TO_PER_SRC (5ULL) +#define DMA_TTFC_MEM_TO_PER_PER (6ULL) +#define DMA_TTFC_PER_TO_PER_DST (7ULL) + +/* Address Control Enumeration */ +#define DMA_ADDR_INC (0ULL) +#define DMA_ADDR_DEC (1ULL) +#define DMA_ADDR_NOCHANGE (2ULL) + +/* Width Enumeration */ +#define DMA_WIDTH_8BITS (0ULL) +#define DMA_WIDTH_16BITS (1ULL) +#define DMA_WIDTH_32BITS (2ULL) +#define DMA_WIDTH_64BITS (3ULL) +#define DMA_WIDTH_128BITS (4ULL) +#define DMA_WIDTH_256BITS (5ULL) + +/* Burst Length Enumeration */ +#define DMA_BURST_1 (0ULL) +#define DMA_BURST_4 (1ULL) +#define DMA_BURST_8 (2ULL) +#define DMA_BURST_16 (3ULL) +#define DMA_BURST_32 (4ULL) +#define DMA_BURST_64 (5ULL) +#define DMA_BURST_128 (6ULL) +#define DMA_BURST_256 (7ULL) + +/* AHB Master Port Enumeration */ +#define DMA_MS_1 (0ULL) +#define DMA_MS_2 (1ULL) + +/**************************************************************************** + * 64-bit DMA_CHnCFG Register Bit Fields + * Address Offset: 0x40 + 0x58*n (n=0..7) + * Reset Value:0x0000000400000E00 + ****************************************************************************/ + +/* High 32 Bits (bits 63:32) ************************************************/ +#define DMA_CHCFG_DONE (1ULL << 44) /* 44: Block Completion Flag (Write Back) */ +#define DMA_CHCFG_BTS_SHIFT 32 /* 43:32: Block Transfer Size */ +#define DMA_CHCFG_BTS_MASK (0xFFFULL << DMA_CHCFG_BTS_SHIFT) +#define DMA_CHCFG_BTS(n) ((n) << DMA_CHCFG_BTS_SHIFT) + +#define DMA_CHCFG_DSTPER_SHIFT 43 /* 45:43: Destination Peripheral Interface Number */ +#define DMA_CHCFG_DSTPER_MASK (0x7ULL << DMA_CHCFG_DSTPER_SHIFT) +#define DMA_CHCFG_DSTPER(n) ((n) << DMA_CHCFG_DSTPER_SHIFT) + +#define DMA_CHCFG_SRCPER_SHIFT 39 /* 41:39: Source Peripheral Interface Number */ +#define DMA_CHCFG_SRCPER_MASK (0x7ULL << DMA_CHCFG_SRCPER_SHIFT) +#define DMA_CHCFG_SRCPER(n) ((n) << DMA_CHCFG_SRCPER_SHIFT) + +#define DMA_CHCFG_PROTCTL_SHIFT 34 /* 36:34: AHB Protection Control Register */ +#define DMA_CHCFG_PROTCTL_MASK (0x7ULL << DMA_CHCFG_PROTCTL_SHIFT) +#define DMA_CHCFG_PROTCTL(n) ((n) << DMA_CHCFG_PROTCTL_SHIFT) + +#define DMA_CHCFG_FIFOMS (1ULL << 33) /* 33: FIFO Mode Select */ +#define DMA_CHCFG_FCM (1ULL << 32) /* 32: Flow Control Mode */ + +/* Low 32 Bits (bits 31:0) **************************************************/ +#define DMA_CHCFG_ADR (1ULL << 31) /* 31: Auto Destination Reload */ +#define DMA_CHCFG_ASR (1ULL << 30) /* 30: Auto Source Reload */ + +#define DMA_CHCFG_MAMBABL_SHIFT 20 /* 29:20: AMBA Burst Length (Encoded Value) */ +#define DMA_CHCFG_MAMBABL_MASK (0x3FFULL << DMA_CHCFG_MAMBABL_SHIFT) +#define DMA_CHCFG_MAMBABL(n) ((n) << DMA_CHCFG_MAMBABL_SHIFT) + +#define DMA_CHCFG_SRCHSPO_SHIFT 19 /* 19: Source Handshake Polarity */ +#define DMA_CHCFG_SRCHSPO (1ULL << 19) + +#define DMA_CHCFG_DSTHSPO_SHIFT 18 /* 18: Destination Handshake Polarity */ +#define DMA_CHCFG_DSTHSPO (1ULL << 18) + +#define DMA_CHCFG_LOCKB (1ULL << 17) /* 17: Bus Lock Level */ +#define DMA_CHCFG_LOCKCH (1ULL << 16) /* 16: Channel Lock Level */ + +#define DMA_CHCFG_LOCKBL_SHIFT 14 /* 15:14: Bus Lock Level */ +#define DMA_CHCFG_LOCKBL_MASK (0x3ULL << DMA_CHCFG_LOCKBL_SHIFT) +#define DMA_CHCFG_LOCKBL(n) ((n) << DMA_CHCFG_LOCKBL_SHIFT) + +#define DMA_CHCFG_LOCKCHL_SHIFT 12 /* 13:12: Channel Lock Level */ +#define DMA_CHCFG_LOCKCHL_MASK (0x3ULL << DMA_CHCFG_LOCKCHL_SHIFT) +#define DMA_CHCFG_LOCKCHL(n) ((n) << DMA_CHCFG_LOCKCHL_SHIFT) + +#define DMA_CHCFG_HSSELSRC (1ULL << 11) /* 11: Source Handshake Select */ +#define DMA_CHCFG_HSSELDST (1ULL << 10) /* 10: Destination Handshake Select */ + +#define DMA_CHCFG_FIFOEMPTY (1ULL << 9) /* 9: FIFO Empty Flag (Read Only) */ +#define DMA_CHCFG_CHSUSP (1ULL << 8) /* 8: Channel Suspend */ + +#define DMA_CHCFG_CHPRIOR_SHIFT 5 /* 7:5: Channel Priority */ +#define DMA_CHCFG_CHPRIOR_MASK (0x7ULL << DMA_CHCFG_CHPRIOR_SHIFT) +#define DMA_CHCFG_CHPRIOR(n) ((n) << DMA_CHCFG_CHPRIOR_SHIFT) + +/* 4:0 Reserved */ + +/* ========================================================================== + * CH_SG Register Bit Fields + * ========================================================================== + */ +#define DMA_SG_SGC_SHIFT 20 +#define DMA_SG_SGC_MASK (0xFFFULL << DMA_SG_SGC_SHIFT) +#define DMA_SG_SGI_SHIFT 0 +#define DMA_SG_SGI_MASK (0xFFFFFULL << DMA_SG_SGI_SHIFT) + +/* CH_SG Register Bit Fields */ +#define DMA_SG_SGC(n) ((n) << DMA_SG_SGC_SHIFT) +#define DMA_SG_SGI(n) ((n) << DMA_SG_SGI_SHIFT) + +/* ========================================================================== + * CH_DS Register Bit Fields + * ========================================================================== + */ +#define DMA_DS_DSC_SHIFT 20 +#define DMA_DS_DSC_MASK (0xFFFULL << DMA_DS_DSC_SHIFT) +#define DMA_DS_DSI_SHIFT 0 +#define DMA_DS_DSI_MASK (0xFFFFFULL << DMA_DS_DSI_SHIFT) + +/* CH_DS Register Bit Fields */ +#define DMA_DS_DSC(n) ((n) << DMA_DS_DSC_SHIFT) +#define DMA_DS_DSI(n) ((n) << DMA_DS_DSI_SHIFT) + +/* ========================================================================== + * DMA Miscellaneous Registers Bit Fields + * ========================================================================== + */ + +/* DMA Configuration Register (DMA_CFG) */ +#define DMA_CFG_EN (1U << 0) /* Bit 0: DMA Enable bit */ + +/* DMA Channel Enable Register (DMA_CHEN) */ +#define DMA_CHEN_CH(n) (1U << (n)) /* Bit n: Channel n Enable */ +#define DMA_CHEN_CHWEN(n) (1U << ((n) + 8)) /* Bit n+8: Channel n Enable bit write enable */ + +/* DMA ID Register (DMA_ID) */ +#define DMA_ID_VALUE (0xFFFFFFFFU) /* Bits 31:0: Hardcoded DMA peripheral ID */ + +/* DMA Test Register (DMA_TEST) */ +#define DMA_TEST_TMS (1U << 0) /* Bit 0: Test Mode Select */ + +/* DMA Low Power Timeout Register (DMA_LPTIMEOUT) */ +#define DMA_LPTIMEOUT_VALUE (0xFFU) /* Bits 7:0: Timeout value of low power counter register */ + +/* DMA Component ID Register (DMA_COMPID) */ +#define DMA_COMPID_VERSION (0xFFFFFFFFU << 32) /* Bits 63:32: DMA Component Version */ +#define DMA_COMPID_TYPE (0xFFFFFFFFU) /* Bits 31:0: DMA Component Type */ + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_DMA_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_dmamux.h b/arch/arm/src/n32h7/hardware/n32h7_dmamux.h new file mode 100644 index 0000000000000..393d3f1b23c9a --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_dmamux.h @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_dmamux.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + + #ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_DMAMUX_H + #define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_DMAMUX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#include "n32h7_memorymap.h" + +#if defined(CONFIG_N32H7_N32H76X) +# include "hardware/n32h76x_dmamux.h" +#else +# error "Unsupported N32 H7 part" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMAMUX1 0 +#define DMAMUX2 1 + +/* Register Offsets *********************************************************/ + +#define N32_DMAMUX_CXCR_OFFSET(x) (0x0000U + 0x04U * (x)) +#define N32_DMAMUX_STS_OFFSET 0x0080U +#define N32_DMAMUX_CLR_OFFSET 0x0084U +#define N32_DMAMUX_RGXCR_OFFSET(x) (0x0100U + 0x04U * (x)) +#define N32_DMAMUX_RGSTS_OFFSET 0x0180U +#define N32_DMAMUX_RGCLR_OFFSET 0x0184U + +/* DMAMUX1 Register Addresses ***********************************************/ + +#define N32_DMAMUX1_CxCR(x) (N32_DMAMUX1_BASE + N32_DMAMUX_CXCR_OFFSET(x)) +#define N32_DMAMUX1_STS (N32_DMAMUX1_BASE + N32_DMAMUX_STS_OFFSET) +#define N32_DMAMUX1_CLR (N32_DMAMUX1_BASE + N32_DMAMUX_CLR_OFFSET) +#define N32_DMAMUX1_RGxCR(x) (N32_DMAMUX1_BASE + N32_DMAMUX_RGXCR_OFFSET(x)) +#define N32_DMAMUX1_RGSTS (N32_DMAMUX1_BASE + N32_DMAMUX_RGSTS_OFFSET) +#define N32_DMAMUX1_RGCLR (N32_DMAMUX1_BASE + N32_DMAMUX_RGCLR_OFFSET) + +/* DMAMUX2 Register Addresses ***********************************************/ + +#define N32_DMAMUX2_CxCR(x) (N32_DMAMUX2_BASE + N32_DMAMUX_CXCR_OFFSET(x)) +#define N32_DMAMUX2_STS (N32_DMAMUX2_BASE + N32_DMAMUX_STS_OFFSET) +#define N32_DMAMUX2_CLR (N32_DMAMUX2_BASE + N32_DMAMUX_CLR_OFFSET) +#define N32_DMAMUX2_RGxCR(x) (N32_DMAMUX2_BASE + N32_DMAMUX_RGXCR_OFFSET(x)) +#define N32_DMAMUX2_RGSTS (N32_DMAMUX2_BASE + N32_DMAMUX_RGSTS_OFFSET) +#define N32_DMAMUX2_RGCLR (N32_DMAMUX2_BASE + N32_DMAMUX_RGCLR_OFFSET) + +/* Register Bit Definitions *************************************************/ + +/* DMAMUX_CXCR bit definitions */ +#define DMAMUX_CXCR_REQID_SHIFT 0U +#define DMAMUX_CXCR_REQID_MASK (0x7FU << DMAMUX_CXCR_REQID_SHIFT) + +#define DMAMUX_CXCR_EGE (1U << 9) /* Event generation enable */ +#define DMAMUX_CXCR_SOIE (1U << 8) /* Sync overrun int enable */ + +#define DMAMUX_CXCR_SYEN (1U << 16) /* Sync enable */ +#define DMAMUX_CXCR_SYPOL_SHIFT 17U +#define DMAMUX_CXCR_SYPOL_MASK (0x3U << DMAMUX_CXCR_SYPOL_SHIFT) +#define DMAMUX_CXCR_SYPOL_NONE (0x0U << DMAMUX_CXCR_SYPOL_SHIFT) +#define DMAMUX_CXCR_SYPOL_RISING (0x1U << DMAMUX_CXCR_SYPOL_SHIFT) +#define DMAMUX_CXCR_SYPOL_FALLING (0x2U << DMAMUX_CXCR_SYPOL_SHIFT) +#define DMAMUX_CXCR_SYPOL_BOTH (0x3U << DMAMUX_CXCR_SYPOL_SHIFT) + +#define DMAMUX_CXCR_NUMREQ_SHIFT 19U +#define DMAMUX_CXCR_NUMREQ_MASK (0x1FU << DMAMUX_CXCR_NUMREQ_SHIFT) + +#define DMAMUX_CXCR_SYID_SHIFT 24U +#define DMAMUX_CXCR_SYID_MASK (0xFU << DMAMUX_CXCR_SYID_SHIFT) + +/* DMAMUX_STS bit definitions */ +#define DMAMUX_STS_SOF(x) (1U << (x)) + +/* DMAMUX_CLR bit definitions */ +#define DMAMUX_CLR_CSOF(x) (1U << (x)) + +/* DMAMUX_RGXCR bit definitions */ +#define DMAMUX_RGXCR_SIGID_SHIFT 0U +#define DMAMUX_RGXCR_SIGID_MASK (0x3FU << DMAMUX_RGXCR_SIGID_SHIFT) + +#define DMAMUX_RGXCR_TOVIEN (1U << 8) /* Trigger overrun int enable */ + +#define DMAMUX_RGXCR_GEN (1U << 16) /* Request generator enable */ +#define DMAMUX_RGXCR_GPOL_SHIFT 17U +#define DMAMUX_RGXCR_GPOL_MASK (0x3U << DMAMUX_RGXCR_GPOL_SHIFT) +#define DMAMUX_RGXCR_GPOL_NONE (0x0U << DMAMUX_RGXCR_GPOL_SHIFT) +#define DMAMUX_RGXCR_GPOL_RISING (0x1U << DMAMUX_RGXCR_GPOL_SHIFT) +#define DMAMUX_RGXCR_GPOL_FALLING (0x2U << DMAMUX_RGXCR_GPOL_SHIFT) +#define DMAMUX_RGXCR_GPOL_BOTH (0x3U << DMAMUX_RGXCR_GPOL_SHIFT) + +#define DMAMUX_RGXCR_GNUMREQ_SHIFT 19U +#define DMAMUX_RGXCR_GNUMREQ_MASK (0x1FU << DMAMUX_RGXCR_GNUMREQ_SHIFT) + +/* DMAMUX_RGSTS bit definitions */ +#define DMAMUX_RGSTS_OF(x) (1U << (x)) + +/* DMAMUX_RGCLR bit definitions */ +#define DMAMUX_RGCLR_COF(x) (1U << (x)) + +/**************************************************************************** + * DMA channel mapping + * + * XXXXX.DDD.CCCCCCCC + * C - DMAMUX request + * D - DMA controller + * X - free bits + ****************************************************************************/ + +#define DMAMAP_MAP(d,c) ((d) << 8 | (c-1)) +#define DMAMAP_CONTROLLER(m) ((m) >> 8 & 0x07) +#define DMAMAP_REQUEST(m) ((m) >> 0 & 0xff) + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_DMAMUX_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_exti.h b/arch/arm/src/n32h7/hardware/n32h7_exti.h new file mode 100644 index 0000000000000..5e075b76e7ba9 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_exti.h @@ -0,0 +1,211 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_exti.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32_EXTI_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32_EXTI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" +#include "hardware/n32h7_memorymap.h" + +#if defined(CONFIG_N32H7_N32H76X) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +/* Register Index Calculation (Each register manages 32 EXTI lines) */ +#define N32_EXTI_INDEX(n) ((n) >> 5) /* Calculate register index (0-1) */ +#define N32_EXTI_SHIFT(n) ((n) & 0x1f) /* Calculate bit shift (0-31) */ +#define N32_EXTI_MASK(n) (1 << N32_EXTI_SHIFT(n)) /* Generate bit mask */ + +/* Dynamic Offset Calculation (For RT/FT/SWIE register groups) */ +#define N32_EXTI_RT_CFG_OFFSET(n) (0x0000 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_FT_CFG_OFFSET(n) (0x0020 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_SWIE_OFFSET(n) (0x0040 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M7IMASK_OFFSET(n) (0x0060 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M4IMASK_OFFSET(n) (0x0080 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M7EMASK_OFFSET(n) (0x00A0 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M4EMASK_OFFSET(n) (0x00C0 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M7PEND_OFFSET(n) (0x00E0 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M4PEND_OFFSET(n) (0x0100 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M7IMASK_DRC_OFFSET(n) (0x0120 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M4IMASK_DRC_OFFSET(n) (0x0140 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M7EMASK_DRC_OFFSET(n) (0x0160 + (N32_EXTI_INDEX(n) * 4)) +#define N32_EXTI_M4EMASK_DRC_OFFSET(n) (0x0180 + (N32_EXTI_INDEX(n) * 4)) + +/* Static Offset Definitions */ +#define N32_EXTI_RT_CFG0_OFFSET 0x0000 /* Rising Trigger Config 0 (0-31) */ +#define N32_EXTI_RT_CFG1_OFFSET 0x0004 /* Rising Trigger Config 1 (32-51) */ +#define N32_EXTI_FT_CFG0_OFFSET 0x0020 /* Falling Trigger Config 0 (0-31) */ +#define N32_EXTI_FT_CFG1_OFFSET 0x0024 /* Falling Trigger Config 1 (32-51) */ +#define N32_EXTI_SWIE0_OFFSET 0x0040 /* SW Interrupt Enable 0 (0-31) */ +#define N32_EXTI_SWIE1_OFFSET 0x0044 /* SW Interrupt Enable 1 (32-51) */ +#define N32_EXTI_M7IMASK0_OFFSET 0x0060 /* CM7 Interrupt Mask 0 (0-31) */ +#define N32_EXTI_M7IMASK1_OFFSET 0x0064 /* CM7 Interrupt Mask 1 (32-51) */ +#define N32_EXTI_M4IMASK0_OFFSET 0x0080 /* CM4 Interrupt Mask 0 (0-31) */ +#define N32_EXTI_M4IMASK1_OFFSET 0x0084 /* CM4 Interrupt Mask 1 (32-51) */ +#define N32_EXTI_M7EMASK0_OFFSET 0x00A0 /* CM7 Event Mask 0 (0-31) */ +#define N32_EXTI_M7EMASK1_OFFSET 0x00A4 /* CM7 Event Mask 1 (32-51) */ +#define N32_EXTI_M4EMASK0_OFFSET 0x00C0 /* CM4 Event Mask 0 (0-31) */ +#define N32_EXTI_M4EMASK1_OFFSET 0x00C4 /* CM4 Event Mask 1 (32-51) */ +#define N32_EXTI_M7PEND0_OFFSET 0x00E0 /* CM7 Pending 0 (0-31) */ +#define N32_EXTI_M7PEND1_OFFSET 0x00E4 /* CM7 Pending 1 (32-51) */ +#define N32_EXTI_M4PEND0_OFFSET 0x0100 /* CM4 Pending 0 (0-31) */ +#define N32_EXTI_M4PEND1_OFFSET 0x0104 /* CM4 Pending 1 (32-51) */ +#define N32_EXTI_M7IMASK0_DRC_OFFSET 0x0120 /* CM7 Direct Event Int Mask 0 (0-31) */ +#define N32_EXTI_M7IMASK1_DRC_OFFSET 0x0124 /* CM7 Direct Event Int Mask 1 (32-58) */ +#define N32_EXTI_M4IMASK0_DRC_OFFSET 0x0140 /* CM4 Direct Event Int Mask 0 (0-31) */ +#define N32_EXTI_M4IMASK1_DRC_OFFSET 0x0144 /* CM4 Direct Event Int Mask 1 (32-58) */ +#define N32_EXTI_M7EMASK0_DRC_OFFSET 0x0160 /* CM7 Direct Event Mask 0 (0-31) */ +#define N32_EXTI_M7EMASK1_DRC_OFFSET 0x0164 /* CM7 Direct Event Mask 1 (32-58) */ +#define N32_EXTI_M4EMASK0_DRC_OFFSET 0x0180 /* CM4 Direct Event Mask 0 (0-31) */ +#define N32_EXTI_M4EMASK1_DRC_OFFSET 0x0184 /* CM4 Direct Event Mask 1 (32-58) */ +#define N32_EXTI_TSSEL_OFFSET 0x01C0 /* Timestamp Select */ + +/* Register Addresses *******************************************************/ + +/* Dynamic Address Calculation (For RT/FT/SWIE register groups) */ +#define N32H7_EXTI_RT_CFG(n) (N32_EXTI_WKUP_BASE + N32_EXTI_RT_CFG_OFFSET(n)) +#define N32H7_EXTI_FT_CFG(n) (N32_EXTI_WKUP_BASE + N32_EXTI_FT_CFG_OFFSET(n)) +#define N32H7_EXTI_SWIE(n) (N32_EXTI_WKUP_BASE + N32_EXTI_SWIE_OFFSET(n)) +#define N32H7_EXTI_M7IMASK(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M7IMASK_OFFSET(n)) +#define N32H7_EXTI_M4IMASK(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M4IMASK_OFFSET(n)) +#define N32H7_EXTI_M7EMASK(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M7EMASK_OFFSET(n)) +#define N32H7_EXTI_M4EMASK(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M4EMASK_OFFSET(n)) +#define N32H7_EXTI_M7PEND(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M7PEND_OFFSET(n)) +#define N32H7_EXTI_M4PEND(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M4PEND_OFFSET(n)) +#define N32H7_EXTI_M7IMASK_DRC(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M7IMASK_DRC_OFFSET(n)) +#define N32H7_EXTI_M4IMASK_DRC(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M4IMASK_DRC_OFFSET(n)) +#define N32H7_EXTI_M7EMASK_DRC(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M7EMASK_DRC_OFFSET(n)) +#define N32H7_EXTI_M4EMASK_DRC(n) (N32_EXTI_WKUP_BASE + N32_EXTI_M4EMASK_DRC_OFFSET(n)) + +/* Static Address Definitions */ +#define N32_EXTI_RT_CFG0 (N32_EXTI_WKUP_BASE + N32_EXTI_RT_CFG0_OFFSET) +#define N32_EXTI_RT_CFG1 (N32_EXTI_WKUP_BASE + N32_EXTI_RT_CFG1_OFFSET) +#define N32_EXTI_FT_CFG0 (N32_EXTI_WKUP_BASE + N32_EXTI_FT_CFG0_OFFSET) +#define N32_EXTI_FT_CFG1 (N32_EXTI_WKUP_BASE + N32_EXTI_FT_CFG1_OFFSET) +#define N32_EXTI_SWIE0 (N32_EXTI_WKUP_BASE + N32_EXTI_SWIE0_OFFSET) +#define N32_EXTI_SWIE1 (N32_EXTI_WKUP_BASE + N32_EXTI_SWIE1_OFFSET) +#define N32_EXTI_M7IMASK0 (N32_EXTI_WKUP_BASE + N32_EXTI_M7IMASK0_OFFSET) +#define N32_EXTI_M7IMASK1 (N32_EXTI_WKUP_BASE + N32_EXTI_M7IMASK1_OFFSET) +#define N32_EXTI_M4IMASK0 (N32_EXTI_WKUP_BASE + N32_EXTI_M4IMASK0_OFFSET) +#define N32_EXTI_M4IMASK1 (N32_EXTI_WKUP_BASE + N32_EXTI_M4IMASK1_OFFSET) +#define N32_EXTI_M7EMASK0 (N32_EXTI_WKUP_BASE + N32_EXTI_M7EMASK0_OFFSET) +#define N32_EXTI_M7EMASK1 (N32_EXTI_WKUP_BASE + N32_EXTI_M7EMASK1_OFFSET) +#define N32_EXTI_M4EMASK0 (N32_EXTI_WKUP_BASE + N32_EXTI_M4EMASK0_OFFSET) +#define N32_EXTI_M4EMASK1 (N32_EXTI_WKUP_BASE + N32_EXTI_M4EMASK1_OFFSET) +#define N32_EXTI_M7PEND0 (N32_EXTI_WKUP_BASE + N32_EXTI_M7PEND0_OFFSET) +#define N32_EXTI_M7PEND1 (N32_EXTI_WKUP_BASE + N32_EXTI_M7PEND1_OFFSET) +#define N32_EXTI_M4PEND0 (N32_EXTI_WKUP_BASE + N32_EXTI_M4PEND0_OFFSET) +#define N32_EXTI_M4PEND1 (N32_EXTI_WKUP_BASE + N32_EXTI_M4PEND1_OFFSET) +#define N32_EXTI_M7IMASK0_DRC (N32_EXTI_WKUP_BASE + N32_EXTI_M7IMASK0_DRC_OFFSET) +#define N32_EXTI_M7IMASK1_DRC (N32_EXTI_WKUP_BASE + N32_EXTI_M7IMASK1_DRC_OFFSET) +#define N32_EXTI_M4IMASK0_DRC (N32_EXTI_WKUP_BASE + N32_EXTI_M4IMASK0_DRC_OFFSET) +#define N32_EXTI_M4IMASK1_DRC (N32_EXTI_WKUP_BASE + N32_EXTI_M4IMASK1_DRC_OFFSET) +#define N32_EXTI_M7EMASK0_DRC (N32_EXTI_WKUP_BASE + N32_EXTI_M7EMASK0_DRC_OFFSET) +#define N32_EXTI_M7EMASK1_DRC (N32_EXTI_WKUP_BASE + N32_EXTI_M7EMASK1_DRC_OFFSET) +#define N32_EXTI_M4EMASK0_DRC (N32_EXTI_WKUP_BASE + N32_EXTI_M4EMASK0_DRC_OFFSET) +#define N32_EXTI_M4EMASK1_DRC (N32_EXTI_WKUP_BASE + N32_EXTI_M4EMASK1_DRC_OFFSET) +#define N32_EXTI_TSSEL (N32_EXTI_WKUP_BASE + N32_EXTI_TSSEL_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +#define EXTI_EVENT(n) N32_EXTI_MASK(n) + +/* EXTI_RT_CFGx / EXTI_FT_CFGx */ +#define EXTI_CFG_ENABLE 1 +#define EXTI_CFG_DISABLE 0 + +/* EXTI_SWIEx */ +#define EXTI_SWIE_TRIGGER 1 + +/* Mask Registers (MxIMASK, MxEMASK, etc.) */ +#define EXTI_MASK_UNMASKED 1 +#define EXTI_MASK_MASKED 0 + +/* Pending Registers (MxPEND) */ +#define EXTI_PEND_ACTIVE 1 +#define EXTI_PEND_INACTIVE 0 + +/* EXTI_TSSEL */ +#define EXTI_TSSEL_SHIFT (8) +#define EXTI_TSSEL_MASK (0xF << EXTI_TSSEL_SHIFT) +#define EXTI_TSSEL_LINE(n) (((n) & 0xF) << EXTI_TSSEL_SHIFT) + +/* EXTI event input mapping *************************************************/ + +#define EXTI_EVENT_EXTI(n) (1 << (n))/* Base EXTI line (0-15) */ + +/* Peripheral Specific Event Lines (16-31) */ +#define EXTI_EVENT_PVDAVD 16 /* PVD and AVD event */ +#define EXTI_EVENT_RTC_ALARM 17 /* RTC alarm event */ +#define EXTI_EVENT_RTC_MULTI 18 /* RTC intrusion/LSECSS/LSECSS overflow/LSICSS */ +#define EXTI_EVENT_RTC_WAKEUP 19 /* RTC wakeup timer event */ +#define EXTI_EVENT_COMP1 20 /* Comparator1 output */ +#define EXTI_EVENT_COMP2 21 /* Comparator2 output */ +#define EXTI_EVENT_COMP3 22 /* Comparator3 output */ +#define EXTI_EVENT_SDMMC1_WAKEUP 24 /* SDMMC1 wakeup event */ +#define EXTI_EVENT_SDMMC2_WAKEUP 25 /* SDMMC2 wakeup event */ +#define EXTI_EVENT_LPUART1_WAKEUP 49 /* LPUART1 wakeup event */ +#define EXTI_EVENT_DCMUA_INT 51 /* DCMUA interrupt event */ +#define EXTI_EVENT_LPUART2_WAKEUP 52 /* LPUART2 wakeup event */ +#define EXTI_EVENT_DCMUB_INT 54 /* DCMUB interrupt event */ +#define EXTI_EVENT_CM7_AHBS_ABORT 55 /* CM7 AHBS_ABORT event */ +#define EXTI_EVENT_CM7_AHBSRDY_ERROR 56 /* CM7 AHBSRDY_ERROR event */ +#define EXTI_EVENT_USB1_HS_WAKEUP 62 /* USB1_HS wakeup event */ +#define EXTI_EVENT_USB2_HS_WAKEUP 63 /* USB2_HS wakeup event */ +#define EXTI_EVENT_CM7_CACHE_READ_CER 64 /* CM7 cache read correctable error event */ +#define EXTI_EVENT_CM7_CACHE_READ_FER 65 /* CM7 cache read fatal error event */ +#define EXTI_EVENT_LPTIM1_WAKEUP 66 /* LPTIM1 wakeup event */ +#define EXTI_EVENT_LPTIM2_WAKEUP 67 /* LPTIM2 wakeup event */ +#define EXTI_EVENT_LPTIM3_WAKEUP 68 /* LPTIM3 wakeup event */ +#define EXTI_EVENT_LPTIM4_WAKEUP 69 /* LPTIM4 wakeup event */ +#define EXTI_EVENT_WKUP1 70 /* Wakeup pin 1 event */ +#define EXTI_EVENT_WKUP2 71 /* Wakeup pin 2 event */ +#define EXTI_EVENT_WKUP3 72 /* Wakeup pin 3 event */ +#define EXTI_EVENT_WKUP4 73 /* Wakeup pin 4 event */ +#define EXTI_EVENT_WKUP5 74 /* Wakeup pin 5 event */ +#define EXTI_EVENT_WKUP6 75 /* Wakeup pin 6 event */ +#define EXTI_EVENT_RCC_INT 76 /* RCC interrupt event */ +#define EXTI_EVENT_SEMA1_INT 77 /* SEMA1 interrupt event */ +#define EXTI_EVENT_SEMA2_INT 78 /* SEMA2 interrupt event */ +#define EXTI_EVENT_CM4_SEV_INT 79 /* Cortex-M4 SEV interrupt event */ +#define EXTI_EVENT_CM7_SEV_INT 80 /* Cortex-M7 SEV interrupt event */ +#define EXTI_EVENT_WWDG1_RESET 81 /* WWDG1 reset */ +#define EXTI_EVENT_WWDG2_RESET 82 /* WWDG2 reset */ +#define EXTI_EVENT_ETH1_WAKEUP 83 /* ETHERNET1 wakeup(LPI+PMT) */ +#define EXTI_EVENT_ETH2_WAKEUP 84 /* ETHERNET2 wakeup(LPI+PMT) */ +#define EXTI_EVENT_HSECSS_INT 85 /* HSECSS interrupt event */ +#define EXTI_EVENT_LPTIMER5_WAKEUP 86 /* LPTIMER5 wakeup event */ +#define EXTI_EVENT_DSI_ERROR 87 /* DSI error event */ +#define EXTI_EVENT_BKP_EMC 88 /* BKP EMC event */ +#define EXTI_EVENT_VDDD_EMC 89 /* VDDD EMC event */ + +#endif /* CONFIG_ARCH_CHIP_N32H7 */ +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32_EXTI_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_gpio.h b/arch/arm/src/n32h7/hardware/n32h7_gpio.h new file mode 100644 index 0000000000000..81badc5bbef19 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_gpio.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_gpio.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32_GPIO_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_N32H7_N32H76X) +# include "hardware/n32h76x_gpio.h" +#else +# error "Unsupported N32 H7 part" +#endif + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32_GPIO_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_memorymap.h b/arch/arm/src/n32h7/hardware/n32h7_memorymap.h new file mode 100644 index 0000000000000..930ce3594679e --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_memorymap.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_memorymap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_MEMORYMAP_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_N32H7_N32H76X) +# include "hardware/n32h76x_memorymap.h" +#else +# error "Unsupported N32H7 memory map" +#endif + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_MEMORYMAP_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_pinmap.h b/arch/arm/src/n32h7/hardware/n32h7_pinmap.h new file mode 100644 index 0000000000000..55740996d6b8c --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_pinmap.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_pinmap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_PINMAP_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_PINMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_N32H7_N32H76X) +# include "hardware/n32h76x_pinmap.h" +#else +# error "Unsupported N32H7 Pin map" +#endif + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_PINMAP_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_pwr.h b/arch/arm/src/n32h7/hardware/n32h7_pwr.h new file mode 100644 index 0000000000000..2ef0da86b9fa6 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_pwr.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_pwr.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_PWR_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_PWR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_N32H7_N32H76X) +# include "hardware/n32h76x_pwr.h" +#else +# error "Unsupported N32 H7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32_PWR_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_rcc.h b/arch/arm/src/n32h7/hardware/n32h7_rcc.h new file mode 100644 index 0000000000000..4ab9e5a1df7c8 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_rcc.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_rcc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_RCC_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_RCC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_N32H7_N32H76X) +# include "hardware/n32h76x_rcc.h" +#else +# error "Unsupported STM32 H7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32_RCC_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_sdmmc.h b/arch/arm/src/n32h7/hardware/n32h7_sdmmc.h new file mode 100644 index 0000000000000..5842ac5101921 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_sdmmc.h @@ -0,0 +1,511 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_sdmmc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_SDMMC_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_SDMMC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* SDMMC Configuration Register Offsets (CFG) *******************************/ + +#define N32_SDMMC_CFG1_OFFSET 0x00 /* SDMMC Configuration 1 */ +#define N32_SDMMC_CFG2_OFFSET 0x04 /* SDMMC Configuration 2 (Capabilities) */ +#define N32_SDMMC_CFG3_OFFSET 0x08 /* SDMMC Configuration 3 */ +#define N32_SDMMC_PV0CTRL_OFFSET 0x0C /* Preset Value 0 Control */ +#define N32_SDMMC_PV1CTRL_OFFSET 0x10 /* Preset Value 1 Control */ +#define N32_SDMMC_PV2CTRL_OFFSET 0x14 /* Preset Value 2 Control */ +#define N32_SDMMC_PV3CTRL_OFFSET 0x18 /* Preset Value 3 Control */ +#define N32_SDMMC_DLYCTRL_OFFSET 0x20 /* TX/RX Delay Control */ + +/* SDHOST Register Offsets **************************************************/ + +#define N32_SDHOST_DSADD_OFFSET 0x00 /* SDMA System Address / Parameter 2 */ +#define N32_SDHOST_BLKCFG_OFFSET 0x04 /* Block Count & Size Configuration */ +#define N32_SDHOST_CMDARG1_OFFSET 0x08 /* Command Argument 1 */ +#define N32_SDHOST_TMODE_OFFSET 0x0C /* Transfer Mode */ +#define N32_SDHOST_CMDRSP0_OFFSET 0x10 /* Command Response 0 (31:0) */ +#define N32_SDHOST_CMDRSP1_OFFSET 0x14 /* Command Response 1 (63:32) */ +#define N32_SDHOST_CMDRSP2_OFFSET 0x18 /* Command Response 2 (95:64) */ +#define N32_SDHOST_CMDRSP3_OFFSET 0x1C /* Command Response 3 (127:96) */ +#define N32_SDHOST_BUFDAT_OFFSET 0x20 /* Buffer Data Port (FIFO) */ +#define N32_SDHOST_PRESTS_OFFSET 0x24 /* Present State */ +#define N32_SDHOST_CTRL1_OFFSET 0x28 /* Control 1 */ +#define N32_SDHOST_CTRL2_OFFSET 0x2C /* Control 2 */ +#define N32_SDHOST_INTSTS_OFFSET 0x30 /* Interrupt Status */ +#define N32_SDHOST_IE_OFFSET 0x34 /* Interrupt Enable */ +#define N32_SDHOST_ISE_OFFSET 0x38 /* Interrupt Signal Enable */ +#define N32_SDHOST_CTRLSTS_OFFSET 0x3C /* Control Status */ +#define N32_SDHOST_CAP0STS_OFFSET 0x40 /* Capabilities 0 */ +#define N32_SDHOST_CAP1STS_OFFSET 0x44 /* Capabilities 1 */ +#define N32_SDHOST_STSFE_OFFSET 0x50 /* Status Force Event */ +#define N32_SDHOST_ADMAESTS_OFFSET 0x54 /* ADMA Error Status */ +#define N32_SDHOST_ASADD0_OFFSET 0x58 /* ADMA System Address 0 (low 32-bit) */ +#define N32_SDHOST_ASADD1_OFFSET 0x5C /* ADMA System Address 1 (high 32-bit) */ +#define N32_SDHOST_PV0STS_OFFSET 0x60 /* Preset Value 0 Status */ +#define N32_SDHOST_PV1STS_OFFSET 0x64 /* Preset Value 1 Status */ +#define N32_SDHOST_PV2STS_OFFSET 0x68 /* Preset Value 2 Status */ +#define N32_SDHOST_PV3STS_OFFSET 0x6C /* Preset Value 3 Status */ +#define N32_SDHOST_BOOTCTRL_OFFSET 0x70 /* Boot Timeout Control */ + +/* SDMMC CFG1 Register Bit Definitions **************************************/ + +#define N32_SDMMC_CFG1_WSGM (1 << 0) /* Bit 0: Wakeup Signal Generation Mode */ +#define N32_SDMMC_CFG1_TCNT_SHIFT (1) /* Bits 1-6: Tuning Count */ +#define N32_SDMMC_CFG1_TCNT_MASK (0x3F << N32_SDMMC_CFG1_TCNT_SHIFT) +#define N32_SDMMC_CFG1_TCNT(n) ((n) << N32_SDMMC_CFG1_TCNT_SHIFT) +#define N32_SDMMC_CFG1_TCLKU (1 << 13) /* Bit 13: Timeout Clock Unit (0=KHz, 1=MHz) */ +#define N32_SDMMC_CFG1_BCLKF_SHIFT (14) /* Bits 14-21: Base Clock Frequency (MHz) */ +#define N32_SDMMC_CFG1_BCLKF_MASK (0xFF << N32_SDMMC_CFG1_BCLKF_SHIFT) +#define N32_SDMMC_CFG1_BCLKF(n) ((n) << N32_SDMMC_CFG1_BCLKF_SHIFT) +#define N32_SDMMC_CFG1_MBL_SHIFT (22) /* Bits 22-23: Max Block Length */ +#define N32_SDMMC_CFG1_MBL_MASK (3 << N32_SDMMC_CFG1_MBL_SHIFT) +#define N32_SDMMC_CFG1_MBL_512 (0 << N32_SDMMC_CFG1_MBL_SHIFT) /* 512 bytes */ +#define N32_SDMMC_CFG1_MBL_1024 (1 << N32_SDMMC_CFG1_MBL_SHIFT) /* 1024 bytes */ +#define N32_SDMMC_CFG1_MBL_2048 (2 << N32_SDMMC_CFG1_MBL_SHIFT) /* 2048 bytes */ + +/* SDMMC CFG2 Register Bit Definitions (Capabilities) ***********************/ + +#define N32_SDMMC_CFG2_EMBUS (1 << 0) /* Bit 0: 8-bit Support for Embedded Device */ +#define N32_SDMMC_CFG2_ADMA2 (1 << 1) /* Bit 1: ADMA2 Support */ +#define N32_SDMMC_CFG2_HS (1 << 2) /* Bit 2: High Speed Support */ +#define N32_SDMMC_CFG2_SDMA (1 << 3) /* Bit 3: SDMA Support */ +#define N32_SDMMC_CFG2_SRS (1 << 4) /* Bit 4: Suspend/Resume Support */ +#define N32_SDMMC_CFG2_VS33 (1 << 5) /* Bit 5: 3.3V Support */ +#define N32_SDMMC_CFG2_ASYNCIINT (1 << 9) /* Bit 9: Asynchronous Interrupt Support */ +#define N32_SDMMC_CFG2_STYP_SHIFT (10) /* Bits 10-11: Slot Type */ +#define N32_SDMMC_CFG2_STYP_MASK (3 << N32_SDMMC_CFG2_STYP_SHIFT) +#define N32_SDMMC_CFG2_STYP_REMOVABLE (0 << N32_SDMMC_CFG2_STYP_SHIFT) /* Removable card slot */ +#define N32_SDMMC_CFG2_STYP_EMBEDDED (1 << N32_SDMMC_CFG2_STYP_SHIFT) /* Embedded slot */ +#define N32_SDMMC_CFG2_SDR50 (1 << 12) /* Bit 12: SDR50 Support */ +#define N32_SDMMC_CFG2_SDR104 (1 << 13) /* Bit 13: SDR104 Support */ + +/* SDMMC CFG3 Register Bit Definitions **************************************/ + +#define N32_SDMMC_CFG3_UTFSDR50 (1 << 4) /* Bit 4: Use Tuning for SDR50 */ + +/* SDMMC Preset Value Control Registers Bit Definitions *********************/ + +/* PV0CTRL: Default Speed and Initialization */ +#define N32_SDMMC_PV0CTRL_CLKFS_INIT_SHIFT (0) /* Bits 0-9: Init clock */ +#define N32_SDMMC_PV0CTRL_CLKFS_INIT_MASK (0x3FF << N32_SDMMC_PV0CTRL_CLKFS_INIT_SHIFT) +#define N32_SDMMC_PV0CTRL_CLKFS_INIT(n) ((n) << N32_SDMMC_PV0CTRL_CLKFS_INIT_SHIFT) +#define N32_SDMMC_PV0CTRL_CLKFS_DS_SHIFT (13) /* Bits 13-22: Default speed clock */ +#define N32_SDMMC_PV0CTRL_CLKFS_DS_MASK (0x3FF << N32_SDMMC_PV0CTRL_CLKFS_DS_SHIFT) +#define N32_SDMMC_PV0CTRL_CLKFS_DS(n) ((n) << N32_SDMMC_PV0CTRL_CLKFS_DS_SHIFT) + +/* PV1CTRL: SDR12 and High Speed */ +#define N32_SDMMC_PV1CTRL_CLKFS_HS_SHIFT (0) /* Bits 0-9: HS clock */ +#define N32_SDMMC_PV1CTRL_CLKFS_HS_MASK (0x3FF << N32_SDMMC_PV1CTRL_CLKFS_HS_SHIFT) +#define N32_SDMMC_PV1CTRL_CLKFS_HS(n) ((n) << N32_SDMMC_PV1CTRL_CLKFS_HS_SHIFT) +#define N32_SDMMC_PV1CTRL_CLKFS_SDR12_SHIFT (13) /* Bits 13-22: SDR12 clock */ +#define N32_SDMMC_PV1CTRL_CLKFS_SDR12_MASK (0x3FF << N32_SDMMC_PV1CTRL_CLKFS_SDR12_SHIFT) +#define N32_SDMMC_PV1CTRL_CLKFS_SDR12(n) ((n) << N32_SDMMC_PV1CTRL_CLKFS_SDR12_SHIFT) + +/* PV2CTRL: SDR50 and SDR25 */ +#define N32_SDMMC_PV2CTRL_CLKFS_SDR25_SHIFT (0) /* Bits 0-9: SDR25 clock */ +#define N32_SDMMC_PV2CTRL_CLKFS_SDR25_MASK (0x3FF << N32_SDMMC_PV2CTRL_CLKFS_SDR25_SHIFT) +#define N32_SDMMC_PV2CTRL_CLKFS_SDR25(n) ((n) << N32_SDMMC_PV2CTRL_CLKFS_SDR25_SHIFT) +#define N32_SDMMC_PV2CTRL_CLKFS_SDR50_SHIFT (13) /* Bits 13-22: SDR50 clock */ +#define N32_SDMMC_PV2CTRL_CLKFS_SDR50_MASK (0x3FF << N32_SDMMC_PV2CTRL_CLKFS_SDR50_SHIFT) +#define N32_SDMMC_PV2CTRL_CLKFS_SDR50(n) ((n) << N32_SDMMC_PV2CTRL_CLKFS_SDR50_SHIFT) + +/* PV3CTRL: DDR50 and SDR104 */ +#define N32_SDMMC_PV3CTRL_CLKFS_DDR50_SHIFT (0) /* Bits 0-9: DDR50 clock */ +#define N32_SDMMC_PV3CTRL_CLKFS_DDR50_MASK (0x3FF << N32_SDMMC_PV3CTRL_CLKFS_DDR50_SHIFT) +#define N32_SDMMC_PV3CTRL_CLKFS_DDR50(n) ((n) << N32_SDMMC_PV3CTRL_CLKFS_DDR50_SHIFT) +#define N32_SDMMC_PV3CTRL_CLKFS_SDR104_SHIFT (13) /* Bits 13-22: SDR104 clock */ +#define N32_SDMMC_PV3CTRL_CLKFS_SDR104_MASK (0x3FF << N32_SDMMC_PV3CTRL_CLKFS_SDR104_SHIFT) +#define N32_SDMMC_PV3CTRL_CLKFS_SDR104(n) ((n) << N32_SDMMC_PV3CTRL_CLKFS_SDR104_SHIFT) + +/* SDMMC DLYCTRL Register Bit Definitions ***********************************/ + +#define N32_SDMMC_DLYCTRL_ITDS_SHIFT (0) /* Bits 0-4: Input Tap Delay Select */ +#define N32_SDMMC_DLYCTRL_ITDS_MASK (0x1F << N32_SDMMC_DLYCTRL_ITDS_SHIFT) +#define N32_SDMMC_DLYCTRL_ITDS(n) ((n) << N32_SDMMC_DLYCTRL_ITDS_SHIFT) +#define N32_SDMMC_DLYCTRL_ITDE (1 << 5) /* Bit 5: Input Tap Delay Enable */ +#define N32_SDMMC_DLYCTRL_ITCW (1 << 6) /* Bit 6: Input Tap Change Window */ +#define N32_SDMMC_DLYCTRL_OTDS_SHIFT (7) /* Bits 7-10: Output Tap Delay Select */ +#define N32_SDMMC_DLYCTRL_OTDS_MASK (0xF << N32_SDMMC_DLYCTRL_OTDS_SHIFT) +#define N32_SDMMC_DLYCTRL_OTDS(n) ((n) << N32_SDMMC_DLYCTRL_OTDS_SHIFT) +#define N32_SDMMC_DLYCTRL_OTDE (1 << 11) /* Bit 11: Output Tap Delay Enable */ + +/* SDHOST DSADD Register Bit Definitions ************************************/ + +#define N32_SDHOST_DSADD_ADD_SHIFT (0) /* Bits 0-31: Address or CMD23 parameter */ +#define N32_SDHOST_DSADD_ADD_MASK (0xFFFFFFFFUL << N32_SDHOST_DSADD_ADD_SHIFT) + +/* SDHOST BLKCFG Register Bit Definitions ***********************************/ + +#define N32_SDHOST_BLKCFG_SIZE_SHIFT (0) /* Bits 0-11: Block Size */ +#define N32_SDHOST_BLKCFG_SIZE_MASK (0xFFF << N32_SDHOST_BLKCFG_SIZE_SHIFT) +#define N32_SDHOST_BLKCFG_SIZE(n) ((n) << N32_SDHOST_BLKCFG_SIZE_SHIFT) +#define N32_SDHOST_BLKCFG_HDBS_SHIFT (12) /* Bits 12-14: SDMA Buffer Size */ +#define N32_SDHOST_BLKCFG_HDBS_MASK (7 << N32_SDHOST_BLKCFG_HDBS_SHIFT) +#define N32_SDHOST_BLKCFG_HDBS_4KB (0 << N32_SDHOST_BLKCFG_HDBS_SHIFT) +#define N32_SDHOST_BLKCFG_HDBS_8KB (1 << N32_SDHOST_BLKCFG_HDBS_SHIFT) +#define N32_SDHOST_BLKCFG_HDBS_16KB (2 << N32_SDHOST_BLKCFG_HDBS_SHIFT) +#define N32_SDHOST_BLKCFG_HDBS_32KB (3 << N32_SDHOST_BLKCFG_HDBS_SHIFT) +#define N32_SDHOST_BLKCFG_HDBS_64KB (4 << N32_SDHOST_BLKCFG_HDBS_SHIFT) +#define N32_SDHOST_BLKCFG_HDBS_128KB (5 << N32_SDHOST_BLKCFG_HDBS_SHIFT) +#define N32_SDHOST_BLKCFG_HDBS_256KB (6 << N32_SDHOST_BLKCFG_HDBS_SHIFT) +#define N32_SDHOST_BLKCFG_HDBS_512KB (7 << N32_SDHOST_BLKCFG_HDBS_SHIFT) +#define N32_SDHOST_BLKCFG_CNT_SHIFT (16) /* Bits 16-31: Block Count */ +#define N32_SDHOST_BLKCFG_CNT_MASK (0xFFFF << N32_SDHOST_BLKCFG_CNT_SHIFT) +#define N32_SDHOST_BLKCFG_CNT(n) ((n) << N32_SDHOST_BLKCFG_CNT_SHIFT) + +/* SDHOST CMDARG1 Register Bit Definitions **********************************/ + +#define N32_SDHOST_CMDARG1_ARG1_SHIFT (0) /* Bits 0-31: Command Argument */ +#define N32_SDHOST_CMDARG1_ARG1_MASK (0xFFFFFFFFUL << N32_SDHOST_CMDARG1_ARG1_SHIFT) + +/* SDHOST TMODE Register Bit Definitions ************************************/ + +#define N32_SDHOST_TMODE_DMAE (1 << 0) /* Bit 0: DMA Enable */ +#define N32_SDHOST_TMODE_BCNTE (1 << 1) /* Bit 1: Block Count Enable */ +#define N32_SDHOST_TMODE_ACMDE_SHIFT (2) /* Bits 2-3: Auto CMD Enable */ +#define N32_SDHOST_TMODE_ACMDE_MASK (3 << N32_SDHOST_TMODE_ACMDE_SHIFT) +#define N32_SDHOST_TMODE_ACMDE_DISABLE (0 << N32_SDHOST_TMODE_ACMDE_SHIFT) +#define N32_SDHOST_TMODE_ACMDE_CMD12 (1 << N32_SDHOST_TMODE_ACMDE_SHIFT) +#define N32_SDHOST_TMODE_ACMDE_CMD23 (2 << N32_SDHOST_TMODE_ACMDE_SHIFT) +#define N32_SDHOST_TMODE_DATDIR (1 << 4) /* Bit 4: Data Direction (0=Write, 1=Read) */ +#define N32_SDHOST_TMODE_BLKSEL (1 << 5) /* Bit 5: Multi/Single Block Select (1=Multi) */ +#define N32_SDHOST_TMODE_RTYPES_SHIFT (16) /* Bits 16-17: Response Type */ +#define N32_SDHOST_TMODE_RTYPES_MASK (3 << N32_SDHOST_TMODE_RTYPES_SHIFT) +#define N32_SDHOST_TMODE_RTYPES_NONE (0 << N32_SDHOST_TMODE_RTYPES_SHIFT) /* No response */ +#define N32_SDHOST_TMODE_RTYPES_136 (1 << N32_SDHOST_TMODE_RTYPES_SHIFT) /* Response length 136 bits */ +#define N32_SDHOST_TMODE_RTYPES_48 (2 << N32_SDHOST_TMODE_RTYPES_SHIFT) /* Response length 48 bits */ +#define N32_SDHOST_TMODE_RTYPES_48_BUSY (3 << N32_SDHOST_TMODE_RTYPES_SHIFT) /* 48 bits with busy */ +#define N32_SDHOST_TMODE_CRCCK (1 << 19) /* Bit 19: Command CRC Check Enable */ +#define N32_SDHOST_TMODE_CMDXCK (1 << 20) /* Bit 20: Command Index Check Enable */ +#define N32_SDHOST_TMODE_DPSEL (1 << 21) /* Bit 21: Data Present Select */ +#define N32_SDHOST_TMODE_TYPE_SHIFT (22) /* Bits 22-23: Command Type */ +#define N32_SDHOST_TMODE_TYPE_MASK (3 << N32_SDHOST_TMODE_TYPE_SHIFT) +#define N32_SDHOST_TMODE_TYPE_NORMAL (0 << N32_SDHOST_TMODE_TYPE_SHIFT) /* Normal */ +#define N32_SDHOST_TMODE_TYPE_SUSPEND (1 << N32_SDHOST_TMODE_TYPE_SHIFT) /* Suspend */ +#define N32_SDHOST_TMODE_TYPE_RESUME (2 << N32_SDHOST_TMODE_TYPE_SHIFT) /* Resume */ +#define N32_SDHOST_TMODE_TYPE_ABORT (3 << N32_SDHOST_TMODE_TYPE_SHIFT) /* Abort */ +#define N32_SDHOST_TMODE_CMDINDEX_SHIFT (24) /* Bits 24-29: Command Index */ +#define N32_SDHOST_TMODE_CMDINDEX_MASK (0x3F << N32_SDHOST_TMODE_CMDINDEX_SHIFT) +#define N32_SDHOST_TMODE_CMDINDEX(n) ((n) << N32_SDHOST_TMODE_CMDINDEX_SHIFT) + +/* SDHOST Response Registers ************************************************/ + +#define N32_SDHOST_CMDRSP0_RESP0_SHIFT (0) +#define N32_SDHOST_CMDRSP0_RESP0_MASK (0xFFFFFFFFUL << N32_SDHOST_CMDRSP0_RESP0_SHIFT) +#define N32_SDHOST_CMDRSP1_RESP1_SHIFT (0) +#define N32_SDHOST_CMDRSP1_RESP1_MASK (0xFFFFFFFFUL << N32_SDHOST_CMDRSP1_RESP1_SHIFT) +#define N32_SDHOST_CMDRSP2_RESP2_SHIFT (0) +#define N32_SDHOST_CMDRSP2_RESP2_MASK (0xFFFFFFFFUL << N32_SDHOST_CMDRSP2_RESP2_SHIFT) +#define N32_SDHOST_CMDRSP3_RESP3_SHIFT (0) +#define N32_SDHOST_CMDRSP3_RESP3_MASK (0xFFFFFFFFUL << N32_SDHOST_CMDRSP3_RESP3_SHIFT) + +/* SDHOST BUFDAT Register Bit Definitions ***********************************/ + +#define N32_SDHOST_BUFDAT_DAT_SHIFT (0) +#define N32_SDHOST_BUFDAT_DAT_MASK (0xFFFFFFFFUL << N32_SDHOST_BUFDAT_DAT_SHIFT) + +/* SDHOST PRESTS Register Bit Definitions ***********************************/ + +#define N32_SDHOST_PRESTS_CMDINHC (1 << 0) /* Bit 0: Command Inhibit (CMD) */ +#define N32_SDHOST_PRESTS_CMDINHD (1 << 1) /* Bit 1: Command Inhibit (DAT) */ +#define N32_SDHOST_PRESTS_DLACT (1 << 2) /* Bit 2: DAT Line Active */ +#define N32_SDHOST_PRESTS_RETUNREQ (1 << 3) /* Bit 3: Re-Tuning Request */ +#define N32_SDHOST_PRESTS_WTRANACT (1 << 8) /* Bit 8: Write Transfer Active */ +#define N32_SDHOST_PRESTS_RTRANACT (1 << 9) /* Bit 9: Read Transfer Active */ +#define N32_SDHOST_PRESTS_BUFW (1 << 10) /* Bit 10: Buffer Write Enable */ +#define N32_SDHOST_PRESTS_BUFR (1 << 11) /* Bit 11: Buffer Read Enable */ +#define N32_SDHOST_PRESTS_CINS (1 << 16) /* Bit 16: Card Inserted */ +#define N32_SDHOST_PRESTS_CSTSL (1 << 17) /* Bit 17: Card State Stable */ +#define N32_SDHOST_PRESTS_SDCDL (1 << 18) /* Bit 18: Card Detect Pin Level */ +#define N32_SDHOST_PRESTS_SDWPL (1 << 19) /* Bit 19: Write Protect Switch Pin Level */ +#define N32_SDHOST_PRESTS_DATLH0_SHIFT (20) /* Bits 20-23: DAT[3:0] Line Signal Level */ +#define N32_SDHOST_PRESTS_DATLH0_MASK (0xF << N32_SDHOST_PRESTS_DATLH0_SHIFT) +#define N32_SDHOST_PRESTS_CMDL (1 << 24) /* Bit 24: CMD Line Signal Level */ +#define N32_SDHOST_PRESTS_DATLH1_SHIFT (25) /* Bits 25-28: DAT[7:4] Line Signal Level */ +#define N32_SDHOST_PRESTS_DATLH1_MASK (0xF << N32_SDHOST_PRESTS_DATLH1_SHIFT) + +/* SDHOST CTRL1 Register Bit Definitions ************************************/ + +#define N32_SDHOST_CTRL1_LEDCTRL (1 << 0) /* Bit 0: LED Control */ +#define N32_SDHOST_CTRL1_DTWIDTH (1 << 1) /* Bit 1: Data Transfer Width (0=1-bit, 1=4-bit) */ +#define N32_SDHOST_CTRL1_HSEN (1 << 2) /* Bit 2: High Speed Enable */ +#define N32_SDHOST_CTRL1_DMASEL_SHIFT (3) /* Bits 3-4: DMA Select */ +#define N32_SDHOST_CTRL1_DMASEL_MASK (3 << N32_SDHOST_CTRL1_DMASEL_SHIFT) +#define N32_SDHOST_CTRL1_DMASEL_SDMA (0 << N32_SDHOST_CTRL1_DMASEL_SHIFT) +#define N32_SDHOST_CTRL1_DMASEL_ADMA2 (2 << N32_SDHOST_CTRL1_DMASEL_SHIFT) +#define N32_SDHOST_CTRL1_EDTWIDTH (1 << 5) /* Bit 5: Extended Data Transfer Width (8-bit) */ +#define N32_SDHOST_CTRL1_CDTL (1 << 6) /* Bit 6: Card Detect Test Level */ +#define N32_SDHOST_CTRL1_CDSD (1 << 7) /* Bit 7: Card Detect Signal Detection */ +#define N32_SDHOST_CTRL1_SDPWR (1 << 8) /* Bit 8: SD Bus Power */ +#define N32_SDHOST_CTRL1_SDBVSEL_SHIFT (9) /* Bits 9-11: SD Bus Voltage Select */ +#define N32_SDHOST_CTRL1_SDBVSEL_MASK (7 << N32_SDHOST_CTRL1_SDBVSEL_SHIFT) +#define N32_SDHOST_CTRL1_SDBVSEL_3V3 (7 << N32_SDHOST_CTRL1_SDBVSEL_SHIFT) +#define N32_SDHOST_CTRL1_HWRST (1 << 12) /* Bit 12: Hardware Reset (eMMC) */ +#define N32_SDHOST_CTRL1_SABGREQ (1 << 16) /* Bit 16: Stop At Block Gap Request */ +#define N32_SDHOST_CTRL1_CONTREQ (1 << 17) /* Bit 17: Continue Request */ +#define N32_SDHOST_CTRL1_RWAITCTRL (1 << 18) /* Bit 18: Read Wait Control */ +#define N32_SDHOST_CTRL1_INTATBG (1 << 19) /* Bit 19: Interrupt At Block Gap */ +#define N32_SDHOST_CTRL1_SPIMODE (1 << 20) /* Bit 20: SPI Mode Enable */ +#define N32_SDHOST_CTRL1_BOOTEN (1 << 21) /* Bit 21: Boot Enable */ +#define N32_SDHOST_CTRL1_BOOTINALT (1 << 22) /* Bit 22: Boot in Alternative Mode */ +#define N32_SDHOST_CTRL1_BOOTACKC (1 << 23) /* Bit 23: Boot Ack Check */ +#define N32_SDHOST_CTRL1_INTWKU (1 << 24) /* Bit 24: Card Interrupt Wakeup Enable */ +#define N32_SDHOST_CTRL1_INSTWKU (1 << 25) /* Bit 25: Insertion Wakeup Enable */ +#define N32_SDHOST_CTRL1_RMVWKU (1 << 26) /* Bit 26: Removal Wakeup Enable */ + +/* SDHOST CTRL2 Register Bit Definitions ************************************/ + +#define N32_SDHOST_CTRL2_INCLKE (1 << 0) /* Bit 0: Internal Clock Enable */ +#define N32_SDHOST_CTRL2_INCLKSTS (1 << 1) /* Bit 1: Internal Clock Stable */ +#define N32_SDHOST_CTRL2_SDCLKE (1 << 2) /* Bit 2: SD Clock Enable */ +#define N32_SDHOST_CTRL2_SDCLKSEL70_SHIFT (8) /* Bits 8-15: SDCLK Frequency Select [7:0] */ +#define N32_SDHOST_CTRL2_SDCLKSEL70_MASK (0xFF << N32_SDHOST_CTRL2_SDCLKSEL70_SHIFT) +#define N32_SDHOST_CTRL2_SDCLKSEL98_SHIFT (6) /* Bits 6-7: SDCLK Frequency Select [9:8] */ +#define N32_SDHOST_CTRL2_SDCLKSEL98_MASK (0x3 << N32_SDHOST_CTRL2_SDCLKSEL98_SHIFT) +#define N32_SDHOST_CTRL2_SDCLKSEL(n) (((n & 0xFF) << N32_SDHOST_CTRL2_SDCLKSEL70_SHIFT) | (((n >> 8) & 0x3) << N32_SDHOST_CTRL2_SDCLKSEL98_SHIFT)) +#define N32_SDHOST_CTRL2_DTCNT_SHIFT (16) /* Bits 16-19: Data Timeout Counter Value */ +#define N32_SDHOST_CTRL2_DTCNT_MASK (0xF << N32_SDHOST_CTRL2_DTCNT_SHIFT) +#define N32_SDHOST_CTRL2_DTCNT(n) ((n) << N32_SDHOST_CTRL2_DTCNT_SHIFT) +#define N32_SDHOST_CTRL2_SWRSTALL (1 << 24) /* Bit 24: Software Reset All */ +#define N32_SDHOST_CTRL2_SWRSTCMD (1 << 25) /* Bit 25: Software Reset CMD Line */ +#define N32_SDHOST_CTRL2_SWRSTDAT (1 << 26) /* Bit 26: Software Reset DAT Line */ + +/* SDHOST INTSTS Register Bit Definitions (Interrupt Status) ****************/ + +#define N32_SDHOST_INTSTS_CMDC (1 << 0) /* Bit 0: Command Complete */ +#define N32_SDHOST_INTSTS_TC (1 << 1) /* Bit 1: Transfer Complete */ +#define N32_SDHOST_INTSTS_BLKGAPE (1 << 2) /* Bit 2: Block Gap Event */ +#define N32_SDHOST_INTSTS_DMAINT (1 << 3) /* Bit 3: DMA Interrupt (SDMA) */ +#define N32_SDHOST_INTSTS_BUFWRDY (1 << 4) /* Bit 4: Buffer Write Ready */ +#define N32_SDHOST_INTSTS_BUFRRDY (1 << 5) /* Bit 5: Buffer Read Ready */ +#define N32_SDHOST_INTSTS_CINS (1 << 6) /* Bit 6: Card Insertion */ +#define N32_SDHOST_INTSTS_CRMV (1 << 7) /* Bit 7: Card Removal */ +#define N32_SDHOST_INTSTS_CINT (1 << 8) /* Bit 8: Card Interrupt */ +#define N32_SDHOST_INTSTS_RETUNE (1 << 12) /* Bit 12: Re-Tuning Event */ +#define N32_SDHOST_INTSTS_BOOTACKR (1 << 13) /* Bit 13: Boot Ack Received */ +#define N32_SDHOST_INTSTS_BOOTTER (1 << 14) /* Bit 14: Boot Terminate Interrupt */ +#define N32_SDHOST_INTSTS_ALLERR (1 << 15) /* Bit 15: Error Interrupt (OR of all errors) */ +#define N32_SDHOST_INTSTS_CTERR (1 << 16) /* Bit 16: Command Timeout Error */ +#define N32_SDHOST_INTSTS_CCRCERR (1 << 17) /* Bit 17: Command CRC Error */ +#define N32_SDHOST_INTSTS_CENDBERR (1 << 18) /* Bit 18: Command End Bit Error */ +#define N32_SDHOST_INTSTS_CINXERR (1 << 19) /* Bit 19: Command Index Error */ +#define N32_SDHOST_INTSTS_DTERR (1 << 20) /* Bit 20: Data Timeout Error */ +#define N32_SDHOST_INTSTS_DCRERR (1 << 21) /* Bit 21: Data CRC Error */ +#define N32_SDHOST_INTSTS_DENDERR (1 << 22) /* Bit 22: Data End Bit Error */ +#define N32_SDHOST_INTSTS_ACMDERR (1 << 24) /* Bit 24: Auto CMD Error */ +#define N32_SDHOST_INTSTS_ADMAERR (1 << 25) /* Bit 25: ADMA Error */ +#define N32_SDHOST_INTSTS_TRGRERR (1 << 28) /* Bit 28: Target Response Error (DMA) */ + +/* SDHOST IE Register Bit Definitions (Interrupt Enable) ********************/ + +#define N32_SDHOST_IE_CMDCE (1 << 0) /* Bit 0: Command Complete Enable */ +#define N32_SDHOST_IE_TCE (1 << 1) /* Bit 1: Transfer Complete Enable */ +#define N32_SDHOST_IE_BLKGAPEE (1 << 2) /* Bit 2: Block Gap Event Enable */ +#define N32_SDHOST_IE_DMAINTE (1 << 3) /* Bit 3: DMA Interrupt Enable */ +#define N32_SDHOST_IE_BUFWRDYE (1 << 4) /* Bit 4: Buffer Write Ready Enable */ +#define N32_SDHOST_IE_BUFRRDYE (1 << 5) /* Bit 5: Buffer Read Ready Enable */ +#define N32_SDHOST_IE_CINSE (1 << 6) /* Bit 6: Card Insertion Enable */ +#define N32_SDHOST_IE_CRMVE (1 << 7) /* Bit 7: Card Removal Enable */ +#define N32_SDHOST_IE_CINTE (1 << 8) /* Bit 8: Card Interrupt Enable */ +#define N32_SDHOST_IE_RTUNSE (1 << 12) /* Bit 12: Re-Tuning Event Enable */ +#define N32_SDHOST_IE_BOOTACKRE (1 << 13) /* Bit 13: Boot Ack Received Enable */ +#define N32_SDHOST_IE_BOOTTIE (1 << 14) /* Bit 14: Boot Terminate Enable */ +#define N32_SDHOST_IE_CTEE (1 << 16) /* Bit 16: Command Timeout Error Enable */ +#define N32_SDHOST_IE_CCRCEE (1 << 17) /* Bit 17: Command CRC Error Enable */ +#define N32_SDHOST_IE_CENDBEE (1 << 18) /* Bit 18: Command End Bit Error Enable */ +#define N32_SDHOST_IE_CINXEE (1 << 19) /* Bit 19: Command Index Error Enable */ +#define N32_SDHOST_IE_DTEE (1 << 20) /* Bit 20: Data Timeout Error Enable */ +#define N32_SDHOST_IE_DCRCEE (1 << 21) /* Bit 21: Data CRC Error Enable */ +#define N32_SDHOST_IE_DENDEE (1 << 22) /* Bit 22: Data End Bit Error Enable */ +#define N32_SDHOST_IE_ACMDE (1 << 24) /* Bit 24: Auto CMD Error Enable */ +#define N32_SDHOST_IE_ADMAEE (1 << 25) /* Bit 25: ADMA Error Enable */ +#define N32_SDHOST_IE_TRGREE (1 << 28) /* Bit 28: Target Response Error Enable */ + +/* SDHOST ISE Register Bit Definitions (Interrupt Signal Enable) ************/ + +#define N32_SDHOST_ISE_CMDCS (1 << 0) /* Bit 0: Command Complete Signal Enable */ +#define N32_SDHOST_ISE_TCSE (1 << 1) /* Bit 1: Transfer Complete Signal Enable */ +#define N32_SDHOST_ISE_BLKGAPESE (1 << 2) /* Bit 2: Block Gap Event Signal Enable */ +#define N32_SDHOST_ISE_DMAINTSE (1 << 3) /* Bit 3: DMA Interrupt Signal Enable */ +#define N32_SDHOST_ISE_BUFWRDYSE (1 << 4) /* Bit 4: Buffer Write Ready Signal Enable */ +#define N32_SDHOST_ISE_BUFRRDYSE (1 << 5) /* Bit 5: Buffer Read Ready Signal Enable */ +#define N32_SDHOST_ISE_CINSSE (1 << 6) /* Bit 6: Card Insertion Signal Enable */ +#define N32_SDHOST_ISE_CRMVSE (1 << 7) /* Bit 7: Card Removal Signal Enable */ +#define N32_SDHOST_ISE_CINTSE (1 << 8) /* Bit 8: Card Interrupt Signal Enable */ +#define N32_SDHOST_ISE_RTUNSE (1 << 12) /* Bit 12: Re-Tuning Event Signal Enable */ +#define N32_SDHOST_ISE_BOOTACKRSE (1 << 13) /* Bit 13: Boot Ack Received Signal Enable */ +#define N32_SDHOST_ISE_BOOTTISE (1 << 14) /* Bit 14: Boot Terminate Signal Enable */ +#define N32_SDHOST_ISE_CTESE (1 << 16) /* Bit 16: Command Timeout Error Signal Enable */ +#define N32_SDHOST_ISE_CCRCESE (1 << 17) /* Bit 17: Command CRC Error Signal Enable */ +#define N32_SDHOST_ISE_CENDBESE (1 << 18) /* Bit 18: Command End Bit Error Signal Enable */ +#define N32_SDHOST_ISE_CINXESE (1 << 19) /* Bit 19: Command Index Error Signal Enable */ +#define N32_SDHOST_ISE_DTESE (1 << 20) /* Bit 20: Data Timeout Error Signal Enable */ +#define N32_SDHOST_ISE_DCRCESE (1 << 21) /* Bit 21: Data CRC Error Signal Enable */ +#define N32_SDHOST_ISE_DENDESE (1 << 22) /* Bit 22: Data End Bit Error Signal Enable */ +#define N32_SDHOST_ISE_ACMDESE (1 << 24) /* Bit 24: Auto CMD Error Signal Enable */ +#define N32_SDHOST_ISE_ADMAESE (1 << 25) /* Bit 25: ADMA Error Signal Enable */ +#define N32_SDHOST_ISE_TRGRESE (1 << 28) /* Bit 28: Target Response Error Signal Enable */ + +/* SDHOST CTRLSTS Register Bit Definitions **********************************/ + +#define N32_SDHOST_CTRLSTS_ACMD12NE (1 << 0) /* Bit 0: Auto CMD12 Not Executed */ +#define N32_SDHOST_CTRLSTS_ACMDTE (1 << 1) /* Bit 1: Auto CMD Timeout Error */ +#define N32_SDHOST_CTRLSTS_ACMDCRCE (1 << 2) /* Bit 2: Auto CMD CRC Error */ +#define N32_SDHOST_CTRLSTS_ACMDEBE (1 << 3) /* Bit 3: Auto CMD End Bit Error */ +#define N32_SDHOST_CTRLSTS_ACMDINXE (1 << 4) /* Bit 4: Auto CMD Index Error */ +#define N32_SDHOST_CTRLSTS_ACMD12E (1 << 7) /* Bit 7: Auto CMD12 Not Issued */ +#define N32_SDHOST_CTRLSTS_UHSMOD_SHIFT (16) /* Bits 16-18: UHS Mode Select */ +#define N32_SDHOST_CTRLSTS_UHSMOD_MASK (7 << N32_SDHOST_CTRLSTS_UHSMOD_SHIFT) +#define N32_SDHOST_CTRLSTS_UHSMOD_SDR12 (0 << N32_SDHOST_CTRLSTS_UHSMOD_SHIFT) +#define N32_SDHOST_CTRLSTS_UHSMOD_SDR25 (1 << N32_SDHOST_CTRLSTS_UHSMOD_SHIFT) +#define N32_SDHOST_CTRLSTS_UHSMOD_SDR50 (2 << N32_SDHOST_CTRLSTS_UHSMOD_SHIFT) +#define N32_SDHOST_CTRLSTS_UHSMOD_SDR104 (3 << N32_SDHOST_CTRLSTS_UHSMOD_SHIFT) +#define N32_SDHOST_CTRLSTS_UHSMOD_DDR50 (4 << N32_SDHOST_CTRLSTS_UHSMOD_SHIFT) +#define N32_SDHOST_CTRLSTS_V18SE (1 << 19) /* Bit 19: 1.8V Signaling Enable */ +#define N32_SDHOST_CTRLSTS_ETUN (1 << 22) /* Bit 22: Execute Tuning */ +#define N32_SDHOST_CTRLSTS_SCS (1 << 23) /* Bit 23: Sampling Clock Select */ +#define N32_SDHOST_CTRLSTS_ASYNCIE (1 << 30) /* Bit 30: Asynchronous Interrupt Enable */ +#define N32_SDHOST_CTRLSTS_PREVE (1 << 31) /* Bit 31: Preset Value Enable */ + +/* SDHOST CAP0STS Register Bit Definitions (Capabilities 0) *****************/ + +#define N32_SDHOST_CAP0STS_TCLKU (1 << 7) /* Bit 7: Timeout Clock Unit (0=KHz, 1=MHz) */ +#define N32_SDHOST_CAP0STS_BCLKF_SHIFT (8) /* Bits 8-15: Base Clock Frequency (MHz) */ +#define N32_SDHOST_CAP0STS_BCLKF_MASK (0xFF << N32_SDHOST_CAP0STS_BCLKF_SHIFT) +#define N32_SDHOST_CAP0STS_MBL_SHIFT (16) /* Bits 16-17: Max Block Length */ +#define N32_SDHOST_CAP0STS_MBL_MASK (3 << N32_SDHOST_CAP0STS_MBL_SHIFT) +#define N32_SDHOST_CAP0STS_MBL_512 (0 << N32_SDHOST_CAP0STS_MBL_SHIFT) +#define N32_SDHOST_CAP0STS_MBL_1024 (1 << N32_SDHOST_CAP0STS_MBL_SHIFT) +#define N32_SDHOST_CAP0STS_MBL_2048 (2 << N32_SDHOST_CAP0STS_MBL_SHIFT) +#define N32_SDHOST_CAP0STS_EMBUS (1 << 18) /* Bit 18: 8-bit Support for Embedded Device */ +#define N32_SDHOST_CAP0STS_ADMA2 (1 << 19) /* Bit 19: ADMA2 Support */ +#define N32_SDHOST_CAP0STS_HS (1 << 21) /* Bit 21: High Speed Support */ +#define N32_SDHOST_CAP0STS_SDMA (1 << 22) /* Bit 22: SDMA Support */ +#define N32_SDHOST_CAP0STS_SRS (1 << 23) /* Bit 23: Suspend/Resume Support */ +#define N32_SDHOST_CAP0STS_VS33 (1 << 24) /* Bit 24: 3.3V Support */ +#define N32_SDHOST_CAP0STS_ASYNCIINT (1 << 29) /* Bit 29: Asynchronous Interrupt Support */ +#define N32_SDHOST_CAP0STS_STYP_SHIFT (30) /* Bits 30-31: Slot Type */ +#define N32_SDHOST_CAP0STS_STYP_MASK (3 << N32_SDHOST_CAP0STS_STYP_SHIFT) +#define N32_SDHOST_CAP0STS_STYP_REMOVABLE (0 << N32_SDHOST_CAP0STS_STYP_SHIFT) +#define N32_SDHOST_CAP0STS_STYP_EMBEDDED (1 << N32_SDHOST_CAP0STS_STYP_SHIFT) + +/* SDHOST CAP1STS Register Bit Definitions (Capabilities 1) *****************/ + +#define N32_SDHOST_CAP1STS_SDR50 (1 << 0) /* Bit 0: SDR50 Support */ +#define N32_SDHOST_CAP1STS_SDR104 (1 << 1) /* Bit 1: SDR104 Support */ +#define N32_SDHOST_CAP1STS_DDR50 (1 << 2) /* Bit 2: DDR50 Support */ +#define N32_SDHOST_CAP1STS_UTFSDR50 (1 << 13) /* Bit 13: Use Tuning for SDR50 */ +#define N32_SDHOST_CAP1STS_SPIMOD (1 << 24) /* Bit 24: SPI Mode Support */ +#define N32_SDHOST_CAP1STS_SPIBMOD (1 << 25) /* Bit 25: SPI Block Mode Support */ + +/* SDHOST STSFE Register Bit Definitions (Force Event) **********************/ + +#define N32_SDHOST_STSFE_ACMD12NE (1 << 0) /* Bit 0: Force Auto CMD12 Not Executed */ +#define N32_SDHOST_STSFE_ACMDTE (1 << 1) /* Bit 1: Force Auto CMD Timeout Error */ +#define N32_SDHOST_STSFE_ACMDCRCE (1 << 2) /* Bit 2: Force Auto CMD CRC Error */ +#define N32_SDHOST_STSFE_ACMDEBE (1 << 3) /* Bit 3: Force Auto CMD End Bit Error */ +#define N32_SDHOST_STSFE_ACMDINXE (1 << 4) /* Bit 4: Force Auto CMD Index Error */ +#define N32_SDHOST_STSFE_ACMD12E (1 << 7) /* Bit 7: Force Auto CMD12 Not Issued */ +#define N32_SDHOST_STSFE_CTE (1 << 16) /* Bit 16: Force Command Timeout Error */ +#define N32_SDHOST_STSFE_CCRCE (1 << 17) /* Bit 17: Force Command CRC Error */ +#define N32_SDHOST_STSFE_CEBE (1 << 18) /* Bit 18: Force Command End Bit Error */ +#define N32_SDHOST_STSFE_CINXE (1 << 19) /* Bit 19: Force Command Index Error */ +#define N32_SDHOST_STSFE_DTE (1 << 20) /* Bit 20: Force Data Timeout Error */ +#define N32_SDHOST_STSFE_DCRCE (1 << 21) /* Bit 21: Force Data CRC Error */ +#define N32_SDHOST_STSFE_DEBE (1 << 22) /* Bit 22: Force Data End Bit Error */ +#define N32_SDHOST_STSFE_ACMDE (1 << 24) /* Bit 24: Force Auto CMD Error */ +#define N32_SDHOST_STSFE_ADMAE (1 << 25) /* Bit 25: Force ADMA Error */ +#define N32_SDHOST_STSFE_TRGRE (1 << 28) /* Bit 28: Force Target Response Error */ + +/* SDHOST ADMAESTS Register Bit Definitions *********************************/ + +#define N32_SDHOST_ADMAESTS_ADMAE_SHIFT (0) /* Bits 0-1: ADMA Error State */ +#define N32_SDHOST_ADMAESTS_ADMAE_MASK (3 << N32_SDHOST_ADMAESTS_ADMAE_SHIFT) +#define N32_SDHOST_ADMAESTS_ST_STOP (0 << N32_SDHOST_ADMAESTS_ADMAE_SHIFT) /* Stop DMA */ +#define N32_SDHOST_ADMAESTS_ST_FDS (1 << N32_SDHOST_ADMAESTS_ADMAE_SHIFT) /* Fetch Descriptor */ +#define N32_SDHOST_ADMAESTS_ST_TFR (3 << N32_SDHOST_ADMAESTS_ADMAE_SHIFT) /* Transfer Data */ +#define N32_SDHOST_ADMAESTS_ADMALME (1 << 2) /* Bit 2: ADMA Length Mismatch Error */ + +/* SDHOST ASADD0/1 Register Bit Definitions *********************************/ + +#define N32_SDHOST_ASADD0_ADD_SHIFT (0) /* Bits 0-31: Low 32-bit address */ +#define N32_SDHOST_ASADD0_ADD_MASK (0xFFFFFFFFUL << N32_SDHOST_ASADD0_ADD_SHIFT) +#define N32_SDHOST_ASADD1_ADD_SHIFT (0) /* Bits 0-31: High 32-bit address */ +#define N32_SDHOST_ASADD1_ADD_MASK (0xFFFFFFFFUL << N32_SDHOST_ASADD1_ADD_SHIFT) + +/* SDHOST Preset Value Status Registers (same format as control) ************/ + +#define N32_SDHOST_PV0STS_CLKFS_INIT_SHIFT (0) +#define N32_SDHOST_PV0STS_CLKFS_INIT_MASK (0x3FF << N32_SDHOST_PV0STS_CLKFS_INIT_SHIFT) +#define N32_SDHOST_PV0STS_CLKFS_DS_SHIFT (16) +#define N32_SDHOST_PV0STS_CLKFS_DS_MASK (0x3FF << N32_SDHOST_PV0STS_CLKFS_DS_SHIFT) + +#define N32_SDHOST_PV1STS_CLKFS_HS_SHIFT (0) +#define N32_SDHOST_PV1STS_CLKFS_HS_MASK (0x3FF << N32_SDHOST_PV1STS_CLKFS_HS_SHIFT) +#define N32_SDHOST_PV1STS_CLKFS_SDR12_SHIFT (16) +#define N32_SDHOST_PV1STS_CLKFS_SDR12_MASK (0x3FF << N32_SDHOST_PV1STS_CLKFS_SDR12_SHIFT) + +#define N32_SDHOST_PV2STS_CLKFS_SDR25_SHIFT (0) +#define N32_SDHOST_PV2STS_CLKFS_SDR25_MASK (0x3FF << N32_SDHOST_PV2STS_CLKFS_SDR25_SHIFT) +#define N32_SDHOST_PV2STS_CLKFS_SDR50_SHIFT (16) +#define N32_SDHOST_PV2STS_CLKFS_SDR50_MASK (0x3FF << N32_SDHOST_PV2STS_CLKFS_SDR50_SHIFT) + +#define N32_SDHOST_PV3STS_CLKFS_DDR50_SHIFT (0) +#define N32_SDHOST_PV3STS_CLKFS_DDR50_MASK (0x3FF << N32_SDHOST_PV3STS_CLKFS_DDR50_SHIFT) +#define N32_SDHOST_PV3STS_CLKFS_SDR104_SHIFT (16) +#define N32_SDHOST_PV3STS_CLKFS_SDR104_MASK (0x3FF << N32_SDHOST_PV3STS_CLKFS_SDR104_SHIFT) + +/* SDHOST BOOTCTRL Register Bit Definitions *********************************/ + +#define N32_SDHOST_BOOTCTRL_CNT_SHIFT (0) /* Bits 0-31: Boot Data Timeout Counter Value */ +#define N32_SDHOST_BOOTCTRL_CNT_MASK (0xFFFFFFFFUL << N32_SDHOST_BOOTCTRL_CNT_SHIFT) +#define N32_SDHOST_BOOTCTRL_CNT(n) ((n) << N32_SDHOST_BOOTCTRL_CNT_SHIFT) + +/* ADMA2 Descriptor Structure (32-bit addressing) ***************************/ + +#define N32_ADMA_ACT_SHIFT (4) /* Bits 4-5: Action */ +#define N32_ADMA_ACT_MASK (3 << N32_ADMA_ACT_SHIFT) +#define N32_ADMA_ACT_NOP (0 << N32_ADMA_ACT_SHIFT) /* No operation */ +#define N32_ADMA_ACT_RSV (1 << N32_ADMA_ACT_SHIFT) /* Reserved */ +#define N32_ADMA_ACT_TRAN (2 << N32_ADMA_ACT_SHIFT) /* Transfer data */ +#define N32_ADMA_ACT_LINK (3 << N32_ADMA_ACT_SHIFT) /* Link to another table */ +#define N32_ADMA_ENTRY_INT (1 << 2) /* Bit 2: Generate DMA Interrupt */ +#define N32_ADMA_ENTRY_END (1 << 1) /* Bit 1: End of descriptor list */ +#define N32_ADMA_ENTRY_VALID (1 << 0) /* Bit 0: Descriptor valid */ + +struct n32_sdmmc_adma_desc_s +{ + uint16_t attr; /* Attributes (ACT, INT, END, VALID) */ + uint16_t len; /* Transfer length */ + uint32_t *addr; /* 32-bit system address */ +}; + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_SDMMC_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_tim.h b/arch/arm/src/n32h7/hardware/n32h7_tim.h new file mode 100644 index 0000000000000..2de09b91b19b6 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_tim.h @@ -0,0 +1,1697 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_tim.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32_TIM_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32_TIM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/* The N32H7 timer family includes: + * - 4x Advanced Timers (ATIM1-4) + * - 7x General-purpose Timers A (GTIMA1-7) + * - 3x General-purpose Timers B (GTIMB1-3) + * - 4x Basic Timers (BTIM1-4) + */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ========================================================================== + * ADVANCED TIMERS (ATIM1-4) + * ========================================================================== + */ + +/* Register Offsets - ATIM (common for all ATIM1-4) *************************/ + +#define N32_ATIM_CTRL1_OFFSET 0x0000 /* Control register 1 */ +#define N32_ATIM_CTRL2_OFFSET 0x0004 /* Control register 2 */ +#define N32_ATIM_STS_OFFSET 0x0008 /* Status register */ +#define N32_ATIM_ETGEN_OFFSET 0x000c /* Event generation register */ +#define N32_ATIM_SMCTRL_OFFSET 0x0010 /* Slave mode control register */ +#define N32_ATIM_DINTEN_OFFSET 0x0014 /* DMA/Interrupt enable register */ +#define N32_ATIM_CCMOD1_OFFSET 0x0018 /* Capture/compare mode register 1 */ +#define N32_ATIM_CCMOD2_OFFSET 0x001c /* Capture/compare mode register 2 */ +#define N32_ATIM_CCMOD3_OFFSET 0x0020 /* Capture/compare mode register 3 */ +#define N32_ATIM_CCEN_OFFSET 0x0024 /* Capture/compare enable register */ +#define N32_ATIM_CCDAT1_OFFSET 0x0028 /* Capture/compare register 1 */ +#define N32_ATIM_CCDAT2_OFFSET 0x002c /* Capture/compare register 2 */ +#define N32_ATIM_CCDAT3_OFFSET 0x0030 /* Capture/compare register 3 */ +#define N32_ATIM_CCDAT4_OFFSET 0x0034 /* Capture/compare register 4 */ +#define N32_ATIM_CCDAT5_OFFSET 0x0038 /* Capture/compare register 5 */ +#define N32_ATIM_CCDAT6_OFFSET 0x003c /* Capture/compare register 6 */ +#define N32_ATIM_PSC_OFFSET 0x0040 /* Prescaler */ +#define N32_ATIM_AR_OFFSET 0x0044 /* Auto-reload register */ +#define N32_ATIM_CNT_OFFSET 0x0048 /* Counter */ +#define N32_ATIM_REPCNT_OFFSET 0x004c /* Repetition counter register */ +#define N32_ATIM_BKDT_OFFSET 0x0050 /* Break and dead-time register */ +#define N32_ATIM_CCDAT7_OFFSET 0x0054 /* Capture/compare register 7 */ +#define N32_ATIM_CCDAT8_OFFSET 0x0058 /* Capture/compare register 8 */ +#define N32_ATIM_CCDAT9_OFFSET 0x005c /* Capture/compare register 9 */ +#define N32_ATIM_BKFR_OFFSET 0x0060 /* Break 1 filter register */ +#define N32_ATIM_INSEL_OFFSET 0x0078 /* Input selection register */ +#define N32_ATIM_AF1_OFFSET 0x007c /* Alternate function register 1 */ +#define N32_ATIM_AF2_OFFSET 0x0080 /* Alternate function register 2 */ +#define N32_ATIM_BKFR2_OFFSET 0x0084 /* Break 2 filter register */ +#define N32_ATIM_DCTRL_OFFSET 0x0094 /* DMA control register */ +#define N32_ATIM_DADDR_OFFSET 0x0098 /* DMA address for burst mode */ + +/* Register Addresses - ATIM1 ***********************************************/ + +#define N32_ATIM1_CTRL1 (N32_ATIMER1_BASE + N32_ATIM_CTRL1_OFFSET) +#define N32_ATIM1_CTRL2 (N32_ATIMER1_BASE + N32_ATIM_CTRL2_OFFSET) +#define N32_ATIM1_STS (N32_ATIMER1_BASE + N32_ATIM_STS_OFFSET) +#define N32_ATIM1_ETGEN (N32_ATIMER1_BASE + N32_ATIM_ETGEN_OFFSET) +#define N32_ATIM1_SMCTRL (N32_ATIMER1_BASE + N32_ATIM_SMCTRL_OFFSET) +#define N32_ATIM1_DINTEN (N32_ATIMER1_BASE + N32_ATIM_DINTEN_OFFSET) +#define N32_ATIM1_CCMOD1 (N32_ATIMER1_BASE + N32_ATIM_CCMOD1_OFFSET) +#define N32_ATIM1_CCMOD2 (N32_ATIMER1_BASE + N32_ATIM_CCMOD2_OFFSET) +#define N32_ATIM1_CCMOD3 (N32_ATIMER1_BASE + N32_ATIM_CCMOD3_OFFSET) +#define N32_ATIM1_CCEN (N32_ATIMER1_BASE + N32_ATIM_CCEN_OFFSET) +#define N32_ATIM1_CCDAT1 (N32_ATIMER1_BASE + N32_ATIM_CCDAT1_OFFSET) +#define N32_ATIM1_CCDAT2 (N32_ATIMER1_BASE + N32_ATIM_CCDAT2_OFFSET) +#define N32_ATIM1_CCDAT3 (N32_ATIMER1_BASE + N32_ATIM_CCDAT3_OFFSET) +#define N32_ATIM1_CCDAT4 (N32_ATIMER1_BASE + N32_ATIM_CCDAT4_OFFSET) +#define N32_ATIM1_CCDAT5 (N32_ATIMER1_BASE + N32_ATIM_CCDAT5_OFFSET) +#define N32_ATIM1_CCDAT6 (N32_ATIMER1_BASE + N32_ATIM_CCDAT6_OFFSET) +#define N32_ATIM1_PSC (N32_ATIMER1_BASE + N32_ATIM_PSC_OFFSET) +#define N32_ATIM1_AR (N32_ATIMER1_BASE + N32_ATIM_AR_OFFSET) +#define N32_ATIM1_CNT (N32_ATIMER1_BASE + N32_ATIM_CNT_OFFSET) +#define N32_ATIM1_REPCNT (N32_ATIMER1_BASE + N32_ATIM_REPCNT_OFFSET) +#define N32_ATIM1_BKDT (N32_ATIMER1_BASE + N32_ATIM_BKDT_OFFSET) +#define N32_ATIM1_CCDAT7 (N32_ATIMER1_BASE + N32_ATIM_CCDAT7_OFFSET) +#define N32_ATIM1_CCDAT8 (N32_ATIMER1_BASE + N32_ATIM_CCDAT8_OFFSET) +#define N32_ATIM1_CCDAT9 (N32_ATIMER1_BASE + N32_ATIM_CCDAT9_OFFSET) +#define N32_ATIM1_BKFR (N32_ATIMER1_BASE + N32_ATIM_BKFR_OFFSET) +#define N32_ATIM1_INSEL (N32_ATIMER1_BASE + N32_ATIM_INSEL_OFFSET) +#define N32_ATIM1_AF1 (N32_ATIMER1_BASE + N32_ATIM_AF1_OFFSET) +#define N32_ATIM1_AF2 (N32_ATIMER1_BASE + N32_ATIM_AF2_OFFSET) +#define N32_ATIM1_BKFR2 (N32_ATIMER1_BASE + N32_ATIM_BKFR2_OFFSET) +#define N32_ATIM1_DCTRL (N32_ATIMER1_BASE + N32_ATIM_DCTRL_OFFSET) +#define N32_ATIM1_DADDR (N32_ATIMER1_BASE + N32_ATIM_DADDR_OFFSET) + +/* Register Addresses - ATIM2 ***********************************************/ + +#define N32_ATIM2_CTRL1 (N32_ATIMER2_BASE + N32_ATIM_CTRL1_OFFSET) +#define N32_ATIM2_CTRL2 (N32_ATIMER2_BASE + N32_ATIM_CTRL2_OFFSET) +#define N32_ATIM2_STS (N32_ATIMER2_BASE + N32_ATIM_STS_OFFSET) +#define N32_ATIM2_ETGEN (N32_ATIMER2_BASE + N32_ATIM_ETGEN_OFFSET) +#define N32_ATIM2_SMCTRL (N32_ATIMER2_BASE + N32_ATIM_SMCTRL_OFFSET) +#define N32_ATIM2_DINTEN (N32_ATIMER2_BASE + N32_ATIM_DINTEN_OFFSET) +#define N32_ATIM2_CCMOD1 (N32_ATIMER2_BASE + N32_ATIM_CCMOD1_OFFSET) +#define N32_ATIM2_CCMOD2 (N32_ATIMER2_BASE + N32_ATIM_CCMOD2_OFFSET) +#define N32_ATIM2_CCMOD3 (N32_ATIMER2_BASE + N32_ATIM_CCMOD3_OFFSET) +#define N32_ATIM2_CCEN (N32_ATIMER2_BASE + N32_ATIM_CCEN_OFFSET) +#define N32_ATIM2_CCDAT1 (N32_ATIMER2_BASE + N32_ATIM_CCDAT1_OFFSET) +#define N32_ATIM2_CCDAT2 (N32_ATIMER2_BASE + N32_ATIM_CCDAT2_OFFSET) +#define N32_ATIM2_CCDAT3 (N32_ATIMER2_BASE + N32_ATIM_CCDAT3_OFFSET) +#define N32_ATIM2_CCDAT4 (N32_ATIMER2_BASE + N32_ATIM_CCDAT4_OFFSET) +#define N32_ATIM2_CCDAT5 (N32_ATIMER2_BASE + N32_ATIM_CCDAT5_OFFSET) +#define N32_ATIM2_CCDAT6 (N32_ATIMER2_BASE + N32_ATIM_CCDAT6_OFFSET) +#define N32_ATIM2_PSC (N32_ATIMER2_BASE + N32_ATIM_PSC_OFFSET) +#define N32_ATIM2_AR (N32_ATIMER2_BASE + N32_ATIM_AR_OFFSET) +#define N32_ATIM2_CNT (N32_ATIMER2_BASE + N32_ATIM_CNT_OFFSET) +#define N32_ATIM2_REPCNT (N32_ATIMER2_BASE + N32_ATIM_REPCNT_OFFSET) +#define N32_ATIM2_BKDT (N32_ATIMER2_BASE + N32_ATIM_BKDT_OFFSET) +#define N32_ATIM2_CCDAT7 (N32_ATIMER2_BASE + N32_ATIM_CCDAT7_OFFSET) +#define N32_ATIM2_CCDAT8 (N32_ATIMER2_BASE + N32_ATIM_CCDAT8_OFFSET) +#define N32_ATIM2_CCDAT9 (N32_ATIMER2_BASE + N32_ATIM_CCDAT9_OFFSET) +#define N32_ATIM2_BKFR (N32_ATIMER2_BASE + N32_ATIM_BKFR_OFFSET) +#define N32_ATIM2_INSEL (N32_ATIMER2_BASE + N32_ATIM_INSEL_OFFSET) +#define N32_ATIM2_AF1 (N32_ATIMER2_BASE + N32_ATIM_AF1_OFFSET) +#define N32_ATIM2_AF2 (N32_ATIMER2_BASE + N32_ATIM_AF2_OFFSET) +#define N32_ATIM2_BKFR2 (N32_ATIMER2_BASE + N32_ATIM_BKFR2_OFFSET) +#define N32_ATIM2_DCTRL (N32_ATIMER2_BASE + N32_ATIM_DCTRL_OFFSET) +#define N32_ATIM2_DADDR (N32_ATIMER2_BASE + N32_ATIM_DADDR_OFFSET) + +/* Register Addresses - ATIM3 ***********************************************/ + +#define N32_ATIM3_CTRL1 (N32_ATIMER3_BASE + N32_ATIM_CTRL1_OFFSET) +#define N32_ATIM3_CTRL2 (N32_ATIMER3_BASE + N32_ATIM_CTRL2_OFFSET) +#define N32_ATIM3_STS (N32_ATIMER3_BASE + N32_ATIM_STS_OFFSET) +#define N32_ATIM3_ETGEN (N32_ATIMER3_BASE + N32_ATIM_ETGEN_OFFSET) +#define N32_ATIM3_SMCTRL (N32_ATIMER3_BASE + N32_ATIM_SMCTRL_OFFSET) +#define N32_ATIM3_DINTEN (N32_ATIMER3_BASE + N32_ATIM_DINTEN_OFFSET) +#define N32_ATIM3_CCMOD1 (N32_ATIMER3_BASE + N32_ATIM_CCMOD1_OFFSET) +#define N32_ATIM3_CCMOD2 (N32_ATIMER3_BASE + N32_ATIM_CCMOD2_OFFSET) +#define N32_ATIM3_CCMOD3 (N32_ATIMER3_BASE + N32_ATIM_CCMOD3_OFFSET) +#define N32_ATIM3_CCEN (N32_ATIMER3_BASE + N32_ATIM_CCEN_OFFSET) +#define N32_ATIM3_CCDAT1 (N32_ATIMER3_BASE + N32_ATIM_CCDAT1_OFFSET) +#define N32_ATIM3_CCDAT2 (N32_ATIMER3_BASE + N32_ATIM_CCDAT2_OFFSET) +#define N32_ATIM3_CCDAT3 (N32_ATIMER3_BASE + N32_ATIM_CCDAT3_OFFSET) +#define N32_ATIM3_CCDAT4 (N32_ATIMER3_BASE + N32_ATIM_CCDAT4_OFFSET) +#define N32_ATIM3_CCDAT5 (N32_ATIMER3_BASE + N32_ATIM_CCDAT5_OFFSET) +#define N32_ATIM3_CCDAT6 (N32_ATIMER3_BASE + N32_ATIM_CCDAT6_OFFSET) +#define N32_ATIM3_PSC (N32_ATIMER3_BASE + N32_ATIM_PSC_OFFSET) +#define N32_ATIM3_AR (N32_ATIMER3_BASE + N32_ATIM_AR_OFFSET) +#define N32_ATIM3_CNT (N32_ATIMER3_BASE + N32_ATIM_CNT_OFFSET) +#define N32_ATIM3_REPCNT (N32_ATIMER3_BASE + N32_ATIM_REPCNT_OFFSET) +#define N32_ATIM3_BKDT (N32_ATIMER3_BASE + N32_ATIM_BKDT_OFFSET) +#define N32_ATIM3_CCDAT7 (N32_ATIMER3_BASE + N32_ATIM_CCDAT7_OFFSET) +#define N32_ATIM3_CCDAT8 (N32_ATIMER3_BASE + N32_ATIM_CCDAT8_OFFSET) +#define N32_ATIM3_CCDAT9 (N32_ATIMER3_BASE + N32_ATIM_CCDAT9_OFFSET) +#define N32_ATIM3_BKFR (N32_ATIMER3_BASE + N32_ATIM_BKFR_OFFSET) +#define N32_ATIM3_INSEL (N32_ATIMER3_BASE + N32_ATIM_INSEL_OFFSET) +#define N32_ATIM3_AF1 (N32_ATIMER3_BASE + N32_ATIM_AF1_OFFSET) +#define N32_ATIM3_AF2 (N32_ATIMER3_BASE + N32_ATIM_AF2_OFFSET) +#define N32_ATIM3_BKFR2 (N32_ATIMER3_BASE + N32_ATIM_BKFR2_OFFSET) +#define N32_ATIM3_DCTRL (N32_ATIMER3_BASE + N32_ATIM_DCTRL_OFFSET) +#define N32_ATIM3_DADDR (N32_ATIMER3_BASE + N32_ATIM_DADDR_OFFSET) + +/* Register Addresses - ATIM4 ***********************************************/ + +#define N32_ATIM4_CTRL1 (N32_ATIMER4_BASE + N32_ATIM_CTRL1_OFFSET) +#define N32_ATIM4_CTRL2 (N32_ATIMER4_BASE + N32_ATIM_CTRL2_OFFSET) +#define N32_ATIM4_STS (N32_ATIMER4_BASE + N32_ATIM_STS_OFFSET) +#define N32_ATIM4_ETGEN (N32_ATIMER4_BASE + N32_ATIM_ETGEN_OFFSET) +#define N32_ATIM4_SMCTRL (N32_ATIMER4_BASE + N32_ATIM_SMCTRL_OFFSET) +#define N32_ATIM4_DINTEN (N32_ATIMER4_BASE + N32_ATIM_DINTEN_OFFSET) +#define N32_ATIM4_CCMOD1 (N32_ATIMER4_BASE + N32_ATIM_CCMOD1_OFFSET) +#define N32_ATIM4_CCMOD2 (N32_ATIMER4_BASE + N32_ATIM_CCMOD2_OFFSET) +#define N32_ATIM4_CCMOD3 (N32_ATIMER4_BASE + N32_ATIM_CCMOD3_OFFSET) +#define N32_ATIM4_CCEN (N32_ATIMER4_BASE + N32_ATIM_CCEN_OFFSET) +#define N32_ATIM4_CCDAT1 (N32_ATIMER4_BASE + N32_ATIM_CCDAT1_OFFSET) +#define N32_ATIM4_CCDAT2 (N32_ATIMER4_BASE + N32_ATIM_CCDAT2_OFFSET) +#define N32_ATIM4_CCDAT3 (N32_ATIMER4_BASE + N32_ATIM_CCDAT3_OFFSET) +#define N32_ATIM4_CCDAT4 (N32_ATIMER4_BASE + N32_ATIM_CCDAT4_OFFSET) +#define N32_ATIM4_CCDAT5 (N32_ATIMER4_BASE + N32_ATIM_CCDAT5_OFFSET) +#define N32_ATIM4_CCDAT6 (N32_ATIMER4_BASE + N32_ATIM_CCDAT6_OFFSET) +#define N32_ATIM4_PSC (N32_ATIMER4_BASE + N32_ATIM_PSC_OFFSET) +#define N32_ATIM4_AR (N32_ATIMER4_BASE + N32_ATIM_AR_OFFSET) +#define N32_ATIM4_CNT (N32_ATIMER4_BASE + N32_ATIM_CNT_OFFSET) +#define N32_ATIM4_REPCNT (N32_ATIMER4_BASE + N32_ATIM_REPCNT_OFFSET) +#define N32_ATIM4_BKDT (N32_ATIMER4_BASE + N32_ATIM_BKDT_OFFSET) +#define N32_ATIM4_CCDAT7 (N32_ATIMER4_BASE + N32_ATIM_CCDAT7_OFFSET) +#define N32_ATIM4_CCDAT8 (N32_ATIMER4_BASE + N32_ATIM_CCDAT8_OFFSET) +#define N32_ATIM4_CCDAT9 (N32_ATIMER4_BASE + N32_ATIM_CCDAT9_OFFSET) +#define N32_ATIM4_BKFR (N32_ATIMER4_BASE + N32_ATIM_BKFR_OFFSET) +#define N32_ATIM4_INSEL (N32_ATIMER4_BASE + N32_ATIM_INSEL_OFFSET) +#define N32_ATIM4_AF1 (N32_ATIMER4_BASE + N32_ATIM_AF1_OFFSET) +#define N32_ATIM4_AF2 (N32_ATIMER4_BASE + N32_ATIM_AF2_OFFSET) +#define N32_ATIM4_BKFR2 (N32_ATIMER4_BASE + N32_ATIM_BKFR2_OFFSET) +#define N32_ATIM4_DCTRL (N32_ATIMER4_BASE + N32_ATIM_DCTRL_OFFSET) +#define N32_ATIM4_DADDR (N32_ATIMER4_BASE + N32_ATIM_DADDR_OFFSET) + +/* Bitfield Definitions - ATIM **********************************************/ + +/* Control register 1 (N32_ATIM_CTRL1) */ + +#define N32_ATIM_CTRL1_CNTEN (1 << 0) /* Counter enable */ +#define N32_ATIM_CTRL1_DIR (1 << 1) /* Direction */ +#define N32_ATIM_CTRL1_CAMSEL_SHIFT (2) /* Center-aligned mode selection */ +#define N32_ATIM_CTRL1_CAMSEL_MASK (3 << N32_ATIM_CTRL1_CAMSEL_SHIFT) +# define N32_ATIM_CTRL1_EDGE (0 << N32_ATIM_CTRL1_CAMSEL_SHIFT) /* Edge-aligned */ +# define N32_ATIM_CTRL1_CENTER1 (1 << N32_ATIM_CTRL1_CAMSEL_SHIFT) /* Center-aligned 1 */ +# define N32_ATIM_CTRL1_CENTER2 (2 << N32_ATIM_CTRL1_CAMSEL_SHIFT) /* Center-aligned 2 */ +# define N32_ATIM_CTRL1_CENTER3 (3 << N32_ATIM_CTRL1_CAMSEL_SHIFT) /* Center-aligned 3 */ +#define N32_ATIM_CTRL1_UPRS (1 << 4) /* Update request source */ +#define N32_ATIM_CTRL1_UPDIS (1 << 5) /* Update disable */ +#define N32_ATIM_CTRL1_CLKD_SHIFT (6) /* Clock division */ +#define N32_ATIM_CTRL1_CLKD_MASK (3 << N32_ATIM_CTRL1_CLKD_SHIFT) +# define N32_ATIM_CTRL1_TCKINT (0 << N32_ATIM_CTRL1_CLKD_SHIFT) /* tDTS = tCK_INT */ +# define N32_ATIM_CTRL1_2TCKINT (1 << N32_ATIM_CTRL1_CLKD_SHIFT) /* tDTS = 2tCK_INT */ +# define N32_ATIM_CTRL1_4TCKINT (2 << N32_ATIM_CTRL1_CLKD_SHIFT) /* tDTS = 4tCK_INT */ +#define N32_ATIM_CTRL1_ONEPM (1 << 8) /* One pulse mode */ +#define N32_ATIM_CTRL1_ARPEN (1 << 9) /* Auto-reload preload enable */ +#define N32_ATIM_CTRL1_LBKPEN (1 << 10) /* LockUp as BRK enable */ +#define N32_ATIM_CTRL1_PBKPEN (1 << 11) /* PVD as BRK enable */ +#define N32_ATIM_CTRL1_SMPARERREN (1 << 12) /* SRAM parity error as BRK enable */ +#define N32_ATIM_CTRL1_CLRSEL (1 << 13) /* OcxRef clear selection */ +#define N32_ATIM_CTRL1_SMECCERREN (1 << 15) /* SRAM ECC error as BRK enable */ +#define N32_ATIM_CTRL1_CMODE_SHIFT (20) /* Center-aligned mode for TRGO */ +#define N32_ATIM_CTRL1_CMODE_MASK (3 << N32_ATIM_CTRL1_CMODE_SHIFT) +# define N32_ATIM_CTRL1_CMODE_UP (0 << N32_ATIM_CTRL1_CMODE_SHIFT) /* Up-count trigger */ +# define N32_ATIM_CTRL1_CMODE_DOWN (1 << N32_ATIM_CTRL1_CMODE_SHIFT) /* Down-count trigger */ +# define N32_ATIM_CTRL1_CMODE_UPDOWN (2 << N32_ATIM_CTRL1_CMODE_SHIFT) /* Both edges trigger */ +#define N32_ATIM_CTRL1_ASYMMETRIC (1 << 23) /* Asymmetric mode enable */ + +/* Control register 2 (N32_ATIM_CTRL2) */ + +#define N32_ATIM_CTRL2_O11 (1 << 0) /* Output idle state 1 (OC1) */ +#define N32_ATIM_CTRL2_O11N (1 << 1) /* Output idle state 1N (OC1N) */ +#define N32_ATIM_CTRL2_O12 (1 << 2) /* Output idle state 2 (OC2) */ +#define N32_ATIM_CTRL2_O12N (1 << 3) /* Output idle state 2N (OC2N) */ +#define N32_ATIM_CTRL2_O13 (1 << 4) /* Output idle state 3 (OC3) */ +#define N32_ATIM_CTRL2_O13N (1 << 5) /* Output idle state 3N (OC3N) */ +#define N32_ATIM_CTRL2_O14 (1 << 6) /* Output idle state 4 (OC4) */ +#define N32_ATIM_CTRL2_O14N (1 << 7) /* Output idle state 4N (OC4N) */ +#define N32_ATIM_CTRL2_O15 (1 << 8) /* Output idle state 5 (OC5) */ +#define N32_ATIM_CTRL2_O16 (1 << 10) /* Output idle state 6 (OC6) */ +#define N32_ATIM_CTRL2_MMSEL_SHIFT (12) /* Master mode selection (TRGO) */ +#define N32_ATIM_CTRL2_MMSEL_MASK (15 << N32_ATIM_CTRL2_MMSEL_SHIFT) +# define N32_ATIM_CTRL2_MMSEL_RESET (0 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* Reset */ +# define N32_ATIM_CTRL2_MMSEL_ENABLE (1 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* Enable */ +# define N32_ATIM_CTRL2_MMSEL_UPDATE (2 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* Update */ +# define N32_ATIM_CTRL2_MMSEL_COMPP (3 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* Compare pulse */ +# define N32_ATIM_CTRL2_MMSEL_OC1REF (4 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* OC1REF */ +# define N32_ATIM_CTRL2_MMSEL_OC2REF (5 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* OC2REF */ +# define N32_ATIM_CTRL2_MMSEL_OC3REF (6 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* OC3REF */ +# define N32_ATIM_CTRL2_MMSEL_OC4REF (7 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* OC4REF */ +# define N32_ATIM_CTRL2_MMSEL_OC5REF (8 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* OC5REF */ +# define N32_ATIM_CTRL2_MMSEL_OC6REF (9 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* OC6REF */ +# define N32_ATIM_CTRL2_MMSEL_OC4REFEDGE (10 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* OC4REF edge */ +# define N32_ATIM_CTRL2_MMSEL_OC6REFEDGE (11 << N32_ATIM_CTRL2_MMSEL_SHIFT) /* OC6REF edge */ +#define N32_ATIM_CTRL2_CCUSEL (1 << 16) /* Capture/compare control update sel */ +#define N32_ATIM_CTRL2_CCDSEL (1 << 17) /* Capture/compare DMA selection */ +#define N32_ATIM_CTRL2_CCPCTL (1 << 18) /* Capture/compare preloaded control */ +#define N32_ATIM_CTRL2_TI1SEL (1 << 19) /* TI1 selection */ +#define N32_ATIM_CTRL2_TRIG4 (1 << 20) /* Trigger ADC on channel 4 compare */ +#define N32_ATIM_CTRL2_TRIG7 (1 << 21) /* Trigger ADC on channel 7 compare */ +#define N32_ATIM_CTRL2_TRIG8 (1 << 22) /* Trigger ADC on channel 8 compare */ +#define N32_ATIM_CTRL2_TRIG9 (1 << 23) /* Trigger ADC on channel 9 compare */ +#define N32_ATIM_CTRL2_MMSEL2_SHIFT (24) /* Master mode selection 2 (TRGO2) */ +#define N32_ATIM_CTRL2_MMSEL2_MASK (15 << N32_ATIM_CTRL2_MMSEL2_SHIFT) +# define N32_ATIM_CTRL2_MMSEL2_RESET (0 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* Reset */ +# define N32_ATIM_CTRL2_MMSEL2_ENABLE (1 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* Enable */ +# define N32_ATIM_CTRL2_MMSEL2_UPDATE (2 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* Update */ +# define N32_ATIM_CTRL2_MMSEL2_COMPP (3 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* Compare pulse */ +# define N32_ATIM_CTRL2_MMSEL2_OC1REF (4 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* OC1REF */ +# define N32_ATIM_CTRL2_MMSEL2_OC2REF (5 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* OC2REF */ +# define N32_ATIM_CTRL2_MMSEL2_OC3REF (6 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* OC3REF */ +# define N32_ATIM_CTRL2_MMSEL2_OC4REF (7 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* OC4REF */ +# define N32_ATIM_CTRL2_MMSEL2_OC5REF (8 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* OC5REF */ +# define N32_ATIM_CTRL2_MMSEL2_OC6REF (9 << N32_ATIM_CTRL2_MMSEL2_SHIFT) /* OC6REF */ + +/* Status register (N32_ATIM_STS) */ + +#define N32_ATIM_STS_CC1ITF (1 << 0) /* CC1 interrupt flag */ +#define N32_ATIM_STS_CC2ITF (1 << 1) /* CC2 interrupt flag */ +#define N32_ATIM_STS_CC3ITF (1 << 2) /* CC3 interrupt flag */ +#define N32_ATIM_STS_CC4ITF (1 << 3) /* CC4 interrupt flag */ +#define N32_ATIM_STS_CC5ITF (1 << 4) /* CC5 interrupt flag */ +#define N32_ATIM_STS_CC6ITF (1 << 5) /* CC6 interrupt flag */ +#define N32_ATIM_STS_CC1OCF (1 << 8) /* CC1 overcapture flag */ +#define N32_ATIM_STS_CC2OCF (1 << 9) /* CC2 overcapture flag */ +#define N32_ATIM_STS_CC3OCF (1 << 10) /* CC3 overcapture flag */ +#define N32_ATIM_STS_CC4OCF (1 << 11) /* CC4 overcapture flag */ +#define N32_ATIM_STS_UDITF (1 << 16) /* Update interrupt flag */ +#define N32_ATIM_STS_COMITF (1 << 17) /* COM interrupt flag */ +#define N32_ATIM_STS_TITF (1 << 18) /* Trigger interrupt flag */ +#define N32_ATIM_STS_BITF (1 << 19) /* Break1 interrupt flag */ +#define N32_ATIM_STS_BITF2 (1 << 20) /* Break2 interrupt flag */ +#define N32_ATIM_STS_SBITF (1 << 21) /* System break interrupt flag */ +#define N32_ATIM_STS_CC7ITF (1 << 24) /* CC7 interrupt flag */ +#define N32_ATIM_STS_CC8ITF (1 << 25) /* CC8 interrupt flag */ +#define N32_ATIM_STS_CC9ITF (1 << 26) /* CC9 interrupt flag */ + +/* Event generation register (N32_ATIM_ETGEN) */ + +#define N32_ATIM_ETGEN_CC1GN (1 << 0) /* CC1 generation */ +#define N32_ATIM_ETGEN_CC2GN (1 << 1) /* CC2 generation */ +#define N32_ATIM_ETGEN_CC3GN (1 << 2) /* CC3 generation */ +#define N32_ATIM_ETGEN_CC4GN (1 << 3) /* CC4 generation */ +#define N32_ATIM_ETGEN_UDGN (1 << 8) /* Update generation */ +#define N32_ATIM_ETGEN_CCUDGN (1 << 9) /* CC control update generation */ +#define N32_ATIM_ETGEN_TGN (1 << 10) /* Trigger generation */ +#define N32_ATIM_ETGEN_BGN (1 << 11) /* Break1 generation */ +#define N32_ATIM_ETGEN_BGN2 (1 << 12) /* Break2 generation */ + +/* Slave mode control register (N32_ATIM_SMCTRL) */ + +#define N32_ATIM_SMCTRL_TSEL_SHIFT (0) /* Trigger selection */ +#define N32_ATIM_SMCTRL_TSEL_MASK (7 << N32_ATIM_SMCTRL_TSEL_SHIFT) +# define N32_ATIM_SMCTRL_ITR (0 << N32_ATIM_SMCTRL_TSEL_SHIFT) /* Internal trigger */ +# define N32_ATIM_SMCTRL_TI1FED (4 << N32_ATIM_SMCTRL_TSEL_SHIFT) /* TI1 edge detector */ +# define N32_ATIM_SMCTRL_TI1FP1 (5 << N32_ATIM_SMCTRL_TSEL_SHIFT) /* Filtered TI1 */ +# define N32_ATIM_SMCTRL_TI2FP2 (6 << N32_ATIM_SMCTRL_TSEL_SHIFT) /* Filtered TI2 */ +# define N32_ATIM_SMCTRL_ETRF (7 << N32_ATIM_SMCTRL_TSEL_SHIFT) /* ETRF */ +#define N32_ATIM_SMCTRL_SMSEL_SHIFT (4) /* Slave mode selection */ +#define N32_ATIM_SMCTRL_SMSEL_MASK (15 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_DISAB (0 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_ENCMD1 (1 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_ENCMD2 (2 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_ENCMD3 (3 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_RESET (4 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_GATED (5 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_TRIGGER (6 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_EXTCLK1 (7 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_ENCMD4 (9 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +# define N32_ATIM_SMCTRL_ENCMD5 (10 << N32_ATIM_SMCTRL_SMSEL_SHIFT) +#define N32_ATIM_SMCTRL_EXTPS_SHIFT (8) /* External trigger prescaler */ +#define N32_ATIM_SMCTRL_EXTPS_MASK (3 << N32_ATIM_SMCTRL_EXTPS_SHIFT) +# define N32_ATIM_SMCTRL_PSCOFF (0 << N32_ATIM_SMCTRL_EXTPS_SHIFT) +# define N32_ATIM_SMCTRL_ETRPd2 (1 << N32_ATIM_SMCTRL_EXTPS_SHIFT) +# define N32_ATIM_SMCTRL_ETRPd4 (2 << N32_ATIM_SMCTRL_EXTPS_SHIFT) +# define N32_ATIM_SMCTRL_ETRPd8 (3 << N32_ATIM_SMCTRL_EXTPS_SHIFT) +#define N32_ATIM_SMCTRL_EXCEN (1 << 10) /* External clock enable */ +#define N32_ATIM_SMCTRL_EXTP (1 << 11) /* External trigger polarity */ +#define N32_ATIM_SMCTRL_EXTF_SHIFT (12) /* External trigger filter */ +#define N32_ATIM_SMCTRL_EXTF_MASK (15 << N32_ATIM_SMCTRL_EXTF_SHIFT) +#define N32_ATIM_SMCTRL_MSMD (1 << 16) /* Master/slave mode */ +#define N32_ATIM_SMCTRL_OCRECFLRP (1 << 19) /* tim_ocref_clr polarity */ +#define N32_ATIM_SMCTRL_OCRECFLRF_SHIFT (20) /* tim_ocref_clr filter */ +#define N32_ATIM_SMCTRL_OCRECFLRF_MASK (15 << N32_ATIM_SMCTRL_OCRECFLRF_SHIFT) + +/* Common filter encoding (used by EXTF and OCRECFLRF) */ + +#define N32_ATIM_FILTER_NOFILT (0) /* No filter */ +#define N32_ATIM_FILTER_FCKINT2 (1) /* fCK_INT, N=2 */ +#define N32_ATIM_FILTER_FCKINT4 (2) /* fCK_INT, N=4 */ +#define N32_ATIM_FILTER_FCKINT8 (3) /* fCK_INT, N=8 */ +#define N32_ATIM_FILTER_FDTSd2_6 (4) /* fDTS/2, N=6 */ +#define N32_ATIM_FILTER_FDTSd2_8 (5) /* fDTS/2, N=8 */ +#define N32_ATIM_FILTER_FDTSd4_6 (6) /* fDTS/4, N=6 */ +#define N32_ATIM_FILTER_FDTSd4_8 (7) /* fDTS/4, N=8 */ +#define N32_ATIM_FILTER_FDTSd8_6 (8) /* fDTS/8, N=6 */ +#define N32_ATIM_FILTER_FDTSd8_8 (9) /* fDTS/8, N=8 */ +#define N32_ATIM_FILTER_FDTSd16_5 (10) /* fDTS/16, N=5 */ +#define N32_ATIM_FILTER_FDTSd16_6 (11) /* fDTS/16, N=6 */ +#define N32_ATIM_FILTER_FDTSd16_8 (12) /* fDTS/16, N=8 */ +#define N32_ATIM_FILTER_FDTSd32_5 (13) /* fDTS/32, N=5 */ +#define N32_ATIM_FILTER_FDTSd32_F6 (14) /* fDTS/32, N=6 */ +#define N32_ATIM_FILTER_FDTSd32_8 (15) /* fDTS/32, N=8 */ + +/* DMA/Interrupt enable register (N32_ATIM_DINTEN) */ + +#define N32_ATIM_DINTEN_CC1IEN (1 << 0) /* CC1 interrupt enable */ +#define N32_ATIM_DINTEN_CC2IEN (1 << 1) /* CC2 interrupt enable */ +#define N32_ATIM_DINTEN_CC3IEN (1 << 2) /* CC3 interrupt enable */ +#define N32_ATIM_DINTEN_CC4IEN (1 << 3) /* CC4 interrupt enable */ +#define N32_ATIM_DINTEN_CC5IEN (1 << 4) /* CC5 interrupt enable */ +#define N32_ATIM_DINTEN_CC6IEN (1 << 5) /* CC6 interrupt enable */ +#define N32_ATIM_DINTEN_CC7IEN (1 << 6) /* CC7 interrupt enable */ +#define N32_ATIM_DINTEN_CC8IEN (1 << 7) /* CC8 interrupt enable */ +#define N32_ATIM_DINTEN_CC1DEN (1 << 8) /* CC1 DMA request enable */ +#define N32_ATIM_DINTEN_CC2DEN (1 << 9) /* CC2 DMA request enable */ +#define N32_ATIM_DINTEN_CC3DEN (1 << 10) /* CC3 DMA request enable */ +#define N32_ATIM_DINTEN_CC4DEN (1 << 11) /* CC4 DMA request enable */ +#define N32_ATIM_DINTEN_UIEN (1 << 16) /* Update interrupt enable */ +#define N32_ATIM_DINTEN_TIEN (1 << 17) /* Trigger interrupt enable */ +#define N32_ATIM_DINTEN_BIEN (1 << 18) /* Break interrupt enable */ +#define N32_ATIM_DINTEN_UDEN (1 << 19) /* Update DMA request enable */ +#define N32_ATIM_DINTEN_COMDEN (1 << 20) /* COM DMA request enable */ +#define N32_ATIM_DINTEN_TDEN (1 << 21) /* Trigger DMA request enable */ +#define N32_ATIM_DINTEN_COMIEN (1 << 22) /* COM interrupt enable */ +#define N32_ATIM_DINTEN_CC9IEN (1 << 23) /* CC9 interrupt enable */ + +/* Capture/compare mode register 1 - Output compare (N32_ATIM_CCMOD1) */ + +#define N32_ATIM_CCMOD1_CC1SEL_SHIFT (0) /* CC1 selection */ +#define N32_ATIM_CCMOD1_CC1SEL_MASK (3 << N32_ATIM_CCMOD1_CC1SEL_SHIFT) +# define N32_ATIM_CCMOD1_CC1OUT (0 << N32_ATIM_CCMOD1_CC1SEL_SHIFT) /* Output */ +# define N32_ATIM_CCMOD1_CC1IN_TI1 (1 << N32_ATIM_CCMOD1_CC1SEL_SHIFT) /* Input TI1 */ +# define N32_ATIM_CCMOD1_CC1IN_TI2 (2 << N32_ATIM_CCMOD1_CC1SEL_SHIFT) /* Input TI2 */ +# define N32_ATIM_CCMOD1_CC1IN_TRC (3 << N32_ATIM_CCMOD1_CC1SEL_SHIFT) /* Input TRC */ +#define N32_ATIM_CCMOD1_OC1PEN (1 << 2) /* OC1 preload enable */ +#define N32_ATIM_CCMOD1_OC1FEN (1 << 3) /* OC1 fast enable */ +#define N32_ATIM_CCMOD1_OC1CEN (1 << 4) /* OC1 clear enable */ +#define N32_ATIM_CCMOD1_OC1MD_SHIFT (5) /* OC1 mode */ +#define N32_ATIM_CCMOD1_OC1MD_MASK (7 << N32_ATIM_CCMOD1_OC1MD_SHIFT) +# define N32_ATIM_CCMOD1_OCMODE_FRZN (0 << N32_ATIM_CCMOD1_OC1MD_SHIFT) /* Frozen */ +# define N32_ATIM_CCMOD1_OCMODE_ACTIVE (1 << N32_ATIM_CCMOD1_OC1MD_SHIFT) /* Active */ +# define N32_ATIM_CCMOD1_OCMODE_INACTIVE (2 << N32_ATIM_CCMOD1_OC1MD_SHIFT) /* Inactive */ +# define N32_ATIM_CCMOD1_OCMODE_TOGGLE (3 << N32_ATIM_CCMOD1_OC1MD_SHIFT) /* Toggle */ +# define N32_ATIM_CCMOD1_OCMODE_FORCELO (4 << N32_ATIM_CCMOD1_OC1MD_SHIFT) /* Force low */ +# define N32_ATIM_CCMOD1_OCMODE_FORCEHI (5 << N32_ATIM_CCMOD1_OC1MD_SHIFT) /* Force high */ +# define N32_ATIM_CCMOD1_OCMODE_PWM1 (6 << N32_ATIM_CCMOD1_OC1MD_SHIFT) /* PWM mode 1 */ +# define N32_ATIM_CCMOD1_OCMODE_PWM2 (7 << N32_ATIM_CCMOD1_OC1MD_SHIFT) /* PWM mode 2 */ +#define N32_ATIM_CCMOD1_CC2SEL_SHIFT (8) /* CC2 selection */ +#define N32_ATIM_CCMOD1_CC2SEL_MASK (3 << N32_ATIM_CCMOD1_CC2SEL_SHIFT) +# define N32_ATIM_CCMOD1_CC2OUT (0 << N32_ATIM_CCMOD1_CC2SEL_SHIFT) +# define N32_ATIM_CCMOD1_CC2IN_TI2 (1 << N32_ATIM_CCMOD1_CC2SEL_SHIFT) +# define N32_ATIM_CCMOD1_CC2IN_TI1 (2 << N32_ATIM_CCMOD1_CC2SEL_SHIFT) +# define N32_ATIM_CCMOD1_CC2IN_TRC (3 << N32_ATIM_CCMOD1_CC2SEL_SHIFT) +#define N32_ATIM_CCMOD1_OC2PEN (1 << 10) /* OC2 preload enable */ +#define N32_ATIM_CCMOD1_OC2FEN (1 << 11) /* OC2 fast enable */ +#define N32_ATIM_CCMOD1_OC2CEN (1 << 12) /* OC2 clear enable */ +#define N32_ATIM_CCMOD1_OC2MD_SHIFT (13) /* OC2 mode */ +#define N32_ATIM_CCMOD1_OC2MD_MASK (7 << N32_ATIM_CCMOD1_OC2MD_SHIFT) + +/* Capture/compare mode register 1 - Input capture (N32_ATIM_CCMOD1) */ + +#define N32_ATIM_CCMOD1_IC1PSC_SHIFT (2) /* IC1 prescaler */ +#define N32_ATIM_CCMOD1_IC1PSC_MASK (3 << N32_ATIM_CCMOD1_IC1PSC_SHIFT) +# define N32_ATIM_CCMOD1_ICPSC_NONE (0 << N32_ATIM_CCMOD1_IC1PSC_SHIFT) /* No prescaler */ +# define N32_ATIM_CCMOD1_ICPSC_2 (1 << N32_ATIM_CCMOD1_IC1PSC_SHIFT) /* Every 2 events */ +# define N32_ATIM_CCMOD1_ICPSC_4 (2 << N32_ATIM_CCMOD1_IC1PSC_SHIFT) /* Every 4 events */ +# define N32_ATIM_CCMOD1_ICPSC_8 (3 << N32_ATIM_CCMOD1_IC1PSC_SHIFT) /* Every 8 events */ +#define N32_ATIM_CCMOD1_IC1F_SHIFT (4) /* IC1 filter */ +#define N32_ATIM_CCMOD1_IC1F_MASK (15 << N32_ATIM_CCMOD1_IC1F_SHIFT) +# define N32_ATIM_CCMOD1_IC1F_DTS (0 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time selection */ +# define N32_ATIM_CCMOD1_IC1F_INT_2 (1 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Internal clock, Sample every 2 events */ +# define N32_ATIM_CCMOD1_IC1F_INT_4 (2 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Internal clock, Sample every 4 events */ +# define N32_ATIM_CCMOD1_IC1F_INT_8 (3 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Internal clock, Sample every 8 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_2_N6 (4 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div2, Sample every 6 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_2_N8 (5 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div2, Sample every 8 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_4_N6 (6 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div4, Sample every 6 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_4_N8 (7 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div4, Sample every 8 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_8_N6 (8 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div8, Sample every 6 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_8_N8 (9 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div8, Sample every 8 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_16_N5 (10 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div16, Sample every 5 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_16_N6 (11 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div16, Sample every 6 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_16_N8 (12 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div16, Sample every 8 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_32_N5 (13 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div32, Sample every 5 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_32_N6 (14 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div32, Sample every 6 events */ +# define N32_ATIM_CCMOD1_IC1F_DTS_32_N8 (15 << N32_ATIM_CCMOD1_IC1F_SHIFT) /* Direct time div32, Sample every 8 events */ +#define N32_ATIM_CCMOD1_IC2PSC_SHIFT (10) /* IC2 prescaler */ +#define N32_ATIM_CCMOD1_IC2PSC_MASK (3 << N32_ATIM_CCMOD1_IC2PSC_SHIFT) +#define N32_ATIM_CCMOD1_IC2F_SHIFT (12) /* IC2 filter */ +#define N32_ATIM_CCMOD1_IC2F_MASK (15 << N32_ATIM_CCMOD1_IC2F_SHIFT) + +/* Capture/compare mode register 2 - Output compare (N32_ATIM_CCMOD2) */ + +#define N32_ATIM_CCMOD2_CC3SEL_SHIFT (0) /* CC3 selection */ +#define N32_ATIM_CCMOD2_CC3SEL_MASK (3 << N32_ATIM_CCMOD2_CC3SEL_SHIFT) +# define N32_ATIM_CCMOD2_CC3OUT (0 << N32_ATIM_CCMOD2_CC3SEL_SHIFT) /* Output */ +# define N32_ATIM_CCMOD2_CC3IN_TI3 (1 << N32_ATIM_CCMOD2_CC3SEL_SHIFT) /* Input TI3 */ +# define N32_ATIM_CCMOD2_CC3IN_TI4 (2 << N32_ATIM_CCMOD2_CC3SEL_SHIFT) /* Input TI4 */ +# define N32_ATIM_CCMOD2_CC3IN_TRC (3 << N32_ATIM_CCMOD2_CC3SEL_SHIFT) /* Input TRC */ +#define N32_ATIM_CCMOD2_OC3PEN (1 << 2) /* OC3 preload enable */ +#define N32_ATIM_CCMOD2_OC3FEN (1 << 3) /* OC3 fast enable */ +#define N32_ATIM_CCMOD2_OC3CEN (1 << 4) /* OC3 clear enable */ +#define N32_ATIM_CCMOD2_OC3MD_SHIFT (5) /* OC3 mode */ +#define N32_ATIM_CCMOD2_OC3MD_MASK (7 << N32_ATIM_CCMOD2_OC3MD_SHIFT) +#define N32_ATIM_CCMOD2_CC4SEL_SHIFT (8) /* CC4 selection */ +#define N32_ATIM_CCMOD2_CC4SEL_MASK (3 << N32_ATIM_CCMOD2_CC4SEL_SHIFT) +# define N32_ATIM_CCMOD2_CC4OUT (0 << N32_ATIM_CCMOD2_CC4SEL_SHIFT) /* Output */ +# define N32_ATIM_CCMOD2_CC4IN_TI4 (1 << N32_ATIM_CCMOD2_CC4SEL_SHIFT) /* Input TI4 */ +# define N32_ATIM_CCMOD2_CC4IN_TI3 (2 << N32_ATIM_CCMOD2_CC4SEL_SHIFT) /* Input TI3 */ +# define N32_ATIM_CCMOD2_CC4IN_TRC (3 << N32_ATIM_CCMOD2_CC4SEL_SHIFT) /* Input TRC */ +#define N32_ATIM_CCMOD2_OC4PEN (1 << 10) /* OC4 preload enable */ +#define N32_ATIM_CCMOD2_OC4FEN (1 << 11) /* OC4 fast enable */ +#define N32_ATIM_CCMOD2_OC4CEN (1 << 12) /* OC4 clear enable */ +#define N32_ATIM_CCMOD2_OC4MD_SHIFT (13) /* OC4 mode */ +#define N32_ATIM_CCMOD2_OC4MD_MASK (7 << N32_ATIM_CCMOD2_OC4MD_SHIFT) + +/* Capture/compare mode register 2 - Input capture (N32_ATIM_CCMOD2) */ + +#define N32_ATIM_CCMOD2_IC3PSC_SHIFT (2) /* IC3 prescaler */ +#define N32_ATIM_CCMOD2_IC3PSC_MASK (3 << N32_ATIM_CCMOD2_IC3PSC_SHIFT) +#define N32_ATIM_CCMOD2_IC3F_SHIFT (4) /* IC3 filter */ +#define N32_ATIM_CCMOD2_IC3F_MASK (15 << N32_ATIM_CCMOD2_IC3F_SHIFT) +#define N32_ATIM_CCMOD2_IC4PSC_SHIFT (10) /* IC4 prescaler */ +#define N32_ATIM_CCMOD2_IC4PSC_MASK (3 << N32_ATIM_CCMOD2_IC4PSC_SHIFT) +#define N32_ATIM_CCMOD2_IC4F_SHIFT (12) /* IC4 filter */ +#define N32_ATIM_CCMOD2_IC4F_MASK (15 << N32_ATIM_CCMOD2_IC4F_SHIFT) + +/* Capture/compare mode register 3 (N32_ATIM_CCMOD3) */ + +#define N32_ATIM_CCMOD3_OC5PEN (1 << 2) /* OC5 preload enable */ +#define N32_ATIM_CCMOD3_OC5FEN (1 << 3) /* OC5 fast enable */ +#define N32_ATIM_CCMOD3_OC5CEN (1 << 4) /* OC5 clear enable */ +#define N32_ATIM_CCMOD3_OC5MD_SHIFT (5) /* OC5 mode */ +#define N32_ATIM_CCMOD3_OC5MD_MASK (7 << N32_ATIM_CCMOD3_OC5MD_SHIFT) +#define N32_ATIM_CCMOD3_OC6PEN (1 << 10) /* OC6 preload enable */ +#define N32_ATIM_CCMOD3_OC6FEN (1 << 11) /* OC6 fast enable */ +#define N32_ATIM_CCMOD3_OC6CEN (1 << 12) /* OC6 clear enable */ +#define N32_ATIM_CCMOD3_OC6MD_SHIFT (13) /* OC6 mode */ +#define N32_ATIM_CCMOD3_OC6MD_MASK (7 << N32_ATIM_CCMOD3_OC6MD_SHIFT) +#define N32_ATIM_CCMOD3_OC7PEN (1 << 16) /* OC7 preload enable */ +#define N32_ATIM_CCMOD3_OC8PEN (1 << 20) /* OC8 preload enable */ +#define N32_ATIM_CCMOD3_OC9PEN (1 << 24) /* OC9 preload enable */ + +/* Capture/compare enable register (N32_ATIM_CCEN) */ + +#define N32_ATIM_CCEN_CC1NEN (1 << 0) /* CC1 complementary output enable */ +#define N32_ATIM_CCEN_CC1NP (1 << 1) /* CC1 complementary output polarity */ +#define N32_ATIM_CCEN_CC1EN (1 << 2) /* CC1 output enable */ +#define N32_ATIM_CCEN_CC1P (1 << 3) /* CC1 output polarity */ +#define N32_ATIM_CCEN_CC2NEN (1 << 4) /* CC2 complementary output enable */ +#define N32_ATIM_CCEN_CC2NP (1 << 5) /* CC2 complementary output polarity */ +#define N32_ATIM_CCEN_CC2EN (1 << 6) /* CC2 output enable */ +#define N32_ATIM_CCEN_CC2P (1 << 7) /* CC2 output polarity */ +#define N32_ATIM_CCEN_CC3NEN (1 << 8) /* CC3 complementary output enable */ +#define N32_ATIM_CCEN_CC3NP (1 << 9) /* CC3 complementary output polarity */ +#define N32_ATIM_CCEN_CC3EN (1 << 10) /* CC3 output enable */ +#define N32_ATIM_CCEN_CC3P (1 << 11) /* CC3 output polarity */ +#define N32_ATIM_CCEN_CC4NEN (1 << 12) /* CC4 complementary output enable */ +#define N32_ATIM_CCEN_CC4NP (1 << 13) /* CC4 complementary output polarity */ +#define N32_ATIM_CCEN_CC4EN (1 << 14) /* CC4 output enable */ +#define N32_ATIM_CCEN_CC4P (1 << 15) /* CC4 output polarity */ +#define N32_ATIM_CCEN_CC5EN (1 << 18) /* CC5 output enable */ +#define N32_ATIM_CCEN_CC5P (1 << 19) /* CC5 output polarity */ +#define N32_ATIM_CCEN_CC6EN (1 << 22) /* CC6 output enable */ +#define N32_ATIM_CCEN_CC6P (1 << 23) /* CC6 output polarity */ + +/* Capture/compare registers (N32_ATIM_CCDAT1-9) */ + +#define N32_ATIM_CCDAT_MASK (0xffff) /* CCx value mask */ +#define N32_ATIM_CCDAT_DOWN_SHIFT (16) /* Down-count value shift */ + +/* Prescaler, Auto-reload, Counter */ + +#define N32_ATIM_PSC_MASK (0xffff) /* Prescaler value mask */ +#define N32_ATIM_AR_MASK (0xffff) /* Auto-reload value mask */ +#define N32_ATIM_CNT_MASK (0xffff) /* Counter value mask */ + +/* Repetition counter */ + +#define N32_ATIM_REPCNT_MASK (0xff) /* Repetition counter value mask */ + +/* Break and dead-time register (N32_ATIM_BKDT) */ + +#define N32_ATIM_BKDT_DTGN_SHIFT (0) /* Dead-time generator setup */ +#define N32_ATIM_BKDT_DTGN_MASK (0xff << N32_ATIM_BKDT_DTGN_SHIFT) +#define N32_ATIM_BKDT_MOEN (1 << 8) /* Main output enable */ +#define N32_ATIM_BKDT_AOEN (1 << 9) /* Automatic output enable */ +#define N32_ATIM_BKDT_BKP (1 << 10) /* Break1 polarity */ +#define N32_ATIM_BKDT_BKEN (1 << 11) /* Break1 enable */ +#define N32_ATIM_BKDT_OSSI (1 << 12) /* Off-state selection for Idle mode */ +#define N32_ATIM_BKDT_OSSR (1 << 13) /* Off-state selection for Run mode */ +#define N32_ATIM_BKDT_LCKCFG_SHIFT (14) /* Lock configuration */ +#define N32_ATIM_BKDT_LCKCFG_MASK (3 << N32_ATIM_BKDT_LCKCFG_SHIFT) +# define N32_ATIM_BKDT_LOCKOFF (0 << N32_ATIM_BKDT_LCKCFG_SHIFT) /* No lock */ +# define N32_ATIM_BKDT_LOCK1 (1 << N32_ATIM_BKDT_LCKCFG_SHIFT) /* Lock level 1 */ +# define N32_ATIM_BKDT_LOCK2 (2 << N32_ATIM_BKDT_LCKCFG_SHIFT) /* Lock level 2 */ +# define N32_ATIM_BKDT_LOCK3 (3 << N32_ATIM_BKDT_LCKCFG_SHIFT) /* Lock level 3 */ +#define N32_ATIM_BKDT_BK2P (1 << 16) /* Break2 polarity */ +#define N32_ATIM_BKDT_BK2EN (1 << 17) /* Break2 enable */ +#define N32_ATIM_BKDT_BRKDSRM (1 << 18) /* Break1 disarm */ +#define N32_ATIM_BKDT_BRK2DSRM (1 << 19) /* Break2 disarm */ +#define N32_ATIM_BKDT_BRKBID (1 << 20) /* Break1 bidirectional enable */ +#define N32_ATIM_BKDT_BRK2BID (1 << 21) /* Break2 bidirectional enable */ + +/* Break filter register (N32_ATIM_BKFR) */ + +#define N32_ATIM_BKFR_SLIDFPSC_MASK (0xffff) /* Sampling clock prescaler */ +#define N32_ATIM_BKFR_FILTEN (1 << 16) /* Filter enable */ +#define N32_ATIM_BKFR_WSIZE_SHIFT (17) /* Window size */ +#define N32_ATIM_BKFR_WSIZE_MASK (63 << N32_ATIM_BKFR_WSIZE_SHIFT) +#define N32_ATIM_BKFR_THRESH_SHIFT (24) /* Threshold */ +#define N32_ATIM_BKFR_THRESH_MASK (63 << N32_ATIM_BKFR_THRESH_SHIFT) + +/* Input selection register (N32_ATIM_INSEL) */ + +#define N32_ATIM_INSEL_TI1S_SHIFT (0) /* TI1 input selection */ +#define N32_ATIM_INSEL_TI1S_MASK (15 << N32_ATIM_INSEL_TI1S_SHIFT) +#define N32_ATIM_INSEL_TI2S_SHIFT (4) /* TI2 input selection */ +#define N32_ATIM_INSEL_TI2S_MASK (15 << N32_ATIM_INSEL_TI2S_SHIFT) +#define N32_ATIM_INSEL_TI3S_SHIFT (8) /* TI3 input selection */ +#define N32_ATIM_INSEL_TI3S_MASK (15 << N32_ATIM_INSEL_TI3S_SHIFT) +#define N32_ATIM_INSEL_TI4S_SHIFT (12) /* TI4 input selection */ +#define N32_ATIM_INSEL_TI4S_MASK (15 << N32_ATIM_INSEL_TI4S_SHIFT) +#define N32_ATIM_INSEL_ETRS_SHIFT (16) /* ETR input selection */ +#define N32_ATIM_INSEL_ETRS_MASK (15 << N32_ATIM_INSEL_ETRS_SHIFT) +#define N32_ATIM_INSEL_ITRS_SHIFT (20) /* ITR input selection */ +#define N32_ATIM_INSEL_ITRS_MASK (15 << N32_ATIM_INSEL_ITRS_SHIFT) +#define N32_ATIM_INSEL_CLRS_SHIFT (24) /* OcxRef clear input selection */ +#define N32_ATIM_INSEL_CLRS_MASK (15 << N32_ATIM_INSEL_CLRS_SHIFT) + +/* Alternate function registers (N32_ATIM_AF1, N32_ATIM_AF2) */ + +#define N32_ATIM_AF1_IOMBRKEN (1 << 0) /* TIMx_BKIN break input enable */ +#define N32_ATIM_AF1_COMP1BRKEN (1 << 1) /* COMP1 break input enable */ +#define N32_ATIM_AF1_COMP2BRKEN (1 << 2) /* COMP2 break input enable */ +#define N32_ATIM_AF1_COMP3BRKEN (1 << 3) /* COMP3 break input enable */ +#define N32_ATIM_AF1_COMP4BRKEN (1 << 4) /* COMP4 break input enable */ +#define N32_ATIM_AF1_IOMBRKP (1 << 9) /* TIMx_BKIN polarity selection */ +#define N32_ATIM_AF1_COMP1BRKP (1 << 10) /* COMP1 break polarity */ +#define N32_ATIM_AF1_COMP2BRKP (1 << 11) /* COMP2 break polarity */ +#define N32_ATIM_AF1_COMP3BRKP (1 << 12) /* COMP3 break polarity */ +#define N32_ATIM_AF1_COMP4BRKP (1 << 13) /* COMP4 break polarity */ + +#define N32_ATIM_AF2_IOMBRK2EN (1 << 0) /* TIMx_BKIN2 break input enable */ +#define N32_ATIM_AF2_COMP1BRK2EN (1 << 1) /* COMP1 break2 enable */ +#define N32_ATIM_AF2_COMP2BRK2EN (1 << 2) /* COMP2 break2 enable */ +#define N32_ATIM_AF2_COMP3BRK2EN (1 << 3) /* COMP3 break2 enable */ +#define N32_ATIM_AF2_COMP4BRK2EN (1 << 4) /* COMP4 break2 enable */ +#define N32_ATIM_AF2_IOMBRK2P (1 << 9) /* TIMx_BKIN2 polarity selection */ +#define N32_ATIM_AF2_COMP1BRK2P (1 << 10) /* COMP1 break2 polarity */ +#define N32_ATIM_AF2_COMP2BRK2P (1 << 11) /* COMP2 break2 polarity */ +#define N32_ATIM_AF2_COMP3BRK2P (1 << 12) /* COMP3 break2 polarity */ +#define N32_ATIM_AF2_COMP4BRK2P (1 << 13) /* COMP4 break2 polarity */ +#define N32_ATIM_AF2_DSMU0BRK2EN (1 << 24) /* DSMU0 break2 enable */ +#define N32_ATIM_AF2_DSMU1BRK2EN (1 << 25) /* DSMU1 break2 enable */ +#define N32_ATIM_AF2_DSMU2BRK2EN (1 << 26) /* DSMU2 break2 enable */ +#define N32_ATIM_AF2_DSMU3BRK2EN (1 << 27) /* DSMU3 break2 enable */ + +/* Break 2 filter (N32_ATIM_BKFR2) */ + +#define N32_ATIM_BKFR2_SLIDFPSC_MASK (0xffff) /* Sampling clock prescaler */ +#define N32_ATIM_BKFR2_FILTEN (1 << 16) /* Filter enable */ +#define N32_ATIM_BKFR2_WSIZE_SHIFT (17) /* Window size */ +#define N32_ATIM_BKFR2_WSIZE_MASK (63 << N32_ATIM_BKFR2_WSIZE_SHIFT) +#define N32_ATIM_BKFR2_THRESH_SHIFT (24) /* Threshold */ +#define N32_ATIM_BKFR2_THRESH_MASK (63 << N32_ATIM_BKFR2_THRESH_SHIFT) + +/* DMA control (N32_ATIM_DCTRL) */ + +#define N32_ATIM_DCTRL_DBLEN_SHIFT (0) /* DMA burst length */ +#define N32_ATIM_DCTRL_DBLEN_MASK (63 << N32_ATIM_DCTRL_DBLEN_SHIFT) +# define N32_ATIM_DCTRL_DBLEN(n) (((n)-1) << N32_ATIM_DCTRL_DBLEN_SHIFT) +#define N32_ATIM_DCTRL_DBADDR_SHIFT (8) /* DMA base address */ +#define N32_ATIM_DCTRL_DBADDR_MASK (63 << N32_ATIM_DCTRL_DBADDR_SHIFT) + +#define N32_ATIM_DADDR_BURST_MASK (0xffffffff) /* DMA burst data */ + +/* ========================================================================== + * GENERAL-PURPOSE TIMERS A (GTIMA1-7) + * ========================================================================== + */ + +/* Register Offsets - GTIMA (common for all GTIMA1-7) ***********************/ + +#define N32_GTIMA_CTRL1_OFFSET 0x0000 /* Control register 1 */ +#define N32_GTIMA_CTRL2_OFFSET 0x0004 /* Control register 2 */ +#define N32_GTIMA_STS_OFFSET 0x0008 /* Status register */ +#define N32_GTIMA_ETGEN_OFFSET 0x000c /* Event generation register */ +#define N32_GTIMA_SMCTRL_OFFSET 0x0010 /* Slave mode control register */ +#define N32_GTIMA_DINTEN_OFFSET 0x0014 /* DMA/Interrupt enable register */ +#define N32_GTIMA_CCMOD1_OFFSET 0x0018 /* Capture/compare mode register 1 */ +#define N32_GTIMA_CCMOD2_OFFSET 0x001c /* Capture/compare mode register 2 */ +#define N32_GTIMA_CCEN_OFFSET 0x0024 /* Capture/compare enable register */ +#define N32_GTIMA_CCDAT1_OFFSET 0x0028 /* Capture/compare register 1 */ +#define N32_GTIMA_CCDAT2_OFFSET 0x002c /* Capture/compare register 2 */ +#define N32_GTIMA_CCDAT3_OFFSET 0x0030 /* Capture/compare register 3 */ +#define N32_GTIMA_CCDAT4_OFFSET 0x0034 /* Capture/compare register 4 */ +#define N32_GTIMA_PSC_OFFSET 0x0040 /* Prescaler */ +#define N32_GTIMA_AR_OFFSET 0x0044 /* Auto-reload register */ +#define N32_GTIMA_CNT_OFFSET 0x0048 /* Counter */ +#define N32_GTIMA_C1FILT_OFFSET 0x0064 /* Channel 1 filter register */ +#define N32_GTIMA_C2FILT_OFFSET 0x0068 /* Channel 2 filter register */ +#define N32_GTIMA_C3FILT_OFFSET 0x006c /* Channel 3 filter register */ +#define N32_GTIMA_C4FILT_OFFSET 0x0070 /* Channel 4 filter register */ +#define N32_GTIMA_FILTO_OFFSET 0x0074 /* Filter output register */ +#define N32_GTIMA_INSEL_OFFSET 0x0078 /* Input selection register */ +#define N32_GTIMA_DCTRL_OFFSET 0x0094 /* DMA control register */ +#define N32_GTIMA_DADDR_OFFSET 0x0098 /* DMA address for burst mode */ + +/* Register Addresses - GTIMA1 **********************************************/ + +#define N32_GTIMA1_CTRL1 (N32_GTIMERA1_BASE + N32_GTIMA_CTRL1_OFFSET) +#define N32_GTIMA1_CTRL2 (N32_GTIMERA1_BASE + N32_GTIMA_CTRL2_OFFSET) +#define N32_GTIMA1_STS (N32_GTIMERA1_BASE + N32_GTIMA_STS_OFFSET) +#define N32_GTIMA1_ETGEN (N32_GTIMERA1_BASE + N32_GTIMA_ETGEN_OFFSET) +#define N32_GTIMA1_SMCTRL (N32_GTIMERA1_BASE + N32_GTIMA_SMCTRL_OFFSET) +#define N32_GTIMA1_DINTEN (N32_GTIMERA1_BASE + N32_GTIMA_DINTEN_OFFSET) +#define N32_GTIMA1_CCMOD1 (N32_GTIMERA1_BASE + N32_GTIMA_CCMOD1_OFFSET) +#define N32_GTIMA1_CCMOD2 (N32_GTIMERA1_BASE + N32_GTIMA_CCMOD2_OFFSET) +#define N32_GTIMA1_CCEN (N32_GTIMERA1_BASE + N32_GTIMA_CCEN_OFFSET) +#define N32_GTIMA1_CCDAT1 (N32_GTIMERA1_BASE + N32_GTIMA_CCDAT1_OFFSET) +#define N32_GTIMA1_CCDAT2 (N32_GTIMERA1_BASE + N32_GTIMA_CCDAT2_OFFSET) +#define N32_GTIMA1_CCDAT3 (N32_GTIMERA1_BASE + N32_GTIMA_CCDAT3_OFFSET) +#define N32_GTIMA1_CCDAT4 (N32_GTIMERA1_BASE + N32_GTIMA_CCDAT4_OFFSET) +#define N32_GTIMA1_PSC (N32_GTIMERA1_BASE + N32_GTIMA_PSC_OFFSET) +#define N32_GTIMA1_AR (N32_GTIMERA1_BASE + N32_GTIMA_AR_OFFSET) +#define N32_GTIMA1_CNT (N32_GTIMERA1_BASE + N32_GTIMA_CNT_OFFSET) +#define N32_GTIMA1_C1FILT (N32_GTIMERA1_BASE + N32_GTIMA_C1FILT_OFFSET) +#define N32_GTIMA1_C2FILT (N32_GTIMERA1_BASE + N32_GTIMA_C2FILT_OFFSET) +#define N32_GTIMA1_C3FILT (N32_GTIMERA1_BASE + N32_GTIMA_C3FILT_OFFSET) +#define N32_GTIMA1_C4FILT (N32_GTIMERA1_BASE + N32_GTIMA_C4FILT_OFFSET) +#define N32_GTIMA1_FILTO (N32_GTIMERA1_BASE + N32_GTIMA_FILTO_OFFSET) +#define N32_GTIMA1_INSEL (N32_GTIMERA1_BASE + N32_GTIMA_INSEL_OFFSET) +#define N32_GTIMA1_DCTRL (N32_GTIMERA1_BASE + N32_GTIMA_DCTRL_OFFSET) +#define N32_GTIMA1_DADDR (N32_GTIMERA1_BASE + N32_GTIMA_DADDR_OFFSET) + +/* Register Addresses - GTIMA2 **********************************************/ + +#define N32_GTIMA2_CTRL1 (N32_GTIMERA2_BASE + N32_GTIMA_CTRL1_OFFSET) +#define N32_GTIMA2_CTRL2 (N32_GTIMERA2_BASE + N32_GTIMA_CTRL2_OFFSET) +#define N32_GTIMA2_STS (N32_GTIMERA2_BASE + N32_GTIMA_STS_OFFSET) +#define N32_GTIMA2_ETGEN (N32_GTIMERA2_BASE + N32_GTIMA_ETGEN_OFFSET) +#define N32_GTIMA2_SMCTRL (N32_GTIMERA2_BASE + N32_GTIMA_SMCTRL_OFFSET) +#define N32_GTIMA2_DINTEN (N32_GTIMERA2_BASE + N32_GTIMA_DINTEN_OFFSET) +#define N32_GTIMA2_CCMOD1 (N32_GTIMERA2_BASE + N32_GTIMA_CCMOD1_OFFSET) +#define N32_GTIMA2_CCMOD2 (N32_GTIMERA2_BASE + N32_GTIMA_CCMOD2_OFFSET) +#define N32_GTIMA2_CCEN (N32_GTIMERA2_BASE + N32_GTIMA_CCEN_OFFSET) +#define N32_GTIMA2_CCDAT1 (N32_GTIMERA2_BASE + N32_GTIMA_CCDAT1_OFFSET) +#define N32_GTIMA2_CCDAT2 (N32_GTIMERA2_BASE + N32_GTIMA_CCDAT2_OFFSET) +#define N32_GTIMA2_CCDAT3 (N32_GTIMERA2_BASE + N32_GTIMA_CCDAT3_OFFSET) +#define N32_GTIMA2_CCDAT4 (N32_GTIMERA2_BASE + N32_GTIMA_CCDAT4_OFFSET) +#define N32_GTIMA2_PSC (N32_GTIMERA2_BASE + N32_GTIMA_PSC_OFFSET) +#define N32_GTIMA2_AR (N32_GTIMERA2_BASE + N32_GTIMA_AR_OFFSET) +#define N32_GTIMA2_CNT (N32_GTIMERA2_BASE + N32_GTIMA_CNT_OFFSET) +#define N32_GTIMA2_C1FILT (N32_GTIMERA2_BASE + N32_GTIMA_C1FILT_OFFSET) +#define N32_GTIMA2_C2FILT (N32_GTIMERA2_BASE + N32_GTIMA_C2FILT_OFFSET) +#define N32_GTIMA2_C3FILT (N32_GTIMERA2_BASE + N32_GTIMA_C3FILT_OFFSET) +#define N32_GTIMA2_C4FILT (N32_GTIMERA2_BASE + N32_GTIMA_C4FILT_OFFSET) +#define N32_GTIMA2_FILTO (N32_GTIMERA2_BASE + N32_GTIMA_FILTO_OFFSET) +#define N32_GTIMA2_INSEL (N32_GTIMERA2_BASE + N32_GTIMA_INSEL_OFFSET) +#define N32_GTIMA2_DCTRL (N32_GTIMERA2_BASE + N32_GTIMA_DCTRL_OFFSET) +#define N32_GTIMA2_DADDR (N32_GTIMERA2_BASE + N32_GTIMA_DADDR_OFFSET) + +/* Register Addresses - GTIMA3 **********************************************/ + +#define N32_GTIMA3_CTRL1 (N32_GTIMERA3_BASE + N32_GTIMA_CTRL1_OFFSET) +#define N32_GTIMA3_CTRL2 (N32_GTIMERA3_BASE + N32_GTIMA_CTRL2_OFFSET) +#define N32_GTIMA3_STS (N32_GTIMERA3_BASE + N32_GTIMA_STS_OFFSET) +#define N32_GTIMA3_ETGEN (N32_GTIMERA3_BASE + N32_GTIMA_ETGEN_OFFSET) +#define N32_GTIMA3_SMCTRL (N32_GTIMERA3_BASE + N32_GTIMA_SMCTRL_OFFSET) +#define N32_GTIMA3_DINTEN (N32_GTIMERA3_BASE + N32_GTIMA_DINTEN_OFFSET) +#define N32_GTIMA3_CCMOD1 (N32_GTIMERA3_BASE + N32_GTIMA_CCMOD1_OFFSET) +#define N32_GTIMA3_CCMOD2 (N32_GTIMERA3_BASE + N32_GTIMA_CCMOD2_OFFSET) +#define N32_GTIMA3_CCEN (N32_GTIMERA3_BASE + N32_GTIMA_CCEN_OFFSET) +#define N32_GTIMA3_CCDAT1 (N32_GTIMERA3_BASE + N32_GTIMA_CCDAT1_OFFSET) +#define N32_GTIMA3_CCDAT2 (N32_GTIMERA3_BASE + N32_GTIMA_CCDAT2_OFFSET) +#define N32_GTIMA3_CCDAT3 (N32_GTIMERA3_BASE + N32_GTIMA_CCDAT3_OFFSET) +#define N32_GTIMA3_CCDAT4 (N32_GTIMERA3_BASE + N32_GTIMA_CCDAT4_OFFSET) +#define N32_GTIMA3_PSC (N32_GTIMERA3_BASE + N32_GTIMA_PSC_OFFSET) +#define N32_GTIMA3_AR (N32_GTIMERA3_BASE + N32_GTIMA_AR_OFFSET) +#define N32_GTIMA3_CNT (N32_GTIMERA3_BASE + N32_GTIMA_CNT_OFFSET) +#define N32_GTIMA3_C1FILT (N32_GTIMERA3_BASE + N32_GTIMA_C1FILT_OFFSET) +#define N32_GTIMA3_C2FILT (N32_GTIMERA3_BASE + N32_GTIMA_C2FILT_OFFSET) +#define N32_GTIMA3_C3FILT (N32_GTIMERA3_BASE + N32_GTIMA_C3FILT_OFFSET) +#define N32_GTIMA3_C4FILT (N32_GTIMERA3_BASE + N32_GTIMA_C4FILT_OFFSET) +#define N32_GTIMA3_FILTO (N32_GTIMERA3_BASE + N32_GTIMA_FILTO_OFFSET) +#define N32_GTIMA3_INSEL (N32_GTIMERA3_BASE + N32_GTIMA_INSEL_OFFSET) +#define N32_GTIMA3_DCTRL (N32_GTIMERA3_BASE + N32_GTIMA_DCTRL_OFFSET) +#define N32_GTIMA3_DADDR (N32_GTIMERA3_BASE + N32_GTIMA_DADDR_OFFSET) + +/* Register Addresses - GTIMA4 **********************************************/ + +#define N32_GTIMA4_CTRL1 (N32_GTIMERA4_BASE + N32_GTIMA_CTRL1_OFFSET) +#define N32_GTIMA4_CTRL2 (N32_GTIMERA4_BASE + N32_GTIMA_CTRL2_OFFSET) +#define N32_GTIMA4_STS (N32_GTIMERA4_BASE + N32_GTIMA_STS_OFFSET) +#define N32_GTIMA4_ETGEN (N32_GTIMERA4_BASE + N32_GTIMA_ETGEN_OFFSET) +#define N32_GTIMA4_SMCTRL (N32_GTIMERA4_BASE + N32_GTIMA_SMCTRL_OFFSET) +#define N32_GTIMA4_DINTEN (N32_GTIMERA4_BASE + N32_GTIMA_DINTEN_OFFSET) +#define N32_GTIMA4_CCMOD1 (N32_GTIMERA4_BASE + N32_GTIMA_CCMOD1_OFFSET) +#define N32_GTIMA4_CCMOD2 (N32_GTIMERA4_BASE + N32_GTIMA_CCMOD2_OFFSET) +#define N32_GTIMA4_CCEN (N32_GTIMERA4_BASE + N32_GTIMA_CCEN_OFFSET) +#define N32_GTIMA4_CCDAT1 (N32_GTIMERA4_BASE + N32_GTIMA_CCDAT1_OFFSET) +#define N32_GTIMA4_CCDAT2 (N32_GTIMERA4_BASE + N32_GTIMA_CCDAT2_OFFSET) +#define N32_GTIMA4_CCDAT3 (N32_GTIMERA4_BASE + N32_GTIMA_CCDAT3_OFFSET) +#define N32_GTIMA4_CCDAT4 (N32_GTIMERA4_BASE + N32_GTIMA_CCDAT4_OFFSET) +#define N32_GTIMA4_PSC (N32_GTIMERA4_BASE + N32_GTIMA_PSC_OFFSET) +#define N32_GTIMA4_AR (N32_GTIMERA4_BASE + N32_GTIMA_AR_OFFSET) +#define N32_GTIMA4_CNT (N32_GTIMERA4_BASE + N32_GTIMA_CNT_OFFSET) +#define N32_GTIMA4_C1FILT (N32_GTIMERA4_BASE + N32_GTIMA_C1FILT_OFFSET) +#define N32_GTIMA4_C2FILT (N32_GTIMERA4_BASE + N32_GTIMA_C2FILT_OFFSET) +#define N32_GTIMA4_C3FILT (N32_GTIMERA4_BASE + N32_GTIMA_C3FILT_OFFSET) +#define N32_GTIMA4_C4FILT (N32_GTIMERA4_BASE + N32_GTIMA_C4FILT_OFFSET) +#define N32_GTIMA4_FILTO (N32_GTIMERA4_BASE + N32_GTIMA_FILTO_OFFSET) +#define N32_GTIMA4_INSEL (N32_GTIMERA4_BASE + N32_GTIMA_INSEL_OFFSET) +#define N32_GTIMA4_DCTRL (N32_GTIMERA4_BASE + N32_GTIMA_DCTRL_OFFSET) +#define N32_GTIMA4_DADDR (N32_GTIMERA4_BASE + N32_GTIMA_DADDR_OFFSET) + +/* Register Addresses - GTIMA5 **********************************************/ + +#define N32_GTIMA5_CTRL1 (N32_GTIMERA5_BASE + N32_GTIMA_CTRL1_OFFSET) +#define N32_GTIMA5_CTRL2 (N32_GTIMERA5_BASE + N32_GTIMA_CTRL2_OFFSET) +#define N32_GTIMA5_STS (N32_GTIMERA5_BASE + N32_GTIMA_STS_OFFSET) +#define N32_GTIMA5_ETGEN (N32_GTIMERA5_BASE + N32_GTIMA_ETGEN_OFFSET) +#define N32_GTIMA5_SMCTRL (N32_GTIMERA5_BASE + N32_GTIMA_SMCTRL_OFFSET) +#define N32_GTIMA5_DINTEN (N32_GTIMERA5_BASE + N32_GTIMA_DINTEN_OFFSET) +#define N32_GTIMA5_CCMOD1 (N32_GTIMERA5_BASE + N32_GTIMA_CCMOD1_OFFSET) +#define N32_GTIMA5_CCMOD2 (N32_GTIMERA5_BASE + N32_GTIMA_CCMOD2_OFFSET) +#define N32_GTIMA5_CCEN (N32_GTIMERA5_BASE + N32_GTIMA_CCEN_OFFSET) +#define N32_GTIMA5_CCDAT1 (N32_GTIMERA5_BASE + N32_GTIMA_CCDAT1_OFFSET) +#define N32_GTIMA5_CCDAT2 (N32_GTIMERA5_BASE + N32_GTIMA_CCDAT2_OFFSET) +#define N32_GTIMA5_CCDAT3 (N32_GTIMERA5_BASE + N32_GTIMA_CCDAT3_OFFSET) +#define N32_GTIMA5_CCDAT4 (N32_GTIMERA5_BASE + N32_GTIMA_CCDAT4_OFFSET) +#define N32_GTIMA5_PSC (N32_GTIMERA5_BASE + N32_GTIMA_PSC_OFFSET) +#define N32_GTIMA5_AR (N32_GTIMERA5_BASE + N32_GTIMA_AR_OFFSET) +#define N32_GTIMA5_CNT (N32_GTIMERA5_BASE + N32_GTIMA_CNT_OFFSET) +#define N32_GTIMA5_C1FILT (N32_GTIMERA5_BASE + N32_GTIMA_C1FILT_OFFSET) +#define N32_GTIMA5_C2FILT (N32_GTIMERA5_BASE + N32_GTIMA_C2FILT_OFFSET) +#define N32_GTIMA5_C3FILT (N32_GTIMERA5_BASE + N32_GTIMA_C3FILT_OFFSET) +#define N32_GTIMA5_C4FILT (N32_GTIMERA5_BASE + N32_GTIMA_C4FILT_OFFSET) +#define N32_GTIMA5_FILTO (N32_GTIMERA5_BASE + N32_GTIMA_FILTO_OFFSET) +#define N32_GTIMA5_INSEL (N32_GTIMERA5_BASE + N32_GTIMA_INSEL_OFFSET) +#define N32_GTIMA5_DCTRL (N32_GTIMERA5_BASE + N32_GTIMA_DCTRL_OFFSET) +#define N32_GTIMA5_DADDR (N32_GTIMERA5_BASE + N32_GTIMA_DADDR_OFFSET) + +/* Register Addresses - GTIMA6 **********************************************/ + +#define N32_GTIMA6_CTRL1 (N32_GTIMERA6_BASE + N32_GTIMA_CTRL1_OFFSET) +#define N32_GTIMA6_CTRL2 (N32_GTIMERA6_BASE + N32_GTIMA_CTRL2_OFFSET) +#define N32_GTIMA6_STS (N32_GTIMERA6_BASE + N32_GTIMA_STS_OFFSET) +#define N32_GTIMA6_ETGEN (N32_GTIMERA6_BASE + N32_GTIMA_ETGEN_OFFSET) +#define N32_GTIMA6_SMCTRL (N32_GTIMERA6_BASE + N32_GTIMA_SMCTRL_OFFSET) +#define N32_GTIMA6_DINTEN (N32_GTIMERA6_BASE + N32_GTIMA_DINTEN_OFFSET) +#define N32_GTIMA6_CCMOD1 (N32_GTIMERA6_BASE + N32_GTIMA_CCMOD1_OFFSET) +#define N32_GTIMA6_CCMOD2 (N32_GTIMERA6_BASE + N32_GTIMA_CCMOD2_OFFSET) +#define N32_GTIMA6_CCEN (N32_GTIMERA6_BASE + N32_GTIMA_CCEN_OFFSET) +#define N32_GTIMA6_CCDAT1 (N32_GTIMERA6_BASE + N32_GTIMA_CCDAT1_OFFSET) +#define N32_GTIMA6_CCDAT2 (N32_GTIMERA6_BASE + N32_GTIMA_CCDAT2_OFFSET) +#define N32_GTIMA6_CCDAT3 (N32_GTIMERA6_BASE + N32_GTIMA_CCDAT3_OFFSET) +#define N32_GTIMA6_CCDAT4 (N32_GTIMERA6_BASE + N32_GTIMA_CCDAT4_OFFSET) +#define N32_GTIMA6_PSC (N32_GTIMERA6_BASE + N32_GTIMA_PSC_OFFSET) +#define N32_GTIMA6_AR (N32_GTIMERA6_BASE + N32_GTIMA_AR_OFFSET) +#define N32_GTIMA6_CNT (N32_GTIMERA6_BASE + N32_GTIMA_CNT_OFFSET) +#define N32_GTIMA6_C1FILT (N32_GTIMERA6_BASE + N32_GTIMA_C1FILT_OFFSET) +#define N32_GTIMA6_C2FILT (N32_GTIMERA6_BASE + N32_GTIMA_C2FILT_OFFSET) +#define N32_GTIMA6_C3FILT (N32_GTIMERA6_BASE + N32_GTIMA_C3FILT_OFFSET) +#define N32_GTIMA6_C4FILT (N32_GTIMERA6_BASE + N32_GTIMA_C4FILT_OFFSET) +#define N32_GTIMA6_FILTO (N32_GTIMERA6_BASE + N32_GTIMA_FILTO_OFFSET) +#define N32_GTIMA6_INSEL (N32_GTIMERA6_BASE + N32_GTIMA_INSEL_OFFSET) +#define N32_GTIMA6_DCTRL (N32_GTIMERA6_BASE + N32_GTIMA_DCTRL_OFFSET) +#define N32_GTIMA6_DADDR (N32_GTIMERA6_BASE + N32_GTIMA_DADDR_OFFSET) + +/* Register Addresses - GTIMA7 **********************************************/ + +#define N32_GTIMA7_CTRL1 (N32_GTIMERA7_BASE + N32_GTIMA_CTRL1_OFFSET) +#define N32_GTIMA7_CTRL2 (N32_GTIMERA7_BASE + N32_GTIMA_CTRL2_OFFSET) +#define N32_GTIMA7_STS (N32_GTIMERA7_BASE + N32_GTIMA_STS_OFFSET) +#define N32_GTIMA7_ETGEN (N32_GTIMERA7_BASE + N32_GTIMA_ETGEN_OFFSET) +#define N32_GTIMA7_SMCTRL (N32_GTIMERA7_BASE + N32_GTIMA_SMCTRL_OFFSET) +#define N32_GTIMA7_DINTEN (N32_GTIMERA7_BASE + N32_GTIMA_DINTEN_OFFSET) +#define N32_GTIMA7_CCMOD1 (N32_GTIMERA7_BASE + N32_GTIMA_CCMOD1_OFFSET) +#define N32_GTIMA7_CCMOD2 (N32_GTIMERA7_BASE + N32_GTIMA_CCMOD2_OFFSET) +#define N32_GTIMA7_CCEN (N32_GTIMERA7_BASE + N32_GTIMA_CCEN_OFFSET) +#define N32_GTIMA7_CCDAT1 (N32_GTIMERA7_BASE + N32_GTIMA_CCDAT1_OFFSET) +#define N32_GTIMA7_CCDAT2 (N32_GTIMERA7_BASE + N32_GTIMA_CCDAT2_OFFSET) +#define N32_GTIMA7_CCDAT3 (N32_GTIMERA7_BASE + N32_GTIMA_CCDAT3_OFFSET) +#define N32_GTIMA7_CCDAT4 (N32_GTIMERA7_BASE + N32_GTIMA_CCDAT4_OFFSET) +#define N32_GTIMA7_PSC (N32_GTIMERA7_BASE + N32_GTIMA_PSC_OFFSET) +#define N32_GTIMA7_AR (N32_GTIMERA7_BASE + N32_GTIMA_AR_OFFSET) +#define N32_GTIMA7_CNT (N32_GTIMERA7_BASE + N32_GTIMA_CNT_OFFSET) +#define N32_GTIMA7_C1FILT (N32_GTIMERA7_BASE + N32_GTIMA_C1FILT_OFFSET) +#define N32_GTIMA7_C2FILT (N32_GTIMERA7_BASE + N32_GTIMA_C2FILT_OFFSET) +#define N32_GTIMA7_C3FILT (N32_GTIMERA7_BASE + N32_GTIMA_C3FILT_OFFSET) +#define N32_GTIMA7_C4FILT (N32_GTIMERA7_BASE + N32_GTIMA_C4FILT_OFFSET) +#define N32_GTIMA7_FILTO (N32_GTIMERA7_BASE + N32_GTIMA_FILTO_OFFSET) +#define N32_GTIMA7_INSEL (N32_GTIMERA7_BASE + N32_GTIMA_INSEL_OFFSET) +#define N32_GTIMA7_DCTRL (N32_GTIMERA7_BASE + N32_GTIMA_DCTRL_OFFSET) +#define N32_GTIMA7_DADDR (N32_GTIMERA7_BASE + N32_GTIMA_DADDR_OFFSET) + +/* Bitfield Definitions - GTIMA *********************************************/ + +/* Control register 1 (N32_GTIMA_CTRL1) */ + +#define N32_GTIMA_CTRL1_CNTEN (1 << 0) /* Counter enable */ +#define N32_GTIMA_CTRL1_DIR (1 << 1) /* Direction */ +#define N32_GTIMA_CTRL1_CAMSEL_SHIFT (2) /* Center-aligned mode selection */ +#define N32_GTIMA_CTRL1_CAMSEL_MASK (3 << N32_GTIMA_CTRL1_CAMSEL_SHIFT) +# define N32_GTIMA_CTRL1_EDGE (0 << N32_GTIMA_CTRL1_CAMSEL_SHIFT) +# define N32_GTIMA_CTRL1_CENTER1 (1 << N32_GTIMA_CTRL1_CAMSEL_SHIFT) +# define N32_GTIMA_CTRL1_CENTER2 (2 << N32_GTIMA_CTRL1_CAMSEL_SHIFT) +# define N32_GTIMA_CTRL1_CENTER3 (3 << N32_GTIMA_CTRL1_CAMSEL_SHIFT) +#define N32_GTIMA_CTRL1_UPRS (1 << 4) /* Update request source */ +#define N32_GTIMA_CTRL1_UPDIS (1 << 5) /* Update disable */ +#define N32_GTIMA_CTRL1_CLKD_SHIFT (6) /* Clock division */ +#define N32_GTIMA_CTRL1_CLKD_MASK (3 << N32_GTIMA_CTRL1_CLKD_SHIFT) +# define N32_GTIMA_CTRL1_TCKINT (0 << N32_GTIMA_CTRL1_CLKD_SHIFT) +# define N32_GTIMA_CTRL1_2TCKINT (1 << N32_GTIMA_CTRL1_CLKD_SHIFT) +# define N32_GTIMA_CTRL1_4TCKINT (2 << N32_GTIMA_CTRL1_CLKD_SHIFT) +#define N32_GTIMA_CTRL1_ONEPM (1 << 8) /* One pulse mode */ +#define N32_GTIMA_CTRL1_ARPEN (1 << 9) /* Auto-reload preload enable */ +#define N32_GTIMA_CTRL1_CLRSEL (1 << 13) /* OcxRef clear selection */ + +/* GTIMA1-specific channel source selection */ +#define N32_GTIMA_CTRL1_C1SEL (1 << 16) /* GTIMA1: LSE for CH1 */ +#define N32_GTIMA_CTRL1_C2SEL (1 << 17) /* GTIMA1: LSE for CH2 */ +#define N32_GTIMA_CTRL1_C3SEL (1 << 18) /* GTIMA1: LSI for CH3 */ +#define N32_GTIMA_CTRL1_C4SEL (1 << 19) /* GTIMA1: HSE/128 for CH4 */ + +/* Control register 2 (N32_GTIMA_CTRL2) */ + +#define N32_GTIMA_CTRL2_MMSEL_SHIFT (4) /* Master mode selection (TRGO) */ +#define N32_GTIMA_CTRL2_MMSEL_MASK (7 << N32_GTIMA_CTRL2_MMSEL_SHIFT) +# define N32_GTIMA_CTRL2_MMSEL_RESET (0 << N32_GTIMA_CTRL2_MMSEL_SHIFT) +# define N32_GTIMA_CTRL2_MMSEL_ENABLE (1 << N32_GTIMA_CTRL2_MMSEL_SHIFT) +# define N32_GTIMA_CTRL2_MMSEL_UPDATE (2 << N32_GTIMA_CTRL2_MMSEL_SHIFT) +# define N32_GTIMA_CTRL2_MMSEL_COMPP (3 << N32_GTIMA_CTRL2_MMSEL_SHIFT) +# define N32_GTIMA_CTRL2_MMSEL_OC1REF (4 << N32_GTIMA_CTRL2_MMSEL_SHIFT) +# define N32_GTIMA_CTRL2_MMSEL_OC2REF (5 << N32_GTIMA_CTRL2_MMSEL_SHIFT) +# define N32_GTIMA_CTRL2_MMSEL_OC3REF (6 << N32_GTIMA_CTRL2_MMSEL_SHIFT) +# define N32_GTIMA_CTRL2_MMSEL_OC4REF (7 << N32_GTIMA_CTRL2_MMSEL_SHIFT) + +/* Status register (N32_GTIMA_STS) */ + +#define N32_GTIMA_STS_CC1ITF (1 << 0) /* CC1 interrupt flag */ +#define N32_GTIMA_STS_CC2ITF (1 << 1) /* CC2 interrupt flag */ +#define N32_GTIMA_STS_CC3ITF (1 << 2) /* CC3 interrupt flag */ +#define N32_GTIMA_STS_CC4ITF (1 << 3) /* CC4 interrupt flag */ +#define N32_GTIMA_STS_CC1OCF (1 << 8) /* CC1 overcapture flag */ +#define N32_GTIMA_STS_CC2OCF (1 << 9) /* CC2 overcapture flag */ +#define N32_GTIMA_STS_CC3OCF (1 << 10) /* CC3 overcapture flag */ +#define N32_GTIMA_STS_CC4OCF (1 << 11) /* CC4 overcapture flag */ +#define N32_GTIMA_STS_UDITF (1 << 16) /* Update interrupt flag */ +#define N32_GTIMA_STS_TITF (1 << 18) /* Trigger interrupt flag */ + +/* Event generation register (N32_GTIMA_ETGEN) */ + +#define N32_GTIMA_ETGEN_CC1GN (1 << 0) /* CC1 generation */ +#define N32_GTIMA_ETGEN_CC2GN (1 << 1) /* CC2 generation */ +#define N32_GTIMA_ETGEN_CC3GN (1 << 2) /* CC3 generation */ +#define N32_GTIMA_ETGEN_CC4GN (1 << 3) /* CC4 generation */ +#define N32_GTIMA_ETGEN_UDGN (1 << 8) /* Update generation */ +#define N32_GTIMA_ETGEN_TGN (1 << 10) /* Trigger generation */ + +/* Slave mode control (N32_GTIMA_SMCTRL) */ + +#define N32_GTIMA_SMCTRL_TSEL_SHIFT (0) /* Trigger selection */ +#define N32_GTIMA_SMCTRL_TSEL_MASK (7 << N32_GTIMA_SMCTRL_TSEL_SHIFT) +# define N32_GTIMA_SMCTRL_ITR (0 << N32_GTIMA_SMCTRL_TSEL_SHIFT) +# define N32_GTIMA_SMCTRL_TI1FED (4 << N32_GTIMA_SMCTRL_TSEL_SHIFT) +# define N32_GTIMA_SMCTRL_TI1FP1 (5 << N32_GTIMA_SMCTRL_TSEL_SHIFT) +# define N32_GTIMA_SMCTRL_TI2FP2 (6 << N32_GTIMA_SMCTRL_TSEL_SHIFT) +# define N32_GTIMA_SMCTRL_ETRF (7 << N32_GTIMA_SMCTRL_TSEL_SHIFT) +#define N32_GTIMA_SMCTRL_SMSEL_SHIFT (4) /* Slave mode selection */ +#define N32_GTIMA_SMCTRL_SMSEL_MASK (15 << N32_GTIMA_SMCTRL_SMSEL_SHIFT) +# define N32_GTIMA_SMCTRL_DISAB (0 << N32_GTIMA_SMCTRL_SMSEL_SHIFT) +# define N32_GTIMA_SMCTRL_ENCMD1 (1 << N32_GTIMA_SMCTRL_SMSEL_SHIFT) +# define N32_GTIMA_SMCTRL_ENCMD2 (2 << N32_GTIMA_SMCTRL_SMSEL_SHIFT) +# define N32_GTIMA_SMCTRL_ENCMD3 (3 << N32_GTIMA_SMCTRL_SMSEL_SHIFT) +# define N32_GTIMA_SMCTRL_RESET (4 << N32_GTIMA_SMCTRL_SMSEL_SHIFT) +# define N32_GTIMA_SMCTRL_GATED (5 << N32_GTIMA_SMCTRL_SMSEL_SHIFT) +# define N32_GTIMA_SMCTRL_TRIGGER (6 << N32_GTIMA_SMCTRL_SMSEL_SHIFT) +# define N32_GTIMA_SMCTRL_EXTCLK1 (7 << N32_GTIMA_SMCTRL_SMSEL_SHIFT) +#define N32_GTIMA_SMCTRL_EXTPS_SHIFT (8) /* External trigger prescaler */ +#define N32_GTIMA_SMCTRL_EXTPS_MASK (3 << N32_GTIMA_SMCTRL_EXTPS_SHIFT) +# define N32_GTIMA_SMCTRL_PSCOFF (0 << N32_GTIMA_SMCTRL_EXTPS_SHIFT) +# define N32_GTIMA_SMCTRL_ETRPd2 (1 << N32_GTIMA_SMCTRL_EXTPS_SHIFT) +# define N32_GTIMA_SMCTRL_ETRPd4 (2 << N32_GTIMA_SMCTRL_EXTPS_SHIFT) +# define N32_GTIMA_SMCTRL_ETRPd8 (3 << N32_GTIMA_SMCTRL_EXTPS_SHIFT) +#define N32_GTIMA_SMCTRL_EXCEN (1 << 10) /* External clock enable */ +#define N32_GTIMA_SMCTRL_EXTP (1 << 11) /* External trigger polarity */ +#define N32_GTIMA_SMCTRL_EXTF_SHIFT (12) /* External trigger filter */ +#define N32_GTIMA_SMCTRL_EXTF_MASK (15 << N32_GTIMA_SMCTRL_EXTF_SHIFT) +#define N32_GTIMA_SMCTRL_MSMD (1 << 16) /* Master/slave mode */ +#define N32_GTIMA_SMCTRL_OCRECFLRP (1 << 19) /* tim_ocref_clr polarity */ +#define N32_GTIMA_SMCTRL_OCRECFLRF_SHIFT (20) /* tim_ocref_clr filter */ +#define N32_GTIMA_SMCTRL_OCRECFLRF_MASK (15 << N32_GTIMA_SMCTRL_OCRECFLRF_SHIFT) + +/* DMA/Interrupt enable (N32_GTIMA_DINTEN) */ + +#define N32_GTIMA_DINTEN_CC1IEN (1 << 0) /* CC1 interrupt enable */ +#define N32_GTIMA_DINTEN_CC2IEN (1 << 1) /* CC2 interrupt enable */ +#define N32_GTIMA_DINTEN_CC3IEN (1 << 2) /* CC3 interrupt enable */ +#define N32_GTIMA_DINTEN_CC4IEN (1 << 3) /* CC4 interrupt enable */ +#define N32_GTIMA_DINTEN_CC1DEN (1 << 8) /* CC1 DMA request enable */ +#define N32_GTIMA_DINTEN_CC2DEN (1 << 9) /* CC2 DMA request enable */ +#define N32_GTIMA_DINTEN_CC3DEN (1 << 10) /* CC3 DMA request enable */ +#define N32_GTIMA_DINTEN_CC4DEN (1 << 11) /* CC4 DMA request enable */ +#define N32_GTIMA_DINTEN_UIEN (1 << 16) /* Update interrupt enable */ +#define N32_GTIMA_DINTEN_TIEN (1 << 17) /* Trigger interrupt enable */ +#define N32_GTIMA_DINTEN_UDEN (1 << 19) /* Update DMA request enable */ +#define N32_GTIMA_DINTEN_TDEN (1 << 21) /* Trigger DMA request enable */ + +/* CCMOD1 - Output compare (N32_GTIMA_CCMOD1) */ + +#define N32_GTIMA_CCMOD1_CC1SEL_SHIFT (0) /* CC1 selection */ +#define N32_GTIMA_CCMOD1_CC1SEL_MASK (3 << N32_GTIMA_CCMOD1_CC1SEL_SHIFT) +# define N32_GTIMA_CCMOD1_CC1OUT (0 << N32_GTIMA_CCMOD1_CC1SEL_SHIFT) +# define N32_GTIMA_CCMOD1_CC1IN_TI1 (1 << N32_GTIMA_CCMOD1_CC1SEL_SHIFT) +# define N32_GTIMA_CCMOD1_CC1IN_TI2 (2 << N32_GTIMA_CCMOD1_CC1SEL_SHIFT) +# define N32_GTIMA_CCMOD1_CC1IN_TRC (3 << N32_GTIMA_CCMOD1_CC1SEL_SHIFT) +#define N32_GTIMA_CCMOD1_OC1PEN (1 << 2) /* OC1 preload enable */ +#define N32_GTIMA_CCMOD1_OC1FEN (1 << 3) /* OC1 fast enable */ +#define N32_GTIMA_CCMOD1_OC1CEN (1 << 4) /* OC1 clear enable */ +#define N32_GTIMA_CCMOD1_OC1MD_SHIFT (5) /* OC1 mode */ +#define N32_GTIMA_CCMOD1_OC1MD_MASK (7 << N32_GTIMA_CCMOD1_OC1MD_SHIFT) +#define N32_GTIMA_CCMOD1_CC2SEL_SHIFT (8) /* CC2 selection */ +#define N32_GTIMA_CCMOD1_CC2SEL_MASK (3 << N32_GTIMA_CCMOD1_CC2SEL_SHIFT) +# define N32_GTIMA_CCMOD1_CC2OUT (0 << N32_GTIMA_CCMOD1_CC2SEL_SHIFT) +# define N32_GTIMA_CCMOD1_CC2IN_TI2 (1 << N32_GTIMA_CCMOD1_CC2SEL_SHIFT) +# define N32_GTIMA_CCMOD1_CC2IN_TI1 (2 << N32_GTIMA_CCMOD1_CC2SEL_SHIFT) +# define N32_GTIMA_CCMOD1_CC2IN_TRC (3 << N32_GTIMA_CCMOD1_CC2SEL_SHIFT) +#define N32_GTIMA_CCMOD1_OC2PEN (1 << 10) /* OC2 preload enable */ +#define N32_GTIMA_CCMOD1_OC2FEN (1 << 11) /* OC2 fast enable */ +#define N32_GTIMA_CCMOD1_OC2CEN (1 << 12) /* OC2 clear enable */ +#define N32_GTIMA_CCMOD1_OC2MD_SHIFT (13) /* OC2 mode */ +#define N32_GTIMA_CCMOD1_OC2MD_MASK (7 << N32_GTIMA_CCMOD1_OC2MD_SHIFT) + +/* CCMOD1 - Input capture (N32_GTIMA_CCMOD1) */ + +#define N32_GTIMA_CCMOD1_IC1PSC_SHIFT (2) /* IC1 prescaler */ +#define N32_GTIMA_CCMOD1_IC1PSC_MASK (3 << N32_GTIMA_CCMOD1_IC1PSC_SHIFT) +#define N32_GTIMA_CCMOD1_IC1F_SHIFT (4) /* IC1 filter */ +#define N32_GTIMA_CCMOD1_IC1F_MASK (15 << N32_GTIMA_CCMOD1_IC1F_SHIFT) +#define N32_GTIMA_CCMOD1_IC2PSC_SHIFT (10) /* IC2 prescaler */ +#define N32_GTIMA_CCMOD1_IC2PSC_MASK (3 << N32_GTIMA_CCMOD1_IC2PSC_SHIFT) +#define N32_GTIMA_CCMOD1_IC2F_SHIFT (12) /* IC2 filter */ +#define N32_GTIMA_CCMOD1_IC2F_MASK (15 << N32_GTIMA_CCMOD1_IC2F_SHIFT) + +/* CCMOD2 - Output compare (N32_GTIMA_CCMOD2) */ + +#define N32_GTIMA_CCMOD2_CC3SEL_SHIFT (0) /* CC3 selection */ +#define N32_GTIMA_CCMOD2_CC3SEL_MASK (3 << N32_GTIMA_CCMOD2_CC3SEL_SHIFT) +# define N32_GTIMA_CCMOD2_CC3OUT (0 << N32_GTIMA_CCMOD2_CC3SEL_SHIFT) +# define N32_GTIMA_CCMOD2_CC3IN_TI3 (1 << N32_GTIMA_CCMOD2_CC3SEL_SHIFT) +# define N32_GTIMA_CCMOD2_CC3IN_TI4 (2 << N32_GTIMA_CCMOD2_CC3SEL_SHIFT) +# define N32_GTIMA_CCMOD2_CC3IN_TRC (3 << N32_GTIMA_CCMOD2_CC3SEL_SHIFT) +#define N32_GTIMA_CCMOD2_OC3PEN (1 << 2) /* OC3 preload enable */ +#define N32_GTIMA_CCMOD2_OC3FEN (1 << 3) /* OC3 fast enable */ +#define N32_GTIMA_CCMOD2_OC3CEN (1 << 4) /* OC3 clear enable */ +#define N32_GTIMA_CCMOD2_OC3MD_SHIFT (5) /* OC3 mode */ +#define N32_GTIMA_CCMOD2_OC3MD_MASK (7 << N32_GTIMA_CCMOD2_OC3MD_SHIFT) +#define N32_GTIMA_CCMOD2_CC4SEL_SHIFT (8) /* CC4 selection */ +#define N32_GTIMA_CCMOD2_CC4SEL_MASK (3 << N32_GTIMA_CCMOD2_CC4SEL_SHIFT) +# define N32_GTIMA_CCMOD2_CC4OUT (0 << N32_GTIMA_CCMOD2_CC4SEL_SHIFT) +# define N32_GTIMA_CCMOD2_CC4IN_TI4 (1 << N32_GTIMA_CCMOD2_CC4SEL_SHIFT) +# define N32_GTIMA_CCMOD2_CC4IN_TI3 (2 << N32_GTIMA_CCMOD2_CC4SEL_SHIFT) +# define N32_GTIMA_CCMOD2_CC4IN_TRC (3 << N32_GTIMA_CCMOD2_CC4SEL_SHIFT) +#define N32_GTIMA_CCMOD2_OC4PEN (1 << 10) /* OC4 preload enable */ +#define N32_GTIMA_CCMOD2_OC4FEN (1 << 11) /* OC4 fast enable */ +#define N32_GTIMA_CCMOD2_OC4CEN (1 << 12) /* OC4 clear enable */ +#define N32_GTIMA_CCMOD2_OC4MD_SHIFT (13) /* OC4 mode */ +#define N32_GTIMA_CCMOD2_OC4MD_MASK (7 << N32_GTIMA_CCMOD2_OC4MD_SHIFT) + +/* CCMOD2 - Input capture (N32_GTIMA_CCMOD2) */ + +#define N32_GTIMA_CCMOD2_IC3PSC_SHIFT (2) /* IC3 prescaler */ +#define N32_GTIMA_CCMOD2_IC3PSC_MASK (3 << N32_GTIMA_CCMOD2_IC3PSC_SHIFT) +#define N32_GTIMA_CCMOD2_IC3F_SHIFT (4) /* IC3 filter */ +#define N32_GTIMA_CCMOD2_IC3F_MASK (15 << N32_GTIMA_CCMOD2_IC3F_SHIFT) +#define N32_GTIMA_CCMOD2_IC4PSC_SHIFT (10) /* IC4 prescaler */ +#define N32_GTIMA_CCMOD2_IC4PSC_MASK (3 << N32_GTIMA_CCMOD2_IC4PSC_SHIFT) +#define N32_GTIMA_CCMOD2_IC4F_SHIFT (12) /* IC4 filter */ +#define N32_GTIMA_CCMOD2_IC4F_MASK (15 << N32_GTIMA_CCMOD2_IC4F_SHIFT) + +/* CCEN (N32_GTIMA_CCEN) - No complementary outputs */ + +#define N32_GTIMA_CCEN_CC1EN (1 << 0) /* CC1 output enable */ +#define N32_GTIMA_CCEN_CC1P (1 << 1) /* CC1 output polarity */ +#define N32_GTIMA_CCEN_CC2EN (1 << 2) /* CC2 output enable */ +#define N32_GTIMA_CCEN_CC2P (1 << 3) /* CC2 output polarity */ +#define N32_GTIMA_CCEN_CC3EN (1 << 4) /* CC3 output enable */ +#define N32_GTIMA_CCEN_CC3P (1 << 5) /* CC3 output polarity */ +#define N32_GTIMA_CCEN_CC4EN (1 << 6) /* CC4 output enable */ +#define N32_GTIMA_CCEN_CC4P (1 << 7) /* CC4 output polarity */ + +/* CCDAT registers, PSC, AR, CNT */ + +#define N32_GTIMA_CCDAT_MASK (0xffff) /* CCx value mask */ +#define N32_GTIMA_PSC_MASK (0xffff) /* Prescaler value mask */ +#define N32_GTIMA_AR_MASK (0xffff) /* Auto-reload value mask */ +#define N32_GTIMA_CNT_MASK (0xffff) /* Counter value mask */ + +/* Filter registers (C1FILT..C4FILT) */ + +#define N32_GTIMA_CXFILT_SLIDFPSC_MASK (0xffff) /* Sampling clock prescaler */ +#define N32_GTIMA_CXFILT_FILTEN (1 << 16) /* Filter enable */ +#define N32_GTIMA_CXFILT_WSIZE_SHIFT (17) /* Window size */ +#define N32_GTIMA_CXFILT_WSIZE_MASK (63 << N32_GTIMA_CXFILT_WSIZE_SHIFT) +#define N32_GTIMA_CXFILT_THRESH_SHIFT (24) /* Threshold */ +#define N32_GTIMA_CXFILT_THRESH_MASK (63 << N32_GTIMA_CXFILT_THRESH_SHIFT) + +/* FILTO register */ + +#define N32_GTIMA_FILTO_C1FILTO (1 << 0) /* Channel 1 filter output */ +#define N32_GTIMA_FILTO_C2FILTO (1 << 1) /* Channel 2 filter output */ +#define N32_GTIMA_FILTO_C3FILTO (1 << 2) /* Channel 3 filter output */ +#define N32_GTIMA_FILTO_C4FILTO (1 << 3) /* Channel 4 filter output */ + +/* INSEL (same as ATIM) */ + +#define N32_GTIMA_INSEL_TI1S_SHIFT (0) /* TI1 input selection */ +#define N32_GTIMA_INSEL_TI1S_MASK (15 << N32_GTIMA_INSEL_TI1S_SHIFT) +#define N32_GTIMA_INSEL_TI2S_SHIFT (4) /* TI2 input selection */ +#define N32_GTIMA_INSEL_TI2S_MASK (15 << N32_GTIMA_INSEL_TI2S_SHIFT) +#define N32_GTIMA_INSEL_TI3S_SHIFT (8) /* TI3 input selection */ +#define N32_GTIMA_INSEL_TI3S_MASK (15 << N32_GTIMA_INSEL_TI3S_SHIFT) +#define N32_GTIMA_INSEL_TI4S_SHIFT (12) /* TI4 input selection */ +#define N32_GTIMA_INSEL_TI4S_MASK (15 << N32_GTIMA_INSEL_TI4S_SHIFT) +#define N32_GTIMA_INSEL_ETRS_SHIFT (16) /* ETR input selection */ +#define N32_GTIMA_INSEL_ETRS_MASK (15 << N32_GTIMA_INSEL_ETRS_SHIFT) +#define N32_GTIMA_INSEL_ITRS_SHIFT (20) /* ITR input selection */ +#define N32_GTIMA_INSEL_ITRS_MASK (15 << N32_GTIMA_INSEL_ITRS_SHIFT) +#define N32_GTIMA_INSEL_CLRS_SHIFT (24) /* OcxRef clear input selection */ +#define N32_GTIMA_INSEL_CLRS_MASK (15 << N32_GTIMA_INSEL_CLRS_SHIFT) + +/* DCTRL/DADDR */ + +#define N32_GTIMA_DCTRL_DBLEN_SHIFT (0) /* DMA burst length */ +#define N32_GTIMA_DCTRL_DBLEN_MASK (63 << N32_GTIMA_DCTRL_DBLEN_SHIFT) +# define N32_GTIMA_DCTRL_DBLEN(n) (((n)-1) << N32_GTIMA_DCTRL_DBLEN_SHIFT) +#define N32_GTIMA_DCTRL_DBADDR_SHIFT (8) /* DMA base address */ +#define N32_GTIMA_DCTRL_DBADDR_MASK (63 << N32_GTIMA_DCTRL_DBADDR_SHIFT) +#define N32_GTIMA_DADDR_BURST_MASK (0xffffffff) + +/* ========================================================================== + * GENERAL-PURPOSE TIMERS B (GTIMB1-3) + * ========================================================================== + */ + +/* Register Offsets - GTIMB (common for all GTIMB1-3) ***********************/ + +#define N32_GTIMB_CTRL1_OFFSET 0x0000 /* Control register 1 */ +#define N32_GTIMB_CTRL2_OFFSET 0x0004 /* Control register 2 */ +#define N32_GTIMB_STS_OFFSET 0x0008 /* Status register */ +#define N32_GTIMB_ETGEN_OFFSET 0x000c /* Event generation register */ +#define N32_GTIMB_SMCTRL_OFFSET 0x0010 /* Slave mode control register */ +#define N32_GTIMB_DINTEN_OFFSET 0x0014 /* DMA/Interrupt enable register */ +#define N32_GTIMB_CCMOD1_OFFSET 0x0018 /* Capture/compare mode register 1 */ +#define N32_GTIMB_CCMOD2_OFFSET 0x001c /* Capture/compare mode register 2 */ +#define N32_GTIMB_CCMOD3_OFFSET 0x0020 /* Capture/compare mode register 3 */ +#define N32_GTIMB_CCEN_OFFSET 0x0024 /* Capture/compare enable register */ +#define N32_GTIMB_CCDAT1_OFFSET 0x0028 /* Capture/compare register 1 */ +#define N32_GTIMB_CCDAT2_OFFSET 0x002c /* Capture/compare register 2 */ +#define N32_GTIMB_CCDAT3_OFFSET 0x0030 /* Capture/compare register 3 */ +#define N32_GTIMB_CCDAT4_OFFSET 0x0034 /* Capture/compare register 4 */ +#define N32_GTIMB_CCDAT5_OFFSET 0x0038 /* Capture/compare register 5 */ +#define N32_GTIMB_PSC_OFFSET 0x0040 /* Prescaler */ +#define N32_GTIMB_AR_OFFSET 0x0044 /* Auto-reload register */ +#define N32_GTIMB_CNT_OFFSET 0x0048 /* Counter */ +#define N32_GTIMB_REPCNT_OFFSET 0x004c /* Repetition counter register */ +#define N32_GTIMB_BKDT_OFFSET 0x0050 /* Break and dead-time register */ +#define N32_GTIMB_BKFR_OFFSET 0x0060 /* Break 1 filter register */ +#define N32_GTIMB_C1FILT_OFFSET 0x0064 /* Channel 1 filter register */ +#define N32_GTIMB_C2FILT_OFFSET 0x0068 /* Channel 2 filter register */ +#define N32_GTIMB_C3FILT_OFFSET 0x006c /* Channel 3 filter register */ +#define N32_GTIMB_C4FILT_OFFSET 0x0070 /* Channel 4 filter register */ +#define N32_GTIMB_FILTO_OFFSET 0x0074 /* Filter output register */ +#define N32_GTIMB_INSEL_OFFSET 0x0078 /* Input selection register */ +#define N32_GTIMB_AF1_OFFSET 0x007c /* Alternate function register 1 */ +#define N32_GTIMB_DCTRL_OFFSET 0x0094 /* DMA control register */ +#define N32_GTIMB_DADDR_OFFSET 0x0098 /* DMA address for burst mode */ + +/* Register Addresses - GTIMB1 **********************************************/ + +#define N32_GTIMB1_CTRL1 (N32_GTIMERB1_BASE + N32_GTIMB_CTRL1_OFFSET) +#define N32_GTIMB1_CTRL2 (N32_GTIMERB1_BASE + N32_GTIMB_CTRL2_OFFSET) +#define N32_GTIMB1_STS (N32_GTIMERB1_BASE + N32_GTIMB_STS_OFFSET) +#define N32_GTIMB1_ETGEN (N32_GTIMERB1_BASE + N32_GTIMB_ETGEN_OFFSET) +#define N32_GTIMB1_SMCTRL (N32_GTIMERB1_BASE + N32_GTIMB_SMCTRL_OFFSET) +#define N32_GTIMB1_DINTEN (N32_GTIMERB1_BASE + N32_GTIMB_DINTEN_OFFSET) +#define N32_GTIMB1_CCMOD1 (N32_GTIMERB1_BASE + N32_GTIMB_CCMOD1_OFFSET) +#define N32_GTIMB1_CCMOD2 (N32_GTIMERB1_BASE + N32_GTIMB_CCMOD2_OFFSET) +#define N32_GTIMB1_CCMOD3 (N32_GTIMERB1_BASE + N32_GTIMB_CCMOD3_OFFSET) +#define N32_GTIMB1_CCEN (N32_GTIMERB1_BASE + N32_GTIMB_CCEN_OFFSET) +#define N32_GTIMB1_CCDAT1 (N32_GTIMERB1_BASE + N32_GTIMB_CCDAT1_OFFSET) +#define N32_GTIMB1_CCDAT2 (N32_GTIMERB1_BASE + N32_GTIMB_CCDAT2_OFFSET) +#define N32_GTIMB1_CCDAT3 (N32_GTIMERB1_BASE + N32_GTIMB_CCDAT3_OFFSET) +#define N32_GTIMB1_CCDAT4 (N32_GTIMERB1_BASE + N32_GTIMB_CCDAT4_OFFSET) +#define N32_GTIMB1_CCDAT5 (N32_GTIMERB1_BASE + N32_GTIMB_CCDAT5_OFFSET) +#define N32_GTIMB1_PSC (N32_GTIMERB1_BASE + N32_GTIMB_PSC_OFFSET) +#define N32_GTIMB1_AR (N32_GTIMERB1_BASE + N32_GTIMB_AR_OFFSET) +#define N32_GTIMB1_CNT (N32_GTIMERB1_BASE + N32_GTIMB_CNT_OFFSET) +#define N32_GTIMB1_REPCNT (N32_GTIMERB1_BASE + N32_GTIMB_REPCNT_OFFSET) +#define N32_GTIMB1_BKDT (N32_GTIMERB1_BASE + N32_GTIMB_BKDT_OFFSET) +#define N32_GTIMB1_BKFR (N32_GTIMERB1_BASE + N32_GTIMB_BKFR_OFFSET) +#define N32_GTIMB1_C1FILT (N32_GTIMERB1_BASE + N32_GTIMB_C1FILT_OFFSET) +#define N32_GTIMB1_C2FILT (N32_GTIMERB1_BASE + N32_GTIMB_C2FILT_OFFSET) +#define N32_GTIMB1_C3FILT (N32_GTIMERB1_BASE + N32_GTIMB_C3FILT_OFFSET) +#define N32_GTIMB1_C4FILT (N32_GTIMERB1_BASE + N32_GTIMB_C4FILT_OFFSET) +#define N32_GTIMB1_FILTO (N32_GTIMERB1_BASE + N32_GTIMB_FILTO_OFFSET) +#define N32_GTIMB1_INSEL (N32_GTIMERB1_BASE + N32_GTIMB_INSEL_OFFSET) +#define N32_GTIMB1_AF1 (N32_GTIMERB1_BASE + N32_GTIMB_AF1_OFFSET) +#define N32_GTIMB1_DCTRL (N32_GTIMERB1_BASE + N32_GTIMB_DCTRL_OFFSET) +#define N32_GTIMB1_DADDR (N32_GTIMERB1_BASE + N32_GTIMB_DADDR_OFFSET) + +/* Register Addresses - GTIMB2 **********************************************/ + +#define N32_GTIMB2_CTRL1 (N32_GTIMERB2_BASE + N32_GTIMB_CTRL1_OFFSET) +#define N32_GTIMB2_CTRL2 (N32_GTIMERB2_BASE + N32_GTIMB_CTRL2_OFFSET) +#define N32_GTIMB2_STS (N32_GTIMERB2_BASE + N32_GTIMB_STS_OFFSET) +#define N32_GTIMB2_ETGEN (N32_GTIMERB2_BASE + N32_GTIMB_ETGEN_OFFSET) +#define N32_GTIMB2_SMCTRL (N32_GTIMERB2_BASE + N32_GTIMB_SMCTRL_OFFSET) +#define N32_GTIMB2_DINTEN (N32_GTIMERB2_BASE + N32_GTIMB_DINTEN_OFFSET) +#define N32_GTIMB2_CCMOD1 (N32_GTIMERB2_BASE + N32_GTIMB_CCMOD1_OFFSET) +#define N32_GTIMB2_CCMOD2 (N32_GTIMERB2_BASE + N32_GTIMB_CCMOD2_OFFSET) +#define N32_GTIMB2_CCMOD3 (N32_GTIMERB2_BASE + N32_GTIMB_CCMOD3_OFFSET) +#define N32_GTIMB2_CCEN (N32_GTIMERB2_BASE + N32_GTIMB_CCEN_OFFSET) +#define N32_GTIMB2_CCDAT1 (N32_GTIMERB2_BASE + N32_GTIMB_CCDAT1_OFFSET) +#define N32_GTIMB2_CCDAT2 (N32_GTIMERB2_BASE + N32_GTIMB_CCDAT2_OFFSET) +#define N32_GTIMB2_CCDAT3 (N32_GTIMERB2_BASE + N32_GTIMB_CCDAT3_OFFSET) +#define N32_GTIMB2_CCDAT4 (N32_GTIMERB2_BASE + N32_GTIMB_CCDAT4_OFFSET) +#define N32_GTIMB2_CCDAT5 (N32_GTIMERB2_BASE + N32_GTIMB_CCDAT5_OFFSET) +#define N32_GTIMB2_PSC (N32_GTIMERB2_BASE + N32_GTIMB_PSC_OFFSET) +#define N32_GTIMB2_AR (N32_GTIMERB2_BASE + N32_GTIMB_AR_OFFSET) +#define N32_GTIMB2_CNT (N32_GTIMERB2_BASE + N32_GTIMB_CNT_OFFSET) +#define N32_GTIMB2_REPCNT (N32_GTIMERB2_BASE + N32_GTIMB_REPCNT_OFFSET) +#define N32_GTIMB2_BKDT (N32_GTIMERB2_BASE + N32_GTIMB_BKDT_OFFSET) +#define N32_GTIMB2_BKFR (N32_GTIMERB2_BASE + N32_GTIMB_BKFR_OFFSET) +#define N32_GTIMB2_C1FILT (N32_GTIMERB2_BASE + N32_GTIMB_C1FILT_OFFSET) +#define N32_GTIMB2_C2FILT (N32_GTIMERB2_BASE + N32_GTIMB_C2FILT_OFFSET) +#define N32_GTIMB2_C3FILT (N32_GTIMERB2_BASE + N32_GTIMB_C3FILT_OFFSET) +#define N32_GTIMB2_C4FILT (N32_GTIMERB2_BASE + N32_GTIMB_C4FILT_OFFSET) +#define N32_GTIMB2_FILTO (N32_GTIMERB2_BASE + N32_GTIMB_FILTO_OFFSET) +#define N32_GTIMB2_INSEL (N32_GTIMERB2_BASE + N32_GTIMB_INSEL_OFFSET) +#define N32_GTIMB2_AF1 (N32_GTIMERB2_BASE + N32_GTIMB_AF1_OFFSET) +#define N32_GTIMB2_DCTRL (N32_GTIMERB2_BASE + N32_GTIMB_DCTRL_OFFSET) +#define N32_GTIMB2_DADDR (N32_GTIMERB2_BASE + N32_GTIMB_DADDR_OFFSET) + +/* Register Addresses - GTIMB3 **********************************************/ + +#define N32_GTIMB3_CTRL1 (N32_GTIMERB3_BASE + N32_GTIMB_CTRL1_OFFSET) +#define N32_GTIMB3_CTRL2 (N32_GTIMERB3_BASE + N32_GTIMB_CTRL2_OFFSET) +#define N32_GTIMB3_STS (N32_GTIMERB3_BASE + N32_GTIMB_STS_OFFSET) +#define N32_GTIMB3_ETGEN (N32_GTIMERB3_BASE + N32_GTIMB_ETGEN_OFFSET) +#define N32_GTIMB3_SMCTRL (N32_GTIMERB3_BASE + N32_GTIMB_SMCTRL_OFFSET) +#define N32_GTIMB3_DINTEN (N32_GTIMERB3_BASE + N32_GTIMB_DINTEN_OFFSET) +#define N32_GTIMB3_CCMOD1 (N32_GTIMERB3_BASE + N32_GTIMB_CCMOD1_OFFSET) +#define N32_GTIMB3_CCMOD2 (N32_GTIMERB3_BASE + N32_GTIMB_CCMOD2_OFFSET) +#define N32_GTIMB3_CCMOD3 (N32_GTIMERB3_BASE + N32_GTIMB_CCMOD3_OFFSET) +#define N32_GTIMB3_CCEN (N32_GTIMERB3_BASE + N32_GTIMB_CCEN_OFFSET) +#define N32_GTIMB3_CCDAT1 (N32_GTIMERB3_BASE + N32_GTIMB_CCDAT1_OFFSET) +#define N32_GTIMB3_CCDAT2 (N32_GTIMERB3_BASE + N32_GTIMB_CCDAT2_OFFSET) +#define N32_GTIMB3_CCDAT3 (N32_GTIMERB3_BASE + N32_GTIMB_CCDAT3_OFFSET) +#define N32_GTIMB3_CCDAT4 (N32_GTIMERB3_BASE + N32_GTIMB_CCDAT4_OFFSET) +#define N32_GTIMB3_CCDAT5 (N32_GTIMERB3_BASE + N32_GTIMB_CCDAT5_OFFSET) +#define N32_GTIMB3_PSC (N32_GTIMERB3_BASE + N32_GTIMB_PSC_OFFSET) +#define N32_GTIMB3_AR (N32_GTIMERB3_BASE + N32_GTIMB_AR_OFFSET) +#define N32_GTIMB3_CNT (N32_GTIMERB3_BASE + N32_GTIMB_CNT_OFFSET) +#define N32_GTIMB3_REPCNT (N32_GTIMERB3_BASE + N32_GTIMB_REPCNT_OFFSET) +#define N32_GTIMB3_BKDT (N32_GTIMERB3_BASE + N32_GTIMB_BKDT_OFFSET) +#define N32_GTIMB3_BKFR (N32_GTIMERB3_BASE + N32_GTIMB_BKFR_OFFSET) +#define N32_GTIMB3_C1FILT (N32_GTIMERB3_BASE + N32_GTIMB_C1FILT_OFFSET) +#define N32_GTIMB3_C2FILT (N32_GTIMERB3_BASE + N32_GTIMB_C2FILT_OFFSET) +#define N32_GTIMB3_C3FILT (N32_GTIMERB3_BASE + N32_GTIMB_C3FILT_OFFSET) +#define N32_GTIMB3_C4FILT (N32_GTIMERB3_BASE + N32_GTIMB_C4FILT_OFFSET) +#define N32_GTIMB3_FILTO (N32_GTIMERB3_BASE + N32_GTIMB_FILTO_OFFSET) +#define N32_GTIMB3_INSEL (N32_GTIMERB3_BASE + N32_GTIMB_INSEL_OFFSET) +#define N32_GTIMB3_AF1 (N32_GTIMERB3_BASE + N32_GTIMB_AF1_OFFSET) +#define N32_GTIMB3_DCTRL (N32_GTIMERB3_BASE + N32_GTIMB_DCTRL_OFFSET) +#define N32_GTIMB3_DADDR (N32_GTIMERB3_BASE + N32_GTIMB_DADDR_OFFSET) + +/* Bitfield Definitions - GTIMB *********************************************/ + +/* Control register 1 (N32_GTIMB_CTRL1) */ + +#define N32_GTIMB_CTRL1_CNTEN (1 << 0) /* Counter enable */ +#define N32_GTIMB_CTRL1_DIR (1 << 1) /* Direction */ +#define N32_GTIMB_CTRL1_CAMSEL_SHIFT (2) /* Center-aligned mode selection */ +#define N32_GTIMB_CTRL1_CAMSEL_MASK (3 << N32_GTIMB_CTRL1_CAMSEL_SHIFT) +# define N32_GTIMB_CTRL1_EDGE (0 << N32_GTIMB_CTRL1_CAMSEL_SHIFT) +# define N32_GTIMB_CTRL1_CENTER1 (1 << N32_GTIMB_CTRL1_CAMSEL_SHIFT) +# define N32_GTIMB_CTRL1_CENTER2 (2 << N32_GTIMB_CTRL1_CAMSEL_SHIFT) +# define N32_GTIMB_CTRL1_CENTER3 (3 << N32_GTIMB_CTRL1_CAMSEL_SHIFT) +#define N32_GTIMB_CTRL1_UPRS (1 << 4) /* Update request source */ +#define N32_GTIMB_CTRL1_UPDIS (1 << 5) /* Update disable */ +#define N32_GTIMB_CTRL1_CLKD_SHIFT (6) /* Clock division */ +#define N32_GTIMB_CTRL1_CLKD_MASK (3 << N32_GTIMB_CTRL1_CLKD_SHIFT) +# define N32_GTIMB_CTRL1_TCKINT (0 << N32_GTIMB_CTRL1_CLKD_SHIFT) +# define N32_GTIMB_CTRL1_2TCKINT (1 << N32_GTIMB_CTRL1_CLKD_SHIFT) +# define N32_GTIMB_CTRL1_4TCKINT (2 << N32_GTIMB_CTRL1_CLKD_SHIFT) +#define N32_GTIMB_CTRL1_ONEPM (1 << 8) /* One pulse mode */ +#define N32_GTIMB_CTRL1_ARPEN (1 << 9) /* Auto-reload preload enable */ +#define N32_GTIMB_CTRL1_LBKPEN (1 << 10) /* LockUp as BRK enable */ +#define N32_GTIMB_CTRL1_PBKPEN (1 << 11) /* PVD as BRK enable */ +#define N32_GTIMB_CTRL1_SRAMPARRERREN (1 << 12) /* SRAM parity error as BRK enable */ +#define N32_GTIMB_CTRL1_CLRSEL (1 << 13) /* OcxRef clear selection */ +#define N32_GTIMB_CTRL1_SRAMECERREN (1 << 15) /* SRAM ECC error as BRK enable */ +#define N32_GTIMB_CTRL1_ASYMMETRIC (1 << 23) /* Asymmetric mode enable */ +#define N32_GTIMB_CTRL1_UDITFREMAP (1 << 24) /* UDITF status bit remapping */ + +/* Control register 2 (N32_GTIMB_CTRL2) */ + +#define N32_GTIMB_CTRL2_O11 (1 << 0) /* Output idle state 1 (OC1) */ +#define N32_GTIMB_CTRL2_O11N (1 << 1) /* Output idle state 1N (OC1N) */ +#define N32_GTIMB_CTRL2_O12 (1 << 2) /* Output idle state 2 (OC2) */ +#define N32_GTIMB_CTRL2_O13 (1 << 4) /* Output idle state 3 (OC3) */ +#define N32_GTIMB_CTRL2_O14 (1 << 6) /* Output idle state 4 (OC4) */ +#define N32_GTIMB_CTRL2_O15 (1 << 8) /* Output idle state 5 (OC5) */ +#define N32_GTIMB_CTRL2_MMSEL_SHIFT (12) /* Master mode selection (TRGO) */ +#define N32_GTIMB_CTRL2_MMSEL_MASK (15 << N32_GTIMB_CTRL2_MMSEL_SHIFT) +# define N32_GTIMB_CTRL2_MMSEL_RESET (0 << N32_GTIMB_CTRL2_MMSEL_SHIFT) +# define N32_GTIMB_CTRL2_MMSEL_ENABLE (1 << N32_GTIMB_CTRL2_MMSEL_SHIFT) +# define N32_GTIMB_CTRL2_MMSEL_UPDATE (2 << N32_GTIMB_CTRL2_MMSEL_SHIFT) +# define N32_GTIMB_CTRL2_MMSEL_COMPP (3 << N32_GTIMB_CTRL2_MMSEL_SHIFT) +# define N32_GTIMB_CTRL2_MMSEL_OC1REF (4 << N32_GTIMB_CTRL2_MMSEL_SHIFT) +# define N32_GTIMB_CTRL2_MMSEL_OC2REF (5 << N32_GTIMB_CTRL2_MMSEL_SHIFT) +# define N32_GTIMB_CTRL2_MMSEL_OC3REF (6 << N32_GTIMB_CTRL2_MMSEL_SHIFT) +# define N32_GTIMB_CTRL2_MMSEL_OC4REF (7 << N32_GTIMB_CTRL2_MMSEL_SHIFT) +#define N32_GTIMB_CTRL2_CCUSEL (1 << 16) /* CC control update selection */ +#define N32_GTIMB_CTRL2_CCDSEL (1 << 17) /* CC DMA selection */ +#define N32_GTIMB_CTRL2_CCPCTL (1 << 18) /* CC preloaded control */ +#define N32_GTIMB_CTRL2_TIISEL (1 << 19) /* TI1 selection (XOR mode) */ + +/* Status register (N32_GTIMB_STS) */ + +#define N32_GTIMB_STS_CC1ITF (1 << 0) /* CC1 interrupt flag */ +#define N32_GTIMB_STS_CC2ITF (1 << 1) /* CC2 interrupt flag */ +#define N32_GTIMB_STS_CC3ITF (1 << 2) /* CC3 interrupt flag */ +#define N32_GTIMB_STS_CC4ITF (1 << 3) /* CC4 interrupt flag */ +#define N32_GTIMB_STS_CC5ITF (1 << 4) /* CC5 interrupt flag */ +#define N32_GTIMB_STS_CC1OCF (1 << 8) /* CC1 overcapture flag */ +#define N32_GTIMB_STS_CC2OCF (1 << 9) /* CC2 overcapture flag */ +#define N32_GTIMB_STS_CC3OCF (1 << 10) /* CC3 overcapture flag */ +#define N32_GTIMB_STS_CC4OCF (1 << 11) /* CC4 overcapture flag */ +#define N32_GTIMB_STS_UDITF (1 << 16) /* Update interrupt flag */ +#define N32_GTIMB_STS_TITF (1 << 18) /* Trigger interrupt flag */ +#define N32_GTIMB_STS_BITF (1 << 19) /* Break1 interrupt flag */ +#define N32_GTIMB_STS_SBITF (1 << 21) /* System break interrupt flag */ + +/* Event generation (N32_GTIMB_ETGEN) */ + +#define N32_GTIMB_ETGEN_CC1GN (1 << 0) /* CC1 generation */ +#define N32_GTIMB_ETGEN_CC2GN (1 << 1) /* CC2 generation */ +#define N32_GTIMB_ETGEN_CC3GN (1 << 2) /* CC3 generation */ +#define N32_GTIMB_ETGEN_CC4GN (1 << 3) /* CC4 generation */ +#define N32_GTIMB_ETGEN_UDGN (1 << 8) /* Update generation */ +#define N32_GTIMB_ETGEN_CCUDGN (1 << 9) /* CC control update generation */ +#define N32_GTIMB_ETGEN_TGN (1 << 10) /* Trigger generation */ +#define N32_GTIMB_ETGEN_BGN (1 << 11) /* Break1 generation */ + +/* SMCTRL (same as ATIM/GTIMA) */ + +#define N32_GTIMB_SMCTRL_TSEL_SHIFT (0) /* Trigger selection */ +#define N32_GTIMB_SMCTRL_TSEL_MASK (7 << N32_GTIMB_SMCTRL_TSEL_SHIFT) +#define N32_GTIMB_SMCTRL_SMSEL_SHIFT (4) /* Slave mode selection */ +#define N32_GTIMB_SMCTRL_SMSEL_MASK (15 << N32_GTIMB_SMCTRL_SMSEL_SHIFT) +#define N32_GTIMB_SMCTRL_EXTPS_SHIFT (8) /* External trigger prescaler */ +#define N32_GTIMB_SMCTRL_EXTPS_MASK (3 << N32_GTIMB_SMCTRL_EXTPS_SHIFT) +#define N32_GTIMB_SMCTRL_EXCEN (1 << 10) /* External clock enable */ +#define N32_GTIMB_SMCTRL_EXTP (1 << 11) /* External trigger polarity */ +#define N32_GTIMB_SMCTRL_EXTF_SHIFT (12) /* External trigger filter */ +#define N32_GTIMB_SMCTRL_EXTF_MASK (15 << N32_GTIMB_SMCTRL_EXTF_SHIFT) +#define N32_GTIMB_SMCTRL_MSMD (1 << 16) /* Master/slave mode */ +#define N32_GTIMB_SMCTRL_OCRECFLRP (1 << 19) /* tim_ocref_clr polarity */ +#define N32_GTIMB_SMCTRL_OCRECFLRF_SHIFT (20) /* tim_ocref_clr filter */ +#define N32_GTIMB_SMCTRL_OCRECFLRF_MASK (15 << N32_GTIMB_SMCTRL_OCRECFLRF_SHIFT) + +/* DINTEN (N32_GTIMB_DINTEN) */ + +#define N32_GTIMB_DINTEN_CC1IEN (1 << 0) /* CC1 interrupt enable */ +#define N32_GTIMB_DINTEN_CC2IEN (1 << 1) /* CC2 interrupt enable */ +#define N32_GTIMB_DINTEN_CC3IEN (1 << 2) /* CC3 interrupt enable */ +#define N32_GTIMB_DINTEN_CC4IEN (1 << 3) /* CC4 interrupt enable */ +#define N32_GTIMB_DINTEN_CC1DEN (1 << 8) /* CC1 DMA request enable */ +#define N32_GTIMB_DINTEN_CC2DEN (1 << 9) /* CC2 DMA request enable */ +#define N32_GTIMB_DINTEN_CC3DEN (1 << 10) /* CC3 DMA request enable */ +#define N32_GTIMB_DINTEN_CC4DEN (1 << 11) /* CC4 DMA request enable */ +#define N32_GTIMB_DINTEN_UIEN (1 << 16) /* Update interrupt enable */ +#define N32_GTIMB_DINTEN_TIEN (1 << 17) /* Trigger interrupt enable */ +#define N32_GTIMB_DINTEN_BIEN (1 << 18) /* Break interrupt enable */ +#define N32_GTIMB_DINTEN_UDEN (1 << 19) /* Update DMA request enable */ +#define N32_GTIMB_DINTEN_COMDEN (1 << 20) /* COM DMA request enable */ +#define N32_GTIMB_DINTEN_TDEN (1 << 21) /* Trigger DMA request enable */ +#define N32_GTIMB_DINTEN_COMIEN (1 << 22) /* COM interrupt enable */ + +/* CCMOD1 - Output compare (N32_GTIMB_CCMOD1) - 4-bit OC mode */ + +#define N32_GTIMB_CCMOD1_CC1SEL_SHIFT (0) /* CC1 selection */ +#define N32_GTIMB_CCMOD1_CC1SEL_MASK (3 << N32_GTIMB_CCMOD1_CC1SEL_SHIFT) +# define N32_GTIMB_CCMOD1_CC1OUT (0 << N32_GTIMB_CCMOD1_CC1SEL_SHIFT) +# define N32_GTIMB_CCMOD1_CC1IN_TI1 (1 << N32_GTIMB_CCMOD1_CC1SEL_SHIFT) +# define N32_GTIMB_CCMOD1_CC1IN_TI2 (2 << N32_GTIMB_CCMOD1_CC1SEL_SHIFT) +# define N32_GTIMB_CCMOD1_CC1IN_TRC (3 << N32_GTIMB_CCMOD1_CC1SEL_SHIFT) +#define N32_GTIMB_CCMOD1_OC1PEN (1 << 2) /* OC1 preload enable */ +#define N32_GTIMB_CCMOD1_OC1FEN (1 << 3) /* OC1 fast enable */ +#define N32_GTIMB_CCMOD1_OC1CEN (1 << 4) /* OC1 clear enable */ +#define N32_GTIMB_CCMOD1_OC1MD_SHIFT (5) /* OC1 mode (bits 0-2) */ +#define N32_GTIMB_CCMOD1_OC1MD_MASK (7 << N32_GTIMB_CCMOD1_OC1MD_SHIFT) +#define N32_GTIMB_CCMOD1_OC1MD3 (1 << 17) /* OC1 mode bit 3 */ +#define N32_GTIMB_CCMOD1_CC2SEL_SHIFT (8) /* CC2 selection */ +#define N32_GTIMB_CCMOD1_CC2SEL_MASK (3 << N32_GTIMB_CCMOD1_CC2SEL_SHIFT) +# define N32_GTIMB_CCMOD1_CC2OUT (0 << N32_GTIMB_CCMOD1_CC2SEL_SHIFT) +# define N32_GTIMB_CCMOD1_CC2IN_TI2 (1 << N32_GTIMB_CCMOD1_CC2SEL_SHIFT) +# define N32_GTIMB_CCMOD1_CC2IN_TI1 (2 << N32_GTIMB_CCMOD1_CC2SEL_SHIFT) +# define N32_GTIMB_CCMOD1_CC2IN_TRC (3 << N32_GTIMB_CCMOD1_CC2SEL_SHIFT) +#define N32_GTIMB_CCMOD1_OC2PEN (1 << 10) /* OC2 preload enable */ +#define N32_GTIMB_CCMOD1_OC2FEN (1 << 11) /* OC2 fast enable */ +#define N32_GTIMB_CCMOD1_OC2CEN (1 << 12) /* OC2 clear enable */ +#define N32_GTIMB_CCMOD1_OC2MD_SHIFT (13) /* OC2 mode (bits 0-2) */ +#define N32_GTIMB_CCMOD1_OC2MD_MASK (7 << N32_GTIMB_CCMOD1_OC2MD_SHIFT) +#define N32_GTIMB_CCMOD1_OC2MD3 (1 << 18) /* OC2 mode bit 3 */ + +/* 4-bit OC mode values (OCxMD3 + OCxMD[2:0]) */ +#define N32_GTIMB_OCMODE_FRZN (0) /* Frozen */ +#define N32_GTIMB_OCMODE_ACTIVE (1) /* Active */ +#define N32_GTIMB_OCMODE_INACTIVE (2) /* Inactive */ +#define N32_GTIMB_OCMODE_TOGGLE (3) /* Toggle */ +#define N32_GTIMB_OCMODE_FORCELO (4) /* Force low */ +#define N32_GTIMB_OCMODE_FORCEHI (5) /* Force high */ +#define N32_GTIMB_OCMODE_PWM1 (6) /* PWM mode 1 */ +#define N32_GTIMB_OCMODE_PWM2 (7) /* PWM mode 2 */ +#define N32_GTIMB_OCMODE_RETRIG1 (8) /* Retriggerable OPM 1 */ +#define N32_GTIMB_OCMODE_RETRIG2 (9) /* Retriggerable OPM 2 */ +#define N32_GTIMB_OCMODE_COMBINED1 (14) /* Combined PWM 1 */ +#define N32_GTIMB_OCMODE_COMBINED2 (15) /* Combined PWM 2 */ + +/* CCMOD1 - Input capture (N32_GTIMB_CCMOD1) */ + +#define N32_GTIMB_CCMOD1_IC1PSC_SHIFT (2) /* IC1 prescaler */ +#define N32_GTIMB_CCMOD1_IC1PSC_MASK (3 << N32_GTIMB_CCMOD1_IC1PSC_SHIFT) +#define N32_GTIMB_CCMOD1_IC1F_SHIFT (4) /* IC1 filter */ +#define N32_GTIMB_CCMOD1_IC1F_MASK (15 << N32_GTIMB_CCMOD1_IC1F_SHIFT) +#define N32_GTIMB_CCMOD1_IC2PSC_SHIFT (10) /* IC2 prescaler */ +#define N32_GTIMB_CCMOD1_IC2PSC_MASK (3 << N32_GTIMB_CCMOD1_IC2PSC_SHIFT) +#define N32_GTIMB_CCMOD1_IC2F_SHIFT (12) /* IC2 filter */ +#define N32_GTIMB_CCMOD1_IC2F_MASK (15 << N32_GTIMB_CCMOD1_IC2F_SHIFT) + +/* CCMOD2 - Output compare (N32_GTIMB_CCMOD2) */ + +#define N32_GTIMB_CCMOD2_CC3SEL_SHIFT (0) /* CC3 selection */ +#define N32_GTIMB_CCMOD2_CC3SEL_MASK (3 << N32_GTIMB_CCMOD2_CC3SEL_SHIFT) +# define N32_GTIMB_CCMOD2_CC3OUT (0 << N32_GTIMB_CCMOD2_CC3SEL_SHIFT) +# define N32_GTIMB_CCMOD2_CC3IN_TI3 (1 << N32_GTIMB_CCMOD2_CC3SEL_SHIFT) +# define N32_GTIMB_CCMOD2_CC3IN_TI4 (2 << N32_GTIMB_CCMOD2_CC3SEL_SHIFT) +# define N32_GTIMB_CCMOD2_CC3IN_TRC (3 << N32_GTIMB_CCMOD2_CC3SEL_SHIFT) +#define N32_GTIMB_CCMOD2_OC3PEN (1 << 2) /* OC3 preload enable */ +#define N32_GTIMB_CCMOD2_OC3FEN (1 << 3) /* OC3 fast enable */ +#define N32_GTIMB_CCMOD2_OC3CEN (1 << 4) /* OC3 clear enable */ +#define N32_GTIMB_CCMOD2_OC3MD_SHIFT (5) /* OC3 mode (bits 0-2) */ +#define N32_GTIMB_CCMOD2_OC3MD_MASK (7 << N32_GTIMB_CCMOD2_OC3MD_SHIFT) +#define N32_GTIMB_CCMOD2_OC3MD3 (1 << 17) /* OC3 mode bit 3 */ +#define N32_GTIMB_CCMOD2_CC4SEL_SHIFT (8) /* CC4 selection */ +#define N32_GTIMB_CCMOD2_CC4SEL_MASK (3 << N32_GTIMB_CCMOD2_CC4SEL_SHIFT) +# define N32_GTIMB_CCMOD2_CC4OUT (0 << N32_GTIMB_CCMOD2_CC4SEL_SHIFT) +# define N32_GTIMB_CCMOD2_CC4IN_TI4 (1 << N32_GTIMB_CCMOD2_CC4SEL_SHIFT) +# define N32_GTIMB_CCMOD2_CC4IN_TI3 (2 << N32_GTIMB_CCMOD2_CC4SEL_SHIFT) +# define N32_GTIMB_CCMOD2_CC4IN_TRC (3 << N32_GTIMB_CCMOD2_CC4SEL_SHIFT) +#define N32_GTIMB_CCMOD2_OC4PEN (1 << 10) /* OC4 preload enable */ +#define N32_GTIMB_CCMOD2_OC4FEN (1 << 11) /* OC4 fast enable */ +#define N32_GTIMB_CCMOD2_OC4CEN (1 << 12) /* OC4 clear enable */ +#define N32_GTIMB_CCMOD2_OC4MD_SHIFT (13) /* OC4 mode (bits 0-2) */ +#define N32_GTIMB_CCMOD2_OC4MD_MASK (7 << N32_GTIMB_CCMOD2_OC4MD_SHIFT) +#define N32_GTIMB_CCMOD2_OC4MD3 (1 << 18) /* OC4 mode bit 3 */ + +/* CCMOD2 - Input capture (N32_GTIMB_CCMOD2) */ + +#define N32_GTIMB_CCMOD2_IC3PSC_SHIFT (2) /* IC3 prescaler */ +#define N32_GTIMB_CCMOD2_IC3PSC_MASK (3 << N32_GTIMB_CCMOD2_IC3PSC_SHIFT) +#define N32_GTIMB_CCMOD2_IC3F_SHIFT (4) /* IC3 filter */ +#define N32_GTIMB_CCMOD2_IC3F_MASK (15 << N32_GTIMB_CCMOD2_IC3F_SHIFT) +#define N32_GTIMB_CCMOD2_IC4PSC_SHIFT (10) /* IC4 prescaler */ +#define N32_GTIMB_CCMOD2_IC4PSC_MASK (3 << N32_GTIMB_CCMOD2_IC4PSC_SHIFT) +#define N32_GTIMB_CCMOD2_IC4F_SHIFT (12) /* IC4 filter */ +#define N32_GTIMB_CCMOD2_IC4F_MASK (15 << N32_GTIMB_CCMOD2_IC4F_SHIFT) + +/* CCMOD3 (N32_GTIMB_CCMOD3) - CC5 only */ + +#define N32_GTIMB_CCMOD3_OC5PEN (1 << 2) /* OC5 preload enable */ +#define N32_GTIMB_CCMOD3_OC5FEN (1 << 3) /* OC5 fast enable */ +#define N32_GTIMB_CCMOD3_OC5CEN (1 << 4) /* OC5 clear enable */ +#define N32_GTIMB_CCMOD3_OC5MD_SHIFT (5) /* OC5 mode */ +#define N32_GTIMB_CCMOD3_OC5MD_MASK (7 << N32_GTIMB_CCMOD3_OC5MD_SHIFT) + +/* CCEN (N32_GTIMB_CCEN) - With complementary outputs */ + +#define N32_GTIMB_CCEN_CC1NEN (1 << 0) /* CC1 complementary output enable */ +#define N32_GTIMB_CCEN_CC1NP (1 << 1) /* CC1 complementary output polarity */ +#define N32_GTIMB_CCEN_CC1EN (1 << 2) /* CC1 output enable */ +#define N32_GTIMB_CCEN_CC1P (1 << 3) /* CC1 output polarity */ +#define N32_GTIMB_CCEN_CC2EN (1 << 6) /* CC2 output enable */ +#define N32_GTIMB_CCEN_CC2P (1 << 7) /* CC2 output polarity */ +#define N32_GTIMB_CCEN_CC3EN (1 << 10) /* CC3 output enable */ +#define N32_GTIMB_CCEN_CC3P (1 << 11) /* CC3 output polarity */ +#define N32_GTIMB_CCEN_CC4EN (1 << 14) /* CC4 output enable */ +#define N32_GTIMB_CCEN_CC4P (1 << 15) /* CC4 output polarity */ +#define N32_GTIMB_CCEN_CC5EN (1 << 18) /* CC5 output enable */ +#define N32_GTIMB_CCEN_CC5P (1 << 19) /* CC5 output polarity */ + +/* CCDAT (with down-count value in high 16 bits) */ + +#define N32_GTIMB_CCDAT_MASK (0xffff) /* CCx value mask */ +#define N32_GTIMB_CCDAT_DOWN_SHIFT (16) /* Down-count value shift */ + +/* PSC, AR, CNT */ + +#define N32_GTIMB_PSC_MASK (0xffff) /* Prescaler value mask */ +#define N32_GTIMB_AR_MASK (0xffff) /* Auto-reload value mask */ +#define N32_GTIMB_CNT_MASK (0xffff) /* Counter value mask */ +#define N32_GTIMB_CNT_UDITFCPY (1 << 31) /* UDITF copy */ + +/* REPCNT */ + +#define N32_GTIMB_REPCNT_MASK (0xff) /* Repetition counter value mask */ + +/* BKDT (N32_GTIMB_BKDT) - Break1 only (no Break2) */ + +#define N32_GTIMB_BKDT_DTGN_SHIFT (0) /* Dead-time generator setup */ +#define N32_GTIMB_BKDT_DTGN_MASK (0xff << N32_GTIMB_BKDT_DTGN_SHIFT) +#define N32_GTIMB_BKDT_MOEN (1 << 8) /* Main output enable */ +#define N32_GTIMB_BKDT_AOEN (1 << 9) /* Automatic output enable */ +#define N32_GTIMB_BKDT_BKP (1 << 10) /* Break1 polarity */ +#define N32_GTIMB_BKDT_BKEN (1 << 11) /* Break1 enable */ +#define N32_GTIMB_BKDT_OSSI (1 << 12) /* Off-state selection for Idle mode */ +#define N32_GTIMB_BKDT_OSSR (1 << 13) /* Off-state selection for Run mode */ +#define N32_GTIMB_BKDT_LCKCFG_SHIFT (14) /* Lock configuration */ +#define N32_GTIMB_BKDT_LCKCFG_MASK (3 << N32_GTIMB_BKDT_LCKCFG_SHIFT) +# define N32_GTIMB_BKDT_LOCKOFF (0 << N32_GTIMB_BKDT_LCKCFG_SHIFT) +# define N32_GTIMB_BKDT_LOCK1 (1 << N32_GTIMB_BKDT_LCKCFG_SHIFT) +# define N32_GTIMB_BKDT_LOCK2 (2 << N32_GTIMB_BKDT_LCKCFG_SHIFT) +# define N32_GTIMB_BKDT_LOCK3 (3 << N32_GTIMB_BKDT_LCKCFG_SHIFT) +#define N32_GTIMB_BKDT_BRKDSRM (1 << 18) /* Break1 disarm */ +#define N32_GTIMB_BKDT_BRKBID (1 << 20) /* Break1 bidirectional enable */ + +/* BKFR (same as ATIM) */ + +#define N32_GTIMB_BKFR_SLIDFPSC_MASK (0xffff) /* Sampling clock prescaler */ +#define N32_GTIMB_BKFR_FILTEN (1 << 16) /* Filter enable */ +#define N32_GTIMB_BKFR_WSIZE_SHIFT (17) /* Window size */ +#define N32_GTIMB_BKFR_WSIZE_MASK (63 << N32_GTIMB_BKFR_WSIZE_SHIFT) +#define N32_GTIMB_BKFR_THRESH_SHIFT (24) /* Threshold */ +#define N32_GTIMB_BKFR_THRESH_MASK (63 << N32_GTIMB_BKFR_THRESH_SHIFT) + +/* Filter registers (C1FILT..C4FILT) */ + +#define N32_GTIMB_CXFILT_SLIDFPSC_MASK (0xffff) /* Sampling clock prescaler */ +#define N32_GTIMB_CXFILT_FILTEN (1 << 16) /* Filter enable */ +#define N32_GTIMB_CXFILT_WSIZE_SHIFT (17) /* Window size */ +#define N32_GTIMB_CXFILT_WSIZE_MASK (63 << N32_GTIMB_CXFILT_WSIZE_SHIFT) +#define N32_GTIMB_CXFILT_THRESH_SHIFT (24) /* Threshold */ +#define N32_GTIMB_CXFILT_THRESH_MASK (63 << N32_GTIMB_CXFILT_THRESH_SHIFT) + +/* FILTO */ + +#define N32_GTIMB_FILTO_C1FILTO (1 << 0) /* Channel 1 filter output */ +#define N32_GTIMB_FILTO_C2FILTO (1 << 1) /* Channel 2 filter output */ +#define N32_GTIMB_FILTO_C3FILTO (1 << 2) /* Channel 3 filter output */ +#define N32_GTIMB_FILTO_C4FILTO (1 << 3) /* Channel 4 filter output */ + +/* INSEL (same as ATIM/GTIMA) */ + +#define N32_GTIMB_INSEL_TI1S_SHIFT (0) /* TI1 input selection */ +#define N32_GTIMB_INSEL_TI1S_MASK (15 << N32_GTIMB_INSEL_TI1S_SHIFT) +#define N32_GTIMB_INSEL_TI2S_SHIFT (4) /* TI2 input selection */ +#define N32_GTIMB_INSEL_TI2S_MASK (15 << N32_GTIMB_INSEL_TI2S_SHIFT) +#define N32_GTIMB_INSEL_TI3S_SHIFT (8) /* TI3 input selection */ +#define N32_GTIMB_INSEL_TI3S_MASK (15 << N32_GTIMB_INSEL_TI3S_SHIFT) +#define N32_GTIMB_INSEL_TI4S_SHIFT (12) /* TI4 input selection */ +#define N32_GTIMB_INSEL_TI4S_MASK (15 << N32_GTIMB_INSEL_TI4S_SHIFT) +#define N32_GTIMB_INSEL_ETRS_SHIFT (16) /* ETR input selection */ +#define N32_GTIMB_INSEL_ETRS_MASK (15 << N32_GTIMB_INSEL_ETRS_SHIFT) +#define N32_GTIMB_INSEL_ITRS_SHIFT (20) /* ITR input selection */ +#define N32_GTIMB_INSEL_ITRS_MASK (15 << N32_GTIMB_INSEL_ITRS_SHIFT) +#define N32_GTIMB_INSEL_CLRS_SHIFT (24) /* OcxRef clear input selection */ +#define N32_GTIMB_INSEL_CLRS_MASK (15 << N32_GTIMB_INSEL_CLRS_SHIFT) + +/* AF1 (N32_GTIMB_AF1) - Break input sources */ + +#define N32_GTIMB_AF1_IOMBRKEN (1 << 0) /* TIMx_BKIN break input enable */ +#define N32_GTIMB_AF1_COMP1BRKEN (1 << 1) /* COMP1 break input enable */ +#define N32_GTIMB_AF1_COMP2BRKEN (1 << 2) /* COMP2 break input enable */ +#define N32_GTIMB_AF1_COMP3BRKEN (1 << 3) /* COMP3 break input enable */ +#define N32_GTIMB_AF1_COMP4BRKEN (1 << 4) /* COMP4 break input enable */ +#define N32_GTIMB_AF1_DSMU0BRKEN (1 << 24) /* DSMU0 break enable */ +#define N32_GTIMB_AF1_DSMU1BRKEN (1 << 25) /* DSMU1 break enable */ +#define N32_GTIMB_AF1_DSMU2BRKEN (1 << 26) /* DSMU2 break enable */ +#define N32_GTIMB_AF1_DSMU3BRKEN (1 << 27) /* DSMU3 break enable */ +#define N32_GTIMB_AF1_IOMBRKP (1 << 9) /* TIMx_BKIN polarity selection */ +#define N32_GTIMB_AF1_COMP1BRKP (1 << 10) /* COMP1 break polarity */ +#define N32_GTIMB_AF1_COMP2BRKP (1 << 11) /* COMP2 break polarity */ +#define N32_GTIMB_AF1_COMP3BRKP (1 << 12) /* COMP3 break polarity */ +#define N32_GTIMB_AF1_COMP4BRKP (1 << 13) /* COMP4 break polarity */ + +/* DCTRL/DADDR */ + +#define N32_GTIMB_DCTRL_DBLEN_SHIFT (0) /* DMA burst length */ +#define N32_GTIMB_DCTRL_DBLEN_MASK (63 << N32_GTIMB_DCTRL_DBLEN_SHIFT) +# define N32_GTIMB_DCTRL_DBLEN(n) (((n)-1) << N32_GTIMB_DCTRL_DBLEN_SHIFT) +#define N32_GTIMB_DCTRL_DBADDR_SHIFT (8) /* DMA base address */ +#define N32_GTIMB_DCTRL_DBADDR_MASK (63 << N32_GTIMB_DCTRL_DBADDR_SHIFT) +#define N32_GTIMB_DADDR_BURST_MASK (0xffffffff) + +/* ========================================================================== + * BASIC TIMERS (BTIM1-4) + * ========================================================================== + */ + +/* Register Offsets - BTIM (common for all BTIM1-4) *************************/ + +#define N32_BTIM_CTRL1_OFFSET 0x0000 /* Control register 1 */ +#define N32_BTIM_CTRL2_OFFSET 0x0004 /* Control register 2 */ +#define N32_BTIM_STS_OFFSET 0x0008 /* Status register */ +#define N32_BTIM_ETGEN_OFFSET 0x000c /* Event generation register */ +#define N32_BTIM_DINTEN_OFFSET 0x0014 /* DMA/Interrupt enable register */ +#define N32_BTIM_PSC_OFFSET 0x0040 /* Prescaler */ +#define N32_BTIM_AR_OFFSET 0x0044 /* Auto-reload register (32-bit) */ +#define N32_BTIM_CNT_OFFSET 0x0048 /* Counter (32-bit) */ + +/* Register Addresses - BTIM1 ***********************************************/ + +#define N32_BTIM1_CTRL1 (N32_BTIMER1_BASE + N32_BTIM_CTRL1_OFFSET) +#define N32_BTIM1_CTRL2 (N32_BTIMER1_BASE + N32_BTIM_CTRL2_OFFSET) +#define N32_BTIM1_STS (N32_BTIMER1_BASE + N32_BTIM_STS_OFFSET) +#define N32_BTIM1_ETGEN (N32_BTIMER1_BASE + N32_BTIM_ETGEN_OFFSET) +#define N32_BTIM1_DINTEN (N32_BTIMER1_BASE + N32_BTIM_DINTEN_OFFSET) +#define N32_BTIM1_PSC (N32_BTIMER1_BASE + N32_BTIM_PSC_OFFSET) +#define N32_BTIM1_AR (N32_BTIMER1_BASE + N32_BTIM_AR_OFFSET) +#define N32_BTIM1_CNT (N32_BTIMER1_BASE + N32_BTIM_CNT_OFFSET) + +/* Register Addresses - BTIM2 ***********************************************/ + +#define N32_BTIM2_CTRL1 (N32_BTIMER2_BASE + N32_BTIM_CTRL1_OFFSET) +#define N32_BTIM2_CTRL2 (N32_BTIMER2_BASE + N32_BTIM_CTRL2_OFFSET) +#define N32_BTIM2_STS (N32_BTIMER2_BASE + N32_BTIM_STS_OFFSET) +#define N32_BTIM2_ETGEN (N32_BTIMER2_BASE + N32_BTIM_ETGEN_OFFSET) +#define N32_BTIM2_DINTEN (N32_BTIMER2_BASE + N32_BTIM_DINTEN_OFFSET) +#define N32_BTIM2_PSC (N32_BTIMER2_BASE + N32_BTIM_PSC_OFFSET) +#define N32_BTIM2_AR (N32_BTIMER2_BASE + N32_BTIM_AR_OFFSET) +#define N32_BTIM2_CNT (N32_BTIMER2_BASE + N32_BTIM_CNT_OFFSET) + +/* Register Addresses - BTIM3 ***********************************************/ + +#define N32_BTIM3_CTRL1 (N32_BTIMER3_BASE + N32_BTIM_CTRL1_OFFSET) +#define N32_BTIM3_CTRL2 (N32_BTIMER3_BASE + N32_BTIM_CTRL2_OFFSET) +#define N32_BTIM3_STS (N32_BTIMER3_BASE + N32_BTIM_STS_OFFSET) +#define N32_BTIM3_ETGEN (N32_BTIMER3_BASE + N32_BTIM_ETGEN_OFFSET) +#define N32_BTIM3_DINTEN (N32_BTIMER3_BASE + N32_BTIM_DINTEN_OFFSET) +#define N32_BTIM3_PSC (N32_BTIMER3_BASE + N32_BTIM_PSC_OFFSET) +#define N32_BTIM3_AR (N32_BTIMER3_BASE + N32_BTIM_AR_OFFSET) +#define N32_BTIM3_CNT (N32_BTIMER3_BASE + N32_BTIM_CNT_OFFSET) + +/* Register Addresses - BTIM4 ***********************************************/ + +#define N32_BTIM4_CTRL1 (N32_BTIMER4_BASE + N32_BTIM_CTRL1_OFFSET) +#define N32_BTIM4_CTRL2 (N32_BTIMER4_BASE + N32_BTIM_CTRL2_OFFSET) +#define N32_BTIM4_STS (N32_BTIMER4_BASE + N32_BTIM_STS_OFFSET) +#define N32_BTIM4_ETGEN (N32_BTIMER4_BASE + N32_BTIM_ETGEN_OFFSET) +#define N32_BTIM4_DINTEN (N32_BTIMER4_BASE + N32_BTIM_DINTEN_OFFSET) +#define N32_BTIM4_PSC (N32_BTIMER4_BASE + N32_BTIM_PSC_OFFSET) +#define N32_BTIM4_AR (N32_BTIMER4_BASE + N32_BTIM_AR_OFFSET) +#define N32_BTIM4_CNT (N32_BTIMER4_BASE + N32_BTIM_CNT_OFFSET) + +/* Bitfield Definitions - BTIM **********************************************/ + +/* Control register 1 (N32_BTIM_CTRL1) */ + +#define N32_BTIM_CTRL1_CNTEN (1 << 0) /* Counter enable */ +#define N32_BTIM_CTRL1_UPRS (1 << 4) /* Update request source */ +#define N32_BTIM_CTRL1_UPDIS (1 << 5) /* Update disable */ +#define N32_BTIM_CTRL1_ONEPM (1 << 8) /* One pulse mode */ +#define N32_BTIM_CTRL1_ARPEN (1 << 9) /* Auto-reload preload enable */ + +/* Control register 2 (N32_BTIM_CTRL2) */ + +#define N32_BTIM_CTRL2_MMSEL_SHIFT (12) /* Master mode selection (TRGO) */ +#define N32_BTIM_CTRL2_MMSEL_MASK (15 << N32_BTIM_CTRL2_MMSEL_SHIFT) +# define N32_BTIM_CTRL2_MMSEL_RESET (0 << N32_BTIM_CTRL2_MMSEL_SHIFT) /* Reset */ +# define N32_BTIM_CTRL2_MMSEL_ENABLE (1 << N32_BTIM_CTRL2_MMSEL_SHIFT) /* Enable */ +# define N32_BTIM_CTRL2_MMSEL_UPDATE (2 << N32_BTIM_CTRL2_MMSEL_SHIFT) /* Update */ + +/* Status register (N32_BTIM_STS) */ + +#define N32_BTIM_STS_UDITF (1 << 16) /* Update interrupt flag */ + +/* Event generation register (N32_BTIM_ETGEN) */ + +#define N32_BTIM_ETGEN_UDGN (1 << 8) /* Update generation */ + +/* DMA/Interrupt enable register (N32_BTIM_DINTEN) */ + +#define N32_BTIM_DINTEN_UIEN (1 << 16) /* Update interrupt enable */ +#define N32_BTIM_DINTEN_UDEN (1 << 19) /* Update DMA request enable */ + +/* Prescaler (N32_BTIM_PSC) */ + +#define N32_BTIM_PSC_MASK (0xffff) /* Prescaler value mask */ + +/* Auto-reload register (N32_BTIM_AR) - 32-bit */ + +#define N32_BTIM_AR_MASK (0xffffffff) /* Auto-reload value mask */ + +/* Counter (N32_BTIM_CNT) - 32-bit */ + +#define N32_BTIM_CNT_MASK (0xffffffff) /* Counter value mask */ + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32_TIM_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_uart.h b/arch/arm/src/n32h7/hardware/n32h7_uart.h new file mode 100644 index 0000000000000..d07933e75d05f --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_uart.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_uart.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_UART_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_N32H7_N32H76X) +# include "hardware/n32h76x_uart.h" +#else +# error "Unsupported N32H7 memory map" +#endif + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_UART_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7_usbhs.h b/arch/arm/src/n32h7/hardware/n32h7_usbhs.h new file mode 100644 index 0000000000000..9c9eb71d04aa6 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7_usbhs.h @@ -0,0 +1,946 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7_usbhs.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_USBHS_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_USBHS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" +#include "hardware/n32h7_memorymap.h" + +/* ========================================================================== + * Register Offsets + * ========================================================================== + */ + +/* Core global registers */ +#define N32_USBHS_GCTRLSTS_OFF 0x0000UL +#define N32_USBHS_GAHBCFG_OFF 0x0008UL +#define N32_USBHS_GCFG_OFF 0x000CUL +#define N32_USBHS_GRSTCTRL_OFF 0x0010UL +#define N32_USBHS_GINTSTS_OFF 0x0014UL +#define N32_USBHS_GINTEN_OFF 0x0018UL +#define N32_USBHS_GRXSTS_OFF 0x001CUL +#define N32_USBHS_GRXSTSP_OFF 0x0020UL +#define N32_USBHS_GRXFSIZ_OFF 0x0024UL +#define N32_USBHS_GNPTXFSIZ_OFF 0x0028UL +#define N32_USBHS_GNPTXFSTS_OFF 0x002CUL +#define N32_USBHS_CID_OFF 0x003CUL +#define N32_USBHS_GPD_OFF 0x0058UL +#define N32_USBHS_HPTXFSIZ_OFF 0x0100UL +#define N32_USBHS_DINEPPTXFSIZ_OFF 0x0104UL /* x = 1..8, offset = 0x0104 + (x1)4 */ + +/* Host mode registers */ +#define N32_USBHS_HCFG_OFF 0x0400UL +#define N32_USBHS_HFRI_OFF 0x0404UL +#define N32_USBHS_HFNUM_OFF 0x0408UL +#define N32_USBHS_HPTXFQSTS_OFF 0x0410UL +#define N32_USBHS_HACHINT_OFF 0x0414UL +#define N32_USBHS_HACHINTEN_OFF 0x0418UL +#define N32_USBHS_HPCS_OFF 0x0440UL + +/* Host channel registers (each 0x20) */ +#define N32_USBHS_HCH_OFF(n) (0x0500UL + ((n) << 5)) +#define N32_USBHS_HCHCTRL_OFF(n) (N32_USBHS_HCH_OFF(n) + 0x0000UL) +#define N32_USBHS_HCSCTRL_OFF(n) (N32_USBHS_HCH_OFF(n) + 0x0004UL) +#define N32_USBHS_HCHINTSTS_OFF(n) (N32_USBHS_HCH_OFF(n) + 0x0008UL) +#define N32_USBHS_HCHINTEN_OFF(n) (N32_USBHS_HCH_OFF(n) + 0x000CUL) +#define N32_USBHS_HCHTXSIZ_OFF(n) (N32_USBHS_HCH_OFF(n) + 0x0010UL) +#define N32_USBHS_HCHDMADD_OFF(n) (N32_USBHS_HCH_OFF(n) + 0x0014UL) + +/* Device mode registers */ +#define N32_USBHS_DCFG_OFF 0x0800UL +#define N32_USBHS_DCTRL_OFF 0x0804UL +#define N32_USBHS_DSTS_OFF 0x0808UL +#define N32_USBHS_DINEPINTEN_OFF 0x0810UL +#define N32_USBHS_DOUTEPINTEN_OFF 0x0814UL +#define N32_USBHS_DAEPINTSTS_OFF 0x0818UL +#define N32_USBHS_DAEPINTEN_OFF 0x081CUL +#define N32_USBHS_DTHRCTRL_OFF 0x0830UL +#define N32_USBHS_DINEPFEINTEN_OFF 0x0834UL +#define N32_USBHS_DEEPINTSTS_OFF 0x0838UL +#define N32_USBHS_DEEPINTEN_OFF 0x083CUL +#define N32_USBHS_DINEPXINTEN_OFF 0x0840UL /* x = 0..8, offset = 0x0840 + x4 */ +#define N32_USBHS_DOUTEPXINTEN_OFF 0x0880UL /* x = 0..8, offset = 0x0880 + x4 */ + +/* Device IN endpoint registers (each 0x20) */ +#define N32_USBHS_DINEP_OFF(n) (0x0900UL + ((n) << 5)) +#define N32_USBHS_DINEPCTRL_OFF(n) (N32_USBHS_DINEP_OFF(n) + 0x0000UL) +#define N32_USBHS_DINEPINTSTS_OFF(n) (N32_USBHS_DINEP_OFF(n) + 0x0008UL) +#define N32_USBHS_DINEPTXSIZ_OFF(n) (N32_USBHS_DINEP_OFF(n) + 0x0010UL) +#define N32_USBHS_DINEPDMADD_OFF(n) (N32_USBHS_DINEP_OFF(n) + 0x0014UL) +#define N32_USBHS_DINEPTXFSTS_OFF(n) (N32_USBHS_DINEP_OFF(n) + 0x0018UL) + +/* Device OUT endpoint registers (each 0x20) */ +#define N32_USBHS_DOUTEP_OFF(n) (0x0B00UL + ((n) << 5)) +#define N32_USBHS_DOUTEPCTRL_OFF(n) (N32_USBHS_DOUTEP_OFF(n) + 0x0000UL) +#define N32_USBHS_DOUTEPINTSTS_OFF(n) (N32_USBHS_DOUTEP_OFF(n) + 0x0008UL) +#define N32_USBHS_DOUTEPTXSIZ_OFF(n) (N32_USBHS_DOUTEP_OFF(n) + 0x0010UL) +#define N32_USBHS_DOUTEPDMADD_OFF(n) (N32_USBHS_DOUTEP_OFF(n) + 0x0014UL) + +/* Power control registers */ +#define N32_USBHS_PWRCTRL_OFF 0x0E00UL +#define N32_USBHS_PWRCTRL1_OFF 0x0E04UL + +/* Wrapper registers (separate base) */ +#define N32_USBHS_WRPCTRL_OFF 0x0000UL +#define N32_USBHS_WRPCFG_OFF 0x0004UL + +/* ========================================================================== + * Register Addresses + * ========================================================================== + */ +#define N32_USBHS1_GCTRLSTS (N32_USBCTRL1_BASE + N32_USBHS_GCTRLSTS_OFF) +#define N32_USBHS1_GAHBCFG (N32_USBCTRL1_BASE + N32_USBHS_GAHBCFG_OFF) +#define N32_USBHS1_GCFG (N32_USBCTRL1_BASE + N32_USBHS_GCFG_OFF) +#define N32_USBHS1_GRSTCTRL (N32_USBCTRL1_BASE + N32_USBHS_GRSTCTRL_OFF) +#define N32_USBHS1_GINTSTS (N32_USBCTRL1_BASE + N32_USBHS_GINTSTS_OFF) +#define N32_USBHS1_GINTEN (N32_USBCTRL1_BASE + N32_USBHS_GINTEN_OFF) +#define N32_USBHS1_GRXSTS (N32_USBCTRL1_BASE + N32_USBHS_GRXSTS_OFF) +#define N32_USBHS1_GRXSTSP (N32_USBCTRL1_BASE + N32_USBHS_GRXSTSP_OFF) +#define N32_USBHS1_GRXFSIZ (N32_USBCTRL1_BASE + N32_USBHS_GRXFSIZ_OFF) +#define N32_USBHS1_GNPTXFSIZ (N32_USBCTRL1_BASE + N32_USBHS_GNPTXFSIZ_OFF) +#define N32_USBHS1_GNPTXFSTS (N32_USBCTRL1_BASE + N32_USBHS_GNPTXFSTS_OFF) +#define N32_USBHS1_CID (N32_USBCTRL1_BASE + N32_USBHS_CID_OFF) +#define N32_USBHS1_GPD (N32_USBCTRL1_BASE + N32_USBHS_GPD_OFF) +#define N32_USBHS1_HPTXFSIZ (N32_USBCTRL1_BASE + N32_USBHS_HPTXFSIZ_OFF) + +#define N32_USBHS1_DINEPPTXFSIZ(n) (N32_USBCTRL1_BASE + N32_USBHS_DINEPPTXFSIZ_OFF + (((n)-1) << 2)) + +#define N32_USBHS2_GCTRLSTS (N32_USBCTRL2_BASE + N32_USBHS_GCTRLSTS_OFF) +#define N32_USBHS2_GAHBCFG (N32_USBCTRL2_BASE + N32_USBHS_GAHBCFG_OFF) +#define N32_USBHS2_GCFG (N32_USBCTRL2_BASE + N32_USBHS_GCFG_OFF) +#define N32_USBHS2_GRSTCTRL (N32_USBCTRL2_BASE + N32_USBHS_GRSTCTRL_OFF) +#define N32_USBHS2_GINTSTS (N32_USBCTRL2_BASE + N32_USBHS_GINTSTS_OFF) +#define N32_USBHS2_GINTEN (N32_USBCTRL2_BASE + N32_USBHS_GINTEN_OFF) +#define N32_USBHS2_GRXSTS (N32_USBCTRL2_BASE + N32_USBHS_GRXSTS_OFF) +#define N32_USBHS2_GRXSTSP (N32_USBCTRL2_BASE + N32_USBHS_GRXSTSP_OFF) +#define N32_USBHS2_GRXFSIZ (N32_USBCTRL2_BASE + N32_USBHS_GRXFSIZ_OFF) +#define N32_USBHS2_GNPTXFSIZ (N32_USBCTRL2_BASE + N32_USBHS_GNPTXFSIZ_OFF) +#define N32_USBHS2_GNPTXFSTS (N32_USBCTRL2_BASE + N32_USBHS_GNPTXFSTS_OFF) +#define N32_USBHS2_CID (N32_USBCTRL2_BASE + N32_USBHS_CID_OFF) +#define N32_USBHS2_GPD (N32_USBCTRL2_BASE + N32_USBHS_GPD_OFF) +#define N32_USBHS2_HPTXFSIZ (N32_USBCTRL2_BASE + N32_USBHS_HPTXFSIZ_OFF) + +#define N32_USBHS2_DINEPPTXFSIZ(n) (N32_USBCTRL2_BASE + N32_USBHS_DINEPPTXFSIZ_OFF + (((n)-1) << 2)) + +/* Host mode */ +#define N32_USBHS1_HCFG (N32_USBCTRL1_BASE + N32_USBHS_HCFG_OFF) +#define N32_USBHS1_HFRI (N32_USBCTRL1_BASE + N32_USBHS_HFRI_OFF) +#define N32_USBHS1_HFNUM (N32_USBCTRL1_BASE + N32_USBHS_HFNUM_OFF) +#define N32_USBHS1_HPTXFQSTS (N32_USBCTRL1_BASE + N32_USBHS_HPTXFQSTS_OFF) +#define N32_USBHS1_HACHINT (N32_USBCTRL1_BASE + N32_USBHS_HACHINT_OFF) +#define N32_USBHS1_HACHINTEN (N32_USBCTRL1_BASE + N32_USBHS_HACHINTEN_OFF) +#define N32_USBHS1_HPCS (N32_USBCTRL1_BASE + N32_USBHS_HPCS_OFF) + +#define N32_USBHS1_HCHCTRL(n) (N32_USBCTRL1_BASE + N32_USBHS_HCHCTRL_OFF(n)) +#define N32_USBHS1_HCSCTRL(n) (N32_USBCTRL1_BASE + N32_USBHS_HCSCTRL_OFF(n)) +#define N32_USBHS1_HCHINTSTS(n) (N32_USBCTRL1_BASE + N32_USBHS_HCHINTSTS_OFF(n)) +#define N32_USBHS1_HCHINTEN(n) (N32_USBCTRL1_BASE + N32_USBHS_HCHINTEN_OFF(n)) +#define N32_USBHS1_HCHTXSIZ(n) (N32_USBCTRL1_BASE + N32_USBHS_HCHTXSIZ_OFF(n)) +#define N32_USBHS1_HCHDMADD(n) (N32_USBCTRL1_BASE + N32_USBHS_HCHDMADD_OFF(n)) + +#define N32_USBHS2_HCFG (N32_USBCTRL2_BASE + N32_USBHS_HCFG_OFF) +#define N32_USBHS2_HFRI (N32_USBCTRL2_BASE + N32_USBHS_HFRI_OFF) +#define N32_USBHS2_HFNUM (N32_USBCTRL2_BASE + N32_USBHS_HFNUM_OFF) +#define N32_USBHS2_HPTXFQSTS (N32_USBCTRL2_BASE + N32_USBHS_HPTXFQSTS_OFF) +#define N32_USBHS2_HACHINT (N32_USBCTRL2_BASE + N32_USBHS_HACHINT_OFF) +#define N32_USBHS2_HACHINTEN (N32_USBCTRL2_BASE + N32_USBHS_HACHINTEN_OFF) +#define N32_USBHS2_HPCS (N32_USBCTRL2_BASE + N32_USBHS_HPCS_OFF) + +#define N32_USBHS2_HCHCTRL(n) (N32_USBCTRL2_BASE + N32_USBHS_HCHCTRL_OFF(n)) +#define N32_USBHS2_HCSCTRL(n) (N32_USBCTRL2_BASE + N32_USBHS_HCSCTRL_OFF(n)) +#define N32_USBHS2_HCHINTSTS(n) (N32_USBCTRL2_BASE + N32_USBHS_HCHINTSTS_OFF(n)) +#define N32_USBHS2_HCHINTEN(n) (N32_USBCTRL2_BASE + N32_USBHS_HCHINTEN_OFF(n)) +#define N32_USBHS2_HCHTXSIZ(n) (N32_USBCTRL2_BASE + N32_USBHS_HCHTXSIZ_OFF(n)) +#define N32_USBHS2_HCHDMADD(n) (N32_USBCTRL2_BASE + N32_USBHS_HCHDMADD_OFF(n)) + +/* Device mode */ +#define N32_USBHS1_DCFG (N32_USBCTRL1_BASE + N32_USBHS_DCFG_OFF) +#define N32_USBHS1_DCTRL (N32_USBCTRL1_BASE + N32_USBHS_DCTRL_OFF) +#define N32_USBHS1_DSTS (N32_USBCTRL1_BASE + N32_USBHS_DSTS_OFF) +#define N32_USBHS1_DINEPINTEN (N32_USBCTRL1_BASE + N32_USBHS_DINEPINTEN_OFF) +#define N32_USBHS1_DOUTEPINTEN (N32_USBCTRL1_BASE + N32_USBHS_DOUTEPINTEN_OFF) +#define N32_USBHS1_DAEPINTSTS (N32_USBCTRL1_BASE + N32_USBHS_DAEPINTSTS_OFF) +#define N32_USBHS1_DAEPINTEN (N32_USBCTRL1_BASE + N32_USBHS_DAEPINTEN_OFF) +#define N32_USBHS1_DTHRCTRL (N32_USBCTRL1_BASE + N32_USBHS_DTHRCTRL_OFF) +#define N32_USBHS1_DINEPFEINTEN (0x40040000N32_USBCTRL1_BASE + N32_USBHS_DINEPFEINTEN_OFF) +#define N32_USBHS1_DEEPINTSTS (N32_USBCTRL1_BASE + N32_USBHS_DEEPINTSTS_OFF) +#define N32_USBHS1_DEEPINTEN (N32_USBCTRL1_BASE + N32_USBHS_DEEPINTEN_OFF) + +#define N32_USBHS1_DINEPXINTEN(n) (N32_USBCTRL1_BASE + N32_USBHS_DINEPXINTEN_OFF + ((n) << 2)) +#define N32_USBHS1_DOUTEPXINTEN(n) (N32_USBCTRL1_BASE + N32_USBHS_DOUTEPXINTEN_OFF + ((n) << 2)) + +#define N32_USBHS1_DINEPCTRL(n) (N32_USBCTRL1_BASE + N32_USBHS_DINEPCTRL_OFF(n)) +#define N32_USBHS1_DINEPINTSTS(n) (N32_USBCTRL1_BASE + N32_USBHS_DINEPINTSTS_OFF(n)) +#define N32_USBHS1_DINEPTXSIZ(n) (N32_USBCTRL1_BASE + N32_USBHS_DINEPTXSIZ_OFF(n)) +#define N32_USBHS1_DINEPDMADD(n) (N32_USBCTRL1_BASE + N32_USBHS_DINEPDMADD_OFF(n)) +#define N32_USBHS1_DINEPTXFSTS(n) (N32_USBCTRL1_BASE + N32_USBHS_DINEPTXFSTS_OFF(n)) + +#define N32_USBHS1_DOUTEPCTRL(n) (N32_USBCTRL1_BASE + N32_USBHS_DOUTEPCTRL_OFF(n)) +#define N32_USBHS1_DOUTEPINTSTS(n) (N32_USBCTRL1_BASE + N32_USBHS_DOUTEPINTSTS_OFF(n)) +#define N32_USBHS1_DOUTEPTXSIZ(n) (N32_USBCTRL1_BASE + N32_USBHS_DOUTEPTXSIZ_OFF(n)) +#define N32_USBHS1_DOUTEPDMADD(n) (N32_USBCTRL1_BASE + N32_USBHS_DOUTEPDMADD_OFF(n)) + +#define N32_USBHS2_DCFG (N32_USBCTRL2_BASE + N32_USBHS_DCFG_OFF) +#define N32_USBHS2_DCTRL (N32_USBCTRL2_BASE + N32_USBHS_DCTRL_OFF) +#define N32_USBHS2_DSTS (N32_USBCTRL2_BASE + N32_USBHS_DSTS_OFF) +#define N32_USBHS2_DINEPINTEN (N32_USBCTRL2_BASE + N32_USBHS_DINEPINTEN_OFF) +#define N32_USBHS2_DOUTEPINTEN (N32_USBCTRL2_BASE + N32_USBHS_DOUTEPINTEN_OFF) +#define N32_USBHS2_DAEPINTSTS (N32_USBCTRL2_BASE + N32_USBHS_DAEPINTSTS_OFF) +#define N32_USBHS2_DAEPINTEN (N32_USBCTRL2_BASE + N32_USBHS_DAEPINTEN_OFF) +#define N32_USBHS2_DTHRCTRL (N32_USBCTRL2_BASE + N32_USBHS_DTHRCTRL_OFF) +#define N32_USBHS2_DINEPFEINTEN (N32_USBCTRL2_BASE + N32_USBHS_DINEPFEINTEN_OFF) +#define N32_USBHS2_DEEPINTSTS (N32_USBCTRL2_BASE + N32_USBHS_DEEPINTSTS_OFF) +#define N32_USBHS2_DEEPINTEN (N32_USBCTRL2_BASE + N32_USBHS_DEEPINTEN_OFF) + +#define N32_USBHS2_DINEPXINTEN(n) (N32_USBCTRL2_BASE + N32_USBHS_DINEPXINTEN_OFF + ((n) << 2)) +#define N32_USBHS2_DOUTEPXINTEN(n) (N32_USBCTRL2_BASE + N32_USBHS_DOUTEPXINTEN_OFF + ((n) << 2)) + +#define N32_USBHS2_DINEPCTRL(n) (N32_USBCTRL2_BASE + N32_USBHS_DINEPCTRL_OFF(n)) +#define N32_USBHS2_DINEPINTSTS(n) (N32_USBCTRL2_BASE + N32_USBHS_DINEPINTSTS_OFF(n)) +#define N32_USBHS2_DINEPTXSIZ(n) (N32_USBCTRL2_BASE + N32_USBHS_DINEPTXSIZ_OFF(n)) +#define N32_USBHS2_DINEPDMADD(n) (N32_USBCTRL2_BASE + N32_USBHS_DINEPDMADD_OFF(n)) +#define N32_USBHS2_DINEPTXFSTS(n) (N32_USBCTRL2_BASE + N32_USBHS_DINEPTXFSTS_OFF(n)) + +#define N32_USBHS2_DOUTEPCTRL(n) (N32_USBCTRL2_BASE + N32_USBHS_DOUTEPCTRL_OFF(n)) +#define N32_USBHS2_DOUTEPINTSTS(n) (N32_USBCTRL2_BASE + N32_USBHS_DOUTEPINTSTS_OFF(n)) +#define N32_USBHS2_DOUTEPTXSIZ(n) (N32_USBCTRL2_BASE + N32_USBHS_DOUTEPTXSIZ_OFF(n)) +#define N32_USBHS2_DOUTEPDMADD(n) (N32_USBCTRL2_BASE + N32_USBHS_DOUTEPDMADD_OFF(n)) + +/* Power control */ +#define N32_USBHS1_PWRCTRL (N32_USBCTRL1_BASE + N32_USBHS_PWRCTRL_OFF) +#define N32_USBHS1_PWRCTRL1 (N32_USBCTRL1_BASE + N32_USBHS_PWRCTRL1_OFF) + +#define N32_USBHS2_PWRCTRL (N32_USBCTRL2_BASE + N32_USBHS_PWRCTRL_OFF) +#define N32_USBHS2_PWRCTRL1 (N32_USBCTRL2_BASE + N32_USBHS_PWRCTRL1_OFF) + +/* Wrapper (separate base) */ +#define N32_USBHS1_WRPCTRL (N32_USBCTRL1_WRAPPER_BASE + N32_USBHS_WRPCTRL_OFF) +#define N32_USBHS1_WRPCFG (N32_USBCTRL1_WRAPPER_BASE + N32_USBHS_WRPCFG_OFF) + +#define N32_USBHS2_WRPCTRL (N32_USBCTRL2_WRAPPER_BASE + N32_USBHS_WRPCTRL_OFF) +#define N32_USBHS2_WRPCFG (N32_USBCTRL2_WRAPPER_BASE + N32_USBHS_WRPCFG_OFF) + +/* ========================================================================== + * Bitfield Definitions (no _POS macros, only _SHIFT and _MASK where needed) + * ========================================================================== + */ + +/* GCTRLSTS (0x000) *********************************************************/ +#define N32_USBHS_GCTRLSTS_VBVALOVEN (1UL << 2) /* VBUS valid override enable */ +#define N32_USBHS_GCTRLSTS_VBVALOVAL (1UL << 3) /* VBUS valid override value */ +#define N32_USBHS_GCTRLSTS_IDSTS (1UL << 16) /* Connector ID status */ +#define N32_USBHS_GCTRLSTS_DETIM (1UL << 17) /* Long/short debounce time */ +#define N32_USBHS_GCTRLSTS_CMODE (1UL << 21) /* Current mode (0:Device, 1:Host) */ + +/* GAHBCFG (0x008) **********************************************************/ +#define N32_USBHS_GAHBCFG_GINTEN (1UL << 0) /* Global interrupt mask */ +#define N32_USBHS_GAHBCFG_BURSTTYP_SHIFT 1 +#define N32_USBHS_GAHBCFG_BURSTTYP_MASK (0xFUL << N32_USBHS_GAHBCFG_BURSTTYP_SHIFT) +# define N32_USBHS_GAHBCFG_BURSTTYP_SINGLE (0UL << N32_USBHS_GAHBCFG_BURSTTYP_SHIFT) +# define N32_USBHS_GAHBCFG_BURSTTYP_INCR (1UL << N32_USBHS_GAHBCFG_BURSTTYP_SHIFT) +# define N32_USBHS_GAHBCFG_BURSTTYP_INCR4 (3UL << N32_USBHS_GAHBCFG_BURSTTYP_SHIFT) +# define N32_USBHS_GAHBCFG_BURSTTYP_INCR8 (5UL << N32_USBHS_GAHBCFG_BURSTTYP_SHIFT) +# define N32_USBHS_GAHBCFG_BURSTTYP_INCR16 (7UL << N32_USBHS_GAHBCFG_BURSTTYP_SHIFT) +#define N32_USBHS_GAHBCFG_DMAEN (1UL << 5) /* DMA enable */ +#define N32_USBHS_GAHBCFG_NPTXFETH (1UL << 7) /* Non-periodic TxFIFO empty level */ +#define N32_USBHS_GAHBCFG_PTXFETH (1UL << 8) /* Periodic TxFIFO empty level */ + +/* GCFG (0x00C) *************************************************************/ +#define N32_USBHS_GCFG_TOCAL_SHIFT 0 +#define N32_USBHS_GCFG_TOCAL_MASK (7UL << N32_USBHS_GCFG_TOCAL_SHIFT) /* FS timeout calibration */ +#define N32_USBHS_GCFG_PHYIF (1UL << 3) /* PHY interface (0:8bit, 1:16bit) */ +#define N32_USBHS_GCFG_PHYSEL (1UL << 6) /* PHY select (0:USB2.0 HS, 1:USB1.1 FS) */ +#define N32_USBHS_GCFG_TRDTIM_SHIFT 10 +#define N32_USBHS_GCFG_TRDTIM_MASK (0xFUL << N32_USBHS_GCFG_TRDTIM_SHIFT) /* USB turnaround time */ +#define N32_USBHS_GCFG_FHMODE (1UL << 29) /* Force host mode */ +#define N32_USBHS_GCFG_FDMODE (1UL << 30) /* Force device mode */ + +/* GRSTCTRL (0x010) *********************************************************/ +#define N32_USBHS_GRSTCTRL_CSRST (1UL << 0) /* Core soft reset */ +#define N32_USBHS_GRSTCTRL_PFSSRST (1UL << 1) /* PIU FS-specific controller reset */ +#define N32_USBHS_GRSTCTRL_HFCRST (1UL << 2) /* Host frame counter reset */ +#define N32_USBHS_GRSTCTRL_RXFFLSH (1UL << 4) /* RxFIFO flush */ +#define N32_USBHS_GRSTCTRL_TXFFLSH (1UL << 5) /* TxFIFO flush */ +#define N32_USBHS_GRSTCTRL_TXFNUM_SHIFT 6 +#define N32_USBHS_GRSTCTRL_TXFNUM_MASK (0x1FUL << N32_USBHS_GRSTCTRL_TXFNUM_SHIFT) /* TxFIFO number */ +#define N32_USBHS_GRSTCTRL_SRSTDNE (1UL << 29) /* Software reset done */ +#define N32_USBHS_GRSTCTRL_DMAREQ (1UL << 30) /* DMA request signal */ +#define N32_USBHS_GRSTCTRL_AHBIDLE (1UL << 31) /* AHB master idle */ + +/* GINTSTS (0x014) **********************************************************/ +#define N32_USBHS_GINTSTS_CMODE (1UL << 0) /* Current mode (0:Device, 1:Host) */ +#define N32_USBHS_GINTSTS_MODMISIF (1UL << 1) /* Mode mismatch interrupt */ +#define N32_USBHS_GINTSTS_SOFIF (1UL << 3) /* Start of frame */ +#define N32_USBHS_GINTSTS_RXFNEIF (1UL << 4) /* RxFIFO non-empty */ +#define N32_USBHS_GINTSTS_NPTXFEIF (1UL << 5) /* Non-periodic TxFIFO empty */ +#define N32_USBHS_GINTSTS_GINNPNAKEIF (1UL << 6) /* Global IN non-periodic NAK effective */ +#define N32_USBHS_GINTSTS_GOUTNAKEIF (1UL << 7) /* Global OUT NAK effective */ +#define N32_USBHS_GINTSTS_ESUSPIF (1UL << 10) /* Early suspend */ +#define N32_USBHS_GINTSTS_USBSUSPIF (1UL << 11) /* USB suspend */ +#define N32_USBHS_GINTSTS_USBRSTIF (1UL << 12) /* USB reset */ +#define N32_USBHS_GINTSTS_ENUMDIF (1UL << 13) /* Enumeration done */ +#define N32_USBHS_GINTSTS_ISOUTPDIF (1UL << 14) /* Isochronous OUT packet dropped */ +#define N32_USBHS_GINTSTS_EOPFIF (1UL << 15) /* End of periodic frame */ +#define N32_USBHS_GINTSTS_INEPIF (1UL << 18) /* IN endpoint interrupt */ +#define N32_USBHS_GINTSTS_OUTEPIF (1UL << 19) /* OUT endpoint interrupt */ +#define N32_USBHS_GINTSTS_ISOINCIF (1UL << 20) /* Incomplete isochronous IN transfer */ +#define N32_USBHS_GINTSTS_PTNCIF_ISOUTNCIF (1UL << 21) /* Incomplete periodic / isochronous OUT */ +#define N32_USBHS_GINTSTS_FETSUSPIF (1UL << 22) /* Data fetch suspended */ +#define N32_USBHS_GINTSTS_RSTDIF (1UL << 23) /* Reset detected */ +#define N32_USBHS_GINTSTS_HPIF (1UL << 24) /* Host port interrupt */ +#define N32_USBHS_GINTSTS_HCHIF (1UL << 25) /* Host channels interrupt */ +#define N32_USBHS_GINTSTS_PTXFEIF (1UL << 26) /* Periodic TxFIFO empty */ +#define N32_USBHS_GINTSTS_IDSTSCIF (1UL << 28) /* ID pin status change */ +#define N32_USBHS_GINTSTS_DISCIF (1UL << 29) /* Disconnect detected */ +#define N32_USBHS_GINTSTS_WKUPIF (1UL << 31) /* Resume/remote wakeup detected */ + +/* GINTEN (0x018) ***********************************************************/ +#define N32_USBHS_GINTEN_MODMISIEN (1UL << 1) /* Mode mismatch interrupt enable */ +#define N32_USBHS_GINTEN_USBHSIEN (1UL << 2) /* USBHS interrupt enable */ +#define N32_USBHS_GINTEN_SOFIEN (1UL << 3) /* SOF interrupt enable */ +#define N32_USBHS_GINTEN_RXFNEIEN (1UL << 4) /* RxFIFO non-empty interrupt enable */ +#define N32_USBHS_GINTEN_NPTXFEIEN (1UL << 5) /* Non-periodic TxFIFO empty interrupt enable */ +#define N32_USBHS_GINTEN_GINNPNAKEIEN (1UL << 6) /* Global IN non-periodic NAK effective interrupt enable */ +#define N32_USBHS_GINTEN_GOUTNAKEIEN (1UL << 7) /* Global OUT NAK effective interrupt enable */ +#define N32_USBHS_GINTEN_ESUSPIEN (1UL << 10) /* Early suspend interrupt enable */ +#define N32_USBHS_GINTEN_USBSUSPIEN (1UL << 11) /* USB suspend interrupt enable */ +#define N32_USBHS_GINTEN_USBRSTIEN (1UL << 12) /* USB reset interrupt enable */ +#define N32_USBHS_GINTEN_ENUMDIEN (1UL << 13) /* Enumeration done interrupt enable */ +#define N32_USBHS_GINTEN_ISOUTPDIEN (1UL << 14) /* Isochronous OUT packet dropped interrupt enable */ +#define N32_USBHS_GINTEN_EOPFIEN (1UL << 15) /* End of periodic frame interrupt enable */ +#define N32_USBHS_GINTEN_INEPIEN (1UL << 18) /* IN endpoint interrupt enable */ +#define N32_USBHS_GINTEN_OUTEPIEN (1UL << 19) /* OUT endpoint interrupt enable */ +#define N32_USBHS_GINTEN_ISOINCIEN (1UL << 20) /* Incomplete isochronous IN interrupt enable */ +#define N32_USBHS_GINTEN_PTNCIEN_ISOUTNCIEN (1UL << 21) /* Incomplete periodic / isochronous OUT interrupt enable */ +#define N32_USBHS_GINTEN_FETSUSPIEN (1UL << 22) /* Data fetch suspended interrupt enable */ +#define N32_USBHS_GINTEN_RSTDIEN (1UL << 23) /* Reset detected interrupt enable */ +#define N32_USBHS_GINTEN_HPIEN (1UL << 24) /* Host port interrupt enable */ +#define N32_USBHS_GINTEN_HCHIEN (1UL << 25) /* Host channels interrupt enable */ +#define N32_USBHS_GINTEN_PTXFEIEN (1UL << 26) /* Periodic TxFIFO empty interrupt enable */ +#define N32_USBHS_GINTEN_IDSTSCIEN (1UL << 28) /* ID pin status change interrupt enable */ +#define N32_USBHS_GINTEN_DISCIEN (1UL << 29) /* Disconnect interrupt enable */ +#define N32_USBHS_GINTEN_VBUSVIF (1UL << 30) /* VBUS valid interrupt enable */ +#define N32_USBHS_GINTEN_WKUPIEN (1UL << 31) /* Resume/remote wakeup interrupt enable */ + +/* GRXSTS / GRXSTSP (0x01C / 0x020) *****************************************/ +#define N32_USBHS_GRXSTS_CHEPNUM_SHIFT 0 +#define N32_USBHS_GRXSTS_CHEPNUM_MASK (0xFUL << N32_USBHS_GRXSTS_CHEPNUM_SHIFT) /* Channel/endpoint number */ +#define N32_USBHS_GRXSTS_BCNT_SHIFT 4 +#define N32_USBHS_GRXSTS_BCNT_MASK (0x7FFUL << N32_USBHS_GRXSTS_BCNT_SHIFT) /* Byte count */ +#define N32_USBHS_GRXSTS_DPID_SHIFT 15 +#define N32_USBHS_GRXSTS_DPID_MASK (3UL << N32_USBHS_GRXSTS_DPID_SHIFT) /* Data PID */ +# define N32_USBHS_GRXSTS_DPID_0 (0UL << N32_USBHS_GRXSTS_DPID_SHIFT) /* Data0 */ +# define N32_USBHS_GRXSTS_DPID_2 (1UL << N32_USBHS_GRXSTS_DPID_SHIFT) /* Data2 */ +# define N32_USBHS_GRXSTS_DPID_1 (2UL << N32_USBHS_GRXSTS_DPID_SHIFT) /* Data1 */ +# define N32_USBHS_GRXSTS_DPID_M (3UL << N32_USBHS_GRXSTS_DPID_SHIFT) /* MData */ +#define N32_USBHS_GRXSTS_PKTSTS_SHIFT 17 +#define N32_USBHS_GRXSTS_PKTSTS_MASK (0xFUL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Packet status */ + +/* Host mode */ +# define N32_USBHS_GRXSTS_IN_RCVD (2UL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Received IN packet */ +# define N32_USBHS_GRXSTS_IN_CPLT (3UL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Completed IN packet (Trigger interrupt) */ +# define N32_USBHS_GRXSTS_DATA_TOGERR (5UL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Data toggle error (Trigger interrupt) */ +# define N32_USBHS_GRXSTS_CHAN_TERMIN (7UL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Channel terminated (Trigger interrupt) */ + +/* Device mode */ +# define N32_USBHS_GRXSTS_OUT_NAK (1UL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Global OUT NAK (Trigger interrupt) */ +# define N32_USBHS_GRXSTS_OUT_RCVD (2UL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Received OUT packet */ +# define N32_USBHS_GRXSTS_OUT_CPLT (3UL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Completed OUT packet (Trigger interrupt) */ +# define N32_USBHS_GRXSTS_SETUP_DNE (4UL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Setup done (Trigger interrupt) */ +# define N32_USBHS_GRXSTS_SETUP_RCVD (6UL << N32_USBHS_GRXSTS_PKTSTS_SHIFT) /* Received setup packet (Trigger interrupt) */ +#define N32_USBHS_GRXSTS_FUNM_SHIFT 21 +#define N32_USBHS_GRXSTS_FUNM_MASK (0xFUL << N32_USBHS_GRXSTS_FUNM_SHIFT) /* Frame number (device) */ + +/* GRXFSIZ (0x024) **********************************************************/ +#define N32_USBHS_GRXFSIZ_RXFDEP_MASK (0x7FFUL) /* Rx FIFO depth (words) */ + +/* GNPTXFSIZ (0x028) ********************************************************/ + +/* Host mode */ +#define N32_USBHS_GNPTXFSIZ_NPTXFSADD_SHIFT 0 +#define N32_USBHS_GNPTXFSIZ_NPTXFSADD_MASK (0x7FFUL << N32_USBHS_GNPTXFSIZ_NPTXFSADD_SHIFT) +#define N32_USBHS_GNPTXFSIZ_NPTXFDEP_SHIFT 16 +#define N32_USBHS_GNPTXFSIZ_NPTXFDEP_MASK (0x7FFUL << N32_USBHS_GNPTXFSIZ_NPTXFDEP_SHIFT) + +/* Device mode (EP0) */ +#define N32_USBHS_GNPTXFSIZ_IEP0TXFRSADD_SHIFT 0 +#define N32_USBHS_GNPTXFSIZ_IEP0TXFRSADD_MASK (0x7FFUL << N32_USBHS_GNPTXFSIZ_IEP0TXFRSADD_SHIFT) +#define N32_USBHS_GNPTXFSIZ_IEP0TXFDEP_SHIFT 16 +#define N32_USBHS_GNPTXFSIZ_IEP0TXFDEP_MASK (0x7FFUL << N32_USBHS_GNPTXFSIZ_IEP0TXFDEP_SHIFT) + +/* GNPTXFSTS (0x02C) ********************************************************/ +#define N32_USBHS_GNPTXFSTS_NPTXFSAV_SHIFT 0 +#define N32_USBHS_GNPTXFSTS_NPTXFSAV_MASK (0xFFFFUL << N32_USBHS_GNPTXFSTS_NPTXFSAV_SHIFT) +#define N32_USBHS_GNPTXFSTS_NPTXRQSAV_SHIFT 16 +#define N32_USBHS_GNPTXFSTS_NPTXRQSAV_MASK (0xFFUL << N32_USBHS_GNPTXFSTS_NPTXRQSAV_SHIFT) +#define N32_USBHS_GNPTXFSTS_NPTXRQTOP_SHIFT 24 +#define N32_USBHS_GNPTXFSTS_NPTXRQTOP_MASK (0x7FUL << N32_USBHS_GNPTXFSTS_NPTXRQTOP_SHIFT) +# define N32_USBHS_GNPTXFSTS_NPTXRQTOP_END (1UL << 24) /* Terminate */ +# define N32_USBHS_GNPTXFSTS_NPTXRQTOP_TOKEN_SHIFT 25 +# define N32_USBHS_GNPTXFSTS_NPTXRQTOP_TOKEN_MASK (3UL << N32_USBHS_GNPTXFSTS_NPTXRQTOP_TOKEN_SHIFT) +# define N32_USBHS_GNPTXFSTS_NPTXRQTOP_TOKEN_INOUT (0UL << N32_USBHS_GNPTXFSTS_NPTXRQTOP_TOKEN_SHIFT) /* IN/OUT token */ +# define N32_USBHS_GNPTXFSTS_NPTXRQTOP_TOKEN_0LEN (1UL << N32_USBHS_GNPTXFSTS_NPTXRQTOP_TOKEN_SHIFT) /* 0-length packet token */ +# define N32_USBHS_GNPTXFSTS_NPTXRQTOP_TOKEN_DISCH (3UL << N32_USBHS_GNPTXFSTS_NPTXRQTOP_TOKEN_SHIFT) /* Disable channel command */ +# define N32_USBHS_GNPTXFSTS_NPTXRQTOP_CHNUM_SHIFT 27 +# define N32_USBHS_GNPTXFSTS_NPTXRQTOP_CHNUM_MASK (0xFUL << N32_USBHS_GNPTXFSTS_NPTXRQTOP_CHNUM_SHIFT) + +/* CID (0x03C) **************************************************************/ +#define N32_USBHS_CID_MASK (0xFFFFFFFFUL) /* User ID */ + +/* GPD (0x058) **************************************************************/ +#define N32_USBHS_GPD_LINSTSCHNGSTS (1UL << 7) /* Line status change status */ +#define N32_USBHS_GPD_LINSTSCHNGINTEN (1UL << 8) /* Line status change interrupt enable */ +#define N32_USBHS_GPD_RESTDETSTS (1UL << 9) /* Reset detected status */ +#define N32_USBHS_GPD_RESTDETINTEN (1UL << 10) /* Reset detected interrupt enable */ +#define N32_USBHS_GPD_DISCONNDETSTS (1UL << 11) /* Disconnect detected status */ +#define N32_USBHS_GPD_DISCONNDETINTEN (1UL << 12) /* Disconnect detected interrupt enable */ +#define N32_USBHS_GPD_CONNDETSTS (1UL << 13) /* Connect detected status */ +#define N32_USBHS_GPD_CONNDETINTEN (1UL << 14) /* Connect detected interrupt enable */ +#define N32_USBHS_GPD_STSCHNGINTSTS (1UL << 17) /* Status change interrupt status */ +#define N32_USBHS_GPD_STSCHNGINTEN (1UL << 18) /* Status change interrupt enable */ +#define N32_USBHS_GPD_LINSTS_SHIFT 19 +#define N32_USBHS_GPD_LINSTS_MASK (3UL << N32_USBHS_GPD_LINSTS_SHIFT) /* Line status */ +# define N32_USBHS_GPD_LINSTS_DM0DP0 (0UL << N32_USBHS_GPD_LINSTS_SHIFT) /* DM=0, DP=0 */ +# define N32_USBHS_GPD_LINSTS_DM0DP1 (1UL << N32_USBHS_GPD_LINSTS_SHIFT) /* DM=0, DP=1 */ +# define N32_USBHS_GPD_LINSTS_DM1DP0 (2UL << N32_USBHS_GPD_LINSTS_SHIFT) /* DM=1, DP=0 */ +#define N32_USBHS_GPD_IDDIG (1UL << 21) /* IDDIG signal state (0:Host, 1:Device) */ + +/* HPTXFSIZ (0x100) *********************************************************/ +#define N32_USBHS_HPTXFSIZ_HPTXFSADD_SHIFT 0 +#define N32_USBHS_HPTXFSIZ_HPTXFSADD_MASK (0xFFFFUL << N32_USBHS_HPTXFSIZ_HPTXFSADD_SHIFT) +#define N32_USBHS_HPTXFSIZ_HPTXFDEP_SHIFT 16 +#define N32_USBHS_HPTXFSIZ_HPTXFDEP_MASK (0xFFFFUL << N32_USBHS_HPTXFSIZ_HPTXFDEP_SHIFT) + +/* DINEPPTXFSIZ[1..8] (0x104 + (x1)4) ***************************************/ +#define N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT 0 +#define N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_MASK (0xFFFFUL << N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT) +#define N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT 16 +#define N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_MASK (0xFFFFUL << N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT) + +/* ========================================================================== + * Host Mode Registers + * ========================================================================== + */ + +/* HCFG (0x400) *************************************************************/ +#define N32_USBHS_HCFG_SPSEL (1UL << 2) /* USB speed select (0:HS/FS/LS, 1:FS/LS only) */ + +/* HFRI (0x404) *************************************************************/ +#define N32_USBHS_HFRI_FRI_SHIFT 0 +#define N32_USBHS_HFRI_FRI_MASK (0xFFFFUL << N32_USBHS_HFRI_FRI_SHIFT) /* Frame interval */ +#define N32_USBHS_HFRI_DRLDEN (1UL << 16) /* Dynamic reload enable */ + +/* HFNUM (0x408) ************************************************************/ +#define N32_USBHS_HFNUM_FRNUM_SHIFT 0 +#define N32_USBHS_HFNUM_FRNUM_MASK (0xFFFFUL << N32_USBHS_HFNUM_FRNUM_SHIFT) /* Frame number */ +#define N32_USBHS_HFNUM_FRT_SHIFT 16 +#define N32_USBHS_HFNUM_FRT_MASK (0xFFFFUL << N32_USBHS_HFNUM_FRT_SHIFT) /* Frame time remaining */ + +/* HPTXFQSTS (0x410) ********************************************************/ +#define N32_USBHS_HPTXFQSTS_PTXFSAVL_SHIFT 0 +#define N32_USBHS_HPTXFQSTS_PTXFSAVL_MASK (0xFFFFUL << N32_USBHS_HPTXFQSTS_PTXFSAVL_SHIFT) +#define N32_USBHS_HPTXFQSTS_PTXRQSAVL_SHIFT 16 +#define N32_USBHS_HPTXFQSTS_PTXRQSAVL_MASK (0x7FUL << N32_USBHS_HPTXFQSTS_PTXRQSAVL_SHIFT) +#define N32_USBHS_HPTXFQSTS_PTXRQTOP_SHIFT 23 +#define N32_USBHS_HPTXFQSTS_PTXRQTOP_MASK (0xFFUL << N32_USBHS_HPTXFQSTS_PTXRQTOP_SHIFT) +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_END (1UL << 23) /* Terminate */ +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_PEND (1UL << 24) /* Pending */ +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_SHIFT 25 +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_MASK (3UL << N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_SHIFT) +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_INOUT (0UL << N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_SHIFT) /* IN/OUT token */ +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_0LEN (1UL << N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_SHIFT) /* 0-length packet token */ +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_CSPLIT (2UL << N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_SHIFT) /* CSPLIT */ +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_DISCH (3UL << N32_USBHS_HPTXFQSTS_PTXRQTOP_TOKEN_SHIFT) /* Disable channel command */ +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_CHNUM_SHIFT 27 +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_CHNUM_MASK (0xFUL << N32_USBHS_HPTXFQSTS_PTXRQTOP_CHNUM_SHIFT) +# define N32_USBHS_HPTXFQSTS_PTXRQTOP_OEFRM (1UL << 31) /* Odd/even frame */ + +/* HACHINT (0x414) **********************************************************/ +#define N32_USBHS_HACHINT_MASK (0xFFFFUL) /* Channel interrupt bits */ + +/* HACHINTEN (0x418) ********************************************************/ +#define N32_USBHS_HACHINTEN_MASK (0xFFFFUL) /* Channel interrupt enable bits */ + +/* HPCS (0x440) *************************************************************/ +#define N32_USBHS_HPCS_PCSTS (1UL << 0) /* Port connect status */ +#define N32_USBHS_HPCS_PCDET (1UL << 1) /* Port connect detected */ +#define N32_USBHS_HPCS_PEN (1UL << 2) /* Port enable */ +#define N32_USBHS_HPCS_PENC (1UL << 3) /* Port enable/disable change */ +#define N32_USBHS_HPCS_POCA (1UL << 4) /* Port overcurrent active */ +#define N32_USBHS_HPCS_POCC (1UL << 5) /* Port overcurrent change */ +#define N32_USBHS_HPCS_PRES (1UL << 6) /* Port resume */ +#define N32_USBHS_HPCS_PSUSP (1UL << 7) /* Port suspend */ +#define N32_USBHS_HPCS_PRST (1UL << 8) /* Port reset */ +#define N32_USBHS_HPCS_PLSTS_SHIFT 10 +#define N32_USBHS_HPCS_PLSTS_MASK (3UL << N32_USBHS_HPCS_PLSTS_SHIFT) /* Port line status */ +#define N32_USBHS_HPCS_PPWR (1UL << 12) /* Port power */ +#define N32_USBHS_HPCS_PTCTRL_SHIFT 13 +#define N32_USBHS_HPCS_PTCTRL_MASK (0xFUL << N32_USBHS_HPCS_PTCTRL_SHIFT) /* Port test control */ +# define N32_USBHS_HPCS_PTCTRL_TEST_NO (0UL << N32_USBHS_HPCS_PTCTRL_SHIFT) /* No test */ +# define N32_USBHS_HPCS_PTCTRL_TEST_J (1UL << N32_USBHS_HPCS_PTCTRL_SHIFT) /* Test_J mode */ +# define N32_USBHS_HPCS_PTCTRL_TEST_K (2UL << N32_USBHS_HPCS_PTCTRL_SHIFT) /* Test_K mode */ +# define N32_USBHS_HPCS_PTCTRL_TEST_SN (3UL << N32_USBHS_HPCS_PTCTRL_SHIFT) /* Test_SE0_NAK mode */ +# define N32_USBHS_HPCS_PTCTRL_TEST_PK (4UL << N32_USBHS_HPCS_PTCTRL_SHIFT) /* Test_Packet mode */ +# define N32_USBHS_HPCS_PTCTRL_TEST_FE (5UL << N32_USBHS_HPCS_PTCTRL_SHIFT) /* Test forced enable */ +#define N32_USBHS_HPCS_PSPD_SHIFT 17 +#define N32_USBHS_HPCS_PSPD_MASK (3UL << N32_USBHS_HPCS_PSPD_SHIFT) /* Port speed */ +# define N32_USBHS_HPCS_PSPD_HS (0UL << N32_USBHS_HPCS_PSPD_SHIFT) /* High-speed */ +# define N32_USBHS_HPCS_PSPD_FS (1UL << N32_USBHS_HPCS_PSPD_SHIFT) /* Full-speed */ +# define N32_USBHS_HPCS_PSPD_LS (2UL << N32_USBHS_HPCS_PSPD_SHIFT) /* Low-speed */ + +/* HCHCTRL (0x500 + n0x20) **************************************************/ +#define N32_USBHS_HCHCTRL_MPS_SHIFT 0 +#define N32_USBHS_HCHCTRL_MPS_MASK (0x7FFUL << N32_USBHS_HCHCTRL_MPS_SHIFT) /* Max packet size */ +#define N32_USBHS_HCHCTRL_EPNUM_SHIFT 11 +#define N32_USBHS_HCHCTRL_EPNUM_MASK (0xFUL << N32_USBHS_HCHCTRL_EPNUM_SHIFT) /* Endpoint number */ +#define N32_USBHS_HCHCTRL_EPDIR (1UL << 15) /* Endpoint direction (0:OUT, 1:IN) */ +#define N32_USBHS_HCHCTRL_LSPDDEV (1UL << 17) /* Low-speed device */ +#define N32_USBHS_HCHCTRL_EPTYPE_SHIFT 18 +#define N32_USBHS_HCHCTRL_EPTYPE_MASK (3UL << N32_USBHS_HCHCTRL_EPTYPE_SHIFT) /* Endpoint type */ +# define N32_USBHS_HCHCTRL_EPTYPE_CTRL (0UL << N32_USBHS_HCHCTRL_EPTYPE_SHIFT) +# define N32_USBHS_HCHCTRL_EPTYPE_ISOC (1UL << N32_USBHS_HCHCTRL_EPTYPE_SHIFT) +# define N32_USBHS_HCHCTRL_EPTYPE_BULK (2UL << N32_USBHS_HCHCTRL_EPTYPE_SHIFT) +# define N32_USBHS_HCHCTRL_EPTYPE_INTR (3UL << N32_USBHS_HCHCTRL_EPTYPE_SHIFT) +#define N32_USBHS_HCHCTRL_DEVADDR_SHIFT 22 +#define N32_USBHS_HCHCTRL_DEVADDR_MASK (0x7FUL << N32_USBHS_HCHCTRL_DEVADDR_SHIFT) /* Device address */ +#define N32_USBHS_HCHCTRL_ODDFRM (1UL << 29) /* Odd frame */ +#define N32_USBHS_HCHCTRL_CHDIS (1UL << 30) /* Channel disable */ +#define N32_USBHS_HCHCTRL_CHEN (1UL << 31) /* Channel enable */ + +/* HCSCTRL (0x504 + n0x20) **************************************************/ +#define N32_USBHS_HCSCTRL_PRTADD_SHIFT 0 +#define N32_USBHS_HCSCTRL_PRTADD_MASK (0x7FUL << N32_USBHS_HCSCTRL_PRTADD_SHIFT) /* Port address */ +#define N32_USBHS_HCSCTRL_HUBADD_SHIFT 7 +#define N32_USBHS_HCSCTRL_HUBADD_MASK (0x7FUL << N32_USBHS_HCSCTRL_HUBADD_SHIFT) /* Hub address */ +#define N32_USBHS_HCSCTRL_TRANPOS_SHIFT 14 +#define N32_USBHS_HCSCTRL_TRANPOS_MASK (3UL << N32_USBHS_HCSCTRL_TRANPOS_SHIFT) /* Transaction position */ +# define N32_USBHS_HCSCTRL_TRANPOS_MID (0UL << N32_USBHS_HCSCTRL_TRANPOS_SHIFT) /* Middle */ +# define N32_USBHS_HCSCTRL_TRANPOS_END (1UL << N32_USBHS_HCSCTRL_TRANPOS_SHIFT) /* Last */ +# define N32_USBHS_HCSCTRL_TRANPOS_ALL (2UL << N32_USBHS_HCSCTRL_TRANPOS_SHIFT) /* All */ +# define N32_USBHS_HCSCTRL_TRANPOS_BGN (3UL << N32_USBHS_HCSCTRL_TRANPOS_SHIFT) /* First */ +#define N32_USBHS_HCSCTRL_COMPSPLF (1UL << 16) /* Complete split */ +#define N32_USBHS_HCSCTRL_SPLEN (1UL << 31) /* Split enable */ + +/* HCHINTSTS (0x508 + n0x20) ************************************************/ +#define N32_USBHS_HCHINTSTS_TXCFIF (1UL << 0) /* Transfer completed */ +#define N32_USBHS_HCHINTSTS_CHHTDIF (1UL << 1) /* Channel halted */ +#define N32_USBHS_HCHINTSTS_AHBERRIF (1UL << 2) /* AHB error */ +#define N32_USBHS_HCHINTSTS_STALLIF (1UL << 3) /* STALL response received */ +#define N32_USBHS_HCHINTSTS_NAKIF (1UL << 4) /* NAK response received */ +#define N32_USBHS_HCHINTSTS_ACKIF (1UL << 5) /* ACK response received/transmitted */ +#define N32_USBHS_HCHINTSTS_NYETIF (1UL << 6) /* NYET response received */ +#define N32_USBHS_HCHINTSTS_TXERRIF (1UL << 7) /* Transaction error */ +#define N32_USBHS_HCHINTSTS_BBERRIF (1UL << 8) /* Babble error */ +#define N32_USBHS_HCHINTSTS_FOVRIF (1UL << 9) /* Frame overrun */ +#define N32_USBHS_HCHINTSTS_DTERRIF (1UL << 10) /* Data toggle error */ + +/* HCHINTEN (0x50C + n0x20) *************************************************/ +#define N32_USBHS_HCHINTEN_TXCIEN (1UL << 0) /* Transfer completed interrupt enable */ +#define N32_USBHS_HCHINTEN_CHHTDIEN (1UL << 1) /* Channel halted interrupt enable */ +#define N32_USBHS_HCHINTEN_AHBERRIEN (1UL << 2) /* AHB error interrupt enable */ +#define N32_USBHS_HCHINTEN_STALLIEN (1UL << 3) /* STALL response interrupt enable */ +#define N32_USBHS_HCHINTEN_NAKIEN (1UL << 4) /* NAK response interrupt enable */ +#define N32_USBHS_HCHINTEN_ACKIEN (1UL << 5) /* ACK response interrupt enable */ +#define N32_USBHS_HCHINTEN_NYETIEN (1UL << 6) /* NYET response interrupt enable */ +#define N32_USBHS_HCHINTEN_TXERRIEN (1UL << 7) /* Transaction error interrupt enable */ +#define N32_USBHS_HCHINTEN_BBERRIEN (1UL << 8) /* Babble error interrupt enable */ +#define N32_USBHS_HCHINTEN_FOVRIEN (1UL << 9) /* Frame overrun interrupt enable */ +#define N32_USBHS_HCHINTEN_DTERRIEN (1UL << 10) /* Data toggle error interrupt enable */ + +/* HCHTXSIZ (0x510 + n0x20) *************************************************/ +#define N32_USBHS_HCHTXSIZ_TXSIZ_SHIFT 0 +#define N32_USBHS_HCHTXSIZ_TXSIZ_MASK (0x7FFFFUL << N32_USBHS_HCHTXSIZ_TXSIZ_SHIFT) /* Transfer size */ +#define N32_USBHS_HCHTXSIZ_PKCNT_SHIFT 19 +#define N32_USBHS_HCHTXSIZ_PKCNT_MASK (0x3FFUL << N32_USBHS_HCHTXSIZ_PKCNT_SHIFT) /* Packet count */ +#define N32_USBHS_HCHTXSIZ_PID_SHIFT 29 +#define N32_USBHS_HCHTXSIZ_PID_MASK (3UL << N32_USBHS_HCHTXSIZ_PID_SHIFT) /* Data PID */ +# define N32_USBHS_HCHTXSIZ_PID_0 (0UL << N32_USBHS_HCHTXSIZ_PID_SHIFT) /* Data0 */ +# define N32_USBHS_HCHTXSIZ_PID_2 (1UL << N32_USBHS_HCHTXSIZ_PID_SHIFT) /* Data2 */ +# define N32_USBHS_HCHTXSIZ_PID_1 (2UL << N32_USBHS_HCHTXSIZ_PID_SHIFT) /* Data1 */ +# define N32_USBHS_HCHTXSIZ_PID_M_S (3UL << N32_USBHS_HCHTXSIZ_PID_SHIFT) /* MData/Setup */ +#define N32_USBHS_HCHTXSIZ_DPING (1UL << 31) /* PING token request */ + +/* HCHDMADD (0x514 + n0x20) *************************************************/ +#define N32_USBHS_HCHDMADD_MASK (0xFFFFFFFFUL) /* DMA address */ + +/* ========================================================================== + * Device Mode Registers + * ========================================================================== + */ + +/* DCFG (0x800) *************************************************************/ +#define N32_USBHS_DCFG_DEVSPD_SHIFT 0 +#define N32_USBHS_DCFG_DEVSPD_MASK (3UL << N32_USBHS_DCFG_DEVSPD_SHIFT) /* Device speed (00:High speed, 01:Full speed) */ +#define N32_USBHS_DCFG_NZLSOUTHSK (1UL << 2) /* Non-zero-length status OUT handshake */ +#define N32_USBHS_DCFG_DEVARR_SHIFT 4 +#define N32_USBHS_DCFG_DEVARR_MASK (0x7FUL << N32_USBHS_DCFG_DEVARR_SHIFT) /* Device address */ +#define N32_USBHS_DCFG_PFRITVL_SHIFT 11 +#define N32_USBHS_DCFG_PFRITVL_MASK (3UL << N32_USBHS_DCFG_PFRITVL_SHIFT) /* Periodic frame interval */ +# define N32_USBHS_DCFG_PFRITVL_80 (0UL << N32_USBHS_DCFG_PFRITVL_SHIFT) /* 80% frame interval */ +# define N32_USBHS_DCFG_PFRITVL_85 (1UL << N32_USBHS_DCFG_PFRITVL_SHIFT) /* 85% frame interval */ +# define N32_USBHS_DCFG_PFRITVL_90 (2UL << N32_USBHS_DCFG_PFRITVL_SHIFT) /* 90% frame interval */ +# define N32_USBHS_DCFG_PFRITVL_95 (3UL << N32_USBHS_DCFG_PFRITVL_SHIFT) /* 95% frame interval */ +#define N32_USBHS_DCFG_XCVDRLY (1UL << 14) /* Transceiver delay */ +#define N32_USBHS_DCFG_EERRAIEN (1UL << 15) /* Erratic error interrupt enable */ +#define N32_USBHS_DCFG_PSITVL_SHIFT 24 +#define N32_USBHS_DCFG_PSITVL_MASK (3UL << N32_USBHS_DCFG_PSITVL_SHIFT) /* Periodic schedule interval */ +# define N32_USBHS_DCFG_PSITVL_25 (0UL << N32_USBHS_DCFG_PSITVL_SHIFT) /* 25% frame interval */ +# define N32_USBHS_DCFG_PSITVL_50 (1UL << N32_USBHS_DCFG_PSITVL_SHIFT) /* 50% frame interval */ +# define N32_USBHS_DCFG_PSITVL_75 (2UL << N32_USBHS_DCFG_PSITVL_SHIFT) /* 75% frame interval */ + +/* DCTRL (0x804) ************************************************************/ +#define N32_USBHS_DCTRL_RMWKUP (1UL << 0) /* Remote wakeup signaling */ +#define N32_USBHS_DCTRL_SFTDIS (1UL << 1) /* Soft disconnect */ +#define N32_USBHS_DCTRL_GINAKSTS (1UL << 2) /* Global IN NAK status */ +#define N32_USBHS_DCTRL_GONAKSTS (1UL << 3) /* Global OUT NAK status */ +#define N32_USBHS_DCTRL_TSCTRL_SHIFT 4 +#define N32_USBHS_DCTRL_TSCTRL_MASK (7UL << N32_USBHS_DCTRL_TSCTRL_SHIFT) /* Test control */ +# define N32_USBHS_DCTRL_TSCTRL_TEST_NO (0UL << N32_USBHS_DCTRL_TSCTRL_SHIFT) /* No test */ +# define N32_USBHS_DCTRL_TSCTRL_TEST_J (1UL << N32_USBHS_DCTRL_TSCTRL_SHIFT) /* Test_J mode */ +# define N32_USBHS_DCTRL_TSCTRL_TEST_K (2UL << N32_USBHS_DCTRL_TSCTRL_SHIFT) /* Test_K mode */ +# define N32_USBHS_DCTRL_TSCTRL_TEST_SN (3UL << N32_USBHS_DCTRL_TSCTRL_SHIFT) /* Test_SE0_NAK mode */ +# define N32_USBHS_DCTRL_TSCTRL_TEST_PK (4UL << N32_USBHS_DCTRL_TSCTRL_SHIFT) /* Test_Packet mode */ +# define N32_USBHS_DCTRL_TSCTRL_TEST_FE (5UL << N32_USBHS_DCTRL_TSCTRL_SHIFT) /* Test forced enable */ +#define N32_USBHS_DCTRL_SGINAK (1UL << 7) /* Set global IN NAK */ +#define N32_USBHS_DCTRL_CGNPINAK (1UL << 8) /* Clear global IN NAK */ +#define N32_USBHS_DCTRL_SGONAK (1UL << 9) /* Set global OUT NAK */ +#define N32_USBHS_DCTRL_CGONAK (1UL << 10) /* Clear global OUT NAK */ +#define N32_USBHS_DCTRL_POPDNE (1UL << 11) /* Power-on programming done */ +#define N32_USBHS_DCTRL_NAKOBBLE (1UL << 16) /* NAK on babble error */ + +/* DSTS (0x808) *************************************************************/ +#define N32_USBHS_DSTS_SUSPF (1UL << 0) /* Suspend status */ +#define N32_USBHS_DSTS_ENUMSPD_SHIFT 1 +#define N32_USBHS_DSTS_ENUMSPD_MASK (3UL << N32_USBHS_DSTS_ENUMSPD_SHIFT) /* Enumerated speed (00:High speed, 01:Full speed, 10:Low speed, 11:Low speed) */ +#define N32_USBHS_DSTS_ERERRF (1UL << 3) /* Erratic error */ +#define N32_USBHS_DSTS_SOFFN_SHIFT 8 +#define N32_USBHS_DSTS_SOFFN_MASK (0x3FFFUL << N32_USBHS_DSTS_SOFFN_SHIFT) /* SOF frame number */ +#define N32_USBHS_DSTS_DEVLINSTS_SHIFT 22 +#define N32_USBHS_DSTS_DEVLINSTS_MASK (3UL << N32_USBHS_DSTS_DEVLINSTS_SHIFT) /* Device line status */ +# define N32_USBHS_DSTS_DEVLINSTS_DM0DP0 (0UL << N32_USBHS_DSTS_DEVLINSTS_SHIFT) /* DM=0, DP=0 */ +# define N32_USBHS_DSTS_DEVLINSTS_DM0DP1 (1UL << N32_USBHS_DSTS_DEVLINSTS_SHIFT) /* DM=0, DP=1 */ +# define N32_USBHS_DSTS_DEVLINSTS_DM1DP0 (2UL << N32_USBHS_DSTS_DEVLINSTS_SHIFT) /* DM=1, DP=0 */ + +/* DINEPINTEN (0x810) *******************************************************/ +#define N32_USBHS_DINEPINTEN_TXCIEN (1UL << 0) /* Transfer completed interrupt enable */ +#define N32_USBHS_DINEPINTEN_EPDIEN (1UL << 1) /* Endpoint disabled interrupt enable */ +#define N32_USBHS_DINEPINTEN_AHBERRIEN (1UL << 2) /* AHB error interrupt enable */ +#define N32_USBHS_DINEPINTEN_TOIEN (1UL << 3) /* Timeout interrupt enable */ +#define N32_USBHS_DINEPINTEN_TXFERINTKIEN (1UL << 4) /* IN token when TxFIFO empty */ +#define N32_USBHS_DINEPINTEN_INTREPMISIEN (1UL << 5) /* IN token with EP mismatch */ +#define N32_USBHS_DINEPINTEN_INEPNAKEIEN (1UL << 6) /* IN endpoint NAK effective */ +#define N32_USBHS_DINEPINTEN_TXFUDIEN (1UL << 8) /* Tx FIFO underrun interrupt enable */ +#define N32_USBHS_DINEPINTEN_NAKIEN (1UL << 13) /* NAK interrupt enable */ + +/* DOUTEPINTEN (0x814) ******************************************************/ +#define N32_USBHS_DOUTEPINTEN_TXCIEN (1UL << 0) /* Transfer completed interrupt enable */ +#define N32_USBHS_DOUTEPINTEN_EPDIEN (1UL << 1) /* Endpoint disabled interrupt enable */ +#define N32_USBHS_DOUTEPINTEN_AHBERRIEN (1UL << 2) /* AHB error interrupt enable */ +#define N32_USBHS_DOUTEPINTEN_STUPDNEIEN (1UL << 3) /* SETUP phase done interrupt enable */ +#define N32_USBHS_DOUTEPINTEN_EPDISROTIEN (1UL << 4) /* OUT token when EP disabled */ +#define N32_USBHS_DOUTEPINTEN_B2BSTUPIEN (1UL << 6) /* Back-to-back SETUP packets */ +#define N32_USBHS_DOUTEPINTEN_OPERRIEN (1UL << 8) /* OUT packet error interrupt enable */ +#define N32_USBHS_DOUTEPINTEN_BERRIEN (1UL << 12) /* Babble error interrupt enable */ +#define N32_USBHS_DOUTEPINTEN_NAKIEN (1UL << 13) /* NAK interrupt enable */ +#define N32_USBHS_DOUTEPINTEN_NYETIEN (1UL << 14) /* NYET interrupt enable */ + +/* DAEPINTSTS (0x818) *******************************************************/ +#define N32_USBHS_DAEPINTSTS_INEPINT_SHIFT 0 +#define N32_USBHS_DAEPINTSTS_INEPINT_MASK (0x1FFUL << N32_USBHS_DAEPINTSTS_INEPINT_SHIFT) /* IN EP bits 0..8 */ +#define N32_USBHS_DAEPINTSTS_OUTEPINT_SHIFT 16 +#define N32_USBHS_DAEPINTSTS_OUTEPINT_MASK (0x1FFUL << N32_USBHS_DAEPINTSTS_OUTEPINT_SHIFT) /* OUT EP bits 0..8 */ + +/* DAEPINTEN (0x81C) ********************************************************/ +#define N32_USBHS_DAEPINTEN_INEPIEN_SHIFT 0 +#define N32_USBHS_DAEPINTEN_INEPIEN_MASK (0x1FFUL << N32_USBHS_DAEPINTEN_INEPIEN_SHIFT) +#define N32_USBHS_DAEPINTEN_OUTEPIEN_SHIFT 16 +#define N32_USBHS_DAEPINTEN_OUTEPIEN_MASK (0x1FFUL << N32_USBHS_DAEPINTEN_OUTEPIEN_SHIFT) + +/* DTHRCTRL (0x830) *********************************************************/ +#define N32_USBHS_DTHRCTRL_NISOINEPTHREN (1UL << 0) /* Non-isochronous IN EP threshold enable */ +#define N32_USBHS_DTHRCTRL_ISOINEPTHREN (1UL << 1) /* Isochronous IN EP threshold enable */ +#define N32_USBHS_DTHRCTRL_TXTHRLEN_SHIFT 2 +#define N32_USBHS_DTHRCTRL_TXTHRLEN_MASK (0x1FFUL << N32_USBHS_DTHRCTRL_TXTHRLEN_SHIFT) /* Tx threshold length */ +#define N32_USBHS_DTHRCTRL_RXTHREN (1UL << 16) /* Receive threshold enable */ +#define N32_USBHS_DTHRCTRL_RXTHRLEN_SHIFT 17 +#define N32_USBHS_DTHRCTRL_RXTHRLEN_MASK (0x1FFUL << N32_USBHS_DTHRCTRL_RXTHRLEN_SHIFT) /* Rx threshold length */ +#define N32_USBHS_DTHRCTRL_ARPEN (1UL << 27) /* Arbiter register enable */ + +/* DINEPFEINTEN (0x834) *****************************************************/ +#define N32_USBHS_DINEPFEINTEN_INEPTXFEIEN_MASK (0xFFFFUL) /* IN EP Tx FIFO empty interrupt enable */ + +/* DEEPINTSTS (0x838) *******************************************************/ +#define N32_USBHS_DEEPINTSTS_INEPINT_SHIFT 0 +#define N32_USBHS_DEEPINTSTS_INEPINT_MASK (0xFFUL << N32_USBHS_DEEPINTSTS_INEPINT_SHIFT) /* IN EP 0..7 */ +#define N32_USBHS_DEEPINTSTS_OUTEPINT_SHIFT 16 +#define N32_USBHS_DEEPINTSTS_OUTEPINT_MASK (0xFFUL << N32_USBHS_DEEPINTSTS_OUTEPINT_SHIFT) /* OUT EP 0..7 */ + +/* DEEPINTEN (0x83C) ********************************************************/ +#define N32_USBHS_DEEPINTEN_INEPIEN_SHIFT 0 +#define N32_USBHS_DEEPINTEN_INEPIEN_MASK (0xFFUL << N32_USBHS_DEEPINTEN_INEPIEN_SHIFT) +#define N32_USBHS_DEEPINTEN_OUTEPIEN_SHIFT 16 +#define N32_USBHS_DEEPINTEN_OUTEPIEN_MASK (0xFFUL << N32_USBHS_DEEPINTEN_OUTEPIEN_SHIFT) + +/* DINEPXINTEN (0x840 + x4) (x=0..8) ****************************************/ +#define N32_USBHS_DINEPXINTEN_TXCIEN (1UL << 0) /* Transfer completed interrupt enable */ +#define N32_USBHS_DINEPXINTEN_EPDISIEN (1UL << 1) /* Endpoint disabled interrupt enable */ +#define N32_USBHS_DINEPXINTEN_AHBERRIEN (1UL << 2) /* AHB error interrupt enable */ +#define N32_USBHS_DINEPXINTEN_TOIEN (1UL << 3) /* Timeout interrupt enable */ +#define N32_USBHS_DINEPXINTEN_TXFERINTKIEN (1UL << 4) /* IN token when TxFIFO empty */ +#define N32_USBHS_DINEPXINTEN_INTREPMISIEN (1UL << 5) /* EP mismatch interrupt enable */ +#define N32_USBHS_DINEPXINTEN_INEPNAKEIEN (1UL << 6) /* IN EP NAK effective interrupt enable */ +#define N32_USBHS_DINEPXINTEN_TXFUDIEN (1UL << 8) /* Tx FIFO underrun interrupt enable */ +#define N32_USBHS_DINEPXINTEN_NAKIEN (1UL << 13) /* NAK interrupt enable */ + +/* DOUTEPXINTEN (0x880 + x4) (x=0..8) ***************************************/ +#define N32_USBHS_DOUTEPXINTEN_TXCIEN (1UL << 0) /* Transfer completed interrupt enable */ +#define N32_USBHS_DOUTEPXINTEN_EPDIEN (1UL << 1) /* Endpoint disabled interrupt enable */ +#define N32_USBHS_DOUTEPXINTEN_AHBERRIEN (1UL << 2) /* AHB error interrupt enable */ +#define N32_USBHS_DOUTEPXINTEN_STUPDNEIEN (1UL << 3) /* SETUP phase done interrupt enable */ +#define N32_USBHS_DOUTEPXINTEN_EPDISROTIEN (1UL << 4) /* OUT token when EP disabled */ +#define N32_USBHS_DOUTEPXINTEN_B2BSTUPIEN (1UL << 6) /* Back-to-back SETUP packets */ +#define N32_USBHS_DOUTEPXINTEN_OPERRIEN (1UL << 8) /* OUT packet error interrupt enable */ +#define N32_USBHS_DOUTEPXINTEN_BERRIEN (1UL << 12) /* Babble error interrupt enable */ +#define N32_USBHS_DOUTEPXINTEN_NAKIEN (1UL << 13) /* NAK interrupt enable */ +#define N32_USBHS_DOUTEPXINTEN_NYETIEN (1UL << 14) /* NYET interrupt enable */ + +/* ========================================================================== + * Device IN Endpoint Registers (0x900 + ep*0x20) + * ========================================================================== + */ + +/* DINEPCTRL (EP0) **********************************************************/ +#define N32_USBHS_DINEP0CTRL_MPLEN_SHIFT 0 +#define N32_USBHS_DINEP0CTRL_MPLEN_MASK (3UL << N32_USBHS_DINEP0CTRL_MPLEN_SHIFT) /* Max packet size */ +# define N32_USBHS_DINEP0CTRL_MPLEN_64 (0UL << N32_USBHS_DINEP0CTRL_MPLEN_SHIFT) /* 64 bytes */ +# define N32_USBHS_DINEP0CTRL_MPLEN_32 (1UL << N32_USBHS_DINEP0CTRL_MPLEN_SHIFT) /* 32 bytes */ +# define N32_USBHS_DINEP0CTRL_MPLEN_16 (2UL << N32_USBHS_DINEP0CTRL_MPLEN_SHIFT) /* 16 bytes */ +# define N32_USBHS_DINEP0CTRL_MPLEN_8 (3UL << N32_USBHS_DINEP0CTRL_MPLEN_SHIFT) /* 8 bytes */ +#define N32_USBHS_DINEP0CTRL_EPACT (1UL << 15) /* USB active endpoint */ +#define N32_USBHS_DINEP0CTRL_NAKSTS (1UL << 17) /* NAK status */ +#define N32_USBHS_DINEP0CTRL_EPTYPE_MASK (3UL << 18) /* Endpoint type (must be 00:CTRL) */ +#define N32_USBHS_DINEP0CTRL_STALL (1UL << 21) /* STALL handshake */ +#define N32_USBHS_DINEP0CTRL_TXFNUM_SHIFT 22 +#define N32_USBHS_DINEP0CTRL_TXFNUM_MASK (0xFUL << N32_USBHS_DINEP0CTRL_TXFNUM_SHIFT) /* Tx FIFO number */ +#define N32_USBHS_DINEP0CTRL_CNAK (1UL << 26) /* Clear NAK */ +#define N32_USBHS_DINEP0CTRL_SNAK (1UL << 27) /* Set NAK */ +#define N32_USBHS_DINEP0CTRL_EPDIS (1UL << 30) /* Endpoint disable */ +#define N32_USBHS_DINEP0CTRL_EPEN (1UL << 31) /* Endpoint enable */ + +/* DINEPCTRL (EP1..8) *******************************************************/ +#define N32_USBHS_DINEPCTRL_MPLEN_SHIFT 0 +#define N32_USBHS_DINEPCTRL_MPLEN_MASK (0x7FFUL << N32_USBHS_DINEPCTRL_MPLEN_SHIFT) /* Max packet size */ +#define N32_USBHS_DINEPCTRL_EPACT (1UL << 15) /* USB active endpoint */ +#define N32_USBHS_DINEPCTRL_EPDPID_EPEOFRM (1UL << 16) /* Data PID / Even/odd frame */ +#define N32_USBHS_DINEPCTRL_NAKSTS (1UL << 17) /* NAK status */ +#define N32_USBHS_DINEPCTRL_EPTYPE_SHIFT 18 +#define N32_USBHS_DINEPCTRL_EPTYPE_MASK (3UL << N32_USBHS_DINEPCTRL_EPTYPE_SHIFT) /* Endpoint type */ +# define N32_USBHS_DINEPCTRL_EPTYPE_CTRL (0UL << N32_USBHS_DINEPCTRL_EPTYPE_SHIFT) /* CTRL */ +# define N32_USBHS_DINEPCTRL_EPTYPE_ISOC (1UL << N32_USBHS_DINEPCTRL_EPTYPE_SHIFT) /* ISOC */ +# define N32_USBHS_DINEPCTRL_EPTYPE_BULK (2UL << N32_USBHS_DINEPCTRL_EPTYPE_SHIFT) /* BULK */ +# define N32_USBHS_DINEPCTRL_EPTYPE_INTR (3UL << N32_USBHS_DINEPCTRL_EPTYPE_SHIFT) /* INTR */ +#define N32_USBHS_DINEPCTRL_STALL (1UL << 21) /* STALL handshake */ +#define N32_USBHS_DINEPCTRL_TXFNUM_SHIFT 22 +#define N32_USBHS_DINEPCTRL_TXFNUM_MASK (0xFUL << N32_USBHS_DINEPCTRL_TXFNUM_SHIFT) /* Tx FIFO number */ +#define N32_USBHS_DINEPCTRL_CNAK (1UL << 26) /* Clear NAK */ +#define N32_USBHS_DINEPCTRL_SNAK (1UL << 27) /* Set NAK */ +#define N32_USBHS_DINEPCTRL_SD0PID_SEVNFRM (1UL << 28) /* Set DATA0 / Even frame */ +#define N32_USBHS_DINEPCTRL_SD1PID_SODDFRM (1UL << 29) /* Set DATA1 / Odd frame */ +#define N32_USBHS_DINEPCTRL_EPDIS (1UL << 30) /* Endpoint disable */ +#define N32_USBHS_DINEPCTRL_EPEN (1UL << 31) /* Endpoint enable */ + +/* DINEPINTSTS (0x908 + ep0x20) *********************************************/ +#define N32_USBHS_DINEPINTSTS_TXCIF (1UL << 0) /* Transfer completed interrupt */ +#define N32_USBHS_DINEPINTSTS_EPDISIF (1UL << 1) /* Endpoint disabled interrupt */ +#define N32_USBHS_DINEPINTSTS_AHBERRIF (1UL << 2) /* AHB error interrupt */ +#define N32_USBHS_DINEPINTSTS_TOUTIF (1UL << 3) /* Timeout condition */ +#define N32_USBHS_DINEPINTSTS_TXFERINTIF (1UL << 4) /* IN token when TxFIFO empty */ +#define N32_USBHS_DINEPINTSTS_INEPMISIF (1UL << 5) /* IN endpoint mismatch */ +#define N32_USBHS_DINEPINTSTS_INEPNAKEIF (1UL << 6) /* IN endpoint NAK effective */ +#define N32_USBHS_DINEPINTSTS_TXFEIF (1UL << 7) /* Transmit FIFO empty */ +#define N32_USBHS_DINEPINTSTS_TXFUDRIF (1UL << 8) /* Tx FIFO underrun */ +#define N32_USBHS_DINEPINTSTS_PKDRPSTS (1UL << 11) /* Packet dropped status */ +#define N32_USBHS_DINEPINTSTS_BBERRIF (1UL << 12) /* Babble error */ +#define N32_USBHS_DINEPINTSTS_NAKIF (1UL << 13) /* NAK interrupt */ +#define N32_USBHS_DINEPINTSTS_NYETIF (1UL << 14) /* NYET interrupt */ + +/* DINEPTXSIZ (0x910 + ep0x20) EP0 vs others ********************************/ + +/* EP0 */ +#define N32_USBHS_DINEP0TXSIZ_TLEN_SHIFT 0 +#define N32_USBHS_DINEP0TXSIZ_TLEN_MASK (0x7FUL << N32_USBHS_DINEP0TXSIZ_TLEN_SHIFT) /* Transfer size */ +#define N32_USBHS_DINEP0TXSIZ_PKTCNT_SHIFT 19 +#define N32_USBHS_DINEP0TXSIZ_PKTCNT_MASK (3UL << N32_USBHS_DINEP0TXSIZ_PKTCNT_SHIFT) /* Packet count */ + +/* EP1..8 */ +#define N32_USBHS_DINEPTXSIZ_TLEN_SHIFT 0 +#define N32_USBHS_DINEPTXSIZ_TLEN_MASK (0x7FFFFUL << N32_USBHS_DINEPTXSIZ_TLEN_SHIFT) +#define N32_USBHS_DINEPTXSIZ_PKTCNT_SHIFT 19 +#define N32_USBHS_DINEPTXSIZ_PKTCNT_MASK (0x3FFUL << N32_USBHS_DINEPTXSIZ_PKTCNT_SHIFT) +#define N32_USBHS_DINEPTXSIZ_MCNT_SHIFT 29 +#define N32_USBHS_DINEPTXSIZ_MCNT_MASK (3UL << N32_USBHS_DINEPTXSIZ_MCNT_SHIFT) /* Multi count */ + +/* DINEPDMADD (0x914 + ep0x20) **********************************************/ +#define N32_USBHS_DINEPDMADD_MASK (0xFFFFFFFFUL) /* DMA address */ + +/* DINEPTXFSTS (0x918 + ep0x20) *********************************************/ +#define N32_USBHS_DINEPTXFSTS_TXFSPCAVL_SHIFT 0 +#define N32_USBHS_DINEPTXFSTS_TXFSPCAVL_MASK (0xFFFFUL << N32_USBHS_DINEPTXFSTS_TXFSPCAVL_SHIFT) + +/* ========================================================================== + * Device OUT Endpoint Registers (0xB00 + ep*0x20) + * ========================================================================== + */ + +/* DOUTEPCTRL (EP0) *********************************************************/ +#define N32_USBHS_DOUTEP0CTRL_MPLEN_SHIFT 0 +#define N32_USBHS_DOUTEP0CTRL_MPLEN_MASK (3UL << N32_USBHS_DOUTEP0CTRL_MPLEN_SHIFT) /* Max packet size */ +# define N32_USBHS_DOUTEP0CTRL_MPLEN_64 (0UL << N32_USBHS_DOUTEP0CTRL_MPLEN_SHIFT) /* 64 bytes */ +# define N32_USBHS_DOUTEP0CTRL_MPLEN_32 (1UL << N32_USBHS_DOUTEP0CTRL_MPLEN_SHIFT) /* 32 bytes */ +# define N32_USBHS_DOUTEP0CTRL_MPLEN_16 (2UL << N32_USBHS_DOUTEP0CTRL_MPLEN_SHIFT) /* 16 bytes */ +# define N32_USBHS_DOUTEP0CTRL_MPLEN_8 (3UL << N32_USBHS_DOUTEP0CTRL_MPLEN_SHIFT) /* 8 bytes */ +#define N32_USBHS_DOUTEP0CTRL_EPACT (1UL << 15) /* USB active endpoint */ +#define N32_USBHS_DOUTEP0CTRL_NAKSTS (1UL << 17) /* NAK status */ +#define N32_USBHS_DOUTEP0CTRL_EPTYPE_MASK (3UL << 18) /* Endpoint type (must be 00:CTRL) */ +#define N32_USBHS_DOUTEP0CTRL_STALL (1UL << 21) /* STALL handshake */ +#define N32_USBHS_DOUTEP0CTRL_CNAK (1UL << 26) /* Clear NAK */ +#define N32_USBHS_DOUTEP0CTRL_SNAK (1UL << 27) /* Set NAK */ +#define N32_USBHS_DOUTEP0CTRL_EPDIS (1UL << 30) /* Endpoint disable */ +#define N32_USBHS_DOUTEP0CTRL_EPEN (1UL << 31) /* Endpoint enable */ + +/* DOUTEPCTRL (EP1..8) ******************************************************/ +#define N32_USBHS_DOUTEPCTRL_MPLEN_SHIFT 0 +#define N32_USBHS_DOUTEPCTRL_MPLEN_MASK (0x7FFUL << N32_USBHS_DOUTEPCTRL_MPLEN_SHIFT) /* Max packet size */ +#define N32_USBHS_DOUTEPCTRL_EPACT (1UL << 15) /* USB active endpoint */ +#define N32_USBHS_DOUTEPCTRL_EPDPID_EPEOFRM (1UL << 16) /* Data PID / Even/odd frame */ +#define N32_USBHS_DOUTEPCTRL_NAKSTS (1UL << 17) /* NAK status */ +#define N32_USBHS_DOUTEPCTRL_EPTYPE_SHIFT 18 +#define N32_USBHS_DOUTEPCTRL_EPTYPE_MASK (3UL << N32_USBHS_DOUTEPCTRL_EPTYPE_SHIFT) /* Endpoint type */ +# define N32_USBHS_DOUTEPCTRL_EPTYPE_CTRL (0UL << N32_USBHS_DOUTEPCTRL_EPTYPE_SHIFT) /* CTRL */ +# define N32_USBHS_DOUTEPCTRL_EPTYPE_ISOC (1UL << N32_USBHS_DOUTEPCTRL_EPTYPE_SHIFT) /* ISOOC */ +# define N32_USBHS_DOUTEPCTRL_EPTYPE_BULK (2UL << N32_USBHS_DOUTEPCTRL_EPTYPE_SHIFT) /* BULK */ +# define N32_USBHS_DOUTEPCTRL_EPTYPE_INTR (3UL << N32_USBHS_DOUTEPCTRL_EPTYPE_SHIFT) /* INTR */ +#define N32_USBHS_DOUTEPCTRL_STALL (1UL << 21) /* STALL handshake */ +#define N32_USBHS_DOUTEPCTRL_CNAK (1UL << 26) /* Clear NAK */ +#define N32_USBHS_DOUTEPCTRL_SNAK (1UL << 27) /* Set NAK */ +#define N32_USBHS_DOUTEPCTRL_SD0PID_SEVNFRM (1UL << 28) /* Set DATA0 / Even frame */ +#define N32_USBHS_DOUTEPCTRL_SD1PID_SODDFRM (1UL << 29) /* Set DATA1 / Odd frame */ +#define N32_USBHS_DOUTEPCTRL_EPDIS (1UL << 30) /* Endpoint disable */ +#define N32_USBHS_DOUTEPCTRL_EPEN (1UL << 31) /* Endpoint enable */ + +/* DOUTEPINTSTS (0xB08 + ep0x20) ********************************************/ +#define N32_USBHS_DOUTEPINTSTS_TXCIF (1UL << 0) /* Transfer completed interrupt */ +#define N32_USBHS_DOUTEPINTSTS_EPDISIF (1UL << 1) /* Endpoint disabled interrupt */ +#define N32_USBHS_DOUTEPINTSTS_AHBERRIF (1UL << 2) /* AHB error interrupt */ +#define N32_USBHS_DOUTEPINTSTS_STUPPDNEIF (1UL << 3) /* SETUP phase done */ +#define N32_USBHS_DOUTEPINTSTS_OUTTRXEPDISIF (1UL << 4) /* OUT token when EP disabled */ +#define N32_USBHS_DOUTEPINTSTS_STSPRXIF (1UL << 5) /* Status phase received */ +#define N32_USBHS_DOUTEPINTSTS_B2BSTUPRIF (1UL << 6) /* Back-to-back SETUP packets */ +#define N32_USBHS_DOUTEPINTSTS_OUTPCKERRIF (1UL << 8) /* OUT packet error */ +#define N32_USBHS_DOUTEPINTSTS_PKDRPSTS (1UL << 11) /* Packet dropped status */ +#define N32_USBHS_DOUTEPINTSTS_BBERRIF (1UL << 12) /* Babble error */ +#define N32_USBHS_DOUTEPINTSTS_NAKIF (1UL << 13) /* NAK interrupt */ +#define N32_USBHS_DOUTEPINTSTS_NYETIF (1UL << 14) /* NYET interrupt */ +#define N32_USBHS_DOUTEPINTSTS_STUPPRXIF (1UL << 15) /* SETUP packet received (DMA mode) */ + +/* DOUTEPTXSIZ (0xB10 + ep0x20) EP0 vs others *******************************/ + +/* EP0 */ +#define N32_USBHS_DOUTEP0TXSIZ_TLEN_SHIFT 0 +#define N32_USBHS_DOUTEP0TXSIZ_TLEN_MASK (0x7FUL << N32_USBHS_DOUTEP0TXSIZ_TLEN_SHIFT) /* Transfer size */ +#define N32_USBHS_DOUTEP0TXSIZ_PKTCNT_SHIFT 19 +#define N32_USBHS_DOUTEP0TXSIZ_PKTCNT_MASK (1UL << N32_USBHS_DOUTEP0TXSIZ_PKTCNT_SHIFT) /* Packet count */ +#define N32_USBHS_DOUTEP0TXSIZ_STUPPCNT_SHIFT 29 +#define N32_USBHS_DOUTEP0TXSIZ_STUPPCNT_MASK (3UL << N32_USBHS_DOUTEP0TXSIZ_STUPPCNT_SHIFT) /* SETUP packet count */ + +/* EP1..8 */ +#define N32_USBHS_DOUTEPTXSIZ_TLEN_SHIFT 0 +#define N32_USBHS_DOUTEPTXSIZ_TLEN_MASK (0x7FFFFUL << N32_USBHS_DOUTEPTXSIZ_TLEN_SHIFT) +#define N32_USBHS_DOUTEPTXSIZ_PKTCNT_SHIFT 19 +#define N32_USBHS_DOUTEPTXSIZ_PKTCNT_MASK (0x3FFUL << N32_USBHS_DOUTEPTXSIZ_PKTCNT_SHIFT) +#define N32_USBHS_DOUTEPTXSIZ_STUPPCNT_RXDPID_SHIFT 29 +#define N32_USBHS_DOUTEPTXSIZ_STUPPCNT_RXDPID_MASK (3UL << N32_USBHS_DOUTEPTXSIZ_STUPPCNT_RXDPID_SHIFT) /* SETUP count / RX Data PID */ +# define N32_USBHS_DOUTEPTXSIZ_RXDPID_0 (0UL << N32_USBHS_DOUTEPTXSIZ_STUPPCNT_RXDPID_SHIFT) /* Data0 */ +# define N32_USBHS_DOUTEPTXSIZ_RXDPID_2 (1UL << N32_USBHS_DOUTEPTXSIZ_STUPPCNT_RXDPID_SHIFT) /* Data2 */ +# define N32_USBHS_DOUTEPTXSIZ_RXDPID_1 (2UL << N32_USBHS_DOUTEPTXSIZ_STUPPCNT_RXDPID_SHIFT) /* Data1 */ +# define N32_USBHS_DOUTEPTXSIZ_RXDPID_M (3UL << N32_USBHS_DOUTEPTXSIZ_STUPPCNT_RXDPID_SHIFT) /* MData */ + +/* DOUTEPDMADD (0xB14 + ep0x20) *********************************************/ +#define N32_USBHS_DOUTEPDMADD_MASK (0xFFFFFFFFUL) /* DMA address */ + +/* ========================================================================== + * Power Control Registers + * ========================================================================== + */ + +/* PWRCTRL (0xE00) **********************************************************/ +#define N32_USBHS_PWRCTRL_PHYSTP (1UL << 0) /* Stop PHY clock */ +#define N32_USBHS_PWRCTRL_GATEHCLK (1UL << 1) /* Gate HCLK */ +#define N32_USBHS_PWRCTRL_PDMRST (1UL << 3) /* Reset power-down module */ +#define N32_USBHS_PWRCTRL_PHYSLEEP (1UL << 6) /* PHY sleep */ +#define N32_USBHS_PWRCTRL_DSLEEP (1UL << 7) /* Deep sleep */ + +/* PWRCTRL1 (0xE04) *********************************************************/ +#define N32_USBHS_PWRCTRL1_GATEN (1UL << 0) /* Enable activity clock gating */ +#define N32_USBHS_PWRCTRL1_CNT_SHIFT 1 +#define N32_USBHS_PWRCTRL1_CNT_MASK (3UL << N32_USBHS_PWRCTRL1_CNT_SHIFT) /* Gating clock count */ +# define N32_USBHS_PWRCTRL1_CNT_64 (0UL << N32_USBHS_PWRCTRL1_CNT_SHIFT) /* 64 clocks */ +# define N32_USBHS_PWRCTRL1_CNT_128 (1UL << N32_USBHS_PWRCTRL1_CNT_SHIFT) /* 128 clocks */ +#define N32_USBHS_PWRCTRL1_RAMCLKEN (1UL << 3) /* RAM clock gating enable */ + +/* ========================================================================== + * Wrapper Registers (separate base) + * ========================================================================== + */ + +/* WRPCTRL (0x000) **********************************************************/ +#define N32_USBHS_WRPCTRL_PINDETEN (1UL << 16) /* Pin detection enable */ +#define N32_USBHS_WRPCTRL_VBRMDETEN (1UL << 17) /* VBUS removal detect enable */ +#define N32_USBHS_WRPCTRL_HDISCEN (1UL << 18) /* Host disconnect detect enable */ +#define N32_USBHS_WRPCTRL_IDDETEN (1UL << 19) /* ID detect enable */ +#define N32_USBHS_WRPCTRL_SUSPWKEN (1UL << 20) /* Suspend wake-up enable */ +#define N32_USBHS_WRPCTRL_LSCHGEN (1UL << 21) /* Line status change detection enable */ + +/* WRPCFG (0x004) ***********************************************************/ +#define N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT 0 +#define N32_USBHS_WRPCFG_PHYCLKSEL_MASK (7UL << N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT) /* PHY clock select */ +# define N32_USBHS_WRPCFG_PHYCLKSEL_10 (0UL << N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT) /* 10MHz */ +# define N32_USBHS_WRPCFG_PHYCLKSEL_12 (1UL << N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT) /* 12MHz */ +# define N32_USBHS_WRPCFG_PHYCLKSEL_25 (2UL << N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT) /* 25MHz */ +# define N32_USBHS_WRPCFG_PHYCLKSEL_30 (3UL << N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT) /* 30MHz */ +# define N32_USBHS_WRPCFG_PHYCLKSEL_19_2 (4UL << N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT) /* 19.2MHz */ +# define N32_USBHS_WRPCFG_PHYCLKSEL_24 (5UL << N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT) /* 24MHz */ +# define N32_USBHS_WRPCFG_PHYCLKSEL_27 (6UL << N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT) /* 27MHz */ +# define N32_USBHS_WRPCFG_PHYCLKSEL_40 (7UL << N32_USBHS_WRPCFG_PHYCLKSEL_SHIFT) /* 40MHz */ +#define N32_USBHS_WRPCFG_PLLEN (1UL << 3) /* PLL enable */ +#define N32_USBHS_WRPCFG_IDEN (1UL << 9) /* ID pin enable */ +#define N32_USBHS_WRPCFG_LSEN (1UL << 10) /* Low-swing enable */ +#define N32_USBHS_WRPCFG_SOFDEN (1UL << 11) /* SOF detection enable */ +#define N32_USBHS_WRPCFG_IDSIG (1UL << 12) /* Internal ID signal (when IDEN=0) */ + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7_USBHS_H */ diff --git a/arch/arm/src/n32h7/hardware/n32h7xx_dbgmcu.h b/arch/arm/src/n32h7/hardware/n32h7xx_dbgmcu.h new file mode 100644 index 0000000000000..586d274cc3519 --- /dev/null +++ b/arch/arm/src/n32h7/hardware/n32h7xx_dbgmcu.h @@ -0,0 +1,243 @@ +/**************************************************************************** + * arch/arm/src/n32h7/hardware/n32h7xx_dbgmcu.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7XX_DBGMCU_H +#define __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7XX_DBGMCU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define N32_DBG_ID_OFFSET 0x00 /* ID register */ +#define N32_DBG_CTRL_OFFSET 0x04 /* Control register */ +#define N32_DBG_M7APB1FZ_OFFSET 0x08 /* M7 APB1 freeze register */ +#define N32_DBG_M4APB1FZ_OFFSET 0x0c /* M4 APB1 freeze register */ +#define N32_DBG_M7APB2FZ_OFFSET 0x10 /* M7 APB2 freeze register */ +#define N32_DBG_M4APB2FZ_OFFSET 0x14 /* M4 APB2 freeze register */ +#define N32_DBG_M7APB5FZ_OFFSET 0x18 /* M7 APB5 freeze register */ +#define N32_DBG_M4APB5FZ_OFFSET 0x1c /* M4 APB5 freeze register */ +#define N32_DBG_M7APB6FZ_OFFSET 0x20 /* M7 APB6 freeze register */ +#define N32_DBG_M4APB6FZ_OFFSET 0x24 /* M4 APB6 freeze register */ + +/* Register Addresses *******************************************************/ + +#define N32_DBG_ID (N32_DEBUGMCU_BASE + N32_DBG_ID_OFFSET) +#define N32_DBG_CTRL (N32_DEBUGMCU_BASE + N32_DBG_CTRL_OFFSET) +#define N32_DBG_M7APB1FZ (N32_DEBUGMCU_BASE + N32_DBG_M7APB1FZ_OFFSET) +#define N32_DBG_M4APB1FZ (N32_DEBUGMCU_BASE + N32_DBG_M4APB1FZ_OFFSET) +#define N32_DBG_M7APB2FZ (N32_DEBUGMCU_BASE + N32_DBG_M7APB2FZ_OFFSET) +#define N32_DBG_M4APB2FZ (N32_DEBUGMCU_BASE + N32_DBG_M4APB2FZ_OFFSET) +#define N32_DBG_M7APB5FZ (N32_DEBUGMCU_BASE + N32_DBG_M7APB5FZ_OFFSET) +#define N32_DBG_M4APB5FZ (N32_DEBUGMCU_BASE + N32_DBG_M4APB5FZ_OFFSET) +#define N32_DBG_M7APB6FZ (N32_DEBUGMCU_BASE + N32_DBG_M7APB6FZ_OFFSET) +#define N32_DBG_M4APB6FZ (N32_DEBUGMCU_BASE + N32_DBG_M4APB6FZ_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* ID register (N32_DBG_ID) */ + +#define DBG_ID_REV_NUM_H_SHIFT (28) /* Bits 31-28: MCU revision number high */ +#define DBG_ID_REV_NUM_H_MASK (0xf << DBG_ID_REV_NUM_H_SHIFT) +#define DBG_ID_REV_NUM_L_SHIFT (24) /* Bits 27-24: MCU revision number low */ +#define DBG_ID_REV_NUM_L_MASK (0xf << DBG_ID_REV_NUM_L_SHIFT) +#define DBG_ID_DEV_NUM_H_SHIFT (20) /* Bits 23-20: Device number high */ +#define DBG_ID_DEV_NUM_H_MASK (0xf << DBG_ID_DEV_NUM_H_SHIFT) +#define DBG_ID_DEV_NUM_M_SHIFT (16) /* Bits 19-16: Device number middle */ +#define DBG_ID_DEV_NUM_M_MASK (0xf << DBG_ID_DEV_NUM_M_SHIFT) +#define DBG_ID_DEV_NUM_L_SHIFT (12) /* Bits 15-12: Device number low */ +#define DBG_ID_DEV_NUM_L_MASK (0xf << DBG_ID_DEV_NUM_L_SHIFT) + +/* Device number values (DEV_NUM_H + DEV_NUM_M + DEV_NUM_L) */ +#define DBG_ID_DEV_NUM_N32H760 0x760 +#define DBG_ID_DEV_NUM_N32H762 0x762 +#define DBG_ID_DEV_NUM_N32H765 0x765 +#define DBG_ID_DEV_NUM_N32H785 0x785 +#define DBG_ID_DEV_NUM_N32H787 0x787 +#define DBG_ID_DEV_NUM_N32H788 0x788 + +#define DBG_ID_PINS_SHIFT (8) /* Bits 11-8: Pin count */ +#define DBG_ID_PINS_MASK (0xf << DBG_ID_PINS_SHIFT) +#define DBG_ID_PINS_100 0x2 +#define DBG_ID_PINS_144 0x4 +#define DBG_ID_PINS_169 0x6 +#define DBG_ID_PINS_176 0x8 +#define DBG_ID_PINS_208 0xa +#define DBG_ID_PINS_240 0xc + +#define DBG_ID_FLASH_SHIFT (6) /* Bits 7-6: Flash size */ +#define DBG_ID_FLASH_MASK (0x3 << DBG_ID_FLASH_SHIFT) +#define DBG_ID_FLASH_2MB (0x1 << DBG_ID_FLASH_SHIFT) +#define DBG_ID_FLASH_4MB (0x2 << DBG_ID_FLASH_SHIFT) + +#define DBG_ID_ENC_SHIFT (4) /* Bits 5-4: Package type */ +#define DBG_ID_ENC_MASK (0x3 << DBG_ID_ENC_SHIFT) +#define DBG_ID_ENC_BGA (0x1 << DBG_ID_ENC_SHIFT) +#define DBG_ID_ENC_LQFP (0x2 << DBG_ID_ENC_SHIFT) + +/* Control register (N32_DBG_CTRL) */ + +#define DBG_CTRL_M4SLEEP (1 << 0) /* Bit 0: Debug sleep mode for CM4 */ +#define DBG_CTRL_M4STOP (1 << 1) /* Bit 1: Debug stop mode for CM4 */ +#define DBG_CTRL_M4STBY (1 << 2) /* Bit 2: Debug standby mode for CM4 */ +#define DBG_CTRL_M7SLEEP (1 << 3) /* Bit 3: Debug sleep mode for CM7 */ +#define DBG_CTRL_M7STOP (1 << 4) /* Bit 4: Debug stop mode for CM7 */ +#define DBG_CTRL_M7STBY (1 << 5) /* Bit 5: Debug standby mode for CM7 */ +#define DBG_CTRL_TRGOEN (1 << 6) /* Bit 6: External trigger output enable */ +#define DBG_CTRL_TRACE_MODE_SHIFT (7) /* Bits 9-7: Trace mode */ +#define DBG_CTRL_TRACE_MODE_MASK (0x7 << DBG_CTRL_TRACE_MODE_SHIFT) +#define DBG_CTRL_TRACE_IOEN (1 << 7) /* Bit 7: Trace I/O enable */ +#define DBG_CTRL_TRACE_MODE_ASYNC (0 << 8) /* Bits 9-8: Asynchronous mode */ +#define DBG_CTRL_TRACE_MODE_SYNC1 (1 << 8) /* Bits 9-8: Sync mode, 1-bit data */ +#define DBG_CTRL_TRACE_MODE_SYNC2 (2 << 8) /* Bits 9-8: Sync mode, 2-bit data */ +#define DBG_CTRL_TRACE_MODE_SYNC4 (3 << 8) /* Bits 9-8: Sync mode, 4-bit data */ +#define DBG_CTRL_TRACE_CFG (1 << 10) /* Bit 10: Trace source selection (0=CM7, 1=CM4) */ + +/* M7 APB1 freeze register (N32_DBG_M7APB1FZ) - also used for M4 APB1 */ + +#define DBG_M7APB1FZ_BTIM1_STOP (1 << 0) /* Bit 0: BTIM1 stopped when halted */ +#define DBG_M7APB1FZ_BTIM2_STOP (1 << 1) /* Bit 1: BTIM2 stopped when halted */ +#define DBG_M7APB1FZ_BTIM3_STOP (1 << 2) /* Bit 2: BTIM3 stopped when halted */ +#define DBG_M7APB1FZ_BTIM4_STOP (1 << 3) /* Bit 3: BTIM4 stopped when halted */ +#define DBG_M7APB1FZ_GTIMA4_STOP (1 << 4) /* Bit 4: GTIMA4 stopped when halted */ +#define DBG_M7APB1FZ_GTIMA5_STOP (1 << 5) /* Bit 5: GTIMA5 stopped when halted */ +#define DBG_M7APB1FZ_GTIMA6_STOP (1 << 6) /* Bit 6: GTIMA6 stopped when halted */ +#define DBG_M7APB1FZ_GTIMA7_STOP (1 << 7) /* Bit 7: GTIMA7 stopped when halted */ +#define DBG_M7APB1FZ_GTIMB1_STOP (1 << 8) /* Bit 8: GTIMB1 stopped when halted */ +#define DBG_M7APB1FZ_GTIMB2_STOP (1 << 9) /* Bit 9: GTIMB2 stopped when halted */ +#define DBG_M7APB1FZ_GTIMB3_STOP (1 << 10) /* Bit 10: GTIMB3 stopped when halted */ +#define DBG_M7APB1FZ_I2C1_STOP (1 << 11) /* Bit 11: I2C1 SMBus timeout stopped */ +#define DBG_M7APB1FZ_I2C2_STOP (1 << 12) /* Bit 12: I2C2 SMBus timeout stopped */ +#define DBG_M7APB1FZ_I2C3_STOP (1 << 13) /* Bit 13: I2C3 SMBus timeout stopped */ +#define DBG_M7APB1FZ_WWDG2_STOP (1 << 14) /* Bit 14: WWDG2 stopped when halted */ +#define DBG_M7APB1FZ_CANFD1_STOP (1 << 15) /* Bit 15: FDCAN1 stopped when halted */ +#define DBG_M7APB1FZ_CANFD2_STOP (1 << 16) /* Bit 16: FDCAN2 stopped when halted */ +#define DBG_M7APB1FZ_CANFD5_STOP (1 << 17) /* Bit 17: FDCAN5 stopped when halted */ +#define DBG_M7APB1FZ_CANFD6_STOP (1 << 18) /* Bit 18: FDCAN6 stopped when halted */ + +/* M4 APB1 freeze register (N32_DBG_M4APB1FZ) */ + +#define DBG_M4APB1FZ_BTIM1_STOP DBG_M7APB1FZ_BTIM1_STOP +#define DBG_M4APB1FZ_BTIM2_STOP DBG_M7APB1FZ_BTIM2_STOP +#define DBG_M4APB1FZ_BTIM3_STOP DBG_M7APB1FZ_BTIM3_STOP +#define DBG_M4APB1FZ_BTIM4_STOP DBG_M7APB1FZ_BTIM4_STOP +#define DBG_M4APB1FZ_GTIMA4_STOP DBG_M7APB1FZ_GTIMA4_STOP +#define DBG_M4APB1FZ_GTIMA5_STOP DBG_M7APB1FZ_GTIMA5_STOP +#define DBG_M4APB1FZ_GTIMA6_STOP DBG_M7APB1FZ_GTIMA6_STOP +#define DBG_M4APB1FZ_GTIMA7_STOP DBG_M7APB1FZ_GTIMA7_STOP +#define DBG_M4APB1FZ_GTIMB1_STOP DBG_M7APB1FZ_GTIMB1_STOP +#define DBG_M4APB1FZ_GTIMB2_STOP DBG_M7APB1FZ_GTIMB2_STOP +#define DBG_M4APB1FZ_GTIMB3_STOP DBG_M7APB1FZ_GTIMB3_STOP +#define DBG_M4APB1FZ_I2C1_STOP DBG_M7APB1FZ_I2C1_STOP +#define DBG_M4APB1FZ_I2C2_STOP DBG_M7APB1FZ_I2C2_STOP +#define DBG_M4APB1FZ_I2C3_STOP DBG_M7APB1FZ_I2C3_STOP +#define DBG_M4APB1FZ_WWDG2_STOP DBG_M7APB1FZ_WWDG2_STOP +#define DBG_M4APB1FZ_CANFD1_STOP DBG_M7APB1FZ_CANFD1_STOP +#define DBG_M4APB1FZ_CANFD2_STOP DBG_M7APB1FZ_CANFD2_STOP +#define DBG_M4APB1FZ_CANFD5_STOP DBG_M7APB1FZ_CANFD5_STOP +#define DBG_M4APB1FZ_CANFD6_STOP DBG_M7APB1FZ_CANFD6_STOP + +/* M7 APB2 freeze register (N32_DBG_M7APB2FZ) */ + +#define DBG_M7APB2FZ_SHRTIM1_STOP (1 << 0) /* Bit 0: SHRTIM1 stopped when halted */ +#define DBG_M7APB2FZ_SHRTIM2_STOP (1 << 1) /* Bit 1: SHRTIM2 stopped when halted */ +#define DBG_M7APB2FZ_GTIMA1_STOP (1 << 2) /* Bit 2: GTIMA1 stopped when halted */ +#define DBG_M7APB2FZ_GTIMA2_STOP (1 << 3) /* Bit 3: GTIMA2 stopped when halted */ +#define DBG_M7APB2FZ_GTIMA3_STOP (1 << 4) /* Bit 4: GTIMA3 stopped when halted */ +#define DBG_M7APB2FZ_ATIM1_STOP (1 << 5) /* Bit 5: ATIM1 stopped when halted */ +#define DBG_M7APB2FZ_ATIM2_STOP (1 << 6) /* Bit 6: ATIM2 stopped when halted */ +#define DBG_M7APB2FZ_I2C4_STOP (1 << 7) /* Bit 7: I2C4 SMBus timeout stopped */ +#define DBG_M7APB2FZ_I2C5_STOP (1 << 8) /* Bit 8: I2C5 SMBus timeout stopped */ +#define DBG_M7APB2FZ_I2C6_STOP (1 << 9) /* Bit 9: I2C6 SMBus timeout stopped */ +#define DBG_M7APB2FZ_CANFD3_STOP (1 << 10) /* Bit 10: FDCAN3 stopped when halted */ +#define DBG_M7APB2FZ_CANFD4_STOP (1 << 11) /* Bit 11: FDCAN4 stopped when halted */ +#define DBG_M7APB2FZ_CANFD7_STOP (1 << 12) /* Bit 12: FDCAN7 stopped when halted */ +#define DBG_M7APB2FZ_CANFD8_STOP (1 << 13) /* Bit 13: FDCAN8 stopped when halted */ + +/* M4 APB2 freeze register (N32_DBG_M4APB2FZ) */ + +#define DBG_M4APB2FZ_SHRTIM1_STOP DBG_M7APB2FZ_SHRTIM1_STOP +#define DBG_M4APB2FZ_SHRTIM2_STOP DBG_M7APB2FZ_SHRTIM2_STOP +#define DBG_M4APB2FZ_GTIMA1_STOP DBG_M7APB2FZ_GTIMA1_STOP +#define DBG_M4APB2FZ_GTIMA2_STOP DBG_M7APB2FZ_GTIMA2_STOP +#define DBG_M4APB2FZ_GTIMA3_STOP DBG_M7APB2FZ_GTIMA3_STOP +#define DBG_M4APB2FZ_ATIM1_STOP DBG_M7APB2FZ_ATIM1_STOP +#define DBG_M4APB2FZ_ATIM2_STOP DBG_M7APB2FZ_ATIM2_STOP +#define DBG_M4APB2FZ_I2C4_STOP DBG_M7APB2FZ_I2C4_STOP +#define DBG_M4APB2FZ_I2C5_STOP DBG_M7APB2FZ_I2C5_STOP +#define DBG_M4APB2FZ_I2C6_STOP DBG_M7APB2FZ_I2C6_STOP +#define DBG_M4APB2FZ_CANFD3_STOP DBG_M7APB2FZ_CANFD3_STOP +#define DBG_M4APB2FZ_CANFD4_STOP DBG_M7APB2FZ_CANFD4_STOP +#define DBG_M4APB2FZ_CANFD7_STOP DBG_M7APB2FZ_CANFD7_STOP +#define DBG_M4APB2FZ_CANFD8_STOP DBG_M7APB2FZ_CANFD8_STOP + +/* M7 APB5 freeze register (N32_DBG_M7APB5FZ) - ATIM3/ATIM4 and LPTIM */ + +#define DBG_M7APB5FZ_ATIM3_STOP (1 << 0) /* Bit 0: ATIM3 stopped when halted */ +#define DBG_M7APB5FZ_ATIM4_STOP (1 << 1) /* Bit 1: ATIM4 stopped when halted */ +#define DBG_M7APB5FZ_I2C7_STOP (1 << 2) /* Bit 2: I2C7 SMBus timeout stopped */ +#define DBG_M7APB5FZ_I2C8_STOP (1 << 3) /* Bit 3: I2C8 SMBus timeout stopped */ +#define DBG_M7APB5FZ_I2C9_STOP (1 << 4) /* Bit 4: I2C9 SMBus timeout stopped */ +#define DBG_M7APB5FZ_I2C10_STOP (1 << 5) /* Bit 5: I2C10 SMBus timeout stopped */ +#define DBG_M7APB5FZ_IWDG1_STOP (1 << 6) /* Bit 6: IWDG1 stopped when halted */ +#define DBG_M7APB5FZ_IWDG2_STOP (1 << 7) /* Bit 7: IWDG2 stopped when halted */ +#define DBG_M7APB5FZ_LPTIM1_STOP (1 << 8) /* Bit 8: LPTIM1 stopped when halted */ +#define DBG_M7APB5FZ_LPTIM2_STOP (1 << 9) /* Bit 9: LPTIM2 stopped when halted */ +#define DBG_M7APB5FZ_LPTIM3_STOP (1 << 10) /* Bit 10: LPTIM3 stopped when halted */ +#define DBG_M7APB5FZ_LPTIM4_STOP (1 << 11) /* Bit 11: LPTIM4 stopped when halted */ +#define DBG_M7APB5FZ_LPTIM5_STOP (1 << 12) /* Bit 12: LPTIM5 stopped when halted */ +#define DBG_M7APB5FZ_RTC_STOP (1 << 13) /* Bit 13: RTC stopped when halted */ + +/* M4 APB5 freeze register (N32_DBG_M4APB5FZ) */ + +#define DBG_M4APB5FZ_ATIM3_STOP DBG_M7APB5FZ_ATIM3_STOP +#define DBG_M4APB5FZ_ATIM4_STOP DBG_M7APB5FZ_ATIM4_STOP +#define DBG_M4APB5FZ_I2C7_STOP DBG_M7APB5FZ_I2C7_STOP +#define DBG_M4APB5FZ_I2C8_STOP DBG_M7APB5FZ_I2C8_STOP +#define DBG_M4APB5FZ_I2C9_STOP DBG_M7APB5FZ_I2C9_STOP +#define DBG_M4APB5FZ_I2C10_STOP DBG_M7APB5FZ_I2C10_STOP +#define DBG_M4APB5FZ_IWDG1_STOP DBG_M7APB5FZ_IWDG1_STOP +#define DBG_M4APB5FZ_IWDG2_STOP DBG_M7APB5FZ_IWDG2_STOP +#define DBG_M4APB5FZ_LPTIM1_STOP DBG_M7APB5FZ_LPTIM1_STOP +#define DBG_M4APB5FZ_LPTIM2_STOP DBG_M7APB5FZ_LPTIM2_STOP +#define DBG_M4APB5FZ_LPTIM3_STOP DBG_M7APB5FZ_LPTIM3_STOP +#define DBG_M4APB5FZ_LPTIM4_STOP DBG_M7APB5FZ_LPTIM4_STOP +#define DBG_M4APB5FZ_LPTIM5_STOP DBG_M7APB5FZ_LPTIM5_STOP +#define DBG_M4APB5FZ_RTC_STOP DBG_M7APB5FZ_RTC_STOP + +/* M7 APB6 freeze register (N32_DBG_M7APB6FZ) */ + +#define DBG_M7APB6FZ_WWDG1_STOP (1 << 0) /* Bit 0: WWDG1 stopped when halted */ + +/* M4 APB6 freeze register (N32_DBG_M4APB6FZ) */ + +#define DBG_M4APB6FZ_WWDG1_STOP (1 << 0) /* Bit 0: WWDG1 stopped when halted */ + +#endif /* __ARCH_ARM_SRC_N32H7_HARDWARE_N32H7XX_DBGMCU_H */ diff --git a/arch/arm/src/n32h7/n32_allocateheap.c b/arch/arm/src/n32h7/n32_allocateheap.c new file mode 100644 index 0000000000000..391c66a1155d3 --- /dev/null +++ b/arch/arm/src/n32h7/n32_allocateheap.c @@ -0,0 +1,182 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_allocateheap.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "arm_internal.h" +#include "mpu.h" +#include "hardware/n32h7_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +extern const uint8_t _axiram_heap_start[]; +extern const uint8_t _ahbram_heap_start[]; + +/* Adjust memory region definitions */ +#define N32_DTCM_SIZE (128U * 1024U) /* DTCM 128KB */ +#define N32_AHBSRAM_SIZE (352U * 1024U) /* AHBSRAM 352KB */ +#define N32_AXISRAM_SIZE (128U * 1024U) /* AXI SRAM 128KB */ +#define N32_BSRAM_SIZE ( 4U * 1024U) /* BSRAM 4KB */ + +/* Adjust main heap start address to DTCM */ +#define MAIN_HEAP_START DTCM_HEAP_START +#define DTCM_HEAP_START g_idle_topstack +#define AHB_HEAP_START (uint32_t)_ahbram_heap_start +#define AXI_HEAP_START (uint32_t)_axiram_heap_start +#define BSRAM_HEAP_START N32_BSRAM_BASE + +/* Adjust main heap end address to DTCM */ +#define MAIN_HEAP_END DTCM_HEAP_END +#define DTCM_HEAP_END (N32_DTCM_SIZE + N32_DTCRAM_BASE) +#define AHB_HEAP_END (N32_AHBSRAM_SIZE + N32_AHBSRAM_BASE) +#define AXI_HEAP_END (N32_AXISRAM_SIZE + N32_AXISRAM_BASE) +#define BSRAM_HEAP_END (N32_BSRAM_SIZE + N32_BSRAM_BASE) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_HEAP_COLORATION +static inline void up_heap_color(void *start, size_t size) +{ + memset(start, HEAP_COLOR, size); +} +#else +# define up_heap_color(start,size) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_allocate_heap(void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Adjust protected mode heap to SRAM1 */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = MAIN_HEAP_START + N32_SRAM1_SIZE - ubase; + int log2; + + DEBUGASSERT(ubase < (DTCM_HEAP_START + N32_DTCM_SIZE)); + + /* MPU alignment processing */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT(((DTCM_HEAP_START + N32_DTCM_SIZE) & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = (DTCM_HEAP_START + N32_DTCM_SIZE) - usize; + + *heap_start = (void *)ubase; + *heap_size = usize; + + /* Initialize kernel memory manager */ + + kmm_initialize(*heap_start, *heap_size); + + /* Debug message output */ + + minfo("Protected mode heap: %uKB at %p\n", *heap_size / 1024, *heap_start); +#else + + /* Adjust main heap to DTCM */ + + *heap_start = (void *)MAIN_HEAP_START; + *heap_size = MAIN_HEAP_END - MAIN_HEAP_START; + + board_autoled_on(LED_HEAPALLOCATE); + kmm_initialize(*heap_start, *heap_size); + minfo("Main heap: %uKB DTCM at %p\n", *heap_size / 1024, *heap_start); +#endif + + /* Debug heap color */ + + up_heap_color(*heap_start, *heap_size); +} + +#if CONFIG_MM_REGIONS > 1 +void arm_addregion(void) +{ + unsigned mm_regions = 1; + + /* Add AXI SRAM region */ + + if (mm_regions < CONFIG_MM_REGIONS) + { + kumm_addregion((void *)AXI_HEAP_START, AXI_HEAP_END - AXI_HEAP_START); + minfo("Added AXI SRAM: %luKB at %p\n" + , (AXI_HEAP_END - AXI_HEAP_START) / 1024U + , (uint32_t *)AXI_HEAP_START); + mm_regions++; + } + + /* Add AHBSRAM region */ + + if (mm_regions < CONFIG_MM_REGIONS) + { + kumm_addregion((void *)AHB_HEAP_START, AHB_HEAP_END - AHB_HEAP_START); + minfo("Added AHBSRAM: %luKB at %p\n" + , (AHB_HEAP_END - AHB_HEAP_START) / 1024U + , (uint32_t *)AHB_HEAP_START); + mm_regions++; + } + + /* Add backup SRAM region */ + +#if defined(N32_BSRAM_BASE) && !defined(CONFIG_N32H7_BSRAMEXCLUDE) + if (mm_regions < CONFIG_MM_REGIONS) + { + kumm_addregion((void *)BSRAM_HEAP_START + , BSRAM_HEAP_END - BSRAM_HEAP_START); + minfo("Added BSRAM: %luKB at %p\n" + , (BSRAM_HEAP_END - BSRAM_HEAP_START) / 1024U + , (uint32_t *)BSRAM_HEAP_START); + mm_regions++; + } +#endif + + /* Add external memory support region */ +#if defined(CONFIG_N32H7_FMC) + /* Add FMC initialization code here */ +#endif +} +#endif diff --git a/arch/arm/src/n32h7/n32_capture.c b/arch/arm/src/n32h7/n32_capture.c new file mode 100644 index 0000000000000..fcea96880f9fe --- /dev/null +++ b/arch/arm/src/n32h7/n32_capture.c @@ -0,0 +1,1447 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_capture.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "arm_internal.h" +#include "n32_rcc.h" +#include "n32_gpio.h" +#include "n32_capture.h" +#include "hardware/n32h7_rcc.h" +#include "hardware/n32h76x_pinmap.h" + +#ifdef CONFIG_N32H7_CAPTURE + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Timer device private structure */ + +struct n32_cap_priv_s +{ + const struct n32_cap_ops_s *ops; + uint32_t base; /* timer base address */ + int irq; /* main capture/compare IRQ */ + int irq_of; /* update IRQ (0 if combined) */ + uint32_t input_clock; /* timer input clock (before prescaler) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline uint16_t n32_getreg16(const struct n32_cap_priv_s *priv, + uint8_t offset); +static inline void n32_putreg16(const struct n32_cap_priv_s *priv, + uint8_t offset, uint16_t value); +static inline void n32_modifyreg16(const struct n32_cap_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits); +static inline uint32_t n32_getreg32(const struct n32_cap_priv_s *priv, + uint8_t offset); +static inline void n32_putreg32(const struct n32_cap_priv_s *priv, + uint8_t offset, uint32_t value); + +static uint32_t n32_cap_gpio(const struct n32_cap_priv_s *priv, int channel); +static int n32_cap_set_rcc(const struct n32_cap_priv_s *priv, bool on); + +static int n32_cap_setsmc(struct n32_cap_dev_s *dev, n32_cap_smc_cfg_t cfg); +static int n32_cap_setclock(struct n32_cap_dev_s *dev, uint32_t freq, + uint32_t max); +static int n32_cap_setchannel(struct n32_cap_dev_s *dev, uint8_t channel, + n32_cap_ch_cfg_t cfg); +static uint32_t n32_cap_getcapture(struct n32_cap_dev_s *dev, + uint8_t channel); +static uint32_t n32_cap_getedges(struct n32_cap_dev_s *dev, uint8_t channel); +static int n32_cap_setisr(struct n32_cap_dev_s *dev, xcpt_t handler, + void *arg); +static void n32_cap_enableint(struct n32_cap_dev_s *dev, n32_cap_flags_t src, + bool on); +static void n32_cap_ackflags(struct n32_cap_dev_s *dev, int flags); +static n32_cap_flags_t n32_cap_getflags(struct n32_cap_dev_s *dev); + +static const struct n32_cap_priv_s * n32_cap_get_priv(int timer); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct n32_cap_ops_s n32_cap_ops = +{ + .setsmc = n32_cap_setsmc, + .setclock = n32_cap_setclock, + .setchannel = n32_cap_setchannel, + .getcapture = n32_cap_getcapture, + .getedges = n32_cap_getedges, + .setisr = n32_cap_setisr, + .enableint = n32_cap_enableint, + .ackflags = n32_cap_ackflags, + .getflags = n32_cap_getflags, +}; + +/* Timer private structures */ + +#ifdef CONFIG_N32H7_ATIM1_CAP +const struct n32_cap_priv_s n32_atim1_priv = +{ + .ops = &n32_cap_ops, + .base = N32_ATIMER1_BASE, + .irq = N32_IRQ_ATIM1_CC, + .irq_of = N32_IRQ_ATIM1_UP, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM2_CAP +const struct n32_cap_priv_s n32_atim2_priv = +{ + .ops = &n32_cap_ops, + .base = N32_ATIMER2_BASE, + .irq = N32_IRQ_ATIM2_CC, + .irq_of = N32_IRQ_ATIM2_UP, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM3_CAP +const struct n32_cap_priv_s n32_atim3_priv = +{ + .ops = &n32_cap_ops, + .base = N32_ATIMER3_BASE, + .irq = N32_IRQ_ATIM3_CC, + .irq_of = N32_IRQ_ATIM3_UP, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM4_CAP +const struct n32_cap_priv_s n32_atim4_priv = +{ + .ops = &n32_cap_ops, + .base = N32_ATIMER4_BASE, + .irq = N32_IRQ_ATIM4_CC, + .irq_of = N32_IRQ_ATIM4_UP, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA1_CAP +const struct n32_cap_priv_s n32_gtima1_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERA1_BASE, + .irq = N32_IRQ_GTIMA1, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA2_CAP +const struct n32_cap_priv_s n32_gtima2_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERA2_BASE, + .irq = N32_IRQ_GTIMA2, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA3_CAP +const struct n32_cap_priv_s n32_gtima3_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERA3_BASE, + .irq = N32_IRQ_GTIMA3, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA4_CAP +const struct n32_cap_priv_s n32_gtima4_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERA4_BASE, + .irq = N32_IRQ_GTIMA4, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA5_CAP +const struct n32_cap_priv_s n32_gtima5_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERA5_BASE, + .irq = N32_IRQ_GTIMA5, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA6_CAP +const struct n32_cap_priv_s n32_gtima6_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERA6_BASE, + .irq = N32_IRQ_GTIMA6, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA7_CAP +const struct n32_cap_priv_s n32_gtima7_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERA7_BASE, + .irq = N32_IRQ_GTIMA7, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB1_CAP +const struct n32_cap_priv_s n32_gtimb1_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERB1_BASE, + .irq = N32_IRQ_GTIMB1, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB2_CAP +const struct n32_cap_priv_s n32_gtimb2_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERB2_BASE, + .irq = N32_IRQ_GTIMB2, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB3_CAP +const struct n32_cap_priv_s n32_gtimb3_priv = +{ + .ops = &n32_cap_ops, + .base = N32_GTIMERB3_BASE, + .irq = N32_IRQ_GTIMB3, + .irq_of = 0, + .input_clock = N32_AHB_FREQUENCY, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline uint16_t n32_getreg16(const struct n32_cap_priv_s *priv, + uint8_t offset) +{ + return getreg16(priv->base + offset); +} + +static inline void n32_putreg16(const struct n32_cap_priv_s *priv, + uint8_t offset, uint16_t value) +{ + putreg16(value, priv->base + offset); +} + +static inline void n32_modifyreg16(const struct n32_cap_priv_s *priv, + uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg16(priv->base + offset, clearbits, setbits); +} + +static inline void n32_modifyreg32(const struct n32_cap_priv_s *priv, + uint8_t offset, uint32_t clearbits, + uint32_t setbits) +{ + modifyreg32(priv->base + offset, clearbits, setbits); +} + +static inline uint32_t n32_getreg32(const struct n32_cap_priv_s *priv, + uint8_t offset) +{ + return getreg32(priv->base + offset); +} + +static inline void n32_putreg32(const struct n32_cap_priv_s *priv, + uint8_t offset, uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: n32_cap_gpio + * + * Description: + * Return the GPIO configuration for a given timer channel. + * channel = -1: return first available channel + ****************************************************************************/ + +static uint32_t n32_cap_gpio(const struct n32_cap_priv_s *priv, int channel) +{ + if (channel < 0) + { + /* Try counter channel first (ETR) then channels 1..4 */ + + uint32_t gpio = n32_cap_gpio(priv, N32_CAP_CHANNEL_COUNTER); + + if (gpio) + { + return gpio; + } + + for (int ch = 1; ch <= 4; ch++) + { + gpio = n32_cap_gpio(priv, ch); + if (gpio) + { + return gpio; + } + } + + return 0; + } + + switch (priv->base) + { + #ifdef CONFIG_N32H7_ATIM1_CAP + case N32_ATIMER1_BASE: + switch (channel) + { + #ifdef GPIO_ATIM1_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_ATIM1_ETR; + #endif + #ifdef GPIO_ATIM1_CH1IN + case 1: + return GPIO_ATIM1_CH1IN; + #endif + #ifdef GPIO_ATIM1_CH2IN + case 2: + return GPIO_ATIM1_CH2IN; + #endif + #ifdef GPIO_ATIM1_CH3IN + case 3: + return GPIO_ATIM1_CH3IN; + #endif + #ifdef GPIO_ATIM1_CH4IN + case 4: + return GPIO_ATIM1_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_ATIM2_CAP + case N32_ATIMER2_BASE: + switch (channel) + { + #ifdef GPIO_ATIM2_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_ATIM2_ETR; + #endif + #ifdef GPIO_ATIM2_CH1IN + case 1: + return GPIO_ATIM2_CH1IN; + #endif + #ifdef GPIO_ATIM2_CH2IN + case 2: + return GPIO_ATIM2_CH2IN; + #endif + #ifdef GPIO_ATIM2_CH3IN + case 3: + return GPIO_ATIM2_CH3IN; + #endif + #ifdef GPIO_ATIM2_CH4IN + case 4: + return GPIO_ATIM2_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_ATIM3_CAP + case N32_ATIMER3_BASE: + switch (channel) + { + #ifdef GPIO_ATIM3_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_ATIM3_ETR; + #endif + #ifdef GPIO_ATIM3_CH1IN + case 1: + return GPIO_ATIM3_CH1IN; + #endif + #ifdef GPIO_ATIM3_CH2IN + case 2: + return GPIO_ATIM3_CH2IN; + #endif + #ifdef GPIO_ATIM3_CH3IN + case 3: + return GPIO_ATIM3_CH3IN; + #endif + #ifdef GPIO_ATIM3_CH4IN + case 4: + return GPIO_ATIM3_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_ATIM4_CAP + case N32_ATIMER4_BASE: + switch (channel) + { + #ifdef GPIO_ATIM4_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_ATIM4_ETR; + #endif + #ifdef GPIO_ATIM4_CH1IN + case 1: + return GPIO_ATIM4_CH1IN; + #endif + #ifdef GPIO_ATIM4_CH2IN + case 2: + return GPIO_ATIM4_CH2IN; + #endif + #ifdef GPIO_ATIM4_CH3IN + case 3: + return GPIO_ATIM4_CH3IN; + #endif + #ifdef GPIO_ATIM4_CH4IN + case 4: + return GPIO_ATIM4_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMA1_CAP + case N32_GTIMERA1_BASE: + switch (channel) + { + #ifdef GPIO_GTIMA1_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMA1_ETR; + #endif + #ifdef GPIO_GTIMA1_CH1IN + case 1: + return GPIO_GTIMA1_CH1IN; + #endif + #ifdef GPIO_GTIMA1_CH2IN + case 2: + return GPIO_GTIMA1_CH2IN; + #endif + #ifdef GPIO_GTIMA1_CH3IN + case 3: + return GPIO_GTIMA1_CH3IN; + #endif + #ifdef GPIO_GTIMA1_CH4IN + case 4: + return GPIO_GTIMA1_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMA2_CAP + case N32_GTIMERA2_BASE: + switch (channel) + { + #ifdef GPIO_GTIMA2_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMA2_ETR; + #endif + #ifdef GPIO_GTIMA2_CH1IN + case 1: + return GPIO_GTIMA2_CH1IN; + #endif + #ifdef GPIO_GTIMA2_CH2IN + case 2: + return GPIO_GTIMA2_CH2IN; + #endif + #ifdef GPIO_GTIMA2_CH3IN + case 3: + return GPIO_GTIMA2_CH3IN; + #endif + #ifdef GPIO_GTIMA2_CH4IN + case 4: + return GPIO_GTIMA2_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMA3_CAP + case N32_GTIMERA3_BASE: + switch (channel) + { + #ifdef GPIO_GTIMA3_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMA3_ETR; + #endif + #ifdef GPIO_GTIMA3_CH1IN + case 1: + return GPIO_GTIMA3_CH1IN; + #endif + #ifdef GPIO_GTIMA3_CH2IN + case 2: + return GPIO_GTIMA3_CH2IN; + #endif + #ifdef GPIO_GTIMA3_CH3IN + case 3: + return GPIO_GTIMA3_CH3IN; + #endif + #ifdef GPIO_GTIMA3_CH4IN + case 4: + return GPIO_GTIMA3_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMA4_CAP + case N32_GTIMERA4_BASE: + switch (channel) + { + #ifdef GPIO_GTIMA4_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMA4_ETR; + #endif + #ifdef GPIO_GTIMA4_CH1IN + case 1: + return GPIO_GTIMA4_CH1IN; + #endif + #ifdef GPIO_GTIMA4_CH2IN + case 2: + return GPIO_GTIMA4_CH2IN; + #endif + #ifdef GPIO_GTIMA4_CH3IN + case 3: + return GPIO_GTIMA4_CH3IN; + #endif + #ifdef GPIO_GTIMA4_CH4IN + case 4: + return GPIO_GTIMA4_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMA5_CAP + case N32_GTIMERA5_BASE: + switch (channel) + { + #ifdef GPIO_GTIMA5_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMA5_ETR; + #endif + #ifdef GPIO_GTIMA5_CH1IN + case 1: + return GPIO_GTIMA5_CH1IN; + #endif + #ifdef GPIO_GTIMA5_CH2IN + case 2: + return GPIO_GTIMA5_CH2IN; + #endif + #ifdef GPIO_GTIMA5_CH3IN + case 3: + return GPIO_GTIMA5_CH3IN; + #endif + #ifdef GPIO_GTIMA5_CH4IN + case 4: + return GPIO_GTIMA5_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMA6_CAP + case N32_GTIMERA6_BASE: + switch (channel) + { + #ifdef GPIO_GTIMA6_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMA6_ETR; + #endif + #ifdef GPIO_GTIMA6_CH1IN + case 1: + return GPIO_GTIMA6_CH1IN; + #endif + #ifdef GPIO_GTIMA6_CH2IN + case 2: + return GPIO_GTIMA6_CH2IN; + #endif + #ifdef GPIO_GTIMA6_CH3IN + case 3: + return GPIO_GTIMA6_CH3IN; + #endif + #ifdef GPIO_GTIMA6_CH4IN + case 4: + return GPIO_GTIMA6_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMA7_CAP + case N32_GTIMERA7_BASE: + switch (channel) + { + #ifdef GPIO_GTIMA7_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMA7_ETR; + #endif + #ifdef GPIO_GTIMA7_CH1IN + case 1: + return GPIO_GTIMA7_CH1IN; + #endif + #ifdef GPIO_GTIMA7_CH2IN + case 2: + return GPIO_GTIMA7_CH2IN; + #endif + #ifdef GPIO_GTIMA7_CH3IN + case 3: + return GPIO_GTIMA7_CH3IN; + #endif + #ifdef GPIO_GTIMA7_CH4IN + case 4: + return GPIO_GTIMA7_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMB1_CAP + case N32_GTIMERB1_BASE: + switch (channel) + { + #ifdef GPIO_GTIMB1_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMB1_ETR; + #endif + #ifdef GPIO_GTIMB1_CH1PIN + case 1: + return GPIO_GTIMB1_CH1PIN; + #endif + #ifdef GPIO_GTIMB1_CH2IN + case 2: + return GPIO_GTIMB1_CH2IN; + #endif + #ifdef GPIO_GTIMB1_CH3IN + case 3: + return GPIO_GTIMB1_CH3IN; + #endif + #ifdef GPIO_GTIMB1_CH4IN + case 4: + return GPIO_GTIMB1_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMB2_CAP + case N32_GTIMERB2_BASE: + switch (channel) + { + #ifdef GPIO_GTIMB2_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMB2_ETR; + #endif + #ifdef GPIO_GTIMB2_CH1PIN + case 1: + return GPIO_GTIMB2_CH1PIN; + #endif + #ifdef GPIO_GTIMB2_CH2IN + case 2: + return GPIO_GTIMB2_CH2IN; + #endif + #ifdef GPIO_GTIMB2_CH3IN + case 3: + return GPIO_GTIMB2_CH3IN; + #endif + #ifdef GPIO_GTIMB2_CH4IN + case 4: + return GPIO_GTIMB2_CH4IN; + #endif + default: + break; + } + break; + #endif + #ifdef CONFIG_N32H7_GTIMB3_CAP + case N32_GTIMERB3_BASE: + switch (channel) + { + #ifdef GPIO_GTIMB3_ETR + case N32_CAP_CHANNEL_COUNTER: + return GPIO_GTIMB3_ETR; + #endif + #ifdef GPIO_GTIMB3_CH1PIN + case 1: + return GPIO_GTIMB3_CH1PIN; + #endif + #ifdef GPIO_GTIMB3_CH2IN + case 2: + return GPIO_GTIMB3_CH2IN; + #endif + #ifdef GPIO_GTIMB3_CH3IN + case 3: + return GPIO_GTIMB3_CH3IN; + #endif + #ifdef GPIO_GTIMB3_CH4IN + case 4: + return GPIO_GTIMB3_CH4IN; + #endif + default: + break; + } + break; + #endif + default: + break; + } + + return 0; +} + +/**************************************************************************** + * Name: n32_cap_set_rcc + ****************************************************************************/ + +static int n32_cap_set_rcc(const struct n32_cap_priv_s *priv, bool on) +{ + uint32_t reg = 0; + uint32_t bit = 0; + + switch (priv->base) + { + #ifdef CONFIG_N32H7_ATIM1_CAP + case N32_ATIMER1_BASE: + reg = N32_RCC_APB2EN1; + bit = RCC_APB2EN1_M7ATIM1EN; + break; + #endif + #ifdef CONFIG_N32H7_ATIM2_CAP + case N32_ATIMER2_BASE: + reg = N32_RCC_APB2EN1; + bit = RCC_APB2EN1_M7ATIM2EN; + break; + #endif + #ifdef CONFIG_N32H7_ATIM3_CAP + case N32_ATIMER3_BASE: + reg = N32_RCC_APB5EN1; + bit = RCC_APB5EN1_M7ATIM3EN; + break; + #endif + #ifdef CONFIG_N32H7_ATIM4_CAP + case N32_ATIMER4_BASE: + reg = N32_RCC_APB5EN1; + bit = RCC_APB5EN1_M7ATIM4EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA1_CAP + case N32_GTIMERA1_BASE: + reg = N32_RCC_APB2EN1; + bit = RCC_APB2EN1_M7GTIMA1EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA2_CAP + case N32_GTIMERA2_BASE: + reg = N32_RCC_APB2EN1; + bit = RCC_APB2EN1_M7GTIMA2EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA3_CAP + case N32_GTIMERA3_BASE: + reg = N32_RCC_APB2EN1; + bit = RCC_APB2EN1_M7GTIMA3EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA4_CAP + case N32_GTIMERA4_BASE: + reg = N32_RCC_APB1EN1; + bit = RCC_APB1EN1_M7GTIMA4EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA5_CAP + case N32_GTIMERA5_BASE: + reg = N32_RCC_APB1EN2; + bit = RCC_APB1EN2_M7GTIMA5EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA6_CAP + case N32_GTIMERA6_BASE: + reg = N32_RCC_APB1EN2; + bit = RCC_APB1EN2_M7GTIMA6EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA7_CAP + case N32_GTIMERA7_BASE: + reg = N32_RCC_APB1EN2; + bit = RCC_APB1EN2_M7GTIMA7EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMB1_CAP + case N32_GTIMERB1_BASE: + reg = N32_RCC_APB1EN1; + bit = RCC_APB1EN1_M7GTIMB1EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMB2_CAP + case N32_GTIMERB2_BASE: + reg = N32_RCC_APB1EN1; + bit = RCC_APB1EN1_M7GTIMB2EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMB3_CAP + case N32_GTIMERB3_BASE: + reg = N32_RCC_APB1EN1; + bit = RCC_APB1EN1_M7GTIMB3EN; + break; + #endif + default: + return -EINVAL; + } + + if (on) + { + modifyreg32(reg, 0, bit); + } + else + { + modifyreg32(reg, bit, 0); + } + + return OK; +} + +/**************************************************************************** + * Name: n32_cap_setsmc + ****************************************************************************/ + +static int n32_cap_setsmc(struct n32_cap_dev_s *dev, n32_cap_smc_cfg_t cfg) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + uint32_t regval = 0; + uint32_t mask = 0; + + switch (cfg & N32_ATIM_SMCTRL_SMSEL_MASK) + { + case N32_ATIM_SMCTRL_DISAB: + regval |= N32_ATIM_SMCTRL_DISAB; + break; + case N32_ATIM_SMCTRL_ENCMD1: + regval |= N32_ATIM_SMCTRL_ENCMD1; + break; + case N32_ATIM_SMCTRL_ENCMD2: + regval |= N32_ATIM_SMCTRL_ENCMD2; + break; + case N32_ATIM_SMCTRL_ENCMD3: + regval |= N32_ATIM_SMCTRL_ENCMD3; + break; + case N32_ATIM_SMCTRL_RESET: + regval |= N32_ATIM_SMCTRL_RESET; + break; + case N32_ATIM_SMCTRL_GATED: + regval |= N32_ATIM_SMCTRL_GATED; + break; + case N32_ATIM_SMCTRL_TRIGGER: + regval |= N32_ATIM_SMCTRL_TRIGGER; + break; + case N32_ATIM_SMCTRL_EXTCLK1: + regval |= N32_ATIM_SMCTRL_EXTCLK1; + break; + default: + break; + } + + switch (cfg & N32_ATIM_SMCTRL_TSEL_MASK) + { + case N32_ATIM_SMCTRL_ITR: + regval |= N32_ATIM_SMCTRL_ITR; + break; + case N32_ATIM_SMCTRL_TI1FED: + regval |= N32_ATIM_SMCTRL_TI1FED; + break; + case N32_ATIM_SMCTRL_TI1FP1: + regval |= N32_ATIM_SMCTRL_TI1FP1; + break; + case N32_ATIM_SMCTRL_TI2FP2: + regval |= N32_ATIM_SMCTRL_TI2FP2; + break; + case N32_ATIM_SMCTRL_ETRF: + regval |= N32_ATIM_SMCTRL_ETRF; + break; + default: + break; + } + + if (cfg & N32_ATIM_SMCTRL_MSMD) + { + regval |= N32_ATIM_SMCTRL_MSMD; + } + + mask = (uint32_t)(N32_ATIM_SMCTRL_SMSEL_MASK | N32_ATIM_SMCTRL_TSEL_MASK + | N32_ATIM_SMCTRL_MSMD); + n32_modifyreg32(priv, N32_ATIM_SMCTRL_OFFSET, mask, regval); + return OK; +} + +/**************************************************************************** + * Name: n32_cap_setclock + * + * Description: + * Set timer prescaler and auto-reload. 'freq' is the desired counting + * frequency (after prescaler), 'max' is the auto-reload value. + * Returns the actual prescaler value. + ****************************************************************************/ + +static int n32_cap_setclock(struct n32_cap_dev_s *dev, uint32_t freq, + uint32_t max) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + uint32_t freqin = priv->input_clock; + int prescaler; + + if (freq == 0) + { + /* Zero frequency means no prescaling, count at input clock */ + + prescaler = 0; + } + else + { + prescaler = freqin / freq; + if (prescaler > 0) + { + prescaler--; + } + + if (prescaler > 0xffff) + { + prescaler = 0xffff; + } + } + + n32_putreg32(priv, N32_ATIM_AR_OFFSET, max); + n32_putreg16(priv, N32_ATIM_PSC_OFFSET, prescaler); + n32_putreg16(priv, N32_ATIM_ETGEN_OFFSET, N32_ATIM_ETGEN_UDGN); + n32_modifyreg16(priv, N32_ATIM_CTRL1_OFFSET, 0, N32_ATIM_CTRL1_CNTEN); + return prescaler; +} + +/**************************************************************************** + * Name: n32_cap_setchannel + ****************************************************************************/ + +static int n32_cap_setchannel(struct n32_cap_dev_s *dev, uint8_t channel, + n32_cap_ch_cfg_t cfg) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + uint32_t gpio; + uint16_t mask; + uint16_t regval; + uint16_t ccer_en_bit; + + gpio = n32_cap_gpio(priv, channel); + if (!gpio) + { + return -EINVAL; + } + + channel--; + + switch (cfg & N32_CAP_EDGE_MASK) + { + case N32_CAP_EDGE_DISABLED: + regval = 0; + ccer_en_bit = 0; + break; + case N32_CAP_EDGE_RISING: + ccer_en_bit = N32_ATIM_CCEN_CC1EN; + regval = 0; + break; + case N32_CAP_EDGE_FALLING: + ccer_en_bit = N32_ATIM_CCEN_CC1EN; + regval = N32_ATIM_CCEN_CC1P; + break; + case N32_CAP_EDGE_BOTH: + ccer_en_bit = N32_ATIM_CCEN_CC1EN; + regval = N32_ATIM_CCEN_CC1P | N32_ATIM_CCEN_CC1NP; + break; + default: + return -EINVAL; + } + + mask = (N32_ATIM_CCEN_CC1EN | N32_ATIM_CCEN_CC1P | N32_ATIM_CCEN_CC1NP); + mask <<= (channel * 4); + regval <<= (channel * 4); + ccer_en_bit <<= (channel * 4); + + n32_modifyreg16(priv, N32_ATIM_CCEN_OFFSET, mask, regval); + + regval = cfg; + mask = (N32_ATIM_CCMOD1_IC1F_MASK | + N32_ATIM_CCMOD1_IC1PSC_MASK | + N32_ATIM_CCMOD1_CC1SEL_MASK); + regval &= mask; + if (channel & 1) + { + regval <<= 8; + mask <<= 8; + } + + if (channel < 2) + { + n32_modifyreg16(priv, N32_ATIM_CCMOD1_OFFSET, mask, regval); + } + else + { + n32_modifyreg16(priv, N32_ATIM_CCMOD2_OFFSET, mask, regval); + } + + if ((cfg & N32_CAP_EDGE_MASK) == N32_CAP_EDGE_DISABLED) + { + n32_unconfiggpio(gpio); + } + else + { + n32_configgpio(gpio); + } + + n32_modifyreg16(priv, N32_ATIM_CCEN_OFFSET, 0, ccer_en_bit); + return OK; +} + +/**************************************************************************** + * Name: n32_cap_getcapture + ****************************************************************************/ + +static uint32_t n32_cap_getcapture(struct n32_cap_dev_s *dev, + uint8_t channel) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + uint8_t offset; + + switch (channel) + { + case N32_CAP_CHANNEL_COUNTER: + offset = N32_ATIM_CNT_OFFSET; + break; + case 1: + offset = N32_ATIM_CCDAT1_OFFSET; + break; + case 2: + offset = N32_ATIM_CCDAT2_OFFSET; + break; + case 3: + offset = N32_ATIM_CCDAT3_OFFSET; + break; + case 4: + offset = N32_ATIM_CCDAT4_OFFSET; + break; + default: + return 0; + } + + /* All N32 timers here are 16-bit */ + + return n32_getreg16(priv, offset); +} + +/**************************************************************************** + * Name: n32_cap_getedges + ****************************************************************************/ + +static uint32_t n32_cap_getedges(struct n32_cap_dev_s *dev, uint8_t channel) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + uint16_t ccer; + uint8_t shift; + + DEBUGASSERT(dev != NULL && channel >= 1 && channel <= 4); + + shift = (channel - 1) * 4; + ccer = n32_getreg16(priv, N32_ATIM_CCEN_OFFSET); + ccer = (ccer >> shift) & (N32_ATIM_CCEN_CC1P | N32_ATIM_CCEN_CC1NP); + + switch (ccer) + { + case 0: /* Rising edge */ + return (uint32_t)N32_CAP_EDGE_RISING; + case N32_ATIM_CCEN_CC1P: /* Falling edge */ + return (uint32_t)N32_CAP_EDGE_FALLING; + case (N32_ATIM_CCEN_CC1P | N32_ATIM_CCEN_CC1NP): /* Both edges */ + return (uint32_t)N32_CAP_EDGE_BOTH; + default: + return (uint32_t)N32_CAP_EDGE_DISABLED; + } +} + +/**************************************************************************** + * Name: n32_cap_setisr + ****************************************************************************/ + +static int n32_cap_setisr(struct n32_cap_dev_s *dev, xcpt_t handler, + void *arg) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + + if (!handler) + { + up_disable_irq(priv->irq); + irq_detach(priv->irq); + if (priv->irq_of) + { + up_disable_irq(priv->irq_of); + irq_detach(priv->irq_of); + } + + return OK; + } + + irq_attach(priv->irq, handler, arg); + up_enable_irq(priv->irq); + if (priv->irq_of) + { + irq_attach(priv->irq_of, handler, arg); + up_enable_irq(priv->irq_of); + } + + return OK; +} + +/**************************************************************************** + * Name: n32_cap_enableint + ****************************************************************************/ + +static void n32_cap_enableint(struct n32_cap_dev_s *dev, n32_cap_flags_t src, + bool on) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + uint32_t mask = 0; + + if (src & N32_CAP_FLAG_IRQ_COUNTER) + { + mask |= N32_ATIM_DINTEN_UIEN; + } + + if (src & N32_CAP_FLAG_IRQ_CH_1) + { + mask |= N32_ATIM_DINTEN_CC1IEN; + } + + if (src & N32_CAP_FLAG_IRQ_CH_2) + { + mask |= N32_ATIM_DINTEN_CC2IEN; + } + + if (src & N32_CAP_FLAG_IRQ_CH_3) + { + mask |= N32_ATIM_DINTEN_CC3IEN; + } + + if (src & N32_CAP_FLAG_IRQ_CH_4) + { + mask |= N32_ATIM_DINTEN_CC4IEN; + } + + if (on) + { + n32_modifyreg32(priv, N32_ATIM_DINTEN_OFFSET, 0, mask); + } + else + { + n32_modifyreg32(priv, N32_ATIM_DINTEN_OFFSET, mask, 0); + } +} + +/**************************************************************************** + * Name: n32_cap_ackflags + ****************************************************************************/ + +static void n32_cap_ackflags(struct n32_cap_dev_s *dev, int flags) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + uint32_t mask = 0; + + /* Clear by writing 0 to the corresponding bits */ + + if (flags & N32_CAP_FLAG_IRQ_COUNTER) + { + mask |= N32_ATIM_STS_UDITF; + } + + if (flags & N32_CAP_FLAG_IRQ_CH_1) + { + mask |= N32_ATIM_STS_CC1ITF; + } + + if (flags & N32_CAP_FLAG_IRQ_CH_2) + { + mask |= N32_ATIM_STS_CC2ITF; + } + + if (flags & N32_CAP_FLAG_IRQ_CH_3) + { + mask |= N32_ATIM_STS_CC3ITF; + } + + if (flags & N32_CAP_FLAG_IRQ_CH_4) + { + mask |= N32_ATIM_STS_CC4ITF; + } + + if (flags & N32_CAP_FLAG_OF_CH_1) + { + mask |= N32_ATIM_STS_CC1OCF; + } + + if (flags & N32_CAP_FLAG_OF_CH_2) + { + mask |= N32_ATIM_STS_CC2OCF; + } + + if (flags & N32_CAP_FLAG_OF_CH_3) + { + mask |= N32_ATIM_STS_CC3OCF; + } + + if (flags & N32_CAP_FLAG_OF_CH_4) + { + mask |= N32_ATIM_STS_CC4OCF; + } + + n32_putreg32(priv, N32_ATIM_STS_OFFSET, ~mask); +} + +/**************************************************************************** + * Name: n32_cap_getflags + ****************************************************************************/ + +static n32_cap_flags_t n32_cap_getflags(struct n32_cap_dev_s *dev) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + uint32_t regval = n32_getreg32(priv, N32_ATIM_STS_OFFSET); + n32_cap_flags_t flags = 0; + + if (regval & N32_ATIM_STS_UDITF) + { + flags |= N32_CAP_FLAG_IRQ_COUNTER; + } + + if (regval & N32_ATIM_STS_CC1ITF) + { + flags |= N32_CAP_FLAG_IRQ_CH_1; + } + + if (regval & N32_ATIM_STS_CC2ITF) + { + flags |= N32_CAP_FLAG_IRQ_CH_2; + } + + if (regval & N32_ATIM_STS_CC3ITF) + { + flags |= N32_CAP_FLAG_IRQ_CH_3; + } + + if (regval & N32_ATIM_STS_CC4ITF) + { + flags |= N32_CAP_FLAG_IRQ_CH_4; + } + + if (regval & N32_ATIM_STS_CC1OCF) + { + flags |= N32_CAP_FLAG_OF_CH_1; + } + + if (regval & N32_ATIM_STS_CC2OCF) + { + flags |= N32_CAP_FLAG_OF_CH_2; + } + + if (regval & N32_ATIM_STS_CC3OCF) + { + flags |= N32_CAP_FLAG_OF_CH_3; + } + + if (regval & N32_ATIM_STS_CC4OCF) + { + flags |= N32_CAP_FLAG_OF_CH_4; + } + + return flags; +} + +/**************************************************************************** + * Name: n32_cap_get_priv (generated) + ****************************************************************************/ + +static inline const struct n32_cap_priv_s * n32_cap_get_priv(int timer) +{ + switch (timer) + { + #ifdef CONFIG_N32H7_ATIM1_CAP + case 1: + return &n32_atim1_priv; + #endif + #ifdef CONFIG_N32H7_ATIM2_CAP + case 2: + return &n32_atim2_priv; + #endif + #ifdef CONFIG_N32H7_GTIMA1_CAP + case 3: + return &n32_gtima1_priv; + #endif + #ifdef CONFIG_N32H7_GTIMA2_CAP + case 4: + return &n32_gtima2_priv; + #endif + #ifdef CONFIG_N32H7_GTIMA3_CAP + case 5: + return &n32_gtima3_priv; + #endif + #ifdef CONFIG_N32H7_ATIM3_CAP + case 6: + return &n32_atim3_priv; + #endif + #ifdef CONFIG_N32H7_ATIM4_CAP + case 7: + return &n32_atim4_priv; + #endif + #ifdef CONFIG_N32H7_GTIMA4_CAP + case 8: + return &n32_gtima4_priv; + #endif + #ifdef CONFIG_N32H7_GTIMA5_CAP + case 9: + return &n32_gtima5_priv; + #endif + #ifdef CONFIG_N32H7_GTIMA6_CAP + case 10: + return &n32_gtima6_priv; + #endif + #ifdef CONFIG_N32H7_GTIMA7_CAP + case 11: + return &n32_gtima7_priv; + #endif + #ifdef CONFIG_N32H7_GTIMB1_CAP + case 12: + return &n32_gtimb1_priv; + #endif + #ifdef CONFIG_N32H7_GTIMB2_CAP + case 13: + return &n32_gtimb2_priv; + #endif + #ifdef CONFIG_N32H7_GTIMB3_CAP + case 14: + return &n32_gtimb3_priv; + #endif + default: + return NULL; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +struct n32_cap_dev_s *n32_cap_init(int timer) +{ + const struct n32_cap_priv_s *priv = n32_cap_get_priv(timer); + uint32_t gpio; + + if (priv) + { + n32_cap_set_rcc(priv, true); + gpio = n32_cap_gpio(priv, -1); + if (gpio) + { + n32_configgpio(gpio); + } + + n32_modifyreg16(priv, N32_ATIM_CTRL1_OFFSET, N32_ATIM_CTRL1_CNTEN, 0); + } + + return (struct n32_cap_dev_s *)priv; +} + +int n32_cap_deinit(struct n32_cap_dev_s *dev) +{ + const struct n32_cap_priv_s *priv = (const struct n32_cap_priv_s *)dev; + uint32_t gpio; + + if (!priv) + { + return -EINVAL; + } + + n32_modifyreg16(priv, N32_ATIM_CTRL1_OFFSET, N32_ATIM_CTRL1_CNTEN, 0); + gpio = n32_cap_gpio(priv, -1); + if (gpio) + { + n32_unconfiggpio(gpio); + } + + n32_cap_set_rcc(priv, false); + return OK; +} + +#endif /* CONFIG_N32H7_CAPTURE */ diff --git a/arch/arm/src/n32h7/n32_capture.h b/arch/arm/src/n32h7/n32_capture.h new file mode 100644 index 0000000000000..e40260ae3a78c --- /dev/null +++ b/arch/arm/src/n32h7/n32_capture.h @@ -0,0 +1,108 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_capture.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_CAPTURE_H +#define __ARCH_ARM_SRC_N32H7_N32_CAPTURE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" +#include +#include "hardware/n32h7_tim.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define N32_CAP_SETSMC(d,cfg) ((d)->ops->setsmc(d,cfg)) +#define N32_CAP_SETCLOCK(d,clk,max) ((d)->ops->setclock(d,clk,max)) +#define N32_CAP_SETCHANNEL(d,ch,cfg) ((d)->ops->setchannel(d,ch,cfg)) +#define N32_CAP_GETCAPTURE(d,ch) ((d)->ops->getcapture(d,ch)) +#define N32_CAP_GETEDGES(d,ch) ((d)->ops->getedges(d,ch)) +#define N32_CAP_SETISR(d,hnd,arg) ((d)->ops->setisr(d,hnd,arg)) +#define N32_CAP_ENABLEINT(d,s,on) ((d)->ops->enableint(d,s,on)) +#define N32_CAP_ACKFLAGS(d,f) ((d)->ops->ackflags(d,f)) +#define N32_CAP_GETFLAGS(d) ((d)->ops->getflags(d)) + +#define N32_CAP_EDGE_MASK (3 << 8) +#define N32_CAP_EDGE_DISABLED (0 << 8) +#define N32_CAP_EDGE_RISING (1 << 8) +#define N32_CAP_EDGE_FALLING (2 << 8) +#define N32_CAP_EDGE_BOTH (3 << 8) + +/* Flags */ +#define N32_CAP_FLAG_IRQ_COUNTER (N32_ATIM_STS_UDITF) +#define N32_CAP_FLAG_IRQ_CH_1 (N32_ATIM_STS_CC1ITF) +#define N32_CAP_FLAG_IRQ_CH_2 (N32_ATIM_STS_CC2ITF) +#define N32_CAP_FLAG_IRQ_CH_3 (N32_ATIM_STS_CC3ITF) +#define N32_CAP_FLAG_IRQ_CH_4 (N32_ATIM_STS_CC4ITF) +#define N32_CAP_FLAG_OF_CH_1 (N32_ATIM_STS_CC1OCF) +#define N32_CAP_FLAG_OF_CH_2 (N32_ATIM_STS_CC2OCF) +#define N32_CAP_FLAG_OF_CH_3 (N32_ATIM_STS_CC3OCF) +#define N32_CAP_FLAG_OF_CH_4 (N32_ATIM_STS_CC4OCF) + +#define N32_CAP_FLAG_IRQ_CH(ch) (N32_ATIM_STS_CC1ITF << ((ch)-1)) +#define N32_CAP_FLAG_OF_CH(ch) (N32_ATIM_STS_CC1OCF << ((ch)-1)) +#define N32_CAP_CHANNEL_COUNTER 0 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef uint16_t n32_cap_ch_cfg_t; +typedef uint32_t n32_cap_smc_cfg_t; +typedef uint32_t n32_cap_flags_t; + +struct n32_cap_dev_s +{ + const struct n32_cap_ops_s *ops; +}; + +struct n32_cap_ops_s +{ + int (*setsmc)(struct n32_cap_dev_s *dev, n32_cap_smc_cfg_t cfg); + int (*setclock)(struct n32_cap_dev_s *dev, uint32_t freq, uint32_t max); + int (*setchannel)(struct n32_cap_dev_s *dev, uint8_t channel, + n32_cap_ch_cfg_t cfg); + uint32_t (*getcapture)(struct n32_cap_dev_s *dev, uint8_t channel); + uint32_t (*getedges)(struct n32_cap_dev_s *dev, uint8_t channel); + int (*setisr)(struct n32_cap_dev_s *dev, xcpt_t handler, void *arg); + void (*enableint)(struct n32_cap_dev_s *dev, n32_cap_flags_t src, bool on); + void (*ackflags)(struct n32_cap_dev_s *dev, int flags); + n32_cap_flags_t (*getflags)(struct n32_cap_dev_s *dev); +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct n32_cap_dev_s *n32_cap_init(int timer); +int n32_cap_deinit(struct n32_cap_dev_s *dev); + +#ifdef CONFIG_CAPTURE +struct cap_lowerhalf_s *n32_cap_initialize(int timer); +#endif + +#endif /* __ARCH_ARM_SRC_N32H7_N32_CAPTURE_H */ diff --git a/arch/arm/src/n32h7/n32_capture_lowerhalf.c b/arch/arm/src/n32h7/n32_capture_lowerhalf.c new file mode 100644 index 0000000000000..f53c4ec0ed51d --- /dev/null +++ b/arch/arm/src/n32h7/n32_capture_lowerhalf.c @@ -0,0 +1,589 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_capture_lowerhalf.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "n32_capture.h" + +#ifdef CONFIG_CAPTURE + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct n32_lowerhalf_s +{ + const struct cap_ops_s *ops; + struct n32_cap_dev_s *cap; + bool started; + uint8_t resolution; + uint8_t channel; + uint32_t clock; + uint8_t duty; + uint32_t freq; + uint32_t edges; + uint32_t overflow; + uint32_t tmp_duty; + +#ifdef CONFIG_CAPTURE_NOTIFY + capture_notify_t cb; /* Edge notification callback */ + void *priv; /* Private data of the callback */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int n32_cap_handler(int irq, void *context, void *arg); +static int n32_start(struct cap_lowerhalf_s *lower); +static int n32_stop(struct cap_lowerhalf_s *lower); +static int n32_getduty(struct cap_lowerhalf_s *lower, uint8_t *duty); +static int n32_getfreq(struct cap_lowerhalf_s *lower, uint32_t *freq); +static int n32_getedges(struct cap_lowerhalf_s *lower, uint32_t *edges); +static int n32_ioctl(struct cap_lowerhalf_s *lower, int cmd, + unsigned long arg); +#ifdef CONFIG_CAPTURE_NOTIFY +static int n32_bind(struct cap_lowerhalf_s *lower, enum cap_type_e type, + capture_notify_t cb, void *priv); +static int n32_unbind(struct cap_lowerhalf_s *lower); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct cap_ops_s g_cap_ops = +{ + .start = n32_start, + .stop = n32_stop, + .getduty = n32_getduty, + .getfreq = n32_getfreq, + .getedges = n32_getedges, + .ioctl = n32_ioctl, +#ifdef CONFIG_CAPTURE_NOTIFY + .bind = n32_bind, + .unbind = n32_unbind, +#endif +}; + +#ifdef CONFIG_N32H7_ATIM1_CAP +static struct n32_lowerhalf_s g_cap1_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_ATIM1_CHANNEL, + .clock = CONFIG_N32H7_ATIM1_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM2_CAP +static struct n32_lowerhalf_s g_cap2_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_ATIM2_CHANNEL, + .clock = CONFIG_N32H7_ATIM2_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA1_CAP +static struct n32_lowerhalf_s g_cap3_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMA1_CHANNEL, + .clock = CONFIG_N32H7_GTIMA1_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA2_CAP +static struct n32_lowerhalf_s g_cap4_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMA2_CHANNEL, + .clock = CONFIG_N32H7_GTIMA2_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA3_CAP +static struct n32_lowerhalf_s g_cap5_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMA3_CHANNEL, + .clock = CONFIG_N32H7_GTIMA3_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM3_CAP +static struct n32_lowerhalf_s g_cap6_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_ATIM3_CHANNEL, + .clock = CONFIG_N32H7_ATIM3_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM4_CAP +static struct n32_lowerhalf_s g_cap7_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_ATIM4_CHANNEL, + .clock = CONFIG_N32H7_ATIM4_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA4_CAP +static struct n32_lowerhalf_s g_cap8_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMA4_CHANNEL, + .clock = CONFIG_N32H7_GTIMA4_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA5_CAP +static struct n32_lowerhalf_s g_cap9_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMA5_CHANNEL, + .clock = CONFIG_N32H7_GTIMA5_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA6_CAP +static struct n32_lowerhalf_s g_cap10_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMA6_CHANNEL, + .clock = CONFIG_N32H7_GTIMA6_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA7_CAP +static struct n32_lowerhalf_s g_cap11_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMA7_CHANNEL, + .clock = CONFIG_N32H7_GTIMA7_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB1_CAP +static struct n32_lowerhalf_s g_cap12_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMB1_CHANNEL, + .clock = CONFIG_N32H7_GTIMB1_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB2_CAP +static struct n32_lowerhalf_s g_cap13_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMB2_CHANNEL, + .clock = CONFIG_N32H7_GTIMB2_CLOCK, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB3_CAP +static struct n32_lowerhalf_s g_cap14_lowerhalf = +{ + .ops = &g_cap_ops, + .resolution = 16, + .channel = CONFIG_N32H7_GTIMB3_CHANNEL, + .clock = CONFIG_N32H7_GTIMB3_CLOCK, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int n32_cap_handler(int irq, void *context, void *arg) +{ + struct n32_lowerhalf_s *lower = (struct n32_lowerhalf_s *)arg; + uint8_t ch = 0x3 & lower->channel; + uint32_t period = 0; + int flags = 0; + + flags = (int)N32_CAP_GETFLAGS(lower->cap); + N32_CAP_ACKFLAGS(lower->cap, flags); + + if (flags & (N32_CAP_FLAG_IRQ_CH_1 << (ch - 1))) + { + period = N32_CAP_GETCAPTURE(lower->cap, ch) + + lower->overflow * (1 << lower->resolution) + 1; + if (period != 0) + { + lower->duty = (100 * lower->tmp_duty) / period; + lower->freq = lower->clock / period; + lower->edges++; + lower->overflow = 0; + lower->tmp_duty = 0; +#ifdef CONFIG_CAPTURE_NOTIFY + if (lower->cb != NULL) + { + lower->cb((struct cap_lowerhalf_s *)lower, lower->priv); + } +#endif + } + } + else if (flags & (N32_CAP_FLAG_IRQ_CH_2 << (2 - ch))) + { + lower->tmp_duty = N32_CAP_GETCAPTURE(lower->cap, 0x3 & (~ch)) + + lower->overflow * (1 << lower->resolution) + 1; + } + else if (flags & N32_CAP_FLAG_IRQ_COUNTER) + { + lower->overflow++; + } + + return OK; +} + +static int n32_start(struct cap_lowerhalf_s *lower) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + int flags = 0; + uint32_t maxtimeout = (1 << priv->resolution) - 1; + + if (priv->started) + { + return -EBUSY; + } + + switch (priv->channel) + { + case 1: + N32_CAP_SETSMC(priv->cap, (n32_cap_smc_cfg_t)(N32_ATIM_SMCTRL_RESET | + N32_ATIM_SMCTRL_TI1FP1 | + N32_ATIM_SMCTRL_MSMD)); + N32_CAP_SETCLOCK(priv->cap, priv->clock, maxtimeout); + N32_CAP_SETCHANNEL(priv->cap, 1, (n32_cap_ch_cfg_t) + (N32_CAP_EDGE_RISING | N32_ATIM_CCMOD1_CC1IN_TI1)); + N32_CAP_SETCHANNEL(priv->cap, 2, (n32_cap_ch_cfg_t) + (N32_CAP_EDGE_FALLING | N32_ATIM_CCMOD1_CC1IN_TI2)); + flags = (int)N32_CAP_GETFLAGS(priv->cap); + N32_CAP_ACKFLAGS(priv->cap, flags); + N32_CAP_SETISR(priv->cap, n32_cap_handler, priv); + N32_CAP_ENABLEINT(priv->cap, (n32_cap_flags_t) + (N32_CAP_FLAG_IRQ_CH_1 | N32_CAP_FLAG_IRQ_CH_2 | + N32_CAP_FLAG_IRQ_COUNTER), true); + priv->started = true; + break; + case 2: + N32_CAP_SETSMC(priv->cap, (n32_cap_smc_cfg_t)(N32_ATIM_SMCTRL_RESET | + N32_ATIM_SMCTRL_TI2FP2 | + N32_ATIM_SMCTRL_MSMD)); + N32_CAP_SETCLOCK(priv->cap, priv->clock, maxtimeout); + N32_CAP_SETCHANNEL(priv->cap, 2, (n32_cap_ch_cfg_t) + (N32_CAP_EDGE_RISING | N32_ATIM_CCMOD1_CC1IN_TI1)); + N32_CAP_SETCHANNEL(priv->cap, 1, (n32_cap_ch_cfg_t) + (N32_CAP_EDGE_FALLING | N32_ATIM_CCMOD1_CC1IN_TI2)); + flags = (int)N32_CAP_GETFLAGS(priv->cap); + N32_CAP_ACKFLAGS(priv->cap, flags); + N32_CAP_SETISR(priv->cap, n32_cap_handler, priv); + N32_CAP_ENABLEINT(priv->cap, (n32_cap_flags_t) + (N32_CAP_FLAG_IRQ_CH_2 | N32_CAP_FLAG_IRQ_CH_1 | + N32_CAP_FLAG_IRQ_COUNTER), true); + priv->started = true; + break; + default: + return -EINVAL; + } + + /* The actual frequency is priv->clock (as set by SETCLOCK) */ + + return OK; +} + +static int n32_stop(struct cap_lowerhalf_s *lower) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + int flags = 0; + + if (!priv->started) + { + return -ENODEV; + } + + N32_CAP_SETSMC(priv->cap, 0); + N32_CAP_SETCLOCK(priv->cap, 0, 0); + N32_CAP_SETCHANNEL(priv->cap, 1, N32_CAP_EDGE_DISABLED); + N32_CAP_SETCHANNEL(priv->cap, 2, N32_CAP_EDGE_DISABLED); + N32_CAP_ENABLEINT(priv->cap, N32_CAP_FLAG_IRQ_CH_1 | + N32_CAP_FLAG_IRQ_CH_2 | + N32_CAP_FLAG_IRQ_COUNTER, false); + + flags = (int)N32_CAP_GETFLAGS(priv->cap); + N32_CAP_ACKFLAGS(priv->cap, flags); + N32_CAP_SETISR(priv->cap, NULL, NULL); + priv->started = false; + priv->duty = 0; + priv->freq = 0; + priv->edges = 0; + priv->overflow = 0; + priv->tmp_duty = 0; + + return OK; +} + +static int n32_getduty(struct cap_lowerhalf_s *lower, uint8_t *duty) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + irqstate_t flags = enter_critical_section(); + + *duty = priv->duty; + + leave_critical_section(flags); + return OK; +} + +static int n32_getfreq(struct cap_lowerhalf_s *lower, uint32_t *freq) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + irqstate_t flags = enter_critical_section(); + + *freq = priv->freq; + + leave_critical_section(flags); + return OK; +} + +static int n32_getedges(struct cap_lowerhalf_s *lower, uint32_t *edges) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + irqstate_t flags = enter_critical_section(); + + *edges = priv->edges; + + leave_critical_section(flags); + return OK; +} + +static int n32_ioctl(struct cap_lowerhalf_s *lower, int cmd, + unsigned long arg) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + irqstate_t flags = enter_critical_section(); + + switch (cmd) + { + case CAPIOC_CLR_CNT: + priv->edges = 0; + priv->overflow = 0; + break; + case CAPIOC_PULSES: + { + int *count = (int *)((uintptr_t)arg); + + DEBUGASSERT(count != NULL); + *count = (int)priv->edges; + } + + break; + default: + return -EINVAL; + } + + leave_critical_section(flags); + return OK; +} + +#ifdef CONFIG_CAPTURE_NOTIFY +static int n32_bind(struct cap_lowerhalf_s *lower, enum cap_type_e type, + capture_notify_t cb, void *priv) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + irqstate_t flags; + + /* Only the rising edge of channel 0 is reported: it is the edge that + * completes the measurement of a period. + */ + + if (type != CAP_TYPE_RISING) + { + return -ENOSYS; + } + + flags = enter_critical_section(); + priv->cb = cb; + priv->priv = priv; + leave_critical_section(flags); + + return OK; +} + +static int n32_unbind(struct cap_lowerhalf_s *lower) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + irqstate_t flags; + + flags = enter_critical_section(); + priv->cb = NULL; + priv->priv = NULL; + leave_critical_section(flags); + + return OK; +} +#endif /* CONFIG_CAPTURE_NOTIFY */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_cap_initialize + * + * Description: + * Initialize one timer for use with the upper_level capture driver. + * + * Input Parameters: + * timer - A number identifying the timer use. The number of valid timer + * IDs varies with the N32 MCU and MCU family but is somewhere in + * the range of {1,..,5 8,...,14}. + * + * Returned Value: + * On success, a pointer to the N32 lower half capture driver returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +struct cap_lowerhalf_s *n32_cap_initialize(int timer) +{ + struct n32_lowerhalf_s *lower = NULL; + + switch (timer) + { + #ifdef CONFIG_N32H7_ATIM1_CAP + case 1: + lower = &g_cap1_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_ATIM2_CAP + case 2: + lower = &g_cap2_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA1_CAP + case 3: + lower = &g_cap3_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA2_CAP + case 4: + lower = &g_cap4_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA3_CAP + case 5: + lower = &g_cap5_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_ATIM3_CAP + case 6: + lower = &g_cap6_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_ATIM4_CAP + case 7: + lower = &g_cap7_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA4_CAP + case 8: + lower = &g_cap8_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA5_CAP + case 9: + lower = &g_cap9_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA6_CAP + case 10: + lower = &g_cap10_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA7_CAP + case 11: + lower = &g_cap11_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMB1_CAP + case 12: + lower = &g_cap12_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMB2_CAP + case 13: + lower = &g_cap13_lowerhalf; + break; + #endif + #ifdef CONFIG_N32H7_GTIMB3_CAP + case 14: + lower = &g_cap14_lowerhalf; + break; + #endif + default: + { + lower = NULL; + goto errout; + } + } + + /* Initialize the elements of lower half state structure */ + + lower->started = false; + lower->cap = n32_cap_init(timer); + + if (lower->cap == NULL) + { + lower = NULL; + } + +errout: + return (struct cap_lowerhalf_s *)lower; +} +#endif /* CONFIG_CAPTURE */ diff --git a/arch/arm/src/n32h7/n32_cordic.c b/arch/arm/src/n32h7/n32_cordic.c new file mode 100644 index 0000000000000..d0e3b320a6417 --- /dev/null +++ b/arch/arm/src/n32h7/n32_cordic.c @@ -0,0 +1,315 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_cordic.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "arm_internal.h" +#include "chip.h" +#include "hardware/n32h7_cordic.h" +#include "n32_cordic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Fixed precision (iterations = PRECISION * 4) */ +#define N32_CORDIC_PRECISION (6) + +/* Use 32-bit Q1.31 format for input/output */ +#define N32_CORDIC_INSIZE (0) /* 32-bit */ +#define N32_CORDIC_OUTSIZE (0) /* 32-bit */ +#define N32_CORDIC_FLOATIN (0) /* Fixed point */ +#define N32_CORDIC_FLOATOUT (0) /* Fixed point */ +#define N32_CORDIC_PHASELIMIT (0) /* Disable phase limit */ +#define N32_CORDIC_CODINLIMIT (0) /* Disable coordinate limit */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct n32_cordic_s +{ + const struct cordic_ops_s *ops; /* Lower half operations */ + uint32_t base; /* Base address of the CORDIC */ + bool inuse; /* True: driver is in-use */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static uint32_t cordic_getreg(struct n32_cordic_s *priv, int offset); +static void cordic_putreg(struct n32_cordic_s *priv, int offset, + uint32_t value); +static int cordic_calc(struct cordic_lowerhalf_s *lower, + struct cordic_calc_s *calc); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct cordic_ops_s g_n32_cordic_ops = +{ + .calc = cordic_calc, +}; + +static struct n32_cordic_s g_n32_cordic_dev = +{ + .ops = &g_n32_cordic_ops, + .base = N32_CORDIC_BASE, + .inuse = false, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cordic_getreg + ****************************************************************************/ + +static uint32_t cordic_getreg(struct n32_cordic_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: cordic_putreg + ****************************************************************************/ + +static void cordic_putreg(struct n32_cordic_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: cordic_calc + ****************************************************************************/ + +static int cordic_calc(struct cordic_lowerhalf_s *lower, + struct cordic_calc_s *calc) +{ + struct n32_cordic_s *priv = (struct n32_cordic_s *)lower; + int ret = OK; + uint32_t ctrl = 0; + bool arg2_inc = false; + uint8_t scale = 0; + + DEBUGASSERT(lower && calc); + + /* Select function and determine number of arguments and scale factor */ + + switch (calc->func) + { + case CORDIC_CALC_FUNC_COS: + ctrl |= CORDIC_CTRLSTS_FUNC_COS; + arg2_inc = true; + scale = 0; + break; + + case CORDIC_CALC_FUNC_SIN: + ctrl |= CORDIC_CTRLSTS_FUNC_SIN; + arg2_inc = true; + scale = 0; + break; + + case CORDIC_CALC_FUNC_PHASE: + ctrl |= CORDIC_CTRLSTS_FUNC_PHASE; + arg2_inc = true; + scale = 0; + break; + + case CORDIC_CALC_FUNC_MOD: + ctrl |= CORDIC_CTRLSTS_FUNC_MODULUS; + arg2_inc = true; + scale = 0; + break; + + case CORDIC_CALC_FUNC_ARCTAN: + ctrl |= CORDIC_CTRLSTS_FUNC_ARCTAN; + arg2_inc = true; + scale = 0; + break; + + case CORDIC_CALC_FUNC_HCOS: + ctrl |= CORDIC_CTRLSTS_FUNC_HB_COS; + arg2_inc = false; + scale = 1; + break; + + case CORDIC_CALC_FUNC_HSIN: + ctrl |= CORDIC_CTRLSTS_FUNC_HB_SIN; + arg2_inc = false; + scale = 1; + break; + + case CORDIC_CALC_FUNC_HARCTAN: + ctrl |= CORDIC_CTRLSTS_FUNC_HB_ARCT; + arg2_inc = false; + scale = 1; + break; + + case CORDIC_CALC_FUNC_LN: + ctrl |= CORDIC_CTRLSTS_FUNC_NATL; + arg2_inc = false; + scale = 1; + break; + + case CORDIC_CALC_FUNC_SQRT: + ctrl |= CORDIC_CTRLSTS_FUNC_SQRT; + arg2_inc = false; + scale = 1; + break; + + default: + ret = -EINVAL; + goto errout; + } + + /* Set precision (iteration count = PRECISION * 4) */ + + ctrl |= ((N32_CORDIC_PRECISION << CORDIC_CTRLSTS_PRECISION_SHIFT) & + CORDIC_CTRLSTS_PRECISION_MASK); + + /* Set scale factor */ + + ctrl |= ((scale << CORDIC_CTRLSTS_SCALE_SHIFT) & + CORDIC_CTRLSTS_SCALE_MASK); + + /* Input/output width: fixed 32-bit */ + + if (N32_CORDIC_INSIZE) + { + ctrl |= CORDIC_CTRLSTS_INSIZE; + } + + if (N32_CORDIC_OUTSIZE) + { + ctrl |= CORDIC_CTRLSTS_OUTSIZE; + } + + /* Floating point disabled (Q31) */ + + if (N32_CORDIC_FLOATIN) + { + ctrl |= CORDIC_CTRLSTS_FLOATIN; + } + + if (N32_CORDIC_FLOATOUT) + { + ctrl |= CORDIC_CTRLSTS_FLOATOUT; + } + + /* Limit controls disabled */ + + if (N32_CORDIC_PHASELIMIT) + { + ctrl |= CORDIC_CTRLSTS_PHASELIMIT; + } + + if (N32_CORDIC_CODINLIMIT) + { + ctrl |= CORDIC_CTRLSTS_CODINLIMIT; + } + + /* Number of arguments */ + + if (arg2_inc) + { + ctrl |= CORDIC_CTRLSTS_NUMWRITE; + } + + /* Number of results */ + + if (calc->res2_incl) + { + ctrl |= CORDIC_CTRLSTS_NUMREAD; + } + + /* Disable interrupts and DMA */ + + /* (INTEN, DMAREN, DMAWEN remain 0) */ + + /* Write control register */ + + cordic_putreg(priv, N32_CORDIC_CTRLSTS_OFFSET, ctrl); + + /* Write arguments */ + + cordic_putreg(priv, N32_CORDIC_WDATA_OFFSET, calc->arg1); + if (arg2_inc) + { + cordic_putreg(priv, N32_CORDIC_WDATA_OFFSET, calc->arg2); + } + + /* Read results. Hardware inserts wait states if RRF is not set. */ + + calc->res1 = cordic_getreg(priv, N32_CORDIC_RDATA_OFFSET); + if (calc->res2_incl) + { + calc->res2 = cordic_getreg(priv, N32_CORDIC_RDATA_OFFSET); + } + else + { + calc->res2 = 0; + } + +errout: + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_cordicinitialize + ****************************************************************************/ + +struct cordic_lowerhalf_s *n32_cordicinitialize(void) +{ + struct cordic_lowerhalf_s *lower = NULL; + + if (g_n32_cordic_dev.inuse) + { + _err("N32 CORDIC already in use\n"); + set_errno(EBUSY); + goto errout; + } + + lower = (struct cordic_lowerhalf_s *)&g_n32_cordic_dev; + g_n32_cordic_dev.inuse = true; + +errout: + return lower; +} diff --git a/arch/arm/src/n32h7/n32_cordic.h b/arch/arm/src/n32h7/n32_cordic.h new file mode 100644 index 0000000000000..cf8444c393cf1 --- /dev/null +++ b/arch/arm/src/n32h7/n32_cordic.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_cordic.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32_N32_CORDIC_H +#define __ARCH_ARM_SRC_N32_N32_CORDIC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/n32h7_cordic.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_cordicinitialize + * + * Description: + * Initialize the N32H7 CORDIC peripheral. This function must be called + * from board-specific logic. + * + * Returned Value: + * On success, a pointer to the lower half CORDIC driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +struct cordic_lowerhalf_s *n32_cordicinitialize(void); + +#endif /* __ARCH_ARM_SRC_N32H7_N32_CORDIC_H */ diff --git a/arch/arm/src/n32h7/n32_dbgmcu.h b/arch/arm/src/n32h7/n32_dbgmcu.h new file mode 100644 index 0000000000000..1fc29b9e74eac --- /dev/null +++ b/arch/arm/src/n32h7/n32_dbgmcu.h @@ -0,0 +1,34 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_dbgmcu.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_DBGMCU_H +#define __ARCH_ARM_SRC_N32H7_N32_DBGMCU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "hardware/n32h7xx_dbgmcu.h" + +#endif /* __ARCH_ARM_SRC_N32H7_N32_DBGMCU_H */ diff --git a/arch/arm/src/n32h7/n32_dma.c b/arch/arm/src/n32h7/n32_dma.c new file mode 100644 index 0000000000000..858c5836d40bd --- /dev/null +++ b/arch/arm/src/n32h7/n32_dma.c @@ -0,0 +1,1999 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_dma.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "arm_internal.h" +#include "sched/sched.h" + +#include "n32_dma.h" +#include "hardware/n32h7_dma.h" +#include "hardware/n32h7_dmamux.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMAMUX_NUM 2 +#define DMA_CONTROLLERS 4 + +#ifdef CONFIG_N32H7_MDMA +# define MDMA_NCHAN 16 +#else +# define MDMA_NCHAN 0 +#endif +#ifdef CONFIG_N32H7_DMA1 +# define DMA1_NCHAN 8 +#else +# define DMA1_NCHAN 0 +#endif +#ifdef CONFIG_N32H7_DMA2 +# define DMA2_NCHAN 8 +#else +# define DMA2_NCHAN 0 +#endif +#ifdef CONFIG_N32H7_DMA3 +# define DMA3_NCHAN 8 +#else +# define DMA3_NCHAN 0 +#endif + +#define MDMA_FIRST (0) +#define MDMA_LAST (MDMA_FIRST+MDMA_NCHAN) +#define DMA1_FIRST (MDMA_LAST) +#define DMA1_LAST (DMA1_FIRST+DMA1_NCHAN) +#define DMA2_FIRST (DMA1_LAST) +#define DMA2_LAST (DMA2_FIRST+DMA2_NCHAN) +#define DMA3_FIRST (DMA2_LAST) +#define DMA3_LAST (DMA3_FIRST+DMA3_NCHAN) + +/* All available DMA channels (channels from standard DMA and + * channels from DMA3 and MDMA) + */ + +#define DMA_NCHANNELS (DMA1_NCHAN+DMA2_NCHAN+MDMA_NCHAN+DMA3_NCHAN) + +/* Default DMA, MDMA and DMA3 priorities */ + +#ifndef CONFIG_DMA_PRI +# define CONFIG_DMA_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +#ifndef CONFIG_MDMA_PRI +# define CONFIG_MDMA_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure described one DMAMUX device */ + +struct n32_dmamux_s +{ + uint8_t id; /* DMAMUX id */ + uint8_t nchan; /* DMAMUX channels */ + uint32_t base; /* DMAMUX base address */ +}; + +typedef struct n32_dmamux_s *DMA_MUX; + +/* This structure describes one DMA controller */ + +struct n32_dma_s +{ + uint8_t first; /* Offset in n32_dmach_s array */ + uint8_t nchan; /* Number of channels */ + uint8_t dmamux_offset; /* DMAMUX channel offset */ + uint32_t base; /* Base address */ + DMA_MUX dmamux; /* DMAMUX associated with controller */ +}; + +/* This structure describes one DMA channel (DMA123 or MDMA) */ + +struct n32_dmach_s +{ + bool used; /* Channel in use */ + uint8_t ctrl:3; /* DMA controller */ + uint8_t chan:5; /* DMA channel/channel channel id */ + uint8_t irq; /* DMA channel IRQ number */ + uint32_t base; /* DMA register channel base address */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ +}; + +typedef struct n32_dmach_s *DMA_CHANNEL; + +/* DMA operations */ + +struct n32_dma_ops_s +{ + /* Start the DMA transfer */ + + void (*dma_disable)(DMA_CHANNEL dmachan); + + /* DMA interrupt */ + + int (*dma_interrupt)(int irq, void *context, void *arg); + + /* Setup the DMA */ + + void (*dma_setup)(DMA_HANDLE handle, n32_dmacfg_t *cfg); + + /* Start the DMA */ + + void (*dma_start)(DMA_HANDLE handle, dma_callback_t callback, + void *arg); + + /* Read remaining DMA bytes */ + + size_t (*dma_residual)(DMA_HANDLE handle); + + /* Check the DMA configuration */ + + bool (*dma_capable)(n32_dmacfg_t *cfg); + + /* Dump the DMA registers */ + + void (*dma_dump)(DMA_HANDLE handle, const char *msg); +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_N32H7_MDMA +static void n32_mdma_disable(DMA_CHANNEL dmachan); +static int n32_mdma_interrupt(int irq, void *context, void *arg); +static void n32_mdma_setup(DMA_HANDLE handle, n32_dmacfg_t *cfg); +static void n32_mdma_start(DMA_HANDLE handle, dma_callback_t callback, + void *arg); +static size_t n32_mdma_residual(DMA_HANDLE handle); +#ifdef CONFIG_N32H7_DMACAPABLE +static bool n32_mdma_capable(n32_dmacfg_t *cfg); +#endif +#ifdef CONFIG_DEBUG_DMA_INFO +static void n32_mdma_dump(DMA_HANDLE handle, const char *msg); +#endif +#endif + +#if defined(CONFIG_N32H7_DMA1) || defined(CONFIG_N32H7_DMA2) || defined(CONFIG_N32H7_DMA3) +static void n32_sdma_disable(DMA_CHANNEL dmachan); +static int n32_sdma_interrupt(int irq, void *context, void *arg); +static void n32_sdma_setup(DMA_HANDLE handle, n32_dmacfg_t *cfg); +static void n32_sdma_start(DMA_HANDLE handle, dma_callback_t callback, + void *arg); +static size_t n32_sdma_residual(DMA_HANDLE handle); +#ifdef CONFIG_N32H7_DMACAPABLE +static bool n32_sdma_capable(n32_dmacfg_t *cfg); +#endif +#ifdef CONFIG_DEBUG_DMA_INFO +static void n32_sdma_dump(DMA_HANDLE handle, const char *msg); +#endif +#endif + +static uint32_t dmachan_getbase(DMA_CHANNEL dmachan); +static uint32_t dmabase_getreg(DMA_CHANNEL dmachan, uint32_t offset); +static void dmabase_putreg(DMA_CHANNEL dmachan, uint32_t offset, + uint32_t value); +static uint32_t dmachan_getreg(DMA_CHANNEL dmachan, uint32_t offset); +static void dmachan_putreg(DMA_CHANNEL dmachan, uint32_t offset, + uint32_t value); +static void dmamux_putreg(DMA_MUX dmamux, uint32_t offset, uint32_t value); +#ifdef CONFIG_DEBUG_DMA_INFO +static uint32_t dmamux_getreg(DMA_MUX dmamux, uint32_t offset); +static void n32_dmamux_dump(DMA_MUX dmamux, uint8_t chan); +#endif +static DMA_CHANNEL n32_dma_channel_get(uint8_t channel, + uint8_t controller); +static void n32_gdma_limits_get(uint8_t controller, uint8_t *first, + uint8_t *last); + +static inline void dmachan_modifyreg32(DMA_CHANNEL dmachan, + uint32_t offset, uint32_t clrbits, + uint32_t setbits) +{ + modifyreg32(dmachan->base + offset, clrbits, setbits); +} + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Operations specific to DMA controller */ + +struct n32_dma_ops_s g_dma_ops[DMA_CONTROLLERS] = +{ +#ifdef CONFIG_N32H7_MDMA + /* 0 - MDMA */ + + { + .dma_disable = n32_mdma_disable, + .dma_interrupt = n32_mdma_interrupt, + .dma_setup = n32_mdma_setup, + .dma_start = n32_mdma_start, + .dma_residual = n32_mdma_residual, +#ifdef CONFIG_N32H7_DMACAPABLE + .dma_capable = n32_mdma_capable, +#endif +#ifdef CONFIG_DEBUG_DMA_INFO + .dma_dump = n32_mdma_dump, +#endif + }, +#else + { + NULL + }, +#endif + +#ifdef CONFIG_N32H7_DMA1 + /* 1 - DMA1 */ + + { + .dma_disable = n32_sdma_disable, + .dma_interrupt = n32_sdma_interrupt, + .dma_setup = n32_sdma_setup, + .dma_start = n32_sdma_start, + .dma_residual = n32_sdma_residual, +#ifdef CONFIG_N32H7_DMACAPABLE + .dma_capable = n32_sdma_capable, +#endif +#ifdef CONFIG_DEBUG_DMA_INFO + .dma_dump = n32_sdma_dump, +#endif + }, +#else + { + NULL + }, +#endif + +#ifdef CONFIG_N32H7_DMA2 + /* 2 - DMA2 */ + + { + .dma_disable = n32_sdma_disable, + .dma_interrupt = n32_sdma_interrupt, + .dma_setup = n32_sdma_setup, + .dma_start = n32_sdma_start, + .dma_residual = n32_sdma_residual, +#ifdef CONFIG_N32H7_DMACAPABLE + .dma_capable = n32_sdma_capable, +#endif +#ifdef CONFIG_DEBUG_DMA_INFO + .dma_dump = n32_sdma_dump, +#endif + }, +#else + { + NULL + }, +#endif + +#ifdef CONFIG_N32H7_DMA3 + /* 3 - DMA3 */ + + { + .dma_disable = n32_sdma_disable, + .dma_interrupt = n32_sdma_interrupt, + .dma_setup = n32_sdma_setup, + .dma_start = n32_sdma_start, + .dma_residual = n32_sdma_residual, +#ifdef CONFIG_N32H7_DMACAPABLE + .dma_capable = n32_sdma_capable, +#endif +#ifdef CONFIG_DEBUG_DMA_INFO + .dma_dump = n32_sdma_dump, +#endif + }, +#else + { + NULL + }, +#endif +}; + +/* This array describes the state of DMAMUX controller */ + +struct n32_dmamux_s g_dmamux[DMAMUX_NUM] = +{ + { + .id = 1, + .nchan = 24, /* 0-7 - DMA1, 8-15 - DMA2, 16-23 - DMA3 */ + .base = N32_DMAMUX1_BASE + }, + + { + .id = 2, + .nchan = 16, /* 0-15 - MDMA */ + .base = N32_DMAMUX2_BASE + } +}; + +/* This array describes the state of each controller */ + +struct n32_dma_s g_dma[DMA_NCHANNELS] = +{ + /* 0 - MDMA */ + + { + .base = N32_MDMA_BASE, + .first = MDMA_FIRST, + .nchan = MDMA_NCHAN, + .dmamux = &g_dmamux[DMAMUX2], /* DMAMUX2 channels 0-15 */ + .dmamux_offset = 0 + }, + + /* 1 - DMA1 */ + + { + .base = N32_DMA1_BASE, + .first = DMA1_FIRST, + .nchan = DMA1_NCHAN, + .dmamux = &g_dmamux[DMAMUX1], /* DMAMUX1 channels 0-7 */ + .dmamux_offset = 0 + }, + + /* 2 - DMA2 */ + + { + .base = N32_DMA2_BASE, + .first = DMA2_FIRST, + .nchan = DMA2_NCHAN, + .dmamux = &g_dmamux[DMAMUX1], /* DMAMUX1 channels 8-15 */ + .dmamux_offset = 8 + }, + + /* 3 - DMA3 */ + + { + .base = N32_DMA3_BASE, + .first = DMA3_FIRST, + .nchan = DMA3_NCHAN, + .dmamux = &g_dmamux[DMAMUX1], /* DMAMUX1 channels 16-23 */ + .dmamux_offset = 16 + } +}; + +/* This array describes the state of each DMA channel. + * Note that we keep here standard DMA channels, BDMA channels and MDMA + * channels. + */ + +static struct n32_dmach_s g_dmach[DMA_NCHANNELS] = +{ +#ifdef CONFIG_N32H7_MDMA + /* MDMA */ + + { + .ctrl = MDMA, + .chan = 0, + .irq = N32_IRQ_MDMA_CHANNEL0, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(0), + }, + + { + .ctrl = MDMA, + .chan = 1, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(1), + }, + + { + .ctrl = MDMA, + .chan = 2, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(2), + }, + + { + .ctrl = MDMA, + .chan = 3, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(3), + }, + + { + .ctrl = MDMA, + .chan = 4, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(4), + }, + + { + .ctrl = MDMA, + .chan = 5, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(5), + }, + + { + .ctrl = MDMA, + .chan = 6, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(6), + }, + + { + .ctrl = MDMA, + .chan = 7, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(7), + }, + + { + .ctrl = MDMA, + .chan = 8, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(8), + }, + + { + .ctrl = MDMA, + .chan = 9, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(9), + }, + + { + .ctrl = MDMA, + .chan = 10, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(10), + }, + + { + .ctrl = MDMA, + .chan = 11, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(11), + }, + + { + .ctrl = MDMA, + .chan = 12, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(12), + }, + + { + .ctrl = MDMA, + .chan = 13, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(13), + }, + + { + .ctrl = MDMA, + .chan = 14, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(15), + }, + + { + .ctrl = MDMA, + .chan = 15, + .irq = N32_IRQ_MDMA, + .base = N32_MDMA_BASE + N32_MDMA_OFFSET(15), + }, +#endif + +#ifdef CONFIG_N32H7_DMA1 + /* DMA1 */ + + { + .ctrl = DMA1, + .chan = 0, + .irq = N32_IRQ_DMA1_CHANNEL0, + .base = N32_DMA1_BASE + N32_DMA_CH_OFFSET(0), + }, + + { + .ctrl = DMA1, + .chan = 1, + .irq = N32_IRQ_DMA1_CHANNEL1, + .base = N32_DMA1_BASE + N32_DMA_CH_OFFSET(1), + }, + + { + .ctrl = DMA1, + .chan = 2, + .irq = N32_IRQ_DMA1_CHANNEL2, + .base = N32_DMA1_BASE + N32_DMA_CH_OFFSET(2), + }, + + { + .ctrl = DMA1, + .chan = 3, + .irq = N32_IRQ_DMA1_CHANNEL3, + .base = N32_DMA1_BASE + N32_DMA_CH_OFFSET(3), + }, + + { + .ctrl = DMA1, + .chan = 4, + .irq = N32_IRQ_DMA1_CHANNEL4, + .base = N32_DMA1_BASE + N32_DMA_CH_OFFSET(4), + }, + + { + .ctrl = DMA1, + .chan = 5, + .irq = N32_IRQ_DMA1_CHANNEL5, + .base = N32_DMA1_BASE + N32_DMA_CH_OFFSET(5), + }, + + { + .ctrl = DMA1, + .chan = 6, + .irq = N32_IRQ_DMA1_CHANNEL6, + .base = N32_DMA1_BASE + N32_DMA_CH_OFFSET(6), + }, + + { + .ctrl = DMA1, + .chan = 7, + .irq = N32_IRQ_DMA1_CHANNEL7, + .base = N32_DMA1_BASE + N32_DMA_CH_OFFSET(7), + }, +#endif + +#ifdef CONFIG_N32H7_DMA2 + /* DMA2 */ + + { + .ctrl = DMA2, + .chan = 0, + .irq = N32_IRQ_DMA2_CHANNEL0, + .base = N32_DMA2_BASE + N32_DMA_CH_OFFSET(0), + }, + + { + .ctrl = DMA2, + .chan = 1, + .irq = N32_IRQ_DMA2_CHANNEL1, + .base = N32_DMA2_BASE + N32_DMA_CH_OFFSET(1), + }, + + { + .ctrl = DMA2, + .chan = 2, + .irq = N32_IRQ_DMA2_CHANNEL2, + .base = N32_DMA2_BASE + N32_DMA_CH_OFFSET(2), + }, + + { + .ctrl = DMA2, + .chan = 3, + .irq = N32_IRQ_DMA2_CHANNEL3, + .base = N32_DMA2_BASE + N32_DMA_CH_OFFSET(3), + }, + + { + .ctrl = DMA2, + .chan = 4, + .irq = N32_IRQ_DMA2_CHANNEL4, + .base = N32_DMA2_BASE + N32_DMA_CH_OFFSET(4), + }, + + { + .ctrl = DMA2, + .chan = 5, + .irq = N32_IRQ_DMA2_CHANNEL5, + .base = N32_DMA2_BASE + N32_DMA_CH_OFFSET(5), + }, + + { + .ctrl = DMA2, + .chan = 6, + .irq = N32_IRQ_DMA2_CHANNEL6, + .base = N32_DMA2_BASE + N32_DMA_CH_OFFSET(6), + }, + + { + .ctrl = DMA2, + .chan = 7, + .irq = N32_IRQ_DMA2_CHANNEL7, + .base = N32_DMA2_BASE + N32_DMA_CH_OFFSET(7), + }, +#endif + +#ifdef CONFIG_N32H7_DMA3 + /* DMA3 */ + + { + .ctrl = DMA3, + .chan = 0, + .irq = N32_IRQ_DMA3_CHANNEL0, + .base = N32_DMA3_BASE + N32_DMA_CH_OFFSET(0), + }, + + { + .ctrl = DMA3, + .chan = 1, + .irq = N32_IRQ_DMA3_CHANNEL1, + .base = N32_DMA3_BASE + N32_DMA_CH_OFFSET(1), + }, + + { + .ctrl = DMA3, + .chan = 2, + .irq = N32_IRQ_DMA3_CHANNEL2, + .base = N32_DMA3_BASE + N32_DMA_CH_OFFSET(2), + }, + + { + .ctrl = DMA3, + .chan = 3, + .irq = N32_IRQ_DMA3_CHANNEL3, + .base = N32_DMA3_BASE + N32_DMA_CH_OFFSET(3), + }, + + { + .ctrl = DMA3, + .chan = 4, + .irq = N32_IRQ_DMA3_CHANNEL4, + .base = N32_DMA3_BASE + N32_DMA_CH_OFFSET(4), + }, + + { + .ctrl = DMA3, + .chan = 5, + .irq = N32_IRQ_DMA3_CHANNEL5, + .base = N32_DMA3_BASE + N32_DMA_CH_OFFSET(5), + }, + + { + .ctrl = DMA3, + .chan = 6, + .irq = N32_IRQ_DMA3_CHANNEL6, + .base = N32_DMA3_BASE + N32_DMA_CH_OFFSET(6), + }, + + { + .ctrl = DMA3, + .chan = 7, + .irq = N32_IRQ_DMA3_CHANNEL7, + .base = N32_DMA3_BASE + N32_DMA_CH_OFFSET(7), + }, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * DMA register access functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dmachan_getbase + * + * Description: + * Get base DMA address for dmachan + * + ****************************************************************************/ + +static uint32_t dmachan_getbase(DMA_CHANNEL dmachan) +{ + uint8_t controller = dmachan->ctrl; + + return g_dma[controller].base; +} + +/**************************************************************************** + * Name: dmabase_getreg + * + * Description: + * Get non-channel register from DMA controller + * + ****************************************************************************/ + +static uint32_t dmabase_getreg(DMA_CHANNEL dmachan, uint32_t offset) +{ + uint32_t dmabase = dmachan_getbase(dmachan); + + return getreg32(dmabase + offset); +} + +/**************************************************************************** + * Name: dmabase_putreg + * + * Description: + * Write to non-channel register in DMA controller + * + ****************************************************************************/ + +static void dmabase_putreg(DMA_CHANNEL dmachan, uint32_t offset, + uint32_t value) +{ + uint32_t dmabase = dmachan_getbase(dmachan); + + putreg32(value, dmabase + offset); +} + +/**************************************************************************** + * Name: dmachan_getreg + * + * Description: + * Get channel register. + * + ****************************************************************************/ + +static uint32_t dmachan_getreg(DMA_CHANNEL dmachan, uint32_t offset) +{ + return getreg32(dmachan->base + offset); +} + +/**************************************************************************** + * Name: dmachan_putreg + * + * Description: + * Write to channel register. + * + ****************************************************************************/ + +static void dmachan_putreg(DMA_CHANNEL dmachan, uint32_t offset, + uint32_t value) +{ + putreg32(value, dmachan->base + offset); +} + +/**************************************************************************** + * Name: dmamux_getreg + * + * Description: + * Write to DMAMUX + * + ****************************************************************************/ + +static void dmamux_putreg(DMA_MUX dmamux, uint32_t offset, uint32_t value) +{ + putreg32(value, dmamux->base + offset); +} + +/**************************************************************************** + * Name: dmamux_getreg + * + * Description: + * Get DMAMUX register. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +static uint32_t dmamux_getreg(DMA_MUX dmamux, uint32_t offset) +{ + return getreg32(dmamux->base + offset); +} +#endif + +/**************************************************************************** + * Name: n32_dma_channel_get + * + * Description: + * Get the g_dmach table entry associated with a given DMA controller + * and channel number. + * + ****************************************************************************/ + +static DMA_CHANNEL n32_dma_channel_get(uint8_t channel, uint8_t controller) +{ + uint8_t first = 0; + uint8_t nchan = 0; + + /* Get limits for g_dma array */ + + n32_gdma_limits_get(controller, &first, &nchan); + + DEBUGASSERT(channel <= nchan); + + return &g_dmach[first + channel]; +} + +/**************************************************************************** + * Name: n32_gdma_limits_get + * + * Description: + * Get g_dma array limits for a given DMA controller. + * + ****************************************************************************/ + +static void n32_gdma_limits_get(uint8_t controller, uint8_t *first, + uint8_t *nchan) +{ + DEBUGASSERT(first != NULL); + DEBUGASSERT(nchan != NULL); + + DEBUGASSERT(controller >= MDMA && controller <= DMA3); + + *first = g_dma[controller].first; + *nchan = g_dma[controller].nchan; +} + +/**************************************************************************** + * Master DMA functions + ****************************************************************************/ + +#ifdef CONFIG_N32H7_MDMA + +/**************************************************************************** + * Name: n32_mdma_disable + * + * Description: + * Disable the master DMA + * + ****************************************************************************/ + +static void n32_mdma_disable(DMA_CHANNEL dmachan) +{ + uint8_t controller = dmachan->ctrl; + + DEBUGASSERT(controller == MDMA); + +#warning n32_mdma_disable +} + +/**************************************************************************** + * Name: n32_mdma_interrupt + * + * Description: + * Master DMA interrupt handler + * + ****************************************************************************/ + +static int n32_mdma_interrupt(int irq, void *context, void *arg) +{ +#warning n32_mdma_interrupt +} + +/**************************************************************************** + * Name: n32_mdma_setup + * + * Description: + * Configure master DMA before using + * + ****************************************************************************/ + +static void n32_mdma_setup(DMA_HANDLE handle, n32_dmacfg_t *cfg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + + DEBUGASSERT(controller == MDMA); + +#warning n32_mdma_setup not implemented +} + +/**************************************************************************** + * Name: n32_mdma_start + * + * Description: + * Start the master DMA transfer + ****************************************************************************/ + +static void n32_mdma_start(DMA_HANDLE handle, dma_callback_t callback, + void *arg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + + DEBUGASSERT(controller == MDMA); + +#warning n32_mdma_start not implemented +} + +/**************************************************************************** + * Name: n32_mdma_residual + ****************************************************************************/ + +static size_t n32_mdma_residual(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + uint32_t residual = 0; + + DEBUGASSERT(controller == MDMA); + + /* REVISIT */ + + /* Fetch the count of blocks remaining to be transferred */ + + residual = dmachan_getreg(dmachan, N32_MDMACH_CBNDTR_OFFSET); + + return (size_t)(residual & MDMA_CBNDTR_BNDT_MASK); +} + +/**************************************************************************** + * Name: n32_mdma_capable + ****************************************************************************/ + +#ifdef CONFIG_N32H7_DMACAPABLE +static bool n32_mdma_capable(n32_dmacfg_t *cfg) +{ + uint32_t transfer_size; + uint32_t mend; + uint32_t ccr = cfg->cfg1; + uint32_t ctcr = cfg->cfg2; + + dmainfo("0x%08" PRIx32 "/%" PRIu32 " 0x%08" PRIx32 " 0x%08" PRIx32 "\n", + cfg->maddr, cfg->ndata, ccr, ctcr); + +#warning n32_mdma_capable not implemented + + return true; +} +#endif + +/**************************************************************************** + * Name: n32_mdma_dump + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +static void n32_mdma_dump(DMA_HANDLE handle, const char *msg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + + DEBUGASSERT(controller == MDMA); + + dmainfo(" CISR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CISR_OFFSET)); + dmainfo(" CESR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CESR_OFFSET)); + dmainfo(" CCR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CCR_OFFSET)); + dmainfo(" CTCR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CTCR_OFFSET)); + dmainfo(" CBNDTR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CBNDTR_OFFSET)); + dmainfo(" CSAR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CSAR_OFFSET)); + dmainfo(" CDAR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CDAR_OFFSET)); + dmainfo(" CBRUR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CBRUR_OFFSET)); + dmainfo(" CLAR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CLAR_OFFSET)); + dmainfo(" CTBR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CTBR_OFFSET)); + dmainfo(" CMAR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CMAR_OFFSET)); + dmainfo(" CMDR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_MDMACH_CMDR_OFFSET)); +} +#endif + +#endif /* CONFIG_N32H7_MDMA */ + +/**************************************************************************** + * Standard DMA functions + ****************************************************************************/ + +#if defined(CONFIG_N32H7_DMA1) || defined(CONFIG_N32H7_DMA2) || defined(CONFIG_N32H7_DMA3) + +/**************************************************************************** + * Name: n32_sdma_disable + * + * Description: + * Disable standard DMA channel (DMA1/DMA2) + * + ****************************************************************************/ + +static void n32_sdma_disable(DMA_CHANNEL dmachan) +{ + uint32_t regval = 0; + uint8_t channel = 0; + + DEBUGASSERT(dmachan->ctrl == DMA1 || + dmachan->ctrl == DMA2 || + dmachan->ctrl == DMA3); + + /* Get DMA channel */ + + channel = dmachan->chan; + + DEBUGASSERT(channel < 8); + + /* Disable the DMA channel */ + + /* Set channel enable bit writable */ + + regval = dmabase_getreg(dmachan, N32_DMA_CHEN_OFFSET); + regval |= DMA_CHEN_CHWEN(channel); + + /* Clear channel enable bit */ + + regval &= ~DMA_CHEN_CH(channel); + dmabase_putreg(dmachan, N32_DMA_CHEN_OFFSET, regval); + + while (dmachan_getreg(dmachan, N32_DMA_CHEN_OFFSET) & + DMA_CHEN_CH(channel)); + + /* Clear pending channel interrupts */ + + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_TCINTCLR_OFFSET, regval); + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_BTCINTCLR_OFFSET, regval); + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_STCINTCLR_OFFSET, regval); + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_DTCINTCLR_OFFSET, regval); + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_ERRINTCLR_OFFSET, regval); + + /* Disable all interrupts at the DMA controller */ + + regval = dmachan_getreg(dmachan, N32_DMA_CH_CTRL_OFFSET); + regval &= ~DMA_CHCTRL_INTEN; + dmachan_putreg(dmachan, N32_DMA_CH_CTRL_OFFSET, regval); +} + +/**************************************************************************** + * Name: n32_sdma_interrupt + * + * Description: + * Standard DMA interrupt handler + * + ****************************************************************************/ + +static int n32_sdma_interrupt(int irq, void *context, void *arg) +{ + DMA_CHANNEL dmachan = NULL; + uint32_t status = 0; + uint32_t regval = 0; + uint8_t channel = 0; + uint8_t controller = 0; + + /* Get the channel and the controller that generated the interrupt */ + +#ifdef CONFIG_N32H7_DMA1 + if (irq >= N32_IRQ_DMA1_CHANNEL0 && irq <= N32_IRQ_DMA1_CHANNEL7) + { + channel = irq - N32_IRQ_DMA1_CHANNEL0; + controller = DMA1; + } + else +#endif +#ifdef CONFIG_N32H7_DMA2 + if (irq >= N32_IRQ_DMA2_CHANNEL0 && irq <= N32_IRQ_DMA2_CHANNEL7) + { + channel = irq - N32_IRQ_DMA2_CHANNEL0; + controller = DMA2; + } + else +#endif +#ifdef CONFIG_N32H7_DMA3 + if (irq >= N32_IRQ_DMA3_CHANNEL0 && irq <= N32_IRQ_DMA3_CHANNEL7) + { + channel = irq - N32_IRQ_DMA3_CHANNEL0; + controller = DMA3; + } + else +#endif + { + DEBUGPANIC(); + } + + /* Get the channel structure from the channel and controller numbers */ + + dmachan = n32_dma_channel_get(channel, controller); + + /* Get the interrupt status for this channel */ + + status = (((dmabase_getreg(dmachan, N32_DMA_TCINTSTS_OFFSET) & + DMA_INT_CH(channel)) >> channel) << 0) | + (((dmabase_getreg(dmachan, N32_DMA_BTCINTSTS_OFFSET) & + DMA_INT_CH(channel)) >> channel) << 1) | + (((dmabase_getreg(dmachan, N32_DMA_STCINTSTS_OFFSET) & + DMA_INT_CH(channel)) >> channel) << 2) | + (((dmabase_getreg(dmachan, N32_DMA_DTCINTSTS_OFFSET) & + DMA_INT_CH(channel)) >> channel) << 3) | + (((dmabase_getreg(dmachan, N32_DMA_ERRINTSTS_OFFSET) & + DMA_INT_CH(channel)) >> channel) << 4); + + /* Clear fetched channel interrupts */ + + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_TCINTCLR_OFFSET, regval); + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_BTCINTCLR_OFFSET, regval); + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_STCINTCLR_OFFSET, regval); + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_DTCINTCLR_OFFSET, regval); + regval = DMA_INT_CH(channel); + dmabase_putreg(dmachan, N32_DMA_ERRINTCLR_OFFSET, regval); + + /* Invoke the callback */ + + if (dmachan->callback) + { + dmachan->callback(dmachan, status, dmachan->arg); + } + + return OK; +} + +/**************************************************************************** + * Name: n32_sdma_setup + * + * Description: + * Configure standard DMA before using + * + ****************************************************************************/ + +static void n32_sdma_setup(DMA_HANDLE handle, n32_dmacfg_t *cfg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t ch = dmachan->chan; + uint32_t reg; + + /* Disable channel if active, wait until stopped */ + + if (dmabase_getreg(dmachan, N32_DMA_CHEN_OFFSET) & DMA_CHEN_CH(ch)) + { + reg = dmabase_getreg(dmachan, N32_DMA_CHEN_OFFSET); + reg |= DMA_CHEN_CHWEN(ch); + reg &= ~DMA_CHEN_CH(ch); + dmabase_putreg(dmachan, N32_DMA_CHEN_OFFSET, reg); + + int timeout = 100; + + while (timeout-- && (dmabase_getreg(dmachan, N32_DMA_CHEN_OFFSET) & + DMA_CHEN_CH(ch))) + { + up_udelay(1); + } + + DEBUGASSERT((dmabase_getreg(dmachan, N32_DMA_CHEN_OFFSET) & + DMA_CHEN_CH(ch)) == 0); + } + + /* Clear all pending interrupts */ + + uint32_t clr = DMA_INT_CH(ch); + + dmabase_putreg(dmachan, N32_DMA_TCINTCLR_OFFSET, clr); + dmabase_putreg(dmachan, N32_DMA_BTCINTCLR_OFFSET, clr); + dmabase_putreg(dmachan, N32_DMA_STCINTCLR_OFFSET, clr); + dmabase_putreg(dmachan, N32_DMA_DTCINTCLR_OFFSET, clr); + dmabase_putreg(dmachan, N32_DMA_ERRINTCLR_OFFSET, clr); + + /* Set address and linked-list registers */ + + dmachan_putreg(dmachan, N32_DMA_CH_SA_OFFSET, cfg->src_addr); + dmachan_putreg(dmachan, N32_DMA_CH_DA_OFFSET, cfg->dst_addr); + dmachan_putreg(dmachan, N32_DMA_CH_LLP_OFFSET, (uint32_t) + (uintptr_t)cfg->link_list); + + /* Write control register (merge block_size into BTS field) */ + + uint64_t full_ctrl = cfg->ctrl; + + full_ctrl &= ~DMA_CHCTRL_BTS_MASK; + full_ctrl |= DMA_CHCTRL_BTS((uint64_t)cfg->block_size & 0xfffull); + dmachan_putreg(dmachan, N32_DMA_CH_CTRL_OFFSET, + (uint32_t)full_ctrl); + dmachan_putreg(dmachan, N32_DMA_CH_CTRL_OFFSET + 4, + (uint32_t)(full_ctrl >> 32)); + + /* Optional SG/DS registers */ + + if (cfg->sg_cfg) + { + dmachan_putreg(dmachan, N32_DMA_CH_SG_OFFSET, + cfg->sg_cfg); + } + + if (cfg->ds_cfg) + { + dmachan_putreg(dmachan, N32_DMA_CH_DS_OFFSET, + cfg->ds_cfg); + } + + /* Configure CH_CFG: handshake interfaces, priority, and HSSEL bits */ + + uint32_t cfg_low = dmachan_getreg(dmachan, N32_DMA_CH_CFG_OFFSET); + uint32_t cfg_high = dmachan_getreg(dmachan, N32_DMA_CH_CFG_OFFSET + 4); + + cfg_high &= ~(DMA_CHCFG_SRCPER_MASK >> 32); + cfg_high &= ~(DMA_CHCFG_DSTPER_MASK >> 32); + cfg_high |= ((uint64_t)(cfg->src_hs_if & 0x7) << + (DMA_CHCFG_SRCPER_SHIFT - 32)); + cfg_high |= ((uint64_t)(cfg->dst_hs_if & 0x7) << + (DMA_CHCFG_DSTPER_SHIFT - 32)); + + cfg_low &= ~(DMA_CHCFG_HSSELSRC | DMA_CHCFG_HSSELDST | + DMA_CHCFG_CHPRIOR_MASK); + + if (cfg->src_hs_mode == 1) + { + cfg_low |= DMA_CHCFG_HSSELSRC; + } + + if (cfg->dst_hs_mode == 1) + { + cfg_low |= DMA_CHCFG_HSSELDST; + } + + cfg_low |= ((cfg->priority & 0x7) << DMA_CHCFG_CHPRIOR_SHIFT); + + dmachan_putreg(dmachan, N32_DMA_CH_CFG_OFFSET, cfg_low); + dmachan_putreg(dmachan, N32_DMA_CH_CFG_OFFSET + 4, cfg_high); +} + +/**************************************************************************** + * Name: n32_sdma_start + * + * Description: + * Start the standard DMA transfer + ****************************************************************************/ + +static void n32_sdma_start(DMA_HANDLE handle, dma_callback_t callback, + void *arg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint32_t regval = 0; + + DEBUGASSERT(handle != NULL); + DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2); + + /* Save the callback info. This will be invoked when the DMA completes */ + + dmachan->callback = callback; + dmachan->arg = arg; + + /* UnMask TFC and ERR interrupt */ + + regval = DMA_CHEN_CHWEN(dmachan->chan) | DMA_CHEN_CH(dmachan->chan); + dmabase_putreg(dmachan, N32_DMA_TCINTMSK_OFFSET, regval); + dmabase_putreg(dmachan, N32_DMA_ERRINTMSK_OFFSET, regval); + dmabase_putreg(dmachan, N32_DMA_BTCINTMSK_OFFSET, regval); + dmabase_putreg(dmachan, N32_DMA_STCINTMSK_OFFSET, regval); + dmabase_putreg(dmachan, N32_DMA_DTCINTMSK_OFFSET, regval); + + /* Enable all interrupts at the DMA controller */ + + regval = dmachan_getreg(dmachan, N32_DMA_CH_CTRL_OFFSET); + regval |= DMA_CHCTRL_INTEN; + dmachan_putreg(dmachan, N32_DMA_CH_CTRL_OFFSET, regval); + + /* Set channel enable bit writable */ + + regval = dmabase_getreg(dmachan, N32_DMA_CHEN_OFFSET); + regval |= DMA_CHEN_CHWEN(dmachan->chan); + + /* Set channel enable bit */ + + regval |= DMA_CHEN_CH(dmachan->chan); + dmabase_putreg(dmachan, N32_DMA_CHEN_OFFSET, regval); + + n32_dmadump(handle, "DMA after start"); +} + +/**************************************************************************** + * Name: n32_sdma_residual + ****************************************************************************/ + +static size_t n32_sdma_residual(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint32_t residual = 0; + + DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2); + + /* Fetch the count of bytes remaining to be transferred. + * + * If the FIFO is enabled, this count may be inaccurate. ST don't + * appear to document whether this counts the peripheral or the memory + * side of the channel, and they don't make the memory pointer + * available either. + * + * For reception in circular mode the FIFO is disabled in order that + * this value can be useful. + */ + + residual = dmachan_getreg(dmachan, N32_DMA_CH_SG_OFFSET); + + return (size_t)((residual & DMA_SG_SGC_MASK) >> DMA_SG_SGC_SHIFT); +} + +/**************************************************************************** + * Name: n32_sdma_capable + ****************************************************************************/ + +#ifdef CONFIG_N32H7_DMACAPABLE +static bool n32_sdma_capable(n32_dmacfg_t *cfg) +{ + uint32_t transfer_size; + uint32_t burst_length; + uint32_t mend; + uint32_t ccr = cfg->cfg1; + + dmainfo("0x%08" PRIx32 "/%" PRIu32 " 0x%08" PRIx32 "\n", + cfg->maddr, cfg->ndata, cfg->cfg1); + + /* Verify that the address conforms to the memory transfer size. + * Transfers to/from memory performed by the DMA controller are + * required to be aligned to their size. + * + * See ST RM0410 DocID028270 Rev 2, section 8.3.11 Single and burst + * transfers + * + * Compute mend inline to avoid a possible non-constant integer + * multiply. + */ + + switch (ccr & DMA_SCR_MSIZE_MASK) + { + case DMA_SCR_MSIZE_8BITS: + { + transfer_size = 1; + mend = cfg->maddr + cfg->ndata - 1; + break; + } + + case DMA_SCR_MSIZE_16BITS: + { + transfer_size = 2; + mend = cfg->maddr + (cfg->ndata << 1) - 1; + break; + } + + case DMA_SCR_MSIZE_32BITS: + { + transfer_size = 4; + mend = cfg->maddr + (cfg->ndata << 2) - 1; + break; + } + + default: + { + dmainfo("n32_dmacapable: bad transfer size in CCR\n"); + return false; + } + } + + if ((cfg->maddr & (transfer_size - 1)) != 0) + { + dmainfo("n32_dmacapable: transfer unaligned\n"); + return false; + } + +# if defined(CONFIG_ARMV7M_DCACHE) && \ + !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) + /* buffer alignment is required for RX DMA transfers with dcache in + * buffered mode (not write-through) because arch_invalidate_dcache could + * lose buffered writes + */ + + if ((ccr & DMA_SCR_DIR_MASK) == DMA_SCR_DIR_P2M || + (ccr & DMA_SCR_DIR_MASK) == DMA_SCR_DIR_M2M) + { + if ((cfg->maddr & (ARMV7M_DCACHE_LINESIZE - 1)) != 0 || + ((mend + 1) & (ARMV7M_DCACHE_LINESIZE - 1)) != 0) + { + dmainfo("n32_dmacapable: dcache unaligned " + "maddr:0x%08" PRIx32 " mend:0x%08" PRIx32 "\n", + cfg->maddr, mend); +#if !defined(CONFIG_N32H7_DMACAPABLE_ASSUME_CACHE_ALIGNED) + return false; +#endif + } + } +# endif + + /* Verify that burst transfers do not cross a 1KiB boundary. */ + + if ((cfg->maddr / 1024) != (mend / 1024)) + { + /* The transfer as a whole crosses a 1KiB boundary. + * Verify that no burst does by asserting that the address + * is aligned to the burst length. + */ + + switch (ccr & DMA_SCR_MBURST_MASK) + { + case DMA_SCR_MBURST_SINGLE: + { + burst_length = transfer_size; + break; + } + + case DMA_SCR_MBURST_INCR4: + { + burst_length = transfer_size << 2; + break; + } + + case DMA_SCR_MBURST_INCR8: + { + burst_length = transfer_size << 3; + break; + } + + case DMA_SCR_MBURST_INCR16: + { + burst_length = transfer_size << 4; + break; + } + + default: + { + dmainfo("n32_dmacapable: bad burst size in CCR\n"); + return false; + } + } + + if ((cfg->maddr & (burst_length - 1)) != 0) + { + dmainfo("n32_dmacapable: burst crosses 1KiB\n"); + return false; + } + } + + /* Verify that transfer is froma a supported memory region */ + + if ((cfg->paddr & N32_PREGION_MASK) != N32_D2_BASE) + { + /* DMA1/DMA2 support only D2 domain */ + + dmainfo("transfer from unknown/unsupported region\n"); + return false; + } + + /* Verify that the transfer is to a memory region that supports DMA. */ + + if ((cfg->maddr & N32_REGION_MASK) != (mend & N32_REGION_MASK)) + { + dmainfo("n32_dmacapable: transfer crosses memory region\n"); + return false; + } + + switch (cfg->maddr & N32_REGION_MASK) + { + case N32_AXISRAM_BASE: + case N32_FMC_BANK1: + case N32_FMC_BANK2: + case N32_FMC_BANK3: + case N32_FMC_BANK4: + case N32_FMC_BANK5: + case N32_FMC_BANK6: + { + /* All RAM and FMC is supported */ + + break; + } + + case N32_SRAM_BASE: + { + /* DTCM not supported for standard DMA (DMA1/DMA2) */ + + if (cfg->maddr >= N32_DTCRAM_BASE + && (cfg->maddr - N32_DTCRAM_BASE) < 0x1ffff) + { + dmainfo("transfer targets DTCRAM\n"); + return false; + } + break; + } + + case N32_CODE_BASE: + { + /* ITCM not supported for standard DMA (DMA1/DMA2) */ + + if (cfg->maddr >= N32_ITCM_BASE + && (cfg->maddr - N32_ITCM_BASE) < 0xffff) + { + dmainfo("transfer targets ITCM RAM\n"); + return false; + } + break; + } + + default: + { + /* Everything else is unsupported by DMA */ + + dmainfo("transfer targets unknown/unsupported region\n"); + return false; + } + } + + dmainfo("transfer OK\n"); + return true; +} +#endif + +/**************************************************************************** + * Name: n32_sdma_dump + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +static void n32_sdma_dump(DMA_HANDLE handle, const char *msg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2); + + dmainfo(" LISR: %08" PRIx32 "\n", + dmabase_getreg(dmachan, N32_DMA_LISR_OFFSET)); + dmainfo(" HISR: %08" PRIx32 "\n", + dmabase_getreg(dmachan, N32_DMA_HISR_OFFSET)); + dmainfo(" SCR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_DMA_SCR_OFFSET)); + dmainfo(" SNDTR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_DMA_SNDTR_OFFSET)); + dmainfo(" SPAR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_DMA_SPAR_OFFSET)); + dmainfo(" SM0AR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_DMA_SM0AR_OFFSET)); + dmainfo(" SM1AR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_DMA_SM1AR_OFFSET)); + dmainfo(" SFCR: %08" PRIx32 "\n", + dmachan_getreg(dmachan, N32_DMA_SFCR_OFFSET)); + + n32_dmamux_dump(g_dma[dmachan->ctrl].dmamux, + dmachan->chan + g_dma[dmachan->ctrl].dmamux_offset); +} +#endif + +#endif /* CONFIG_N32H7_DMA1 || CONFIG_N32H7_DMA2 || CONFIG_N32H7_DMA3 */ + +/**************************************************************************** + * Name: n32_dmainitialize + * + * Description: + * Initialize the DMA subsystem (DMA1, DMA2, MDMA and DMA3) + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm_dma_initialize(void) +{ + DMA_CHANNEL dmachan = NULL; + uint8_t controller = 0; + int channel = 0; + + dmainfo("Initialize DMA\n"); + + /* Initialize DMA channels */ + + for (channel = 0; channel < DMA_NCHANNELS; channel++) + { + dmachan = &g_dmach[channel]; + + /* Initialize flag */ + + dmachan->used = false; + + /* Get DMA controller associated with channel */ + + controller = dmachan->ctrl; + + DEBUGASSERT(controller >= MDMA && controller <= DMA3); + + /* Attach standard DMA interrupt vectors */ + + irq_attach(dmachan->irq, g_dma_ops[controller].dma_interrupt, + dmachan); + + /* Disable the DMA stream */ + + g_dma_ops[controller].dma_disable(dmachan); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(dmachan->irq); + + /* Set the interrupt priority */ + +#ifdef CONFIG_ARCH_IRQPRIO + switch (controller) + { +#if defined(CONFIG_N32H7_DMA1) || defined(CONFIG_N32H7_DMA2) || defined(CONFIG_N32H7_DMA3) + case DMA1: + case DMA2: + case DMA3: + { + up_prioritize_irq(dmachan->irq, CONFIG_DMA_PRI); + break; + } +#endif /* CONFIG_N32H7_DMA1 && CONFIG_N32H7_DMA2 */ + +#ifdef CONFIG_N32H7_MDMA + case MDMA: + { + up_prioritize_irq(dmachan->irq, CONFIG_MDMA_PRI); + break; + } +#endif /* CONFIG_N32H7_MDMA */ + + default: + { + PANIC(); + break; + } + } +#endif + } +} + +/**************************************************************************** + * Name: n32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'dmamap' argument. + * It is common for standard DMA (DMA1, DMA2), master DMA (MDMA) and + * basic DMA (BDMA) controllers. + * + * Input Parameters: + * dmamap - Identifies the stream/channel resource. For the N32 H7, this + * is a bit-encoded value as provided by the DMAMAP_* definitions + * in chip/n32h7xxxxxxx_dmamux.h + * + * Returned Value: + * On success, this function returns a non-NULL, void* DMA channel handle. + * NULL is returned on any failure. This function can fail only if no DMA + * channel is available. + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE n32_dmachannel(unsigned int dmamap) +{ + DMA_CHANNEL dmachan = NULL; + DMA_MUX dmamux = NULL; + irqstate_t flags; + uint8_t controller = 0; + uint8_t dmamux_req = 0; + uint32_t regval = 0; + uint8_t first = 0; + uint8_t nchan = 0; + int item = -1; + int i = 0; + + /* Get DMA controller from encoded DMAMAP value */ + + controller = DMAMAP_CONTROLLER(dmamap); + DEBUGASSERT(controller >= MDMA && controller <= DMA3); + + /* Get DMAMUX channel from encoded DMAMAP value */ + + dmamux_req = DMAMAP_REQUEST(dmamap); + + /* Get g_dma array limits for given controller */ + + n32_gdma_limits_get(controller, &first, &nchan); + + /* Find available channel for given controller */ + + flags = enter_critical_section(); + for (i = first; i < first + nchan; i += 1) + { + if (g_dmach[i].used == false) + { + item = i; + g_dmach[i].used = true; + break; + } + } + + leave_critical_section(flags); + + dmainfo("ctrl=%" PRIu8 " item=%d\n", controller, item); + + if (item == -1) + { + dmainfo("No available DMA chan for CTRL=%" PRIu8 "\n", + controller); + + /* No available channel */ + + goto errout; + } + + /* Assign DMA item */ + + dmachan = &g_dmach[item]; + + dmainfo("Get g_dmach[%d] CTRL=%" PRIu8 " CH=%" PRIu8 "\n", + i, controller, dmachan->chan); + + /* Be sure that we have proper DMA controller */ + + DEBUGASSERT(dmachan->ctrl == controller); + + /* Get DMAMUX associated with DMA controller */ + + dmamux = g_dma[controller].dmamux; + + /* No DMAMUX for Master DMA */ + + if (dmamux != NULL) + { + uint8_t dmamux_chan = dmachan->chan + g_dma[controller].dmamux_offset; + + dmainfo("Get DMAMUX%" PRIu8 " CH %" PRIu8 "\n", + dmamux->id, dmamux_chan); + + /* DMAMUX Set DMA channel source */ + + regval = dmamux_req << DMAMUX_CXCR_REQID_SHIFT; + dmamux_putreg(dmamux, N32_DMAMUX_CXCR_OFFSET(dmamux_chan), regval); + + /* DMAMUX Set RGCR register */ + + regval = 0; + dmamux_putreg(dmamux, N32_DMAMUX_RGXCR_OFFSET(dmamux_chan), regval); + } + +errout: + return (DMA_HANDLE)dmachan; +} + +/**************************************************************************** + * Name: n32_dmafree + * + * Description: + * Release a DMA channel and unmap DMAMUX if required. + * + * NOTE: The 'handle' used in this argument must NEVER be used again + * until n32_dmachannel() is called again to re-gain access to the + * channel + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void n32_dmafree(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + DMA_MUX dmamux = NULL; + irqstate_t flags; + + DEBUGASSERT(handle != NULL); + + /* Get DMA controller */ + + controller = dmachan->ctrl; + DEBUGASSERT(controller >= MDMA && controller <= DMA3); + + /* Get DMAMUX associated with DMA controller */ + + dmamux = g_dma[controller].dmamux; + + /* No DMAMUX for Master DMA */ + + if (dmamux != NULL) + { + uint8_t dmamux_chan = dmachan->chan + g_dma[controller].dmamux_offset; + + dmainfo("Free DMAMUX%" PRIu8 " CH %" PRIu8 "\n", + dmamux->id, dmamux_chan); + + /* Clear DMAMUX CCR register associated with channel */ + + dmamux_putreg(dmamux, N32_DMAMUX_CXCR_OFFSET(dmamux_chan), 0); + + /* Clear DMAMUX RGCR register associated with channel */ + + dmamux_putreg(dmamux, N32_DMAMUX_RGXCR_OFFSET(dmamux_chan), 0); + } + + /* Release the channel */ + + flags = enter_critical_section(); + dmachan->used = false; + leave_critical_section(flags); + + dmainfo("Unmapping DMAMUX(%" PRIu8 ")\n", dmachan->chan); +} + +/**************************************************************************** + * Name: n32_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void n32_dmasetup(DMA_HANDLE handle, n32_dmacfg_t *cfg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + + /* Get DMA controller */ + + DEBUGASSERT(controller >= MDMA && controller <= DMA3); + + g_dma_ops[controller].dma_setup(handle, cfg); +} + +/**************************************************************************** + * Name: n32_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by n32_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void n32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + + DEBUGASSERT(controller >= MDMA && controller <= DMA3); + + g_dma_ops[controller].dma_start(handle, callback, arg); +} + +/**************************************************************************** + * Name: n32_dmastop + * + * Description: + * Cancel the DMA. After n32_dmastop() is called, the DMA channel is + * reset and n32_dmasetup() must be called before n32_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by n32_dmachannel() + * + ****************************************************************************/ + +void n32_dmastop(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + + DEBUGASSERT(controller >= MDMA && controller <= DMA3); + + g_dma_ops[controller].dma_disable(dmachan); +} + +/**************************************************************************** + * Name: n32_getchannel + * + * Description: + * Read the DMA bytes-remaining register. + * + * Assumptions: + * - DMA handle allocated by n32_dmachannel() + * + ****************************************************************************/ + +size_t n32_getchannel(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + return dmachan->chan; +} + +uint32_t n32_dmaptr_src(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + return dmachan_getreg(dmachan, N32_DMA_CH_SA_OFFSET); +} + +uint32_t n32_dmaptr_dst(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + return dmachan_getreg(dmachan, N32_DMA_CH_DA_OFFSET); +} + +uint32_t n32_getcount(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + return dmachan_getreg(dmachan, N32_DMA_CH_CTRL_OFFSET + 4) & 0x0fff; +} + +/**************************************************************************** + * Name: n32_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address. This depends on the internal connections in the ARM bus matrix + * of the processor. Note that this only applies to memory addresses, it + * will return false for any peripheral address. + * + * Input Parameters: + * cfg - DMA transfer configuration + * + * Returned Value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_N32H7_DMACAPABLE +bool n32_dmacapable(DMA_HANDLE handle, n32_dmacfg_t *cfg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + + DEBUGASSERT(controller >= MDMA && controller <= DMA3); + + return g_dma_ops[controller].dma_capable(cfg); +} +#endif + +/**************************************************************************** + * Name: n32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by n32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +void n32_dmadump(DMA_HANDLE handle, const char *msg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller = dmachan->ctrl; + + DEBUGASSERT(controller >= MDMA && controller <= DMA3); + + dmainfo("DMA %" PRIu8 " CH%" PRIu8 " Registers: %s\n", + dmachan->ctrl, dmachan->ctrl, msg); + + g_dma_ops[controller].dma_dump(handle, msg); +} +#endif diff --git a/arch/arm/src/n32h7/n32_dma.h b/arch/arm/src/n32h7/n32_dma.h new file mode 100644 index 0000000000000..998d47abbebfe --- /dev/null +++ b/arch/arm/src/n32h7/n32_dma.h @@ -0,0 +1,339 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_dma.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_DMA_H +#define __ARCH_ARM_SRC_N32H7_N32_DMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "hardware/n32h7_dma.h" +#include "hardware/n32h7_dmamux.h" + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#define DMA_INT_TFR (1 << 0) +#define DMA_INT_BLOCK (1 << 1) +#define DMA_INT_SRCT (1 << 2) +#define DMA_INT_DSTT (1 << 3) +#define DMA_INT_ERROR (1 << 4) + +/* DMA Channel Initialize configuration structure */ + +typedef struct +{ + uint32_t src_addr; /* Source address */ + uint32_t dst_addr; /* Destination address */ + uint32_t block_size; /* Block transfer size (max 4095) */ + uint64_t ctrl; /* CH_CTRL value (combine macros from n32h7_dma.h) */ + uint32_t sg_cfg; /* CH_SG (source gather), 0 if unused */ + uint32_t ds_cfg; /* CH_DS (dest scatter), 0 if unused */ + + uint8_t src_hs_if; /* Source handshake interface (0~7) -> SRCPER */ + uint8_t dst_hs_if; /* Dest handshake interface (0~7) -> DSTPER */ + uint8_t priority; /* Channel priority (0~7) -> CHPRIOR */ + + uint8_t src_hs_mode; /* 0: HW handshake, 1: SW handshake -> HSSELSRC */ + uint8_t dst_hs_mode; /* 0: HW, 1: SW -> HSSELDST */ + + void *link_list; /* Linked list pointer (NULL if not used) */ +} n32_dmacfg_t; + +/* DMA_HANDLE Provides an opaque reference that can be used to represent a + * DMA stream. + */ + +typedef void *DMA_HANDLE; + +/* Description: + * This is the type of the callback that is used to inform the user of the + * completion of the DMA. NOTE: The DMA module does *NOT* perform any + * cache operations. It is the responsibility of the DMA client to + * invalidate DMA buffers after completion of the DMA RX operations. + * + * Input Parameters: + * handle - Refers to the DMA channel or stream + * status - A bit encoded value that provides the completion status. See + * the DMASTATUS_* definitions above. + * arg - A user-provided value that was provided when n32_dmastart() + * was called. + */ + +typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'dmamap' argument. + * It is common for standard DMA (DMA1, DMA2, DMA3), master DMA (MDMA) + * controllers. + * + * Input Parameters: + * dmamap - Identifies the stream/channel resource. For the N32 H7, this + * is a bit-encoded value as provided by the DMAMAP_* definitions + * in chip/n32h7xxxxxxx_dmamux.h + * + * Returned Value: + * On success, this function returns a non-NULL, void* DMA channel handle. + * NULL is returned on any failure. This function can fail only if no DMA + * channel is available. + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is no + * available. + * + ****************************************************************************/ + +DMA_HANDLE n32_dmachannel(unsigned int dmamap); + +/**************************************************************************** + * Name: n32_dmafree + * + * Description: + * Release a DMA channel and unmap DMAMUX if required. + * + * NOTE: The 'handle' used in this argument must NEVER be used again + * until n32_dmachannel() is called again to re-gain access to the + * channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void n32_dmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: n32_dmasetup + * + * Description: + * Configure DMA before using it. + * + * Input Parameters: + * handle - DMA channel handle + * cfg - Pointer to DMA configuration structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_dmasetup(DMA_HANDLE handle, n32_dmacfg_t *cfg); + +/**************************************************************************** + * Name: n32_dmastart + * + * Description: + * Start DMA transfer. + * + * Input Parameters: + * handle - DMA channel handle + * callback - Pointer to DMA completion callback + * arg - User-provided value to pass to the callback + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); + +/**************************************************************************** + * Name: n32_dmastop + * + * Description: + * Stop DMA transfer. + * + * Input Parameters: + * handle - DMA channel handle + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_dmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: n32_getchannel + * + * Description: + * Get the current DMA channel. + * + * Input Parameters: + * handle - DMA channel handle + * + * Returned Value: + * DMA channel number + * + * Assumptions: + * - The caller holds the DMA channel. + * + ****************************************************************************/ + +size_t n32_getchannel(DMA_HANDLE handle); + +/**************************************************************************** + * Name: n32_dmaptr_src + * + * Description: + * Get the source DMA pointer. + * + * Input Parameters: + * handle - DMA channel handle + * + * Returned Value: + * Source DMA pointer + * + * Assumptions: + * - The caller holds the DMA channel. + * + ****************************************************************************/ + +uint32_t n32_dmaptr_src(DMA_HANDLE handle); + +/**************************************************************************** + * Name: n32_dmaptr_dst + * + * Description: + * Get the destination DMA pointer. + * + * Input Parameters: + * handle - DMA channel handle + * + * Returned Value: + * Destination DMA pointer + * + * Assumptions: + * - The caller holds the DMA channel. + * + ****************************************************************************/ + +uint32_t n32_dmaptr_dst(DMA_HANDLE handle); + +/**************************************************************************** + * Name: n32_getcount + * + * Description: + * Get the number of bytes to be transferred. + * + * Input Parameters: + * handle - DMA channel handle + * + * Returned Value: + * Number of bytes to be transferred + * + * Assumptions: + * - The caller holds the DMA channel. + * + ****************************************************************************/ + +uint32_t n32_getcount(DMA_HANDLE handle); + +/**************************************************************************** + * Name: n32_dmacapable + * + * Description: + * Check if the DMA channel is capable of the transfer. + * + * Input Parameters: + * handle - DMA channel handle + * cfg - Pointer to DMA configuration structure + * + * Returned Value: + * True if the DMA channel is capable of the transfer, False otherwise + * + * Assumptions: + * - The caller holds the DMA channel. + * + ****************************************************************************/ + +#ifdef CONFIG_N32H7_DMACAPABLE +bool n32_dmacapable(DMA_HANDLE handle, n32_dmacfg_t *cfg); +#else +# define n32_dmacapable(handle, cfg) (true) +#endif + +/**************************************************************************** + * Name: n32_dmadump + * + * Description: + * Dump the DMA channel configuration. + * + * Input Parameters: + * handle - DMA channel handle + * msg - Optional message to print before the dump + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +void n32_dmadump(DMA_HANDLE handle, const char *msg); +#else +# define n32_dmadump(handle,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_DMA_H */ diff --git a/arch/arm/src/n32h7/n32_exti.h b/arch/arm/src/n32h7/n32_exti.h new file mode 100644 index 0000000000000..af90a9eb90f97 --- /dev/null +++ b/arch/arm/src/n32h7/n32_exti.h @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_exti.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + + #ifndef __ARCH_ARM_SRC_N32H7_N32_EXTI_H + #define __ARCH_ARM_SRC_N32H7_N32_EXTI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "hardware/n32h7_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: n32_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) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +int n32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func, void *arg); + +/**************************************************************************** + * Name: n32_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Input Parameters: + * - 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) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +int n32_exti_alarm(bool risingedge, bool fallingedge, bool event, + xcpt_t func, void *arg); +#endif + +/**************************************************************************** + * Name: n32_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 n32_exti_wakeup(bool risingedge, bool fallingedge, bool event, + xcpt_t func, void *arg); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_EXTI_H */ diff --git a/arch/arm/src/n32h7/n32_exti_gpio.c b/arch/arm/src/n32h7/n32_exti_gpio.c new file mode 100644 index 0000000000000..92ec83216a1a8 --- /dev/null +++ b/arch/arm/src/n32h7/n32_exti_gpio.c @@ -0,0 +1,428 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_exti_gpio.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "arm_internal.h" +#include "chip.h" +#include "n32_gpio.h" +#include "n32_exti.h" + +/* Content of this file requires verification before it is used with other + * families + */ + +#if defined(CONFIG_N32H7_N32H76X) +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct gpio_callback_s +{ + uint32_t port; + uint32_t pin; + xcpt_t callback; + void *arg; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to each EXTI */ + +static struct gpio_callback_s g_gpio_callbacks[16]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Interrupt Service Routines - Dispatchers + ****************************************************************************/ + +static int n32_exti0_isr(int irq, void *context, void *arg) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x00000001, N32_EXTI_M7PEND0); + + /* And dispatch the interrupt to the handler */ + + if (g_gpio_callbacks[0].callback != NULL) + { + xcpt_t callback = g_gpio_callbacks[0].callback; + void *cbarg = g_gpio_callbacks[0].arg; + + ret = callback(irq, context, cbarg); + } + + return ret; +} + +static int n32_exti1_isr(int irq, void *context, void *arg) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x00000002, N32_EXTI_M7PEND0); + + /* And dispatch the interrupt to the handler */ + + if (g_gpio_callbacks[1].callback != NULL) + { + xcpt_t callback = g_gpio_callbacks[1].callback; + void *cbarg = g_gpio_callbacks[1].arg; + + ret = callback(irq, context, cbarg); + } + + return ret; +} + +static int n32_exti2_isr(int irq, void *context, void *arg) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x00000004, N32_EXTI_M7PEND0); + + /* And dispatch the interrupt to the handler */ + + if (g_gpio_callbacks[2].callback != NULL) + { + xcpt_t callback = g_gpio_callbacks[2].callback; + void *cbarg = g_gpio_callbacks[2].arg; + + ret = callback(irq, context, cbarg); + } + + return ret; +} + +static int n32_exti3_isr(int irq, void *context, void *arg) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x00000008, N32_EXTI_M7PEND0); + + /* And dispatch the interrupt to the handler */ + + if (g_gpio_callbacks[3].callback != NULL) + { + xcpt_t callback = g_gpio_callbacks[3].callback; + void *cbarg = g_gpio_callbacks[3].arg; + + ret = callback(irq, context, cbarg); + } + + return ret; +} + +static int n32_exti4_isr(int irq, void *context, void *arg) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x00000010, N32_EXTI_M7PEND0); + + /* And dispatch the interrupt to the handler */ + + if (g_gpio_callbacks[4].callback != NULL) + { + xcpt_t callback = g_gpio_callbacks[4].callback; + void *cbarg = g_gpio_callbacks[4].arg; + + ret = callback(irq, context, cbarg); + } + + return ret; +} + +static int n32_exti_multiisr(int irq, void *context, int first, int last) +{ + uint32_t pr; + int pin; + int ret = OK; + + /* Examine the state of each pin in the group */ + + pr = getreg32(N32_EXTI_M7PEND0); + + /* And dispatch the interrupt to the handler */ + + for (pin = first; pin <= last; pin++) + { + /* Is an interrupt pending on this pin? */ + + uint32_t mask = (1 << pin); + + if ((pr & mask) != 0) + { + /* Clear the pending interrupt */ + + putreg32(mask, N32_EXTI_M7PEND0); + + /* And dispatch the interrupt to the handler */ + + if (g_gpio_callbacks[pin].callback != NULL) + { + xcpt_t callback = g_gpio_callbacks[pin].callback; + void *cbarg = g_gpio_callbacks[pin].arg; + int tmp; + + tmp = callback(irq, context, cbarg); + if (tmp < 0) + { + ret = tmp; + } + } + } + } + + return ret; +} + +static int n32_exti95_isr(int irq, void *context, void *arg) +{ + return n32_exti_multiisr(irq, context, 5, 9); +} + +static int n32_exti1510_isr(int irq, void *context, void *arg) +{ + return n32_exti_multiisr(irq, context, 10, 15); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_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) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +int n32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func, void *arg) +{ + struct gpio_callback_s *shared_cbs; + uint32_t port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + uint32_t pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + uint32_t exti; + uint32_t regval; + xcpt_t handler; + int nshared; + int i; + int irq; + + /* Find the first available EXTI line */ + + for (exti = 0; exti < 16; exti++) + { + if (func && g_gpio_callbacks[exti].callback != NULL && + g_gpio_callbacks[exti].port == port && + g_gpio_callbacks[exti].pin == pin) + { + break; + } + else if (func && g_gpio_callbacks[exti].callback == NULL) + { + break; + } + else if (!func && g_gpio_callbacks[exti].port == port && + g_gpio_callbacks[exti].pin == pin) + { + break; + } + } + + /* Select the interrupt handler for this EXTI line */ + + if (exti < 5) + { + irq = exti + N32_IRQ_EXTI0; + nshared = 1; + shared_cbs = &g_gpio_callbacks[exti]; + switch (exti) + { + case 0: + handler = n32_exti0_isr; + break; + + case 1: + handler = n32_exti1_isr; + break; + + case 2: + handler = n32_exti2_isr; + break; + + case 3: + handler = n32_exti3_isr; + break; + + default: + handler = n32_exti4_isr; + break; + } + } + else if (exti < 10) + { + irq = N32_IRQ_EXTI9_5; + handler = n32_exti95_isr; + shared_cbs = &g_gpio_callbacks[5]; + nshared = 5; + } + else if (exti < 16) + { + irq = N32_IRQ_EXTI15_10; + handler = n32_exti1510_isr; + shared_cbs = &g_gpio_callbacks[10]; + nshared = 6; + } + else + { + if (func) + { + return -EINVAL; + } + else + { + return OK; + } + } + + /* Install external interrupt handlers */ + + if (func) + { + /* Save the new IRQ handler. */ + + g_gpio_callbacks[exti].port = port; + g_gpio_callbacks[exti].pin = pin; + + regval = getreg32(N32_AFIO_EXTI_CFG(exti >> 2)); + regval &= ~N32_AFIO_EXTICR_EXTI_MASK(exti); + regval |= (pin * 11 + port) << N32_AFIO_EXTICR_EXTI_SHIFT(exti); + putreg32(regval, N32_AFIO_EXTI_CFG(exti >> 2)); + + g_gpio_callbacks[exti].callback = func; + g_gpio_callbacks[exti].arg = arg; + + irq_attach(irq, handler, NULL); + up_enable_irq(irq); + } + else + { + /* Clear the previous IRQ handler. */ + + g_gpio_callbacks[exti].port = 0; + g_gpio_callbacks[exti].pin = 0; + + regval = getreg32(N32_AFIO_EXTI_CFG(exti >> 2)); + regval &= ~N32_AFIO_EXTICR_EXTI_MASK(exti); + putreg32(regval, N32_AFIO_EXTI_CFG(exti >> 2)); + + g_gpio_callbacks[exti].callback = NULL; + g_gpio_callbacks[exti].arg = NULL; + + /* Only disable IRQ if shared handler does not have any active + * callbacks. + */ + + for (i = 0; i < nshared; i++) + { + if (shared_cbs[i].callback != NULL) + { + break; + } + } + + if (i == nshared) + { + up_disable_irq(irq); + } + } + + /* Configure GPIO, enable EXTI line enabled if event or interrupt is + * enabled. + */ + + n32_configgpio(pinset); + + /* Configure rising/falling edges */ + + modifyreg32(N32_EXTI_RT_CFG0, + risingedge ? 0 : (1U << exti), + risingedge ? (1U << exti) : 0); + modifyreg32(N32_EXTI_FT_CFG0, + fallingedge ? 0 : (1U << exti), + fallingedge ? (1U << exti) : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(N32_EXTI_M7EMASK0, + event ? 0 : (1U << exti), + event ? (1U << exti) : 0); + modifyreg32(N32_EXTI_M7IMASK0, + func ? 0 : (1U << exti), + func ? (1U << exti) : 0); + + return OK; +} + +#endif /* CONFIG_N32H7_N32H76X */ diff --git a/arch/arm/src/n32h7/n32_flash.c b/arch/arm/src/n32h7/n32_flash.c new file mode 100644 index 0000000000000..d063ade16da34 --- /dev/null +++ b/arch/arm/src/n32h7/n32_flash.c @@ -0,0 +1,247 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_flash.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "arm_internal.h" +#include "n32_flash.h" + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ + +/* ROM function addresses (Thumb mode entry points) */ +#define ROM_WRITE_FUNC ((uint32_t (*)(uint32_t, uint8_t*, uint32_t))0x1fff7b81) +#define ROM_ERASE_FUNC ((uint32_t (*)(uint32_t))0x1fff7c81) + +/* Return codes from ROM (as defined in SMU, but duplicated here) */ +#define FLASH_SUCCESS 0 +#define FLASH_BUS_ADDR_ERROR 1 +#define FLASH_LOGIC_ADDR_ERROR 2 +#define FLASH_RESTRICTED 3 +#define FLASH_RDP_PROTECTED 4 +#define FLASH_SECURE_AREA 5 +#define FLASH_PFOER_AREA 6 +#define FLASH_WRP_PROTECTED 7 +#define FLASH_FAILED 8 + +/* Helper to check success */ +#define FLASH_OP_OK(code) ((code) == FLASH_SUCCESS) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static mutex_t g_flash_lock = NXMUTEX_INITIALIZER; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static bool n32_flash_valid_addr(uintptr_t addr, size_t len) +{ + return (addr >= (N32_FLASH_BASE | N32_MTD_FLASH_BASE) && + addr + len <= (N32_FLASH_BASE | N32_MTD_FLASH_BASE) + + N32_MTD_FLASH_SIZE); +} + +static ssize_t n32_flash_verify_erased(uintptr_t addr, size_t len) +{ + const uint8_t *p = (const uint8_t *)addr; + size_t count = 0; + + for (size_t i = 0; i < len; i++) + { + if (p[i] != 0xff) + { + count++; + } + } + + return (ssize_t)count; +} + +/**************************************************************************** + * Public Functions – progmem API + ****************************************************************************/ + +size_t up_progmem_pagesize(size_t page) +{ + return N32_FLASH_PAGE_SIZE; +} + +size_t up_progmem_neraseblocks(void) +{ + return N32_FLASH_NBLOCKS; +} + +bool up_progmem_isuniform(void) +{ + return true; +} + +size_t up_progmem_erasesize(size_t block) +{ + if (block >= N32_FLASH_NBLOCKS) + { + return 0; + } + + return N32_FLASH_SECTOR_SIZE; +} + +size_t up_progmem_getaddress(size_t page) +{ + if (page >= N32_FLASH_NPAGES) + { + return SIZE_MAX; + } + + return (N32_FLASH_BASE | N32_MTD_FLASH_BASE) + page * N32_FLASH_PAGE_SIZE; +} + +ssize_t up_progmem_getpage(size_t addr) +{ + if (addr < (N32_FLASH_BASE | N32_MTD_FLASH_BASE) || addr >= (N32_FLASH_BASE + | N32_MTD_FLASH_BASE) + N32_MTD_FLASH_SIZE) + { + return -EFAULT; + } + + return (addr - (N32_FLASH_BASE | N32_MTD_FLASH_BASE)) / + N32_FLASH_PAGE_SIZE; +} + +ssize_t up_progmem_ispageerased(size_t page) +{ + size_t addr = up_progmem_getaddress(page); + + if (addr == SIZE_MAX) + { + return -EFAULT; + } + + return n32_flash_verify_erased(addr, N32_FLASH_PAGE_SIZE); +} + +ssize_t up_progmem_eraseblock(size_t block) +{ + int ret; + uint32_t status; + uintptr_t addr; + + if (block >= N32_FLASH_NBLOCKS) + { + return -EFAULT; + } + + addr = (N32_FLASH_BASE | N32_MTD_FLASH_BASE) + block * + N32_FLASH_SECTOR_SIZE; + + ret = nxmutex_lock(&g_flash_lock); + if (ret < 0) + { + return ret; + } + + /* Invalidate cache before erase */ + + up_invalidate_dcache(addr, addr + N32_FLASH_SECTOR_SIZE); + + status = ROM_ERASE_FUNC(addr); + if (!FLASH_OP_OK(status)) + { + finfo("Erase failed, status=%" PRIu32 "\n", status); + ret = -EIO; + goto unlock; + } + + /* Verify erased */ + + if (n32_flash_verify_erased(addr, N32_FLASH_SECTOR_SIZE) != 0) + { + ret = -EIO; + goto unlock; + } + + ret = (ssize_t)N32_FLASH_SECTOR_SIZE; + +unlock: + nxmutex_unlock(&g_flash_lock); + return ret; +} + +ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) +{ + int ret; + uint32_t status; + + if (!n32_flash_valid_addr(addr, count)) + { + return -EFAULT; + } + + ret = nxmutex_lock(&g_flash_lock); + if (ret < 0) + { + return ret; + } + + up_invalidate_dcache(addr, addr + count); + + status = ROM_WRITE_FUNC(addr, (uint8_t *)buf, count); + if (!FLASH_OP_OK(status)) + { + finfo("Write failed, status=%" PRIu32 "\n", status); + ret = -EIO; + goto unlock; + } + + if (memcmp((const void *)addr, buf, count) != 0) + { + ret = -EIO; + goto unlock; + } + + ret = (ssize_t)count; + +unlock: + nxmutex_unlock(&g_flash_lock); + return ret; +} + +uint8_t up_progmem_erasestate(void) +{ + return 0xff; +} diff --git a/arch/arm/src/n32h7/n32_flash.h b/arch/arm/src/n32h7/n32_flash.h new file mode 100644 index 0000000000000..6c31d9ee965ba --- /dev/null +++ b/arch/arm/src/n32h7/n32_flash.h @@ -0,0 +1,34 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_flash.h + * + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_FLASH_H +#define __ARCH_ARM_SRC_N32H7_N32_FLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "hardware/n32h7_memorymap.h" + +/* Flash geometry */ +#define N32_FLASH_SECTOR_SIZE (4 * 1024) /* 4KB sector */ +#define N32_FLASH_PAGE_SIZE (4 * 1024) /* 4KB page size */ + +#ifdef CONFIG_N32H7_FLASH_CONFIG_I +#define N32_MTD_FLASH_BASE (0x000E0000) +#define N32_MTD_FLASH_SIZE (0x00100000) +#endif /* CONFIG_N32H7_FLASH_CONFIG_I */ +#ifdef CONFIG_N32H7_FLASH_CONFIG_K +#define N32_MTD_FLASH_BASE (0x001E0000) +#define N32_MTD_FLASH_SIZE (0x00200000) +#endif /* CONFIG_N32H7_FLASH_CONFIG_K */ + +#define N32_FLASH_NBLOCKS (N32_MTD_FLASH_SIZE / N32_FLASH_SECTOR_SIZE) +#define N32_FLASH_NPAGES (N32_MTD_FLASH_SIZE / N32_FLASH_PAGE_SIZE) + +#endif /* __ARCH_ARM_SRC_N32H7_N32_FLASH_H */ diff --git a/arch/arm/src/n32h7/n32_gpio.c b/arch/arm/src/n32h7/n32_gpio.c new file mode 100644 index 0000000000000..71af4780b3fa7 --- /dev/null +++ b/arch/arm/src/n32h7/n32_gpio.c @@ -0,0 +1,444 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_gpio.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "arm_internal.h" +#include "hardware/n32h7_afio.h" +#include "n32_gpio.h" + +#if defined(CONFIG_N32H7_N32H76X) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static spinlock_t g_configgpio_lock = SP_UNLOCKED; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Base addresses for each GPIO block */ + +const uint32_t g_gpiobase[N32H7_NGPIO] = +{ + N32_GPIOA_BASE, + N32_GPIOB_BASE, + N32_GPIOC_BASE, + N32_GPIOD_BASE, +#if N32H7_NGPIO > 4 + N32_GPIOE_BASE, +#endif +#if N32H7_NGPIO > 5 + N32_GPIOF_BASE, +#endif +#if N32H7_NGPIO > 6 + N32_GPIOG_BASE, +#endif +#if N32H7_NGPIO > 7 + N32_GPIOH_BASE, +#endif +#if N32H7_NGPIO > 8 + N32_GPIOI_BASE, +#endif +#if N32H7_NGPIO > 9 + N32_GPIOJ_BASE, +#endif +#if N32H7_NGPIO > 10 + N32_GPIOK_BASE, +#endif +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: n32_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from n32_start(). + * + * Assumptions: + * This function is called early in the initialization sequence so that + * no mutual exclusion is necessary. + * + ****************************************************************************/ + +void n32_gpioinit(void) +{ +} + +/**************************************************************************** + * Name: n32_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 n32_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 n32_configgpio(uint32_t cfgset) +{ + uintptr_t base; + uint32_t regval; + uint32_t setting; + uint32_t alt_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 >= N32H7_NGPIO) + { + return -EINVAL; + } + + /* Get the port base address */ + + base = g_gpiobase[port]; + if (base == 0) + { + return -EINVAL; + } + + /* 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 */ + pinmode = GPIO_MODER_OUTPUT; + break; + + case GPIO_ALT: /* Alternate function mode */ + pinmode = GPIO_MODER_ALT; + break; + + case GPIO_ANALOG: /* Analog mode */ + pinmode = GPIO_MODER_ANALOG; + break; + } + + /* Interrupts must be disabled from here on out so that we have mutually + * exclusive access to all of the GPIO configuration registers. + */ + + flags = spin_lock_irqsave(&g_configgpio_lock); + + /* Determine the alternate function (Only alternate function pins) */ + + if (pinmode == GPIO_MODER_ALT) + { + setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; + } + else + { + setting = 0; + } + + if (pinmode == GPIO_MODER_ALT) + { + alt_setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; + } + else + { + alt_setting = 0; + } + + /* Set the alternate function (Only alternate function pins) + * This is done before configuring the Outputs on a change to + * an Alternate function. + */ + + if (pin < 8) + { + regoffset = N32_GPIO_AFL_OFFSET; + pos = pin; + } + else + { + regoffset = N32_GPIO_AFH_OFFSET; + pos = pin - 8; + } + + regval = getreg32(base + regoffset); + regval &= ~GPIO_AFR_MASK(pos); + regval |= (alt_setting << GPIO_AFR_SHIFT(pos)); + putreg32(regval, base + regoffset); + + /* Now apply the configuration to the mode register */ + + regval = getreg32(base + N32_GPIO_MODER_OFFSET); + regval &= ~GPIO_MODER_MASK(pin); + regval |= ((uint32_t)pinmode << GPIO_MODER_SHIFT(pin)); + putreg32(regval, base + N32_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 + N32_GPIO_PUPD_OFFSET); + regval &= ~GPIO_PUPDR_MASK(pin); + regval |= (setting << GPIO_PUPDR_SHIFT(pin)); + putreg32(regval, base + N32_GPIO_PUPD_OFFSET); + + /* Set drive strength (Only outputs and alternate function pins) */ + + if (pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) + { + switch (cfgset & GPIO_DRIVE_MASK) + { + default: + case GPIO_DRIVE_2mA: /* 2 MHz Low speed output */ + setting = GPIO_DS_2mA; + break; + + case GPIO_DRIVE_4mA: /* 4 mA */ + setting = GPIO_DS_4mA; + break; + + case GPIO_DRIVE_8mA: /* 8 mA */ + setting = GPIO_DS_8mA; + break; + + case GPIO_DRIVE_12mA: /* 12 mA */ + setting = GPIO_DS_12mA; + break; + } + } + else + { + setting = 0; + } + + regval = getreg32(base + N32_GPIO_DS_OFFSET); + regval &= ~GPIO_DS_MASK(pin); + regval |= (setting << GPIO_DS_SHIFT(pin)); + putreg32(regval, base + N32_GPIO_DS_OFFSET); + + /* Set slew rate (Only outputs and alternate function pins) */ + + regval = getreg32(base + N32_GPIO_SR_OFFSET); + setting = GPIO_SR_SLOW_SLEW(pin); + + if ((pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) && + (cfgset & GPIO_SLEW_RATE_SLOW) != 0) + { + regval |= setting; + } + else + { + regval &= ~setting; + } + + putreg32(regval, base + N32_GPIO_SR_OFFSET); + + /* Set push-pull/open-drain (Only outputs and alternate function pins) */ + + regval = getreg32(base + N32_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 + N32_GPIO_OTYPER_OFFSET); + + spin_unlock_irqrestore(&g_configgpio_lock, flags); + return OK; +} + +/**************************************************************************** + * Name: n32_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 n32_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 n32_configgpio(cfgset); +} + +/**************************************************************************** + * Name: n32_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void n32_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 < N32H7_NGPIO) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + if (base != 0) + { + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + + if (value) + { + bit = GPIO_PBSC_SET(pin); + } + else + { + bit = GPIO_PBSC_RESET(pin); + } + + putreg32(bit, base + N32_GPIO_PBSC_OFFSET); + } + } +} + +/**************************************************************************** + * Name: n32_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool n32_gpioread(uint32_t pinset) +{ + uint32_t base; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < N32H7_NGPIO) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + if (base != 0) + { + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(base + N32_GPIO_PID_OFFSET) & + (1 << pin)) != 0); + } + } + + return 0; +} + +#endif /* CONFIG_N32H7_N32H76X */ diff --git a/arch/arm/src/n32h7/n32_gpio.h b/arch/arm/src/n32h7/n32_gpio.h new file mode 100644 index 0000000000000..338d7934e987d --- /dev/null +++ b/arch/arm/src/n32h7/n32_gpio.h @@ -0,0 +1,366 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_gpio.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + + #ifndef __ARCH_ARM_SRC_N32H7_N32_GPIO_H + #define __ARCH_ARM_SRC_N32H7_N32_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +#include "chip.h" +#include "hardware/n32h7_gpio.h" +#include "hardware/n32h7_afio.h" + +/**************************************************************************** + * Pre-Processor Declarations + ****************************************************************************/ + +/* Bit-encoded input to n32_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 .... DDOS PPPP BBBB + * Alternate Functions: MMUU AAAA DDOS 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 drive current selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... DD.. .... .... + */ + +#define GPIO_DRIVE_SHIFT (10) /* Bits 10-11: GPIO drive current selection */ +#define GPIO_DRIVE_MASK (3 << GPIO_DRIVE_SHIFT) +# define GPIO_DRIVE_2mA (0 << GPIO_DRIVE_SHIFT) /* 2 mA Low drive current output */ +# define GPIO_DRIVE_4mA (2 << GPIO_DRIVE_SHIFT) /* 4 mA Medium drive current output */ +# define GPIO_DRIVE_8mA (1 << GPIO_DRIVE_SHIFT) /* 8 mA Fast drive current output */ +# define GPIO_DRIVE_12mA (3 << GPIO_DRIVE_SHIFT) /* 12 mA High drive current 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 */ + +/* Output/Alt function slew rate selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...S .... .... + */ + +#define GPIO_SLEW_RATE_SLOW (1 << 8) /* Bit 8: If output, initial value of output */ +#define GPIO_SLEW_RATE_FAST (0) + +/* 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 */ +#if N32H7_NGPIO > 4 +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ +#endif +#if N32H7_NGPIO > 5 +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) /* GPIOF */ +#endif +#if N32H7_NGPIO > 6 +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) /* GPIOG */ +#endif +#if N32H7_NGPIO > 7 +# define GPIO_PORTH (7 << GPIO_PORT_SHIFT) /* GPIOH */ +#endif +#if N32H7_NGPIO > 8 +# define GPIO_PORTI (8 << GPIO_PORT_SHIFT) /* GPIOI */ +#endif +#if N32H7_NGPIO > 9 +# define GPIO_PORTJ (9 << GPIO_PORT_SHIFT) /* GPIOJ */ +#endif +#if N32H7_NGPIO > 10 +# define GPIO_PORTK (10 << GPIO_PORT_SHIFT) /* GPIOK */ +#endif + +/* 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[N32H7_NGPIO]; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_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 n32_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 n32_configgpio(uint32_t cfgset); + +/**************************************************************************** + * Name: n32_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 n32_unconfiggpio(uint32_t cfgset); + +/**************************************************************************** + * Name: n32_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void n32_gpiowrite(uint32_t pinset, bool value); + +/**************************************************************************** + * Name: n32_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool n32_gpioread(uint32_t pinset); + +/**************************************************************************** + * Name: n32_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) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +int n32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func, void *arg); + +/**************************************************************************** + * Function: n32_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO_INFO +int n32_dumpgpio(uint32_t pinset, const char *msg); +#else +# define n32_dumpgpio(p,m) +#endif + +/**************************************************************************** + * Function: n32_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from n32_start(). + * + ****************************************************************************/ + +void n32_gpioinit(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_GPIO_H */ diff --git a/arch/arm/src/n32h7/n32_idle.c b/arch/arm/src/n32h7/n32_idle.c new file mode 100644 index 0000000000000..fcbc1868e53f8 --- /dev/null +++ b/arch/arm/src/n32h7/n32_idle.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_idle.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "n32_pm.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 + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(PM_IDLE_DOMAIN); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = enter_critical_section(); + + /* Perform board-specific, state-dependent logic here */ + + _info("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(PM_IDLE_DOMAIN, newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + pm_changestate(PM_IDLE_DOMAIN, oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + n32_pmstandby(); + break; + + case PM_SLEEP: + n32_pmsleep(false); + break; + + default: + break; + } + + leave_critical_section(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when there is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + nxsched_process_timer(); +#else + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power. + * + * + * "2.17.11 Ethernet DMA not working after WFI/WFE instruction + * Description + * If a WFI/WFE instruction is executed to put the system in sleep mode + * while the Ethernet MAC master clock on the AHB bus matrix is ON and + * all remaining masters clocks are OFF, the Ethernet DMA will be not + * able to perform any AHB master accesses during sleep mode." + * + * Workaround + * Enable DMA1 or DMA2 clocks in the RCC_AHBENR register before + * executing the WFI/WFE instruction." + * + */ + +#if 0 + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif +#endif +} diff --git a/arch/arm/src/n32h7/n32_irq.c b/arch/arm/src/n32h7/n32_irq.c new file mode 100644 index 0000000000000..28d31449ce847 --- /dev/null +++ b/arch/arm/src/n32h7/n32_irq.c @@ -0,0 +1,815 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_irq.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "arm_internal.h" + +#ifdef CONFIG_N32H7_GPIO_IRQ +# include "n32_gpio.h" +#endif + +/**************************************************************************** + * 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) + +#define SYSPRIORITY32 \ + ( ((NVIC_SYSH_PRIORITY_MAX+NVIC_SYSH_PRIORITY_STEP) << 24) | \ + ((NVIC_SYSH_PRIORITY_MAX+NVIC_SYSH_PRIORITY_STEP) << 16) | \ + ((NVIC_SYSH_PRIORITY_MAX+NVIC_SYSH_PRIORITY_STEP) << 8) | \ + ((NVIC_SYSH_PRIORITY_MAX+NVIC_SYSH_PRIORITY_STEP))) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ_INFO) +static void n32_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)); +#if 0 + irqinfo(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x " + "SYSTICK: %08x\n", + getreg32(NVIC_SYSHCON_MEMFAULTENA), + getreg32(NVIC_SYSHCON_BUSFAULTENA), + getreg32(NVIC_SYSHCON_USGFAULTENA), + getreg32(NVIC_SYSTICK_CTRL_ENABLE)); +#endif + 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)); +#if N32H7_IRQ_NEXTINTS > 15 + 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)); +#endif +#if N32H7_IRQ_NEXTINTS > 31 + 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)); +#endif +#if N32H7_IRQ_NEXTINTS > 47 + 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)); +#endif +#if N32H7_IRQ_NEXTINTS > 63 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY), + getreg32(NVIC_IRQ68_71_PRIORITY), + getreg32(NVIC_IRQ72_75_PRIORITY), + getreg32(NVIC_IRQ76_79_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 79 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ80_83_PRIORITY), + getreg32(NVIC_IRQ84_87_PRIORITY), + getreg32(NVIC_IRQ88_91_PRIORITY), + getreg32(NVIC_IRQ92_95_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 95 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ96_99_PRIORITY), + getreg32(NVIC_IRQ100_103_PRIORITY), + getreg32(NVIC_IRQ104_107_PRIORITY), + getreg32(NVIC_IRQ108_111_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 111 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ112_115_PRIORITY), + getreg32(NVIC_IRQ116_119_PRIORITY), + getreg32(NVIC_IRQ120_123_PRIORITY), + getreg32(NVIC_IRQ124_127_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 127 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ128_131_PRIORITY), + getreg32(NVIC_IRQ132_135_PRIORITY), + getreg32(NVIC_IRQ136_139_PRIORITY), + getreg32(NVIC_IRQ140_143_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 143 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ144_147_PRIORITY), + getreg32(NVIC_IRQ148_151_PRIORITY), + getreg32(NVIC_IRQ152_155_PRIORITY), + getreg32(NVIC_IRQ156_159_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 159 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ160_163_PRIORITY), + getreg32(NVIC_IRQ164_167_PRIORITY), + getreg32(NVIC_IRQ168_171_PRIORITY), + getreg32(NVIC_IRQ172_175_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 175 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ176_179_PRIORITY), + getreg32(NVIC_IRQ180_183_PRIORITY), + getreg32(NVIC_IRQ184_187_PRIORITY), + getreg32(NVIC_IRQ188_191_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 191 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ192_195_PRIORITY), + getreg32(NVIC_IRQ196_199_PRIORITY), + getreg32(NVIC_IRQ200_203_PRIORITY), + getreg32(NVIC_IRQ204_207_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 207 + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ208_211_PRIORITY), + getreg32(NVIC_IRQ212_215_PRIORITY), + getreg32(NVIC_IRQ216_219_PRIORITY), + getreg32(NVIC_IRQ220_223_PRIORITY)); +#endif +#if N32H7_IRQ_NEXTINTS > 223 + irqinfo(" %08x %08x %08x\n", + getreg32(NVIC_IRQ224_227_PRIORITY), + getreg32(NVIC_IRQ228_231_PRIORITY), + getreg32(NVIC_IRQ232_235_PRIORITY)); +#else +# error "Missing logic" +#endif + + /* TODO: Make sure this covers all interrupts that are available. */ + + leave_critical_section(flags); +} +#else +# define n32_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: n32_nmi, n32_pendsv, n32_pendsv, n32_reserved + * + * Description: + * Handlers for various exceptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +static int n32_nmi(int irq, void *context, void *arg) +{ + up_irq_save(); + _err("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int n32_pendsv(int irq, void *context, void *arg) +{ + up_irq_save(); + _err("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int n32_reserved(int irq, void *context, void *arg) +{ + up_irq_save(); + _err("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: n32_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +static inline void n32_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} + +/**************************************************************************** + * Name: n32_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int n32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + unsigned int extint = irq - N32_IRQ_FIRST; + + DEBUGASSERT(irq >= N32_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= N32_IRQ_FIRST) + { +#if N32H7_IRQ_NEXTINTS <= 32 + if (extint < N32H7_IRQ_NEXTINTS) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else +#elif N32H7_IRQ_NEXTINTS <= 64 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < N32H7_IRQ_NEXTINTS) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else +#elif N32H7_IRQ_NEXTINTS <= 96 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < N32H7_IRQ_NEXTINTS) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else +#elif N32H7_IRQ_NEXTINTS <= 128 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < 96) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else if (extint < N32H7_IRQ_NEXTINTS) + { + *regaddr = (NVIC_IRQ96_127_ENABLE + offset); + *bit = 1 << (extint - 96); + } + else +#elif N32H7_IRQ_NEXTINTS <= 160 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < 96) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else if (extint < 128) + { + *regaddr = (NVIC_IRQ96_127_ENABLE + offset); + *bit = 1 << (extint - 96); + } + else if (extint < N32H7_IRQ_NEXTINTS) + { + *regaddr = (NVIC_IRQ128_159_ENABLE + offset); + *bit = 1 << (extint - 128); + } + else +#elif N32H7_IRQ_NEXTINTS <= 192 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < 96) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else if (extint < 128) + { + *regaddr = (NVIC_IRQ96_127_ENABLE + offset); + *bit = 1 << (extint - 96); + } + else if (extint < 160) + { + *regaddr = (NVIC_IRQ128_159_ENABLE + offset); + *bit = 1 << (extint - 128); + } + else if (extint < N32H7_IRQ_NEXTINTS) + { + *regaddr = (NVIC_IRQ160_191_ENABLE + offset); + *bit = 1 << (extint - 160); + } + else +#elif N32H7_IRQ_NEXTINTS <= 224 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < 96) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else if (extint < 128) + { + *regaddr = (NVIC_IRQ96_127_ENABLE + offset); + *bit = 1 << (extint - 96); + } + else if (extint < 160) + { + *regaddr = (NVIC_IRQ128_159_ENABLE + offset); + *bit = 1 << (extint - 128); + } + else if (extint < 192) + { + *regaddr = (NVIC_IRQ160_191_ENABLE + offset); + *bit = 1 << (extint - 160); + } + else if (extint < N32H7_IRQ_NEXTINTS) + { + *regaddr = (NVIC_IRQ192_223_ENABLE + offset); + *bit = 1 << (extint - 192); + } + else +#elif N32H7_IRQ_NEXTINTS <= 256 + if (extint < 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << extint; + } + else if (extint < 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (extint - 32); + } + else if (extint < 96) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (extint - 64); + } + else if (extint < 128) + { + *regaddr = (NVIC_IRQ96_127_ENABLE + offset); + *bit = 1 << (extint - 96); + } + else if (extint < 160) + { + *regaddr = (NVIC_IRQ128_159_ENABLE + offset); + *bit = 1 << (extint - 128); + } + else if (extint < 192) + { + *regaddr = (NVIC_IRQ160_191_ENABLE + offset); + *bit = 1 << (extint - 160); + } + else if (extint < N32H7_IRQ_NEXTINTS) + { + *regaddr = (NVIC_IRQ192_223_ENABLE + offset); + *bit = 1 << (extint - 192); + } + else +#else +# warning Missing logic +#endif + { + return ERROR; /* Invalid interrupt */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == N32_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == N32_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == N32_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == N32_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 + * + * Description: + * Initialize the NVIC interrupt controller. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uintptr_t regaddr; + int nintlines; + int i; + + /* The NVIC ICTR register (bits 0-4) holds the number of interrupt + * lines that the NVIC supports, defined in groups of 32. That is, + * the total number of interrupt lines is up to (32*(INTLINESNUM+1)). + * + * 0 -> 32 interrupt lines, 1 enable register, 8 priority registers + * 1 -> 64 " " " ", 2 enable registers, 16 priority registers + * 2 -> 96 " " " ", 3 enable registers, 24 priority registers + * ... + */ + + nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1; + + /* Disable all interrupts. There are nintlines interrupt enable + * registers. + */ + + for (i = nintlines, regaddr = NVIC_IRQ0_31_CLEAR; + i > 0; + i--, regaddr += 4) + { + putreg32(0xffffffff, regaddr); + } + + /* Make sure that we are using the correct vector table. The default + * vector address is 0x0000:0000 but if we are executing code that is + * positioned in SRAM or in external FLASH, then we may need to reset + * the interrupt vector so that it refers to the table in SRAM or in + * external FLASH. + */ + + 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. + */ + + arm_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(SYSPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* Now set all of the interrupt lines to the default priority. There are + * nintlines * 8 priority registers. + */ + + for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY; + i > 0; + i--, regaddr += 4) + { + putreg32(DEFPRIORITY32, regaddr); + } + + /* 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(N32_IRQ_SVCALL, arm_svcall, NULL); + irq_attach(N32_IRQ_HARDFAULT, arm_hardfault, NULL); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(N32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif + n32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(N32_IRQ_MEMFAULT, arm_memfault, NULL); + up_enable_irq(N32_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG_FEATURES + irq_attach(N32_IRQ_NMI, n32_nmi, NULL); +#ifndef CONFIG_ARM_MPU + irq_attach(N32_IRQ_MEMFAULT, arm_memfault, NULL); +#endif + irq_attach(N32_IRQ_BUSFAULT, arm_busfault, NULL); + irq_attach(N32_IRQ_USAGEFAULT, arm_usagefault, NULL); + irq_attach(N32_IRQ_PENDSV, n32_pendsv, NULL); + arm_enable_dbgmonitor(); + irq_attach(N32_IRQ_DBGMONITOR, arm_dbgmonitor, NULL); + irq_attach(N32_IRQ_RESERVED, n32_reserved, NULL); +#endif + + n32_dumpnvic("initial", NR_IRQS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + */ + +#ifdef CONFIG_N32H7_GPIO_IRQ + n32_gpioirqinitialize(); +#endif + + /* 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 (n32_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 >= N32_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_N32H7_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + n32_gpioirqdisable(irq); + } +#endif + +#if 0 /* Might be useful in early bring-up */ + n32_dumpnvic("disable", irq); +#endif +} + +/**************************************************************************** + * 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 (n32_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 >= N32_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } +#ifdef CONFIG_N32H7_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + n32_gpioirqenable(irq); + } +#endif + +#if 0 /* Might be useful in early bring-up */ + n32_dumpnvic("enable", irq); +#endif +} + +/**************************************************************************** + * 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 >= N32_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < N32_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 -= N32_IRQ_FIRST; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + n32_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/n32h7/n32_lowputc.c b/arch/arm/src/n32h7/n32_lowputc.c new file mode 100644 index 0000000000000..d1c37758adba4 --- /dev/null +++ b/arch/arm/src/n32h7/n32_lowputc.c @@ -0,0 +1,274 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_lowputc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "arm_internal.h" +#include "chip.h" + +#include "hardware/n32h7_pinmap.h" +#include "hardware/n32h7_uart.h" +#include "n32_lowputc.h" +#include "n32_rcc.h" +#include "n32_gpio.h" +#include "n32_uart.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select USART parameters for the selected console */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_USART1_SERIAL_CONSOLE) +# define N32_CONSOLE_BASE N32_USART1_BASE +# define N32_AHBCLOCK N32_AHB_FREQUENCY +# define N32_CONSOLE_APBREG N32_RCC_APB1EN3 +# define N32_CONSOLE_APBEN RCC_APB1EN3_M7USART1EN +# define N32_CONSOLE_BAUD CONFIG_USART1_BAUD +# define N32_CONSOLE_BITS CONFIG_USART1_BITS +# define N32_CONSOLE_PARITY CONFIG_USART1_PARITY +# define N32_CONSOLE_2STOP CONFIG_USART1_2STOP +# define N32_CONSOLE_TX GPIO_USART1_TX +# define N32_CONSOLE_RX GPIO_USART1_RX +# else +# error "No valid console configuration" +# endif + + /* CTRL1 settings */ + +# if N32_CONSOLE_BITS == 9 +# define CTRL1_WL USART_CTRL1_WL +# else /* N32_CONSOLE_BITS == 8 */ +# define CTRL1_WL 0b0 +# endif + +# if N32_CONSOLE_PARITY == 1 +# define CTRL1_PARITY (USART_CTRL1_PCEN | USART_CTRL1_PSEL) +# elif N32_CONSOLE_PARITY == 2 +# define CTRL1_PARITY USART_CTRL1_PCEN +# else +# define CTRL1_PARITY 0b00 +# endif + +# define USART_CTRL1_CLRBITS (USART_CTRL1_RXEN | USART_CTRL1_TXEN \ + |USART_CTRL1_PSEL | USART_CTRL1_PCEN \ + |USART_CTRL1_OSPM | USART_CTRL1_WL) + +# define USART_CTRL1_SETBITS (CTRL1_WL | CTRL1_PARITY ) + + /* CTRL2 settings */ + +# if N32_CONSOLE_2STOP != 0 +# define CTRL2_STOP2 USART_CTRL2_STPB(N32_CONSOLE_2STOP) +# else +# define CTRL2_STOP2 0b0 +# endif + +# define USART_CTRL2_CLRBITS (USART_CTRL2_STPB_MASK) + +# define USART_CTRL2_SETBITS CTRL2_STOP2 + + /* CTRL3 settings */ + +# define USART_CTRL3_CLRBITS (USART_CTRL3_CTSEN | USART_CTRL3_RTSEN) + +# define USART_CTRL3_SETBITS 0 + + /* Calculate USART BAUD rate divider */ + + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / (16 * UARTDIV) + * UARTDIV = fCK / (16 * baud) + * + */ + +# define N32_USARTDIV16 \ + ((25 * (N32_AHBCLOCK / 4)) / (N32_CONSOLE_BAUD)) +# define N32_USARTDIV8 \ + ((25 * (N32_AHBCLOCK / 2)) / (N32_CONSOLE_BAUD)) + + /* Use oversampling by 8 only if the divisor is small. But what is + * small? + */ +# undef USE_OVER8 +# if N32_USARTDIV8 > 100 +# define N32_UART_DIV N32_USARTDIV16 +# else +# define USE_OVER8 1 +# define N32_UART_DIV \ + ((N32_USARTDIV8 & 0xfff0) | ((N32_USARTDIV8 & 0x000f) >> 1)) +# endif +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_lowputc + * + * Desregvaliption: + * 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(N32_CONSOLE_BASE + N32_USART_STS_OFFSET) & + USART_STS_TXDE) == 0); + + /* Then send the character */ + + putreg32((uint32_t)ch, N32_CONSOLE_BASE + N32_USART_DAT_OFFSET); + +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * Name: n32_lowsetup + * + * Desregvaliption: + * 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 n32_lowsetup(void) +{ +#if defined(HAVE_UART) +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint32_t regval; + uint32_t tmp; +#endif + +#if defined(HAVE_CONSOLE) + /* Enable USART APB1/2 clock */ + + modifyreg32(N32_CONSOLE_APBREG, 0, N32_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 n32_rcc.c + */ + +#ifdef N32_CONSOLE_TX + n32_configgpio(N32_CONSOLE_TX); +#endif +#ifdef N32_CONSOLE_RX + n32_configgpio(N32_CONSOLE_RX); +#endif + + /* Enable and configure the selected console device */ + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Configure CTRL2 */ + + regval = getreg32(N32_CONSOLE_BASE + N32_USART_CTRL2_OFFSET); + regval &= ~USART_CTRL2_CLRBITS; + regval |= USART_CTRL2_SETBITS; + putreg32(regval, N32_CONSOLE_BASE + N32_USART_CTRL2_OFFSET); + + /* Configure CTRL1 */ + + regval = getreg32(N32_CONSOLE_BASE + N32_USART_CTRL1_OFFSET); + regval &= ~USART_CTRL1_CLRBITS; + regval |= USART_CTRL1_SETBITS; +#ifdef USE_OVER8 + regval |= USART_CTRL1_OSPM; +#endif + putreg32(regval, N32_CONSOLE_BASE + N32_USART_CTRL1_OFFSET); + + /* Configure CTRL3 */ + + regval = getreg32(N32_CONSOLE_BASE + N32_USART_CTRL3_OFFSET); + regval &= ~USART_CTRL3_CLRBITS; + regval |= USART_CTRL3_SETBITS; + putreg32(regval, N32_CONSOLE_BASE + N32_USART_CTRL3_OFFSET); + + /* Configure the USART Baud Rate */ + + regval = (N32_UART_DIV / 100) << 4; + tmp = N32_UART_DIV - ((regval >> 4) * 100); +#ifdef USE_OVER8 + tmp = ((((tmp * 8) + 50) / 100)) & ((uint8_t)0x0f); + if (tmp == 0x08) + { + regval = regval | 0x10; + } + else + { + regval |= tmp; + } +#else + + /* Oversampling mode is 16 Samples */ + + regval += ((((tmp * 16) + 50) / 100)) & ((uint8_t)0x1f); +#endif + putreg32(regval, N32_CONSOLE_BASE + N32_USART_BRCF_OFFSET); + + /* Enable Rx, Tx and the USART */ + + regval = getreg32(N32_CONSOLE_BASE + N32_USART_CTRL1_OFFSET); + regval |= (USART_CTRL1_UEN | USART_CTRL1_TXEN | USART_CTRL1_RXEN); + putreg32(regval, N32_CONSOLE_BASE + N32_USART_CTRL1_OFFSET); + +#endif /* HAVE_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} diff --git a/arch/arm/src/n32h7/n32_lowputc.h b/arch/arm/src/n32h7/n32_lowputc.h new file mode 100644 index 0000000000000..7c4104634c247 --- /dev/null +++ b/arch/arm/src/n32h7/n32_lowputc.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_lowputc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_LOWPUTC_H +#define __ARCH_ARM_SRC_N32H7_N32_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: n32_lowsetup + * + * Description: + * Called at the very beginning of _start. + * Performs low level initialization of serial console. + * + ****************************************************************************/ + +void n32_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_LOWPUTC_H */ diff --git a/arch/arm/src/n32h7/n32_mpuinit.c b/arch/arm/src/n32h7/n32_mpuinit.c new file mode 100644 index 0000000000000..6541fa237d302 --- /dev/null +++ b/arch/arm/src/n32h7/n32_mpuinit.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_mpuinit.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifdef CONFIG_BUILD_PROTECTED +# include +#endif + +#include "mpu.h" +#include "hardware/n32h7_memorymap.h" +#include "n32_mpuinit.h" +#include "arm_internal.h" + +#ifdef CONFIG_ARM_MPU + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_RPTUN +# ifdef CONFIG_N32H7_SHMEM_SRAM3 +# define N32_SHMEM_BASE N32_SRAM3_BASE +# define N32_SHMEM_SIZE N32H7_SRAM3_SIZE +# else +# error missing shmem MPU configuration +# endif +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_mpuinitialize + * + * Description: + * Configure the MPU. + * + * If PROTECTED build: + * - permit user-space access to only restricted N32 resources. + * + * If RPTUN: + * - configure shared memory as non-cacheable + * + ****************************************************************************/ + +void n32_mpuinitialize(void) +{ +#ifdef CONFIG_BUILD_PROTECTED + 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); +#endif + + /* Show MPU information */ + + mpu_showtype(); + + /* Reset MPU if enabled */ + + mpu_reset(); + +#ifdef CONFIG_BUILD_PROTECTED + /* Configure user flash and SRAM space */ + + mpu_user_flash(USERSPACE->us_textstart, + USERSPACE->us_textend - USERSPACE->us_textstart); + + mpu_user_intsram(datastart, dataend - datastart); +#endif + +#ifdef CONFIG_RPTUN + /* Configure shared memory as non-cacheable */ + + mpu_priv_shmem((uintptr_t)N32_SHMEM_BASE, N32_SHMEM_SIZE); +#endif + + /* Then enable the MPU */ + + mpu_control(true, false, true); +} + +#ifdef CONFIG_BUILD_PROTECTED +/**************************************************************************** + * Name: n32_mpu_uheap + * + * Description: + * Map the user-heap region. + * + * This logic may need an extension to handle external SDRAM). + * + ****************************************************************************/ + +void n32_mpu_uheap(uintptr_t start, size_t size) +{ + mpu_user_intsram(start, size); +} +#endif + +#endif /* CONFIG_ARM_MPU */ diff --git a/arch/arm/src/n32h7/n32_mpuinit.h b/arch/arm/src/n32h7/n32_mpuinit.h new file mode 100644 index 0000000000000..501bab2881f8f --- /dev/null +++ b/arch/arm/src/n32h7/n32_mpuinit.h @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_mpuinit.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_MPUINIT_H +#define __ARCH_ARM_SRC_N32H7_N32_MPUINIT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_mpuinitialize + * + * Description: + * Configure the MPU. + * + ****************************************************************************/ + +#ifdef CONFIG_ARM_MPU +void n32_mpuinitialize(void); +#else +# define n32_mpuinitialize() +#endif + +/**************************************************************************** + * Name: n32_mpu_uheap + * + * Description: + * Map the user heap region. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_PROTECTED +void n32_mpu_uheap(uintptr_t start, size_t size); +#else +# define n32_mpu_uheap(start,size) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_MPUINIT_H */ diff --git a/arch/arm/src/n32h7/n32_oneshot.c b/arch/arm/src/n32h7/n32_oneshot.c new file mode 100644 index 0000000000000..0be2e3b351a10 --- /dev/null +++ b/arch/arm/src/n32h7/n32_oneshot.c @@ -0,0 +1,462 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_oneshot.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "n32_oneshot.h" + +#ifdef CONFIG_N32H7_ONESHOT + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int n32_oneshot_handler(int irg_num, void *context, void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct n32_oneshot_s *g_oneshot[CONFIG_N32H7_ONESHOT_MAXCHANNELS]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_oneshot_handler + * + * Description: + * Common timer interrupt callback. When any oneshot timer interrupt + * expires, this function will be called. It will forward the call to + * the next level up. + * + * Input Parameters: + * oneshot - The state associated with the expired timer + * + * Returned Value: + * Always returns OK + * + ****************************************************************************/ + +static int n32_oneshot_handler(int irg_num, void *context, void *arg) +{ + struct n32_oneshot_s *oneshot = (struct n32_oneshot_s *)arg; + n32_oneshot_handler_t oneshot_handler; + void *oneshot_arg; + + tmrinfo("Expired (Interrupt)...\n"); + DEBUGASSERT(oneshot != NULL && oneshot->handler); + + /* The clock was stopped, but not disabled when the CC match occurred. + * Disable the TC now and disable any further interrupts. + */ + + N32_TIM_SETISR(oneshot->tch, NULL, NULL, N32_TIM_ISR_CC); + N32_TIM_DISABLEINT(oneshot->tch, N32_ONESHOT_CCIE(oneshot->channel)); + N32_TIM_SETMODE(oneshot->tch, N32_TIM_MODE_DISABLED); + N32_TIM_ACKINT(oneshot->tch, N32_ONESHOT_CCIF(oneshot->channel)); + + /* The timer is no longer running */ + + oneshot->running = false; + + /* Forward the event, clearing out any vestiges */ + + oneshot_handler = oneshot->handler; + oneshot->handler = NULL; + oneshot_arg = (void *)oneshot->arg; + oneshot->arg = NULL; + + oneshot_handler(oneshot_arg); + return OK; +} + +/**************************************************************************** + * Name: n32_allocate_handler + * + * Description: + * Allocate a timer callback handler for the oneshot instance. + * + * Input Parameters: + * oneshot - The state instance the new oneshot timer + * + * Returned Value: + * Returns zero (OK) on success. This can only fail if the number of + * timers exceeds CONFIG_N32H7_ONESHOT_MAXCHANNELS. + * + ****************************************************************************/ + +static inline int n32_allocate_handler(struct n32_oneshot_s *oneshot) +{ +#if CONFIG_N32H7_ONESHOT_MAXCHANNELS > 1 + int ret = -EBUSY; + int i; + + /* Search for an unused handler */ + + for (i = 0; i < CONFIG_N32H7_ONESHOT_MAXCHANNELS; i++) + { + /* Is this handler available? */ + + if (g_oneshot[i] == NULL) + { + /* Yes... assign it to this oneshot */ + + g_oneshot[i] = oneshot; + oneshot->cbndx = i; + ret = OK; + break; + } + } + + return ret; + +#else + if (g_oneshot[0] == NULL) + { + g_oneshot[0] = oneshot; + return OK; + } + + return -EBUSY; +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_oneshot_initialize + * + * Description: + * Initialize the oneshot timer wrapper + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure + * timer Timer number (1-18, see n32_tim_init mapping) + * channel Capture/compare channel (1-4) + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int n32_oneshot_initialize(struct n32_oneshot_s *oneshot, int timer, + int channel, uint16_t resolution) +{ + uint32_t frequency; + + tmrinfo("timer=%d channel=%d resolution=%u usec, USEC_PER_SEC:%ld\n", + timer, channel, resolution, USEC_PER_SEC); + DEBUGASSERT(oneshot && resolution > 0); + DEBUGASSERT(timer >= 1 && timer <= 18); + DEBUGASSERT(channel >= 1 && channel <= 4); + + /* Get the TC frequency that corresponds to the requested resolution */ + + frequency = USEC_PER_SEC / (uint32_t)resolution; + tmrinfo("frequency: %" PRIu32 "\n", frequency); + oneshot->frequency = frequency; + + /* Store timer and channel information */ + + oneshot->timer = timer; + oneshot->channel = channel; + + /* Initialize the timer hardware. + * n32_tim_init() takes the timer number (1-18). + */ + + oneshot->tch = n32_tim_init(timer); + if (!oneshot->tch) + { + tmrerr("ERROR: Failed to allocate TIM%d\n", timer); + return -EBUSY; + } + + N32_TIM_SETCLOCK(oneshot->tch, frequency); + + /* Initialize the remaining fields in the state structure. */ + + oneshot->running = false; + oneshot->handler = NULL; + oneshot->arg = NULL; + oneshot->period = 0; + + /* Assign a callback handler to the oneshot */ + + return n32_allocate_handler(oneshot); +} + +/**************************************************************************** + * Name: n32_oneshot_max_delay + * + * Description: + * Determine the maximum delay of the one-shot timer (in microseconds) + * + ****************************************************************************/ + +int n32_oneshot_max_delay(struct n32_oneshot_s *oneshot, uint64_t *usec) +{ + int width; + + DEBUGASSERT(oneshot != NULL && usec != NULL); + + width = N32_TIM_GETWIDTH(oneshot->tch); + + tmrinfo("frequency: %" PRIu32 ", USEC_PER_SEC: %ld, width: %d\n", + oneshot->frequency, USEC_PER_SEC, width); + + if (width == 32) + { + *usec = ((uint64_t)UINT32_MAX * (uint64_t)USEC_PER_SEC) / + (uint64_t)oneshot->frequency; + } + else + { + *usec = ((uint64_t)UINT16_MAX * (uint64_t)USEC_PER_SEC) / + (uint64_t)oneshot->frequency; + } + + return OK; +} + +/**************************************************************************** + * Name: n32_oneshot_start + * + * Description: + * Start the oneshot timer + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * n32_oneshot_initialize(); + * handler The function to call when when the oneshot timer expires. + * arg An opaque argument that will accompany the callback. + * ts Provides the duration of the one shot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int n32_oneshot_start(struct n32_oneshot_s *oneshot, + n32_oneshot_handler_t handler, void *arg, + const struct timespec *ts) +{ + uint64_t usec; + uint64_t period; + irqstate_t flags; + + tmrinfo("handler=%p arg=%p, ts=(%lu, %lu)\n", handler, arg, + (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + DEBUGASSERT(oneshot && handler && ts); + DEBUGASSERT(oneshot->tch); + + /* Was the oneshot already running? */ + + flags = enter_critical_section(); + if (oneshot->running) + { + /* Yes.. then cancel it */ + + tmrinfo("Already running... cancelling\n"); + n32_oneshot_cancel(oneshot, NULL); + } + + /* Save the new handler and its argument */ + + oneshot->handler = handler; + oneshot->arg = arg; + + /* Express the delay in microseconds */ + + usec = (uint64_t)ts->tv_sec * USEC_PER_SEC + + (uint64_t)(ts->tv_nsec / NSEC_PER_USEC); + + /* Get the timer counter frequency and determine the number of counts need + * to achieve the requested delay. + * + * frequency = ticks / second + * ticks = seconds * frequency + * = (usecs * frequency) / USEC_PER_SEC; + */ + + period = (usec * (uint64_t)oneshot->frequency) / USEC_PER_SEC; + + tmrinfo("usec=%llu period=%08llx\n", usec, period); + DEBUGASSERT(period <= UINT32_MAX); + + /* Set up to receive the callback when the interrupt occurs */ + + N32_TIM_SETISR(oneshot->tch, n32_oneshot_handler, oneshot, N32_TIM_ISR_CC); + + /* Set timer period (auto-reload) to the calculated period */ + + oneshot->period = (uint32_t)period; + N32_TIM_SETPERIOD(oneshot->tch, (uint32_t)period); + + /* Set the compare register using the channel number */ + + N32_TIM_SETCOMPARE(oneshot->tch, oneshot->channel, (uint32_t)period); + + /* Start the counter in up-count mode (one-shot pulse mode) */ + + N32_TIM_SETMODE(oneshot->tch, N32_TIM_MODE_PULSE); + + /* Acknowledge any pending interrupt and enable the CC interrupt */ + + N32_TIM_ACKINT(oneshot->tch, N32_ONESHOT_CCIF(oneshot->channel)); + N32_TIM_ENABLEINT(oneshot->tch, N32_ONESHOT_CCIE(oneshot->channel)); + + /* Enable interrupts. We should get the callback when the interrupt + * occurs. + */ + + oneshot->running = true; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: n32_oneshot_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + * NOTE: This function may execute at a high rate with no timer running (as + * when pre-emption is enabled and disabled). + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * n32_oneshot_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. A time of zero is returned if the timer is + * not running. ts may be zero in which case the time remaining + * is not returned. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +int n32_oneshot_cancel(struct n32_oneshot_s *oneshot, + struct timespec *ts) +{ + irqstate_t flags; + uint32_t count; + uint32_t period; + uint64_t usec; + + /* Was the timer running? */ + + flags = enter_critical_section(); + if (!oneshot->running) + { + /* No.. Just return zero timer remaining and successful cancellation. + * This function may execute at a high rate with no timer running + * (as when pre-emption is enabled and disabled). + */ + + if (ts) + { + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + + leave_critical_section(flags); + return OK; + } + + tmrinfo("Cancelling...\n"); + + /* Now we can disable the interrupt and stop the timer. */ + + N32_TIM_DISABLEINT(oneshot->tch, N32_ONESHOT_CCIE(oneshot->channel)); + N32_TIM_SETISR(oneshot->tch, NULL, NULL, N32_TIM_ISR_CC); + N32_TIM_SETMODE(oneshot->tch, N32_TIM_MODE_DISABLED); + + /* Get the current counter value and period */ + + count = N32_TIM_GETCOUNTER(oneshot->tch); + period = oneshot->period; + + oneshot->running = false; + oneshot->handler = NULL; + oneshot->arg = NULL; + leave_critical_section(flags); + + /* Did the caller provide us with a location to return the time + * remaining? + */ + + if (ts) + { + /* Calculate remaining time in microseconds */ + + if (count < period) + { + usec = ((uint64_t)(period - count) * USEC_PER_SEC) / + oneshot->frequency; + } + else + { + usec = 0; + } + + ts->tv_sec = (time_t)(usec / USEC_PER_SEC); + ts->tv_nsec = (long)((usec - (uint64_t)(ts->tv_sec * USEC_PER_SEC)) * + NSEC_PER_USEC); + + tmrinfo("Remaining: %lu sec, %lu nsec\n", + (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + } + + return OK; +} + +#endif /* CONFIG_N32H7_ONESHOT */ diff --git a/arch/arm/src/n32h7/n32_oneshot.h b/arch/arm/src/n32h7/n32_oneshot.h new file mode 100644 index 0000000000000..0921674828369 --- /dev/null +++ b/arch/arm/src/n32h7/n32_oneshot.h @@ -0,0 +1,179 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_oneshot.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_ONESHOT_H +#define __ARCH_ARM_SRC_N32H7_N32_ONESHOT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "n32_tim.h" + +#ifdef CONFIG_N32H7_ONESHOT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if !defined(CONFIG_N32H7_ONESHOT_MAXCHANNELS) || \ + CONFIG_N32H7_ONESHOT_MAXCHANNELS < 1 +# undef CONFIG_N32H7_ONESHOT_MAXCHANNELS +# define CONFIG_N32H7_ONESHOT_MAXCHANNELS 1 +#endif + +#if CONFIG_N32H7_ONESHOT_MAXCHANNELS > 8 +# warning Additional logic required to handle more than 8 timers +# undef CONFIG_N32H7_ONESHOT_MAXCHANNELS +# define CONFIG_N32H7_ONESHOT_MAXCHANNELS 8 +#endif + +/* Interrupt source for oneshot timer (capture/compare interrupt) */ + +#define N32_ONESHOT_CCIE(ch) \ + (N32_ATIM_DINTEN_CC1IEN << ((ch) - 1)) + +#define N32_ONESHOT_CCIF(ch) \ + (N32_ATIM_STS_CC1ITF << ((ch) - 1)) + +#define N32_ONESHOT_UIE N32_ATIM_DINTEN_UIEN +#define N32_ONESHOT_UIF N32_ATIM_STS_UDITF + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This describes the callback function that will be invoked when the oneshot + * timer expires. The oneshot fires, the client will receive: + * + * arg - The opaque argument provided when the interrupt was registered + */ + +typedef void (*n32_oneshot_handler_t)(void *arg); + +/* The oneshot client must allocate an instance of this structure and call + * n32_oneshot_initialize() before using the oneshot facilities. The client + * should not access the contents of this structure directly since the + * contents are subject to change. + */ + +struct n32_oneshot_s +{ + uint8_t timer; /* Timer number (1 for ATIM1, 3 for GTIMA1, etc.) */ + uint8_t channel; /* CC channel (1-4) */ +#if CONFIG_N32H7_ONESHOT_MAXCHANNELS > 1 + uint8_t cbndx; /* Timer callback handler index */ +#endif + volatile bool running; /* True: the timer is running */ + struct n32_tim_dev_s *tch; /* Pointer returned by n32_tim_init() */ + volatile n32_oneshot_handler_t handler; /* Oneshot expiration callback */ + volatile void *arg; /* The argument that will accompany the callback */ + uint32_t frequency; /* Timer clock frequency */ + uint32_t period; /* Current period in ticks */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_oneshot_initialize + * + * Description: + * Initialize the oneshot timer wrapper (internal use) + * + * Input Parameters: + * oneshot Caller allocated instance of the oneshot state structure + * timer Timer number (1-18, see n32_tim_init mapping) + * channel Capture/compare channel (1-4) + * resolution The required resolution of the timer in units of + * microseconds. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int n32_oneshot_initialize(struct n32_oneshot_s *oneshot, int timer, + int channel, uint16_t resolution); + +/**************************************************************************** + * Name: n32_oneshot_max_delay + * + * Description: + * Determine the maximum delay of the one-shot timer (in microseconds) + * + ****************************************************************************/ + +int n32_oneshot_max_delay(struct n32_oneshot_s *oneshot, uint64_t *usec); + +/**************************************************************************** + * Name: n32_oneshot_start + * + * Description: + * Start the oneshot timer + * + ****************************************************************************/ + +int n32_oneshot_start(struct n32_oneshot_s *oneshot, + n32_oneshot_handler_t handler, void *arg, + const struct timespec *ts); + +/**************************************************************************** + * Name: n32_oneshot_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + ****************************************************************************/ + +int n32_oneshot_cancel(struct n32_oneshot_s *oneshot, + struct timespec *ts); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_N32H7_ONESHOT */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_ONESHOT_H */ diff --git a/arch/arm/src/n32h7/n32_oneshot_lowerhalf.c b/arch/arm/src/n32h7/n32_oneshot_lowerhalf.c new file mode 100644 index 0000000000000..e249ab7ce8961 --- /dev/null +++ b/arch/arm/src/n32h7/n32_oneshot_lowerhalf.c @@ -0,0 +1,354 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_oneshot_lowerhalf.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "n32_oneshot.h" + +#ifdef CONFIG_ONESHOT + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the state of the oneshot timer lower-half driver + */ + +struct n32_oneshot_lowerhalf_s +{ + /* This is the part of the lower half driver that is visible to the upper- + * half client of the driver. This must be the first thing in this + * structure so that pointers to struct oneshot_lowerhalf_s are cast + * compatible to struct n32_oneshot_lowerhalf_s and vice versa. + */ + + struct oneshot_lowerhalf_s lh; /* Common lower-half driver fields */ + + /* Private lower half data follows */ + + struct n32_oneshot_s oneshot; /* N32-specific oneshot state */ + oneshot_callback_t callback; /* Internal handler that receives callback */ + void *arg; /* Argument that is passed to the handler */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void n32_oneshot_handler(void *arg); + +static int n32_max_delay(struct oneshot_lowerhalf_s *lower, + struct timespec *ts); +static int n32_start(struct oneshot_lowerhalf_s *lower, + const struct timespec *ts); +static int n32_cancel(struct oneshot_lowerhalf_s *lower, + struct timespec *ts); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Lower half operations */ + +static const struct oneshot_operations_s g_oneshot_ops = +{ + .max_delay = n32_max_delay, + .start = n32_start, + .cancel = n32_cancel, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_oneshot_handler + * + * Description: + * Timer expiration handler + * + * Input Parameters: + * arg - Should be the same argument provided when n32_oneshot_start() + * was called. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_oneshot_handler(void *arg) +{ + struct n32_oneshot_lowerhalf_s *priv = + (struct n32_oneshot_lowerhalf_s *)arg; + oneshot_callback_t callback; + void *cbarg; + + DEBUGASSERT(priv != NULL); + + /* Perhaps the callback was nullified in a race condition with + * n32_cancel? + */ + + if (priv->callback) + { + /* Sample and nullify BEFORE executing callback (in case the callback + * restarts the oneshot). + */ + + callback = priv->callback; + cbarg = priv->arg; + priv->callback = NULL; + priv->arg = NULL; + + /* Then perform the callback */ + + callback(&priv->lh, cbarg); + } +} + +/**************************************************************************** + * Name: n32_max_delay + * + * Description: + * Determine the maximum delay of the one-shot timer (in microseconds) + * + * Input Parameters: + * lower An instance of the lower-half oneshot state structure. This + * structure must have been previously initialized via a call to + * oneshot_initialize(); + * ts The location in which to return the maximum delay. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int n32_max_delay(struct oneshot_lowerhalf_s *lower, + struct timespec *ts) +{ + struct n32_oneshot_lowerhalf_s *priv = + (struct n32_oneshot_lowerhalf_s *)lower; + uint64_t usecs; + int ret; + + DEBUGASSERT(priv != NULL && ts != NULL); + ret = n32_oneshot_max_delay(&priv->oneshot, &usecs); + if (ret >= 0) + { + uint64_t sec = usecs / 1000000; + + usecs -= 1000000 * sec; + + ts->tv_sec = (time_t)sec; + ts->tv_nsec = (long)(usecs * 1000); + } + + return ret; +} + +/**************************************************************************** + * Name: n32_start + * + * Description: + * Start the oneshot timer + * + * Input Parameters: + * lower An instance of the lower-half oneshot state structure. This + * structure must have been previously initialized via a call to + * oneshot_initialize(); + * handler The function to call when when the oneshot timer expires. + * arg An opaque argument that will accompany the callback. + * ts Provides the duration of the one shot timer. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int n32_start(struct oneshot_lowerhalf_s *lower, + const struct timespec *ts) +{ + struct n32_oneshot_lowerhalf_s *priv = + (struct n32_oneshot_lowerhalf_s *)lower; + irqstate_t flags; + int ret; + + DEBUGASSERT(priv != NULL && lower->callback != NULL && ts != NULL); + + /* Save the callback information and start the timer */ + + flags = enter_critical_section(); + priv->callback = lower->callback; + priv->arg = lower->arg; + ret = n32_oneshot_start(&priv->oneshot, + n32_oneshot_handler, priv, ts); + leave_critical_section(flags); + + if (ret < 0) + { + tmrerr("ERROR: n32_oneshot_start failed: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: n32_cancel + * + * Description: + * Cancel the oneshot timer and return the time remaining on the timer. + * + * Input Parameters: + * lower Caller allocated instance of the oneshot state structure. This + * structure must have been previously initialized via a call to + * oneshot_initialize(); + * ts The location in which to return the time remaining on the + * oneshot timer. A time of zero is returned if the timer is + * not running. + * + * Returned Value: + * Zero (OK) is returned on success. A call to up_timer_cancel() when + * the timer is not active should also return success; a negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +static int n32_cancel(struct oneshot_lowerhalf_s *lower, + struct timespec *ts) +{ + struct n32_oneshot_lowerhalf_s *priv = + (struct n32_oneshot_lowerhalf_s *)lower; + irqstate_t flags; + int ret; + + DEBUGASSERT(priv != NULL); + + /* Cancel the timer */ + + flags = enter_critical_section(); + ret = n32_oneshot_cancel(&priv->oneshot, ts); + priv->callback = NULL; + priv->arg = NULL; + leave_critical_section(flags); + + if (ret < 0) + { + tmrerr("ERROR: n32_oneshot_cancel failed: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: oneshot_initialize + * + * Description: + * Initialize the oneshot timer and return a oneshot lower half driver + * instance. + * + * Input Parameters: + * chan Encoded timer and channel: (timer << 4) | channel + * timer: 1 for ATIM1, 3 for GTIMA1, 15 for BTIM1, etc. + * channel: 1-4 (CC1-CC4) + * resolution The required resolution of the timer in units of + * microseconds. NOTE that the range is restricted to the + * range of uint16_t (excluding zero). + * + * Returned Value: + * On success, a non-NULL instance of the oneshot lower-half driver is + * returned. NULL is return on any failure. + * + ****************************************************************************/ + +struct oneshot_lowerhalf_s *oneshot_initialize(int chan, + uint16_t resolution) +{ + struct n32_oneshot_lowerhalf_s *priv; + int timer; + int channel; + int ret; + + /* Decode timer and channel from chan parameter. + * Bits 7-4: timer number (1-18) + * Bits 3-0: channel number (1-4) + */ + + timer = (chan >> 4) & 0x0f; + channel = chan & 0x0f; + + /* Validate channel number */ + + if (channel < 1 || channel > 4) + { + tmrerr("ERROR: Invalid channel: %d (must be 1-4)\n", channel); + return NULL; + } + + /* Allocate an instance of the lower half driver */ + + priv = (struct n32_oneshot_lowerhalf_s *) + kmm_zalloc(sizeof(struct n32_oneshot_lowerhalf_s)); + + if (priv == NULL) + { + tmrerr("ERROR: Failed to allocate state structure\n"); + return NULL; + } + + /* Initialize the lower-half driver structure */ + + priv->lh.ops = &g_oneshot_ops; + + /* Initialize the contained N32 oneshot timer */ + + ret = n32_oneshot_initialize(&priv->oneshot, timer, channel, resolution); + if (ret < 0) + { + tmrerr("ERROR: n32_oneshot_initialize failed: %d\n", ret); + kmm_free(priv); + return NULL; + } + + return &priv->lh; +} + +#endif /* CONFIG_ONESHOT */ diff --git a/arch/arm/src/n32h7/n32_pm.h b/arch/arm/src/n32h7/n32_pm.h new file mode 100644 index 0000000000000..e4267f09a4f3e --- /dev/null +++ b/arch/arm/src/n32h7/n32_pm.h @@ -0,0 +1,109 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_pm.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32H7_STM32_PM_H +#define __ARCH_ARM_SRC_STM32H7_STM32_PM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "arm_internal.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: n32_pmstop + * + * Description: + * Enter STOP mode. + * + * Input Parameters: + * stop2 - true: To further reduce power consumption in Stop mode, put the + * internal voltage regulator in low-power under-drive mode using + * the LPDS and LPUDS bits of the Power control register (PWR_CR1). + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_pmstop(bool stop2); + +/**************************************************************************** + * Name: n32_pmstandby + * + * Description: + * Enter STANDBY mode. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_pmstandby(void); + +/**************************************************************************** + * Name: n32_pmsleep + * + * Description: + * Enter SLEEP mode. + * + * Input Parameters: + * sleeponexit - true: SLEEPONEXIT bit is set when the WFI instruction is + * executed, the MCU enters Sleep mode as soon as it + * exits the lowest priority ISR. + * - false: SLEEPONEXIT bit is cleared, the MCU enters Sleep + * mode as soon as WFI or WFE instruction is executed. + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_pmsleep(bool sleeponexit); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_STM32H7_STM32_PM_H */ diff --git a/arch/arm/src/n32h7/n32_pminitialize.c b/arch/arm/src/n32h7/n32_pminitialize.c new file mode 100644 index 0000000000000..97c504f310114 --- /dev/null +++ b/arch/arm/src/n32h7/n32_pminitialize.c @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_pminitialize.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "arm_internal.h" +#include "n32_pm.h" + +#ifdef CONFIG_PM + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_pminitialize + * + * Description: + * This function is called by MCU-specific logic at power-on reset in + * order to provide one-time initialization the power management subsystem. + * This function must be called *very* early in the initialization sequence + * *before* any other device drivers are initialized (since they may + * attempt to register with the power management subsystem). + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void arm_pminitialize(void) +{ + /* Initialize the NuttX power management subsystem proper */ + + pm_initialize(); +} + +#endif /* CONFIG_PM */ diff --git a/arch/arm/src/n32h7/n32_pmsleep.c b/arch/arm/src/n32h7/n32_pmsleep.c new file mode 100644 index 0000000000000..14c138f88e652 --- /dev/null +++ b/arch/arm/src/n32h7/n32_pmsleep.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_pmsleep.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "arm_internal.h" +#include "nvic.h" +#include "n32_pwr.h" +#include "n32_pm.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_pmsleep + * + * Description: + * Enter SLEEP mode. + * + * Input Parameters: + * sleeponexit - true: SLEEPONEXIT bit is set when the WFI instruction is + * executed, the MCU enters Sleep mode as soon as it + * exits the lowest priority ISR. + * - false: SLEEPONEXIT bit is cleared, the MCU enters Sleep + * mode as soon as WFI or WFE instruction is executed. + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_pmsleep(bool sleeponexit) +{ + uint32_t regval; + + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + + regval = getreg32(NVIC_SYSCON); + regval &= ~NVIC_SYSCON_SLEEPDEEP; + if (sleeponexit) + { + regval |= NVIC_SYSCON_SLEEPONEXIT; + } + else + { + regval &= ~NVIC_SYSCON_SLEEPONEXIT; + } + + putreg32(regval, NVIC_SYSCON); + + /* Sleep until the wakeup interrupt or event occurs */ + +#ifdef CONFIG_PM_WFE + /* Mode: SLEEP + Entry with WFE */ + + asm("wfe"); +#else + /* Mode: SLEEP + Entry with WFI */ + + asm("wfi"); +#endif +} diff --git a/arch/arm/src/n32h7/n32_pmstandby.c b/arch/arm/src/n32h7/n32_pmstandby.c new file mode 100644 index 0000000000000..73b8191016296 --- /dev/null +++ b/arch/arm/src/n32h7/n32_pmstandby.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_pmstandby.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "arm_internal.h" +#include "nvic.h" +#include "n32_rcc.h" +#include "n32_pwr.h" +#include "n32_pm.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_pmstandby + * + * Description: + * Enter STANDBY mode. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_pmstandby(void) +{ + uint32_t regval; + + /* Clear the wake-up flags before resetting. */ + + modifyreg32(N32_PWR_C1_PWR_CR, 0, PWR_M7CTRL1_CWKUPF); + modifyreg32(N32_PWR_C1_PWR_CR2, PWR_M7CTRL2_STOP2EN, 0); + + /* Set the domain Power Down Deep Sleep (PDDS) bits in the power control + * register so that D1, D2, and D3 will go into the DStop state. + */ + + modifyreg32(N32_PWR_C1_PWR_CR, 0, PWR_M7CTRL1_PDSEN); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + + regval = getreg32(NVIC_SYSCON); + regval |= NVIC_SYSCON_SLEEPDEEP; + putreg32(regval, NVIC_SYSCON); + + /* Sleep until the wakeup reset occurs */ + + asm("wfi"); +} diff --git a/arch/arm/src/n32h7/n32_pmstop.c b/arch/arm/src/n32h7/n32_pmstop.c new file mode 100644 index 0000000000000..2972313686696 --- /dev/null +++ b/arch/arm/src/n32h7/n32_pmstop.c @@ -0,0 +1,95 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_pmstop.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "arm_internal.h" +#include "nvic.h" +#include "n32_pwr.h" +#include "n32_pm.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_pmstop + * + * Description: + * Enter STOP mode. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_pmstop(bool stop2) +{ + uint32_t regval; + + /* Clear the domain standby bits so D1, D2 and D3 remain in DStop mode */ + + modifyreg32(N32_PWR_C1_PWR_CR, PWR_M7CTRL1_PDSEN, 0); + + if (stop2) + { + modifyreg32(N32_PWR_C1_PWR_CR2, 0, PWR_M7CTRL2_STOP2EN); + } + else + { + modifyreg32(N32_PWR_C1_PWR_CR2, PWR_M7CTRL2_STOP2EN, 0); + } + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + + regval = getreg32(NVIC_SYSCON); + regval |= NVIC_SYSCON_SLEEPDEEP; + putreg32(regval, NVIC_SYSCON); + + /* Sleep until the wakeup interrupt or event occurs */ + +#ifdef CONFIG_PM_WFE + /* Mode: SLEEP + Entry with WFE */ + + asm volatile ("wfe"); +#else + /* Mode: SLEEP + Entry with WFI */ + + asm volatile ("wfi"); +#endif + + /* Clear deep sleep bits, so that MCU does not go into deep sleep in + * idle. + */ + + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + + regval = getreg32(NVIC_SYSCON); + regval &= ~NVIC_SYSCON_SLEEPDEEP; + putreg32(regval, NVIC_SYSCON); +} diff --git a/arch/arm/src/n32h7/n32_pwm.c b/arch/arm/src/n32h7/n32_pwm.c new file mode 100644 index 0000000000000..0e7509b537aac --- /dev/null +++ b/arch/arm/src/n32h7/n32_pwm.c @@ -0,0 +1,2515 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_pwm.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "arm_internal.h" +#include "n32_pwm.h" +#include "n32_gpio.h" +#include "n32_rcc.h" +#include "hardware/n32h7_tim.h" +#include "hardware/n32h76x_pinmap.h" +#include "hardware/n32h7_rcc.h" + +#ifdef CONFIG_N32H7_PWM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets (common for ATIM/GTIMA/GTIMB) */ +#define N32_PWM_CTRL1_OFFSET 0x0000 +#define N32_PWM_CTRL2_OFFSET 0x0004 +#define N32_PWM_STS_OFFSET 0x0008 +#define N32_PWM_ETGEN_OFFSET 0x000c +#define N32_PWM_SMCTRL_OFFSET 0x0010 +#define N32_PWM_DINTEN_OFFSET 0x0014 +#define N32_PWM_CCMOD1_OFFSET 0x0018 +#define N32_PWM_CCMOD2_OFFSET 0x001c +#define N32_PWM_CCMOD3_OFFSET 0x0020 +#define N32_PWM_CCEN_OFFSET 0x0024 +#define N32_PWM_CCDAT1_OFFSET 0x0028 +#define N32_PWM_CCDAT2_OFFSET 0x002c +#define N32_PWM_CCDAT3_OFFSET 0x0030 +#define N32_PWM_CCDAT4_OFFSET 0x0034 +#define N32_PWM_PSC_OFFSET 0x0040 +#define N32_PWM_AR_OFFSET 0x0044 +#define N32_PWM_CNT_OFFSET 0x0048 +#define N32_PWM_REPCNT_OFFSET 0x004c +#define N32_PWM_BKDT_OFFSET 0x0050 + +/* Bit definitions (same as ATIM) */ +#define PWM_CR1_CEN N32_ATIM_CTRL1_CNTEN +#define PWM_CR1_DIR N32_ATIM_CTRL1_DIR +#define PWM_CR1_CMS_MASK N32_ATIM_CTRL1_CAMSEL_MASK +#define PWM_CR1_ARPE N32_ATIM_CTRL1_ARPEN +#define PWM_CR1_OPM N32_ATIM_CTRL1_ONEPM +#define PWM_CR1_CKD_MASK N32_ATIM_CTRL1_CLKD_MASK + +#define PWM_CCER_CC1E N32_ATIM_CCEN_CC1EN +#define PWM_CCER_CC1P N32_ATIM_CCEN_CC1P +#define PWM_CCER_CC1NE N32_ATIM_CCEN_CC1NEN +#define PWM_CCER_CC1NP N32_ATIM_CCEN_CC1NP +#define PWM_CCER_CC2E N32_ATIM_CCEN_CC2EN +#define PWM_CCER_CC2P N32_ATIM_CCEN_CC2P +#define PWM_CCER_CC2NE N32_ATIM_CCEN_CC2NEN +#define PWM_CCER_CC2NP N32_ATIM_CCEN_CC2NP +#define PWM_CCER_CC3E N32_ATIM_CCEN_CC3EN +#define PWM_CCER_CC3P N32_ATIM_CCEN_CC3P +#define PWM_CCER_CC3NE N32_ATIM_CCEN_CC3NEN +#define PWM_CCER_CC3NP N32_ATIM_CCEN_CC3NP +#define PWM_CCER_CC4E N32_ATIM_CCEN_CC4EN +#define PWM_CCER_CC4P N32_ATIM_CCEN_CC4P + +#define PWM_CCMR_CCS_OUT N32_ATIM_CCMOD1_CC1OUT +#define PWM_CCMR_OC1PE N32_ATIM_CCMOD1_OC1PEN +#define PWM_CCMR_OC2PE N32_ATIM_CCMOD1_OC2PEN +#define PWM_CCMR_OC3PE N32_ATIM_CCMOD2_OC3PEN +#define PWM_CCMR_OC4PE N32_ATIM_CCMOD2_OC4PEN + +#define PWM_BDTR_MOE N32_ATIM_BKDT_MOEN +#define PWM_BDTR_BKE N32_ATIM_BKDT_BKEN +#define PWM_BDTR_BKP N32_ATIM_BKDT_BKP +#define PWM_BDTR_DTG_MASK N32_ATIM_BKDT_DTGN_MASK +#define PWM_BDTR_LOCK_MASK N32_ATIM_BKDT_LCKCFG_MASK + +#define PWM_DIER_UIE N32_ATIM_DINTEN_UIEN +#define PWM_DIER_CC1IE N32_ATIM_DINTEN_CC1IEN +#define PWM_DIER_CC2IE N32_ATIM_DINTEN_CC2IEN +#define PWM_DIER_CC3IE N32_ATIM_DINTEN_CC3IEN +#define PWM_DIER_CC4IE N32_ATIM_DINTEN_CC4IEN + +#define PWM_SR_UIF N32_ATIM_STS_UDITF +#define PWM_SR_CC1IF N32_ATIM_STS_CC1ITF +#define PWM_SR_CC2IF N32_ATIM_STS_CC2ITF +#define PWM_SR_CC3IF N32_ATIM_STS_CC3ITF +#define PWM_SR_CC4IF N32_ATIM_STS_CC4ITF + +#define PWM_EGR_UG N32_ATIM_ETGEN_UDGN + +/* Helpers for timer type */ + +static inline bool pwm_has_comp(struct n32_pwmtimer_s *priv) +{ + return (priv->timtype == TIMTYPE_ADVANCED || + priv->timtype == TIMTYPE_GTIMB); +} + +static inline bool pwm_has_break(struct n32_pwmtimer_s *priv) +{ + return (priv->timtype == TIMTYPE_ADVANCED || + priv->timtype == TIMTYPE_GTIMB); +} + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Forward reference for ops */ + +struct pwm_lowerhalf_s; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ + +static int pwm_setup(struct pwm_lowerhalf_s *dev); +static int pwm_shutdown(struct pwm_lowerhalf_s *dev); +static int pwm_start(struct pwm_lowerhalf_s *dev, + const struct pwm_info_s *info); +static int pwm_stop(struct pwm_lowerhalf_s *dev); +static int pwm_ioctl(struct pwm_lowerhalf_s *dev, int cmd, + unsigned long arg); + +#ifdef CONFIG_DEBUG_PWM_INFO +static void pwm_dumpregs(struct pwm_lowerhalf_s *dev, const char *msg); +#else +# define pwm_dumpregs(dev,msg) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = pwm_setup, + .shutdown = pwm_shutdown, + .start = pwm_start, + .stop = pwm_stop, + .ioctl = pwm_ioctl, +}; + +/* -------------------------------------------------------------------------- + * Timer instance data (generated) + * -------------------------------------------------------------------------- + */ + +#ifdef CONFIG_N32H7_ATIM1_PWM +static struct n32_pwmchan_s g_pwmatim1channels[] = +{ +#ifdef CONFIG_N32H7_ATIM1_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_ATIM1_CH1MODE, +#ifdef CONFIG_N32H7_ATIM1_BREAK1 + .brk = + { + .en1 = 1, + .pol1 = CONFIG_N32H7_ATIM1_BRK1POL, + }, +#endif + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM1_CH1POL, + .idle = CONFIG_N32H7_ATIM1_CH1IDLE, + .pincfg = GPIO_ATIM1_CH1OUT, + }, +#ifdef CONFIG_N32H7_ATIM1_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM1_CH1NPOL, + .idle = CONFIG_N32H7_ATIM1_CH1NIDLE, + .pincfg = GPIO_ATIM1_CH1NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM1_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_ATIM1_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM1_CH2POL, + .idle = CONFIG_N32H7_ATIM1_CH2IDLE, + .pincfg = GPIO_ATIM1_CH2OUT, + }, +#ifdef CONFIG_N32H7_ATIM1_CH2NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM1_CH2NPOL, + .idle = CONFIG_N32H7_ATIM1_CH2NIDLE, + .pincfg = GPIO_ATIM1_CH2NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM1_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_ATIM1_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM1_CH3POL, + .idle = CONFIG_N32H7_ATIM1_CH3IDLE, + .pincfg = GPIO_ATIM1_CH3OUT, + }, +#ifdef CONFIG_N32H7_ATIM1_CH3NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM1_CH3NPOL, + .idle = CONFIG_N32H7_ATIM1_CH3NIDLE, + .pincfg = GPIO_ATIM1_CH3NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM1_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_ATIM1_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM1_CH4POL, + .idle = CONFIG_N32H7_ATIM1_CH4IDLE, + .pincfg = GPIO_ATIM1_CH4OUT, + }, +#ifdef CONFIG_N32H7_ATIM1_CH4NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM1_CH4NPOL, + .idle = CONFIG_N32H7_ATIM1_CH4NIDLE, + .pincfg = GPIO_ATIM1_CH4NOUT, + }, +#endif + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmatim1dev = +{ + .ops = &g_pwmops, + .timid = 1, + .channels = g_pwmatim1channels, + .timtype = TIMTYPE_ADVANCED, + .mode = CONFIG_N32H7_ATIM1_MODE, + .lock = CONFIG_N32H7_ATIM1_LOCK, + .deadtime = CONFIG_N32H7_ATIM1_DEADTIME, + .t_dts = CONFIG_N32H7_ATIM1_TDTS, + .base = N32_ATIMER1_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_ATIM1, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_ATIM1_PWM */ + +#ifdef CONFIG_N32H7_ATIM2_PWM +static struct n32_pwmchan_s g_pwmatim2channels[] = +{ +#ifdef CONFIG_N32H7_ATIM2_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_ATIM2_CH1MODE, +#ifdef CONFIG_N32H7_ATIM2_BREAK1 + .brk = + { + .en1 = 1, + .pol1 = CONFIG_N32H7_ATIM2_BRK1POL, + }, +#endif + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM2_CH1POL, + .idle = CONFIG_N32H7_ATIM2_CH1IDLE, + .pincfg = GPIO_ATIM2_CH1OUT, + }, +#ifdef CONFIG_N32H7_ATIM2_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM2_CH1NPOL, + .idle = CONFIG_N32H7_ATIM2_CH1NIDLE, + .pincfg = GPIO_ATIM2_CH1NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM2_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_ATIM2_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM2_CH2POL, + .idle = CONFIG_N32H7_ATIM2_CH2IDLE, + .pincfg = GPIO_ATIM2_CH2OUT, + }, +#ifdef CONFIG_N32H7_ATIM2_CH2NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM2_CH2NPOL, + .idle = CONFIG_N32H7_ATIM2_CH2NIDLE, + .pincfg = GPIO_ATIM2_CH2NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM2_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_ATIM2_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM2_CH3POL, + .idle = CONFIG_N32H7_ATIM2_CH3IDLE, + .pincfg = GPIO_ATIM2_CH3OUT, + }, +#ifdef CONFIG_N32H7_ATIM2_CH3NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM2_CH3NPOL, + .idle = CONFIG_N32H7_ATIM2_CH3NIDLE, + .pincfg = GPIO_ATIM2_CH3NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM2_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_ATIM2_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM2_CH4POL, + .idle = CONFIG_N32H7_ATIM2_CH4IDLE, + .pincfg = GPIO_ATIM2_CH4OUT, + }, +#ifdef CONFIG_N32H7_ATIM2_CH4NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM2_CH4NPOL, + .idle = CONFIG_N32H7_ATIM2_CH4NIDLE, + .pincfg = GPIO_ATIM2_CH4NOUT, + }, +#endif + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmatim2dev = +{ + .ops = &g_pwmops, + .timid = 2, + .channels = g_pwmatim2channels, + .timtype = TIMTYPE_ADVANCED, + .mode = CONFIG_N32H7_ATIM2_MODE, + .lock = CONFIG_N32H7_ATIM2_LOCK, + .deadtime = CONFIG_N32H7_ATIM2_DEADTIME, + .t_dts = CONFIG_N32H7_ATIM2_TDTS, + .base = N32_ATIMER2_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_ATIM2, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_ATIM2_PWM */ + +#ifdef CONFIG_N32H7_ATIM3_PWM +static struct n32_pwmchan_s g_pwmatim3channels[] = +{ +#ifdef CONFIG_N32H7_ATIM3_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_ATIM3_CH1MODE, +#ifdef CONFIG_N32H7_ATIM3_BREAK1 + .brk = + { + .en1 = 1, + .pol1 = CONFIG_N32H7_ATIM3_BRK1POL, + }, +#endif + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM3_CH1POL, + .idle = CONFIG_N32H7_ATIM3_CH1IDLE, + .pincfg = GPIO_ATIM3_CH1OUT, + }, +#ifdef CONFIG_N32H7_ATIM3_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM3_CH1NPOL, + .idle = CONFIG_N32H7_ATIM3_CH1NIDLE, + .pincfg = GPIO_ATIM3_CH1NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM3_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_ATIM3_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM3_CH2POL, + .idle = CONFIG_N32H7_ATIM3_CH2IDLE, + .pincfg = GPIO_ATIM3_CH2OUT, + }, +#ifdef CONFIG_N32H7_ATIM3_CH2NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM3_CH2NPOL, + .idle = CONFIG_N32H7_ATIM3_CH2NIDLE, + .pincfg = GPIO_ATIM3_CH2NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM3_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_ATIM3_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM3_CH3POL, + .idle = CONFIG_N32H7_ATIM3_CH3IDLE, + .pincfg = GPIO_ATIM3_CH3OUT, + }, +#ifdef CONFIG_N32H7_ATIM3_CH3NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM3_CH3NPOL, + .idle = CONFIG_N32H7_ATIM3_CH3NIDLE, + .pincfg = GPIO_ATIM3_CH3NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM3_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_ATIM3_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM3_CH4POL, + .idle = CONFIG_N32H7_ATIM3_CH4IDLE, + .pincfg = GPIO_ATIM3_CH4OUT, + }, +#ifdef CONFIG_N32H7_ATIM3_CH4NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM3_CH4NPOL, + .idle = CONFIG_N32H7_ATIM3_CH4NIDLE, + .pincfg = GPIO_ATIM3_CH4NOUT, + }, +#endif + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmatim3dev = +{ + .ops = &g_pwmops, + .timid = 3, + .channels = g_pwmatim3channels, + .timtype = TIMTYPE_ADVANCED, + .mode = CONFIG_N32H7_ATIM3_MODE, + .lock = CONFIG_N32H7_ATIM3_LOCK, + .deadtime = CONFIG_N32H7_ATIM3_DEADTIME, + .t_dts = CONFIG_N32H7_ATIM3_TDTS, + .base = N32_ATIMER3_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_ATIM3, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_ATIM3_PWM */ + +#ifdef CONFIG_N32H7_ATIM4_PWM +static struct n32_pwmchan_s g_pwmatim4channels[] = +{ +#ifdef CONFIG_N32H7_ATIM4_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_ATIM4_CH1MODE, +#ifdef CONFIG_N32H7_ATIM4_BREAK1 + .brk = + { + .en1 = 1, + .pol1 = CONFIG_N32H7_ATIM4_BRK1POL, + }, +#endif + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM4_CH1POL, + .idle = CONFIG_N32H7_ATIM4_CH1IDLE, + .pincfg = GPIO_ATIM4_CH1OUT, + }, +#ifdef CONFIG_N32H7_ATIM4_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM4_CH1NPOL, + .idle = CONFIG_N32H7_ATIM4_CH1NIDLE, + .pincfg = GPIO_ATIM4_CH1NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM4_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_ATIM4_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM4_CH2POL, + .idle = CONFIG_N32H7_ATIM4_CH2IDLE, + .pincfg = GPIO_ATIM4_CH2OUT, + }, +#ifdef CONFIG_N32H7_ATIM4_CH2NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM4_CH2NPOL, + .idle = CONFIG_N32H7_ATIM4_CH2NIDLE, + .pincfg = GPIO_ATIM4_CH2NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM4_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_ATIM4_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM4_CH3POL, + .idle = CONFIG_N32H7_ATIM4_CH3IDLE, + .pincfg = GPIO_ATIM4_CH3OUT, + }, +#ifdef CONFIG_N32H7_ATIM4_CH3NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM4_CH3NPOL, + .idle = CONFIG_N32H7_ATIM4_CH3NIDLE, + .pincfg = GPIO_ATIM4_CH3NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_ATIM4_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_ATIM4_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM4_CH4POL, + .idle = CONFIG_N32H7_ATIM4_CH4IDLE, + .pincfg = GPIO_ATIM4_CH4OUT, + }, +#ifdef CONFIG_N32H7_ATIM4_CH4NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_ATIM4_CH4NPOL, + .idle = CONFIG_N32H7_ATIM4_CH4NIDLE, + .pincfg = GPIO_ATIM4_CH4NOUT, + }, +#endif + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmatim4dev = +{ + .ops = &g_pwmops, + .timid = 4, + .channels = g_pwmatim4channels, + .timtype = TIMTYPE_ADVANCED, + .mode = CONFIG_N32H7_ATIM4_MODE, + .lock = CONFIG_N32H7_ATIM4_LOCK, + .deadtime = CONFIG_N32H7_ATIM4_DEADTIME, + .t_dts = CONFIG_N32H7_ATIM4_TDTS, + .base = N32_ATIMER4_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_ATIM4, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_ATIM4_PWM */ + +#ifdef CONFIG_N32H7_GTIMA1_PWM +static struct n32_pwmchan_s g_pwmgtima1channels[] = +{ +#ifdef CONFIG_N32H7_GTIMA1_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMA1_CH1MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA1_CH1POL, + .idle = CONFIG_N32H7_GTIMA1_CH1IDLE, + .pincfg = GPIO_GTIMA1_CH1OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA1_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMA1_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA1_CH2POL, + .idle = CONFIG_N32H7_GTIMA1_CH2IDLE, + .pincfg = GPIO_GTIMA1_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA1_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMA1_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA1_CH3POL, + .idle = CONFIG_N32H7_GTIMA1_CH3IDLE, + .pincfg = GPIO_GTIMA1_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA1_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMA1_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA1_CH4POL, + .idle = CONFIG_N32H7_GTIMA1_CH4IDLE, + .pincfg = GPIO_GTIMA1_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtima1dev = +{ + .ops = &g_pwmops, + .timid = 5, + .channels = g_pwmgtima1channels, + .timtype = TIMTYPE_GENERAL16, + .mode = CONFIG_N32H7_GTIMA1_MODE, + .lock = 0, + .deadtime = 0, + .t_dts = 0, + .base = N32_GTIMERA1_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMA1, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMA1_PWM */ + +#ifdef CONFIG_N32H7_GTIMA2_PWM +static struct n32_pwmchan_s g_pwmgtima2channels[] = +{ +#ifdef CONFIG_N32H7_GTIMA2_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMA2_CH1MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA2_CH1POL, + .idle = CONFIG_N32H7_GTIMA2_CH1IDLE, + .pincfg = GPIO_GTIMA2_CH1OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA2_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMA2_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA2_CH2POL, + .idle = CONFIG_N32H7_GTIMA2_CH2IDLE, + .pincfg = GPIO_GTIMA2_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA2_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMA2_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA2_CH3POL, + .idle = CONFIG_N32H7_GTIMA2_CH3IDLE, + .pincfg = GPIO_GTIMA2_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA2_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMA2_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA2_CH4POL, + .idle = CONFIG_N32H7_GTIMA2_CH4IDLE, + .pincfg = GPIO_GTIMA2_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtima2dev = +{ + .ops = &g_pwmops, + .timid = 6, + .channels = g_pwmgtima2channels, + .timtype = TIMTYPE_GENERAL16, + .mode = CONFIG_N32H7_GTIMA2_MODE, + .lock = 0, + .deadtime = 0, + .t_dts = 0, + .base = N32_GTIMERA2_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMA2, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMA2_PWM */ + +#ifdef CONFIG_N32H7_GTIMA3_PWM +static struct n32_pwmchan_s g_pwmgtima3channels[] = +{ +#ifdef CONFIG_N32H7_GTIMA3_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMA3_CH1MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA3_CH1POL, + .idle = CONFIG_N32H7_GTIMA3_CH1IDLE, + .pincfg = GPIO_GTIMA3_CH1OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA3_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMA3_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA3_CH2POL, + .idle = CONFIG_N32H7_GTIMA3_CH2IDLE, + .pincfg = GPIO_GTIMA3_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA3_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMA3_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA3_CH3POL, + .idle = CONFIG_N32H7_GTIMA3_CH3IDLE, + .pincfg = GPIO_GTIMA3_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA3_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMA3_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA3_CH4POL, + .idle = CONFIG_N32H7_GTIMA3_CH4IDLE, + .pincfg = GPIO_GTIMA3_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtima3dev = +{ + .ops = &g_pwmops, + .timid = 7, + .channels = g_pwmgtima3channels, + .timtype = TIMTYPE_GENERAL16, + .mode = CONFIG_N32H7_GTIMA3_MODE, + .lock = 0, + .deadtime = 0, + .t_dts = 0, + .base = N32_GTIMERA3_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMA3, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMA3_PWM */ + +#ifdef CONFIG_N32H7_GTIMA4_PWM +static struct n32_pwmchan_s g_pwmgtima4channels[] = +{ +#ifdef CONFIG_N32H7_GTIMA4_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMA4_CH1MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA4_CH1POL, + .idle = CONFIG_N32H7_GTIMA4_CH1IDLE, + .pincfg = GPIO_GTIMA4_CH1OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA4_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMA4_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA4_CH2POL, + .idle = CONFIG_N32H7_GTIMA4_CH2IDLE, + .pincfg = GPIO_GTIMA4_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA4_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMA4_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA4_CH3POL, + .idle = CONFIG_N32H7_GTIMA4_CH3IDLE, + .pincfg = GPIO_GTIMA4_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA4_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMA4_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA4_CH4POL, + .idle = CONFIG_N32H7_GTIMA4_CH4IDLE, + .pincfg = GPIO_GTIMA4_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtima4dev = +{ + .ops = &g_pwmops, + .timid = 8, + .channels = g_pwmgtima4channels, + .timtype = TIMTYPE_GENERAL16, + .mode = CONFIG_N32H7_GTIMA4_MODE, + .lock = 0, + .deadtime = 0, + .t_dts = 0, + .base = N32_GTIMERA4_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMA4, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMA4_PWM */ + +#ifdef CONFIG_N32H7_GTIMA5_PWM +static struct n32_pwmchan_s g_pwmgtima5channels[] = +{ +#ifdef CONFIG_N32H7_GTIMA5_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMA5_CH1MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA5_CH1POL, + .idle = CONFIG_N32H7_GTIMA5_CH1IDLE, + .pincfg = GPIO_GTIMA5_CH1OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA5_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMA5_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA5_CH2POL, + .idle = CONFIG_N32H7_GTIMA5_CH2IDLE, + .pincfg = GPIO_GTIMA5_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA5_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMA5_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA5_CH3POL, + .idle = CONFIG_N32H7_GTIMA5_CH3IDLE, + .pincfg = GPIO_GTIMA5_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA5_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMA5_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA5_CH4POL, + .idle = CONFIG_N32H7_GTIMA5_CH4IDLE, + .pincfg = GPIO_GTIMA5_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtima5dev = +{ + .ops = &g_pwmops, + .timid = 9, + .channels = g_pwmgtima5channels, + .timtype = TIMTYPE_GENERAL16, + .mode = CONFIG_N32H7_GTIMA5_MODE, + .lock = 0, + .deadtime = 0, + .t_dts = 0, + .base = N32_GTIMERA5_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMA5, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMA5_PWM */ + +#ifdef CONFIG_N32H7_GTIMA6_PWM +static struct n32_pwmchan_s g_pwmgtima6channels[] = +{ +#ifdef CONFIG_N32H7_GTIMA6_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMA6_CH1MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA6_CH1POL, + .idle = CONFIG_N32H7_GTIMA6_CH1IDLE, + .pincfg = GPIO_GTIMA6_CH1OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA6_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMA6_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA6_CH2POL, + .idle = CONFIG_N32H7_GTIMA6_CH2IDLE, + .pincfg = GPIO_GTIMA6_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA6_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMA6_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA6_CH3POL, + .idle = CONFIG_N32H7_GTIMA6_CH3IDLE, + .pincfg = GPIO_GTIMA6_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA6_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMA6_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA6_CH4POL, + .idle = CONFIG_N32H7_GTIMA6_CH4IDLE, + .pincfg = GPIO_GTIMA6_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtima6dev = +{ + .ops = &g_pwmops, + .timid = 10, + .channels = g_pwmgtima6channels, + .timtype = TIMTYPE_GENERAL16, + .mode = CONFIG_N32H7_GTIMA6_MODE, + .lock = 0, + .deadtime = 0, + .t_dts = 0, + .base = N32_GTIMERA6_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMA6, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMA6_PWM */ + +#ifdef CONFIG_N32H7_GTIMA7_PWM +static struct n32_pwmchan_s g_pwmgtima7channels[] = +{ +#ifdef CONFIG_N32H7_GTIMA7_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMA7_CH1MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA7_CH1POL, + .idle = CONFIG_N32H7_GTIMA7_CH1IDLE, + .pincfg = GPIO_GTIMA7_CH1OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA7_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMA7_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA7_CH2POL, + .idle = CONFIG_N32H7_GTIMA7_CH2IDLE, + .pincfg = GPIO_GTIMA7_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA7_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMA7_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA7_CH3POL, + .idle = CONFIG_N32H7_GTIMA7_CH3IDLE, + .pincfg = GPIO_GTIMA7_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMA7_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMA7_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMA7_CH4POL, + .idle = CONFIG_N32H7_GTIMA7_CH4IDLE, + .pincfg = GPIO_GTIMA7_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtima7dev = +{ + .ops = &g_pwmops, + .timid = 11, + .channels = g_pwmgtima7channels, + .timtype = TIMTYPE_GENERAL16, + .mode = CONFIG_N32H7_GTIMA7_MODE, + .lock = 0, + .deadtime = 0, + .t_dts = 0, + .base = N32_GTIMERA7_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMA7, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMA7_PWM */ + +#ifdef CONFIG_N32H7_GTIMB1_PWM +static struct n32_pwmchan_s g_pwmgtimb1channels[] = +{ +#ifdef CONFIG_N32H7_GTIMB1_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMB1_CH1MODE, +#ifdef CONFIG_N32H7_GTIMB1_BREAK1 + .brk = + { + .en1 = 1, + .pol1 = CONFIG_N32H7_GTIMB1_BRK1POL, + }, +#endif + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB1_CH1POL, + .idle = CONFIG_N32H7_GTIMB1_CH1IDLE, + .pincfg = GPIO_GTIMB1_CH1OUT, + }, +#ifdef CONFIG_N32H7_GTIMB1_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB1_CH1NPOL, + .idle = CONFIG_N32H7_GTIMB1_CH1NIDLE, + .pincfg = GPIO_GTIMB1_CH1NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_GTIMB1_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMB1_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB1_CH2POL, + .idle = CONFIG_N32H7_GTIMB1_CH2IDLE, + .pincfg = GPIO_GTIMB1_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMB1_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMB1_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB1_CH3POL, + .idle = CONFIG_N32H7_GTIMB1_CH3IDLE, + .pincfg = GPIO_GTIMB1_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMB1_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMB1_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB1_CH4POL, + .idle = CONFIG_N32H7_GTIMB1_CH4IDLE, + .pincfg = GPIO_GTIMB1_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtimb1dev = +{ + .ops = &g_pwmops, + .timid = 12, + .channels = g_pwmgtimb1channels, + .timtype = TIMTYPE_GTIMB, + .mode = CONFIG_N32H7_GTIMB1_MODE, + .lock = CONFIG_N32H7_GTIMB1_LOCK, + .deadtime = CONFIG_N32H7_GTIMB1_DEADTIME, + .t_dts = CONFIG_N32H7_GTIMB1_TDTS, + .base = N32_GTIMERB1_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMB1, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMB1_PWM */ + +#ifdef CONFIG_N32H7_GTIMB2_PWM +static struct n32_pwmchan_s g_pwmgtimb2channels[] = +{ +#ifdef CONFIG_N32H7_GTIMB2_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMB2_CH1MODE, +#ifdef CONFIG_N32H7_GTIMB2_BREAK1 + .brk = + { + .en1 = 1, + .pol1 = CONFIG_N32H7_GTIMB2_BRK1POL, + }, +#endif + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB2_CH1POL, + .idle = CONFIG_N32H7_GTIMB2_CH1IDLE, + .pincfg = GPIO_GTIMB2_CH1OUT, + }, +#ifdef CONFIG_N32H7_GTIMB2_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB2_CH1NPOL, + .idle = CONFIG_N32H7_GTIMB2_CH1NIDLE, + .pincfg = GPIO_GTIMB2_CH1NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_GTIMB2_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMB2_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB2_CH2POL, + .idle = CONFIG_N32H7_GTIMB2_CH2IDLE, + .pincfg = GPIO_GTIMB2_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMB2_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMB2_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB2_CH3POL, + .idle = CONFIG_N32H7_GTIMB2_CH3IDLE, + .pincfg = GPIO_GTIMB2_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMB2_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMB2_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB2_CH4POL, + .idle = CONFIG_N32H7_GTIMB2_CH4IDLE, + .pincfg = GPIO_GTIMB2_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtimb2dev = +{ + .ops = &g_pwmops, + .timid = 13, + .channels = g_pwmgtimb2channels, + .timtype = TIMTYPE_GTIMB, + .mode = CONFIG_N32H7_GTIMB2_MODE, + .lock = CONFIG_N32H7_GTIMB2_LOCK, + .deadtime = CONFIG_N32H7_GTIMB2_DEADTIME, + .t_dts = CONFIG_N32H7_GTIMB2_TDTS, + .base = N32_GTIMERB2_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMB2, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMB2_PWM */ + +#ifdef CONFIG_N32H7_GTIMB3_PWM +static struct n32_pwmchan_s g_pwmgtimb3channels[] = +{ +#ifdef CONFIG_N32H7_GTIMB3_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_N32H7_GTIMB3_CH1MODE, +#ifdef CONFIG_N32H7_GTIMB3_BREAK1 + .brk = + { + .en1 = 1, + .pol1 = CONFIG_N32H7_GTIMB3_BRK1POL, + }, +#endif + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB3_CH1POL, + .idle = CONFIG_N32H7_GTIMB3_CH1IDLE, + .pincfg = GPIO_GTIMB3_CH1OUT, + }, +#ifdef CONFIG_N32H7_GTIMB3_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB3_CH1NPOL, + .idle = CONFIG_N32H7_GTIMB3_CH1NIDLE, + .pincfg = GPIO_GTIMB3_CH1NOUT, + }, +#endif + }, +#endif +#ifdef CONFIG_N32H7_GTIMB3_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_N32H7_GTIMB3_CH2MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB3_CH2POL, + .idle = CONFIG_N32H7_GTIMB3_CH2IDLE, + .pincfg = GPIO_GTIMB3_CH2OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMB3_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_N32H7_GTIMB3_CH3MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB3_CH3POL, + .idle = CONFIG_N32H7_GTIMB3_CH3IDLE, + .pincfg = GPIO_GTIMB3_CH3OUT, + }, + }, +#endif +#ifdef CONFIG_N32H7_GTIMB3_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_N32H7_GTIMB3_CH4MODE, + .out1 = + { + .in_use = 1, + .pol = CONFIG_N32H7_GTIMB3_CH4POL, + .idle = CONFIG_N32H7_GTIMB3_CH4IDLE, + .pincfg = GPIO_GTIMB3_CH4OUT, + }, + }, +#endif +}; + +static struct n32_pwmtimer_s g_pwmgtimb3dev = +{ + .ops = &g_pwmops, + .timid = 14, + .channels = g_pwmgtimb3channels, + .timtype = TIMTYPE_GTIMB, + .mode = CONFIG_N32H7_GTIMB3_MODE, + .lock = CONFIG_N32H7_GTIMB3_LOCK, + .deadtime = CONFIG_N32H7_GTIMB3_DEADTIME, + .t_dts = CONFIG_N32H7_GTIMB3_TDTS, + .base = N32_GTIMERB3_BASE, + .pclk = N32_AHB_FREQUENCY, + .frequency = 0, +#ifdef CONFIG_PWM_PULSECOUNT + .irq = N32_IRQ_GTIMB3, + .handle = NULL, +#endif +}; +#endif /* CONFIG_N32H7_GTIMB3_PWM */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwm_reg_is_32bit + ****************************************************************************/ + +static bool pwm_reg_is_32bit(uint8_t timtype, uint32_t offset) +{ + bool ret = false; + + /* Only GENERAL32 (not used for PWM) would have 32-bit registers */ + + if (timtype == TIMTYPE_GENERAL32) + { + if (offset == N32_PWM_CNT_OFFSET || + offset == N32_PWM_AR_OFFSET || + offset == N32_PWM_CCDAT1_OFFSET || + offset == N32_PWM_CCDAT2_OFFSET || + offset == N32_PWM_CCDAT3_OFFSET || + offset == N32_PWM_CCDAT4_OFFSET) + { + ret = true; + } + } + + /* Advanced timers have some 32-bit registers (CR2, CCMR, CCER, BDTR) */ + + else if (timtype == TIMTYPE_ADVANCED) + { + if (offset == N32_PWM_CTRL2_OFFSET || + offset == N32_PWM_CCMOD1_OFFSET || + offset == N32_PWM_CCMOD2_OFFSET || + offset == N32_PWM_CCEN_OFFSET || + offset == N32_PWM_BKDT_OFFSET || + offset == N32_PWM_CCMOD3_OFFSET) + { + ret = true; + } + } + + /* GTIMB also has some 32-bit regs (CTRL2, CCMOD1/2/3, CCEN, BKDT) */ + + else if (timtype == TIMTYPE_GTIMB) + { + if (offset == N32_PWM_CTRL2_OFFSET || + offset == N32_PWM_CCMOD1_OFFSET || + offset == N32_PWM_CCMOD2_OFFSET || + offset == N32_PWM_CCMOD3_OFFSET || + offset == N32_PWM_CCEN_OFFSET || + offset == N32_PWM_BKDT_OFFSET) + { + ret = true; + } + } + + return ret; +} + +/**************************************************************************** + * Name: pwm_getreg / pwm_putreg / pwm_modifyreg + ****************************************************************************/ + +static uint32_t pwm_getreg(struct n32_pwmtimer_s *priv, uint32_t offset) +{ + if (pwm_reg_is_32bit(priv->timtype, offset)) + { + return getreg32(priv->base + offset); + } + else + { + return getreg16(priv->base + offset); + } +} + +static void pwm_putreg(struct n32_pwmtimer_s *priv, uint32_t offset, + uint32_t value) +{ + if (pwm_reg_is_32bit(priv->timtype, offset)) + { + putreg32(value, priv->base + offset); + } + else + { + putreg16((uint16_t)value, priv->base + offset); + } +} + +static void pwm_modifyreg(struct n32_pwmtimer_s *priv, uint32_t offset, + uint32_t clearbits, uint32_t setbits) +{ + if (pwm_reg_is_32bit(priv->timtype, offset)) + { + modifyreg32(priv->base + offset, clearbits, setbits); + } + else + { + modifyreg16(priv->base + offset, (uint16_t)clearbits, + (uint16_t)setbits); + } +} + +/**************************************************************************** + * Name: pwm_set_apb_clock + * + * Description: + * Enable or disable APB clock for the timer peripheral + ****************************************************************************/ + +static int pwm_set_apb_clock(struct n32_pwmtimer_s *priv, bool on) +{ + uint32_t regaddr = 0; + uint32_t en_bit = 0; + + switch (priv->timid) + { + #ifdef CONFIG_N32H7_ATIM1_PWM + case 1: + regaddr = N32_RCC_APB2EN1; + en_bit = RCC_APB2EN1_M7ATIM1EN; + break; + #endif + #ifdef CONFIG_N32H7_ATIM2_PWM + case 2: + regaddr = N32_RCC_APB2EN1; + en_bit = RCC_APB2EN1_M7ATIM2EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA1_PWM + case 3: + regaddr = N32_RCC_APB2EN1; + en_bit = RCC_APB2EN1_M7GTIMA1EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA2_PWM + case 4: + regaddr = N32_RCC_APB2EN1; + en_bit = RCC_APB2EN1_M7GTIMA2EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA3_PWM + case 5: + regaddr = N32_RCC_APB2EN1; + en_bit = RCC_APB2EN1_M7GTIMA3EN; + break; + #endif + #ifdef CONFIG_N32H7_ATIM3_PWM + case 6: + regaddr = N32_RCC_APB5EN1; + en_bit = RCC_APB5EN1_M7ATIM3EN; + break; + #endif + #ifdef CONFIG_N32H7_ATIM4_PWM + case 7: + regaddr = N32_RCC_APB5EN1; + en_bit = RCC_APB5EN1_M7ATIM4EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA4_PWM + case 8: + regaddr = N32_RCC_APB1EN1; + en_bit = RCC_APB1EN1_M7GTIMA4EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA5_PWM + case 9: + regaddr = N32_RCC_APB1EN2; + en_bit = RCC_APB1EN2_M7GTIMA5EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA6_PWM + case 10: + regaddr = N32_RCC_APB1EN2; + en_bit = RCC_APB1EN2_M7GTIMA6EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMA7_PWM + case 11: + regaddr = N32_RCC_APB1EN2; + en_bit = RCC_APB1EN2_M7GTIMA7EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMB1_PWM + case 12: + regaddr = N32_RCC_APB1EN1; + en_bit = RCC_APB1EN1_M7GTIMB1EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMB2_PWM + case 13: + regaddr = N32_RCC_APB1EN1; + en_bit = RCC_APB1EN1_M7GTIMB2EN; + break; + #endif + #ifdef CONFIG_N32H7_GTIMB3_PWM + case 14: + regaddr = N32_RCC_APB1EN1; + en_bit = RCC_APB1EN1_M7GTIMB3EN; + break; + #endif + default: + return -EINVAL; + } + + if (on) + { + modifyreg32(regaddr, 0, en_bit); + } + else + { + modifyreg32(regaddr, en_bit, 0); + } + + return OK; +} + +/**************************************************************************** + * Name: pwm_timer_configure + * + * Description: + * Initial configuration for PWM timer (mode, ARPE, etc.) + ****************************************************************************/ + +static int pwm_timer_configure(struct n32_pwmtimer_s *priv) +{ + uint32_t cr1 = pwm_getreg(priv, N32_PWM_CTRL1_OFFSET); + + /* Set counter mode (if not basic) */ + + if (priv->timtype != TIMTYPE_BASIC) /* BASIC not used for PWM */ + { + cr1 &= ~(PWM_CR1_DIR | PWM_CR1_CMS_MASK); + + switch (priv->mode) + { + case 0: /* Up-count */ + cr1 |= N32_ATIM_CTRL1_EDGE; + break; + case 1: /* Down-count */ + cr1 |= N32_ATIM_CTRL1_EDGE | PWM_CR1_DIR; + break; + case 2: /* Center-aligned 1 */ + cr1 |= N32_ATIM_CTRL1_CENTER1; + break; + case 3: /* Center-aligned 2 */ + cr1 |= N32_ATIM_CTRL1_CENTER2; + break; + case 4: /* Center-aligned 3 */ + cr1 |= N32_ATIM_CTRL1_CENTER3; + break; + default: + return -EINVAL; + } + } + + /* Enable ARR preload */ + + cr1 |= PWM_CR1_ARPE; + pwm_putreg(priv, N32_PWM_CTRL1_OFFSET, cr1); + + return OK; +} + +/**************************************************************************** + * Name: pwm_break_dt_configure + * + * Description: + * Configure Break and Dead-time for advanced timers + ****************************************************************************/ + +static int pwm_break_dt_configure(struct n32_pwmtimer_s *priv) +{ + uint32_t bdtr = 0; + + /* Set clock division (CKD) for dead-time */ + + pwm_modifyreg(priv, N32_PWM_CTRL1_OFFSET, PWM_CR1_CKD_MASK, + priv->t_dts << N32_ATIM_CTRL1_CLKD_SHIFT); + + /* Dead-time */ + + bdtr |= (priv->deadtime << N32_ATIM_BKDT_DTGN_SHIFT); + + /* Break1 (if enabled) */ + + if (priv->channels[0].brk.en1) + { + bdtr |= PWM_BDTR_BKE; + if (priv->channels[0].brk.pol1 == N32_POL_NEG) + { + bdtr |= PWM_BDTR_BKP; + } + } + + /* Lock */ + + bdtr |= (priv->lock << N32_ATIM_BKDT_LCKCFG_SHIFT); + + /* Clear OSSI/OSSR (idle mode settings) */ + + bdtr &= ~(N32_ATIM_BKDT_OSSI | N32_ATIM_BKDT_OSSR); + + pwm_putreg(priv, N32_PWM_BKDT_OFFSET, bdtr); + return OK; +} + +/**************************************************************************** + * Name: pwm_frequency_update + * + * Description: + * Calculate and set prescaler and ARR for desired frequency + ****************************************************************************/ + +static int pwm_frequency_update(struct pwm_lowerhalf_s *dev, + uint32_t frequency) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + uint32_t timclk = priv->pclk; + uint32_t prescaler; + uint32_t reload; + + prescaler = (timclk / frequency + 65534) / 65535; + if (prescaler < 1) + { + prescaler = 1; + } + + if (prescaler > 65536) + { + prescaler = 65536; + } + + reload = (timclk / prescaler) / frequency; + if (reload < 2) + { + reload = 1; + } + else if (reload > 65535) + { + reload = 65535; + } + else + { + reload--; + } + + pwm_putreg(priv, N32_PWM_PSC_OFFSET, prescaler - 1); + pwm_putreg(priv, N32_PWM_AR_OFFSET, reload); + priv->frequency = frequency; + return OK; +} + +/**************************************************************************** + * Name: pwm_mode_configure + * + * Description: + * Configure output compare mode for a channel + ****************************************************************************/ + +static int pwm_mode_configure(struct pwm_lowerhalf_s *dev, uint8_t channel, + uint32_t mode) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + uint32_t ccmr_offset; + uint32_t shift; + uint32_t ccmr; + uint32_t ccmr_val; + uint32_t oc_pe_bit; + + if (channel <= 2) + { + ccmr_offset = N32_PWM_CCMOD1_OFFSET; + shift = (channel == 1) ? 0 : (N32_ATIM_CCMOD1_OC2MD_SHIFT - + N32_ATIM_CCMOD1_OC1MD_SHIFT); + oc_pe_bit = (channel == 1) ? N32_ATIM_CCMOD1_OC1PEN : + N32_ATIM_CCMOD1_OC2PEN; + } + else + { + ccmr_offset = N32_PWM_CCMOD2_OFFSET; + shift = (channel == 3) ? 0 : (N32_ATIM_CCMOD2_OC4MD_SHIFT - + N32_ATIM_CCMOD2_OC3MD_SHIFT); + oc_pe_bit = (channel == 3) ? N32_ATIM_CCMOD2_OC3PEN : + N32_ATIM_CCMOD2_OC4PEN; + } + + ccmr = pwm_getreg(priv, ccmr_offset); + ccmr &= ~(0xff << shift); /* clear OCxM and OCxPE */ + switch (mode) + { + case N32_CHANMODE_FRZN: + ccmr_val = N32_ATIM_CCMOD1_OCMODE_FRZN; + break; + case N32_CHANMODE_CHACT: + ccmr_val = N32_ATIM_CCMOD1_OCMODE_ACTIVE; + break; + case N32_CHANMODE_CHINACT: + ccmr_val = N32_ATIM_CCMOD1_OCMODE_INACTIVE; + break; + case N32_CHANMODE_OCREFTOG: + ccmr_val = N32_ATIM_CCMOD1_OCMODE_TOGGLE; + break; + case N32_CHANMODE_OCREFLO: + ccmr_val = N32_ATIM_CCMOD1_OCMODE_FORCELO; + break; + case N32_CHANMODE_OCREFHI: + ccmr_val = N32_ATIM_CCMOD1_OCMODE_FORCEHI; + break; + case N32_CHANMODE_PWM1: + ccmr_val = N32_ATIM_CCMOD1_OCMODE_PWM1; + break; + case N32_CHANMODE_PWM2: + ccmr_val = N32_ATIM_CCMOD1_OCMODE_PWM2; + break; + default: + return -EINVAL; + } + + ccmr |= (ccmr_val << shift) | oc_pe_bit; + pwm_putreg(priv, ccmr_offset, ccmr); + return OK; +} + +/**************************************************************************** + * Name: pwm_output_configure + * + * Description: + * Configure polarity, idle state, and complementary for a channel + ****************************************************************************/ + +static int pwm_output_configure(struct n32_pwmtimer_s *priv, + struct n32_pwmchan_s *chan) +{ + uint32_t cr2 = pwm_getreg(priv, N32_PWM_CTRL2_OFFSET); + uint32_t ccer = pwm_getreg(priv, N32_PWM_CCEN_OFFSET); + uint8_t ch = chan->channel; + uint32_t shift = (ch - 1) * 4; + + /* Main output polarity */ + + if (chan->out1.pol == N32_POL_NEG) + { + ccer |= (PWM_CCER_CC1P << shift); + } + else + { + ccer &= ~(PWM_CCER_CC1P << shift); + } + + if (pwm_has_comp(priv)) + { + /* Main output idle state */ + + if (chan->out1.idle == N32_IDLE_ACTIVE) + { + cr2 |= (N32_ATIM_CTRL2_O11 << ((ch - 1) * 2)); + } + else + { + cr2 &= ~(N32_ATIM_CTRL2_O11 << ((ch - 1) * 2)); + } + + /* Complementary output */ + + if (chan->out2.in_use) + { + /* Polarity */ + + if (chan->out2.pol == N32_POL_NEG) + { + ccer |= (PWM_CCER_CC1NP << shift); + } + else + { + ccer &= ~(PWM_CCER_CC1NP << shift); + } + + /* Idle state */ + + if (chan->out2.idle == N32_IDLE_ACTIVE) + { + cr2 |= (N32_ATIM_CTRL2_O11N << ((ch - 1) * 2)); + } + else + { + cr2 &= ~(N32_ATIM_CTRL2_O11N << ((ch - 1) * 2)); + } + } + } + else + { + /* GTIMA: clear NP bits if any */ + + ccer &= ~(PWM_CCER_CC1NP << shift); + } + + pwm_putreg(priv, N32_PWM_CTRL2_OFFSET, cr2); + pwm_putreg(priv, N32_PWM_CCEN_OFFSET, ccer); + return OK; +} + +/**************************************************************************** + * Name: pwm_outputs_enable + * + * Description: + * Enable or disable outputs in bulk + ****************************************************************************/ + +static int pwm_outputs_enable(struct pwm_lowerhalf_s *dev, uint16_t outputs, + bool state) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + uint32_t ccer = pwm_getreg(priv, N32_PWM_CCEN_OFFSET); + uint32_t mask = 0; + + if (outputs & N32_PWM_OUT1) + { + mask |= PWM_CCER_CC1E; + } + + if (outputs & N32_PWM_OUT2) + { + mask |= PWM_CCER_CC2E; + } + + if (outputs & N32_PWM_OUT3) + { + mask |= PWM_CCER_CC3E; + } + + if (outputs & N32_PWM_OUT4) + { + mask |= PWM_CCER_CC4E; + } + + if (outputs & N32_PWM_OUT1N) + { + mask |= PWM_CCER_CC1NE; + } + + if (outputs & N32_PWM_OUT2N) + { + mask |= PWM_CCER_CC2NE; + } + + if (outputs & N32_PWM_OUT3N) + { + mask |= PWM_CCER_CC3NE; + } + + if (state) + { + ccer |= mask; + } + else + { + ccer &= ~mask; + } + + pwm_putreg(priv, N32_PWM_CCEN_OFFSET, ccer); + return OK; +} + +/**************************************************************************** + * Name: pwm_soft_break + * + * Description: + * Software break (enable/disable MOE) + ****************************************************************************/ + +static int pwm_soft_break(struct pwm_lowerhalf_s *dev, bool state) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + + if (pwm_has_break(priv)) + { + if (state) + { + pwm_modifyreg(priv, N32_PWM_BKDT_OFFSET, PWM_BDTR_MOE, 0); + } + else + { + pwm_modifyreg(priv, N32_PWM_BKDT_OFFSET, 0, PWM_BDTR_MOE); + } + } + + return OK; +} + +/**************************************************************************** + * Name: pwm_soft_update + * + * Description: + * Generate software update event + ****************************************************************************/ + +static int pwm_soft_update(struct pwm_lowerhalf_s *dev) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + + pwm_putreg(priv, N32_PWM_ETGEN_OFFSET, PWM_EGR_UG); + + return OK; +} + +/**************************************************************************** + * Name: pwm_outputs_from_channels + * + * Description: + * Build output mask from channel configuration + ****************************************************************************/ + +static uint16_t pwm_outputs_from_channels(struct n32_pwmtimer_s *priv) +{ + uint16_t outputs = 0; + + for (int i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + if (priv->channels[i].channel == 0) + { + continue; + } + + if (priv->channels[i].out1.in_use) + { + outputs |= (N32_PWM_OUT1 << ((priv->channels[i].channel - 1) * 2)); + } + + if (pwm_has_comp(priv) && priv->channels[i].out2.in_use) + { + outputs |= (N32_PWM_OUT1N << ((priv->channels[i].channel - 1) * 2) + ); + } + } + + return outputs; +} + +/**************************************************************************** + * Name: pwm_configure (non-pulsecount mode) + * + * Description: + * Initial configuration without pulsecount + ****************************************************************************/ + +static int pwm_configure(struct pwm_lowerhalf_s *dev) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + int ret; + int i; + + /* Disable timer */ + + pwm_modifyreg(priv, N32_PWM_CTRL1_OFFSET, PWM_CR1_CEN, 0); + + /* Basic timer config */ + + ret = pwm_timer_configure(priv); + if (ret < 0) + { + return ret; + } + + /* Break/deadtime for advanced timers */ + + if (pwm_has_break(priv)) + { + ret = pwm_break_dt_configure(priv); + if (ret < 0) + { + return ret; + } + } + + /* Configure each channel */ + + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + struct n32_pwmchan_s *chan = &priv->channels[i]; + + if (chan->channel == 0) + { + continue; + } + + ret = pwm_mode_configure(dev, chan->channel, chan->mode); + if (ret < 0) + { + return ret; + } + + ret = pwm_output_configure(priv, chan); + if (ret < 0) + { + return ret; + } + } + + /* Enable main output for advanced timers */ + + if (pwm_has_break(priv)) + { + pwm_soft_break(dev, false); + } + + return OK; +} + +/**************************************************************************** + * Name: pwm_start + ****************************************************************************/ + +static int pwm_start(struct pwm_lowerhalf_s *dev, + const struct pwm_info_s *info) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + int ret; + + /* Set frequency */ + + ret = pwm_frequency_update(dev, info->frequency); + if (ret < 0) + { + return ret; + } + + /* Set duty for each channel */ + + for (int i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + if (info->channels[i].channel == -1) + { + break; + } + + if (info->channels[i].channel == 0) + { + continue; + } + + uint32_t reload = pwm_getreg(priv, N32_PWM_AR_OFFSET); + uint32_t ccr = (uint32_t)(b16toi(info->channels[i].duty * reload + + b16HALF)); + int ch = info->channels[i].channel; + + pwm_putreg(priv, N32_PWM_CCDAT1_OFFSET + (ch - 1) * 4, ccr); + } + + /* Enable outputs */ + + uint16_t outputs = pwm_outputs_from_channels(priv); + + ret = pwm_outputs_enable(dev, outputs, true); + if (ret < 0) + { + return ret; + } + + /* Generate update event and enable counter */ + + pwm_soft_update(dev); + pwm_modifyreg(priv, N32_PWM_CTRL1_OFFSET, 0, PWM_CR1_CEN); + return OK; +} + +/**************************************************************************** + * Name: pwm_stop + ****************************************************************************/ + +static int pwm_stop(struct pwm_lowerhalf_s *dev) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + + pwm_modifyreg(priv, N32_PWM_CTRL1_OFFSET, PWM_CR1_CEN, 0); + pwm_outputs_enable(dev, 0xffff, false); + pwm_putreg(priv, N32_PWM_DINTEN_OFFSET, 0); + pwm_putreg(priv, N32_PWM_CNT_OFFSET, 0); + + priv->frequency = 0; + return OK; +} + +/**************************************************************************** + * Name: pwm_setup + ****************************************************************************/ + +static int pwm_setup(struct pwm_lowerhalf_s *dev) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + int ret; + + /* Enable clock */ + + ret = pwm_set_apb_clock(priv, true); + if (ret < 0) + { + return ret; + } + + /* Configure GPIOs */ + + for (int i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + if (priv->channels[i].channel == 0) + { + continue; + } + + if (priv->channels[i].out1.in_use && priv->channels[i].out1.pincfg) + { + n32_configgpio(priv->channels[i].out1.pincfg); + } + + if (pwm_has_comp(priv) && priv->channels[i].out2.in_use && + priv->channels[i].out2.pincfg) + { + n32_configgpio(priv->channels[i].out2.pincfg); + } + } + + /* Configure timer */ + + ret = pwm_configure(dev); + if (ret < 0) + { + pwm_set_apb_clock(priv, false); + return ret; + } + + pwm_dumpregs(dev, "After setup"); + return OK; +} + +/**************************************************************************** + * Name: pwm_shutdown + ****************************************************************************/ + +static int pwm_shutdown(struct pwm_lowerhalf_s *dev) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + + pwm_stop(dev); + pwm_set_apb_clock(priv, false); + + /* Unconfigure GPIOs */ + + for (int i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + if (priv->channels[i].channel == 0) + { + continue; + } + + if (priv->channels[i].out1.pincfg) + { + n32_unconfiggpio(priv->channels[i].out1.pincfg); + } + + if (priv->channels[i].out2.pincfg) + { + n32_unconfiggpio(priv->channels[i].out2.pincfg); + } + } + + return OK; +} + +/**************************************************************************** + * Name: pwm_ioctl + ****************************************************************************/ + +static int pwm_ioctl(struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: pwm_dumpregs + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_PWM_INFO +static void pwm_dumpregs(struct pwm_lowerhalf_s *dev, const char *msg) +{ + struct n32_pwmtimer_s *priv = (struct n32_pwmtimer_s *)dev; + + pwminfo("%s: CR1=%04x CR2=%04x CCER=%04x CNT=%04x ARR=%04x PSC=%04x\n", + msg, + pwm_getreg(priv, N32_PWM_CTRL1_OFFSET), + pwm_getreg(priv, N32_PWM_CTRL2_OFFSET), + pwm_getreg(priv, N32_PWM_CCEN_OFFSET), + pwm_getreg(priv, N32_PWM_CNT_OFFSET), + pwm_getreg(priv, N32_PWM_AR_OFFSET), + pwm_getreg(priv, N32_PWM_PSC_OFFSET)); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +struct pwm_lowerhalf_s *n32_pwminitialize(int timer) +{ + struct n32_pwmtimer_s *lower = NULL; + + switch (timer) + { + #ifdef CONFIG_N32H7_ATIM1_PWM + case 1: + lower = &g_pwmatim1dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_ATIM2_PWM + case 2: + lower = &g_pwmatim2dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_ATIM3_PWM + case 3: + lower = &g_pwmatim3dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_ATIM4_PWM + case 4: + lower = &g_pwmatim4dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMA1_PWM + case 5: + lower = &g_pwmgtima1dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMA2_PWM + case 6: + lower = &g_pwmgtima2dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMA3_PWM + case 7: + lower = &g_pwmgtima3dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMA4_PWM + case 8: + lower = &g_pwmgtima4dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMA5_PWM + case 9: + lower = &g_pwmgtima5dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMA6_PWM + case 10: + lower = &g_pwmgtima6dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMA7_PWM + case 11: + lower = &g_pwmgtima7dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMB1_PWM + case 12: + lower = &g_pwmgtimb1dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMB2_PWM + case 13: + lower = &g_pwmgtimb2dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + #ifdef CONFIG_N32H7_GTIMB3_PWM + case 14: + lower = &g_pwmgtimb3dev; + #ifdef CONFIG_PWM_PULSECOUNT + irq_attach(lower->irq, pwm_irq_handler, NULL); + up_disable_irq(lower->irq); + #endif + break; + #endif + default: + return NULL; + } + + return (struct pwm_lowerhalf_s *)lower; +} + +#endif /* CONFIG_N32H7_PWM */ diff --git a/arch/arm/src/n32h7/n32_pwm.h b/arch/arm/src/n32h7/n32_pwm.h new file mode 100644 index 0000000000000..881618c888417 --- /dev/null +++ b/arch/arm/src/n32h7/n32_pwm.h @@ -0,0 +1,167 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_pwm.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_PWM_H +#define __ARCH_ARM_SRC_N32H7_N32_PWM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "chip.h" + +#ifdef CONFIG_N32H7_PWM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Timer type */ +#define TIMTYPE_BASIC 0 +#define TIMTYPE_GENERAL16 1 +#define TIMTYPE_GENERAL32 2 +#define TIMTYPE_ADVANCED 3 +#define TIMTYPE_GTIMB 4 /* GTIMB (complementary, no break2) */ + +/* Timer modes */ + +enum n32_pwm_tim_mode_e +{ + N32_TIMMODE_COUNTUP = 0, + N32_TIMMODE_COUNTDOWN = 1, + N32_TIMMODE_CENTER1 = 2, + N32_TIMMODE_CENTER2 = 3, + N32_TIMMODE_CENTER3 = 4, +}; + +/* Polarity */ + +enum n32_pwm_pol_e +{ + N32_POL_POS = 0, + N32_POL_NEG = 1, +}; + +/* Idle state */ + +enum n32_pwm_idle_e +{ + N32_IDLE_INACTIVE = 0, + N32_IDLE_ACTIVE = 1, +}; + +/* PWM channel mode */ + +enum n32_pwm_chanmode_e +{ + N32_CHANMODE_FRZN = 0, + N32_CHANMODE_CHACT = 1, + N32_CHANMODE_CHINACT = 2, + N32_CHANMODE_OCREFTOG = 3, + N32_CHANMODE_OCREFLO = 4, + N32_CHANMODE_OCREFHI = 5, + N32_CHANMODE_PWM1 = 6, + N32_CHANMODE_PWM2 = 7, +}; + +/* PWM channel numbers */ + +enum n32_pwm_chan_e +{ + N32_PWM_CHAN1 = 1, + N32_PWM_CHAN2 = 2, + N32_PWM_CHAN3 = 3, + N32_PWM_CHAN4 = 4, +}; + +/* Output mask */ + +enum n32_pwm_output_e +{ + N32_PWM_OUT1 = (1 << 0), + N32_PWM_OUT1N = (1 << 1), + N32_PWM_OUT2 = (1 << 2), + N32_PWM_OUT2N = (1 << 3), + N32_PWM_OUT3 = (1 << 4), + N32_PWM_OUT3N = (1 << 5), + N32_PWM_OUT4 = (1 << 6), +}; + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct n32_pwm_out_s +{ + uint8_t in_use:1; + uint8_t pol:1; + uint8_t idle:1; + uint32_t pincfg; +}; + +struct n32_pwm_break_s +{ + uint8_t en1:1; + uint8_t pol1:1; +}; + +struct n32_pwmchan_s +{ + uint8_t channel:4; + uint8_t mode:4; + struct n32_pwm_out_s out1; + struct n32_pwm_break_s brk; + struct n32_pwm_out_s out2; /* complementary */ +}; + +struct n32_pwmtimer_s +{ + const struct pwm_ops_s *ops; + uint8_t timid; + uint8_t timtype:3; + uint8_t mode:3; + uint8_t lock:2; + uint8_t deadtime; + uint8_t t_dts; + uint32_t base; + uint32_t pclk; + struct n32_pwmchan_s *channels; + uint32_t frequency; /* current frequency */ +#ifdef CONFIG_PWM_PULSECOUNT + uint8_t irq; + uint8_t prev; + uint8_t curr; + uint32_t count; + void *handle; +#endif +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct pwm_lowerhalf_s *n32_pwminitialize(int timer); + +#endif /* CONFIG_N32H7_PWM */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_PWM_H */ diff --git a/arch/arm/src/n32h7/n32_pwr.c b/arch/arm/src/n32h7/n32_pwr.c new file mode 100644 index 0000000000000..465c0e8d3122c --- /dev/null +++ b/arch/arm/src/n32h7/n32_pwr.c @@ -0,0 +1,228 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_pwr.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include "arm_internal.h" +#include "n32_pwr.h" + +#if defined(CONFIG_N32H7_PWR) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint16_t g_bkp_writable_counter = 0; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline uint32_t n32_pwr_getreg(uint32_t offset) +{ + return getreg32(N32_PWR_BASE + offset); +} + +static inline void n32_pwr_putreg(uint32_t offset, uint32_t value) +{ + putreg32(value, N32_PWR_BASE + offset); +} + +static inline void n32_pwr_modifyreg(uint32_t offset, uint32_t clearbits, + uint32_t setbits) +{ + modifyreg32(N32_PWR_BASE + offset, clearbits, setbits); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_pwr_initbkp + ****************************************************************************/ + +void n32_pwr_initbkp(bool writable) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + regval = n32_pwr_getreg(N32_PWR_SYS_PWR_CR_OFFSET); + regval &= ~PWR_SYSCTRL1_DBKP; + n32_pwr_putreg(N32_PWR_SYS_PWR_CR_OFFSET, regval); + + g_bkp_writable_counter = 0; + + leave_critical_section(flags); + + n32_pwr_enablebkp(writable); +} + +/**************************************************************************** + * Name: n32_pwr_enablebkp + ****************************************************************************/ + +void n32_pwr_enablebkp(bool writable) +{ + irqstate_t flags; + uint32_t regval; + bool waswritable; + + flags = enter_critical_section(); + UP_DSB(); + + regval = n32_pwr_getreg(N32_PWR_C1_PWR_CR_OFFSET); + waswritable = ((regval & PWR_SYSCTRL1_DBKP) != 0); + + if (writable) + { + DEBUGASSERT(g_bkp_writable_counter < UINT16_MAX); + g_bkp_writable_counter++; + } + else if (g_bkp_writable_counter > 0) + { + g_bkp_writable_counter--; + } + + if (waswritable && g_bkp_writable_counter == 0) + { + regval &= ~PWR_SYSCTRL1_DBKP; + n32_pwr_putreg(N32_PWR_C1_PWR_CR_OFFSET, regval); + } + else if (!waswritable && g_bkp_writable_counter > 0) + { + regval |= PWR_SYSCTRL1_DBKP; + n32_pwr_putreg(N32_PWR_C1_PWR_CR_OFFSET, regval); + up_udelay(4); + } + + UP_DSB(); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: n32_pwr_setpvd + ****************************************************************************/ + +void n32_pwr_setpvd(uint32_t pls) +{ + uint32_t regval; + + regval = n32_pwr_getreg(N32_PWR_C1_PWR_CR_OFFSET); + regval &= ~PWR_PVD_LEVEL_MASK; + regval |= (pls & PWR_PVD_LEVEL_MASK); + n32_pwr_putreg(N32_PWR_C1_PWR_CR_OFFSET, regval); +} + +/**************************************************************************** + * Name: n32_pwr_enablepvd + ****************************************************************************/ + +void n32_pwr_enablepvd(void) +{ + n32_pwr_modifyreg(N32_PWR_C1_PWR_CR_OFFSET, 0, PWR_SYSCTRL1_PVDEN); +} + +/**************************************************************************** + * Name: n32_pwr_disablepvd + ****************************************************************************/ + +void n32_pwr_disablepvd(void) +{ + n32_pwr_modifyreg(N32_PWR_C1_PWR_CR_OFFSET, PWR_SYSCTRL1_PVDEN, 0); +} + +/**************************************************************************** + * Name: n32_pwr_configurewkup + ****************************************************************************/ + +void n32_pwr_configurewkup(uint32_t pin, bool en, bool rising, uint32_t pull) +{ + irqstate_t flags; + uint32_t regval; + + DEBUGASSERT(pin < 6); + + flags = enter_critical_section(); + + regval = n32_pwr_getreg(N32_PWR_C1_PWR_CSR_OFFSET); + + if (en) + { + regval |= (PWR_M7CTRLSTS_WKUP0F << pin); /* WKUP0EN -> WKUP5EN */ + } + else + { + regval &= ~(PWR_M7CTRLSTS_WKUP0F << pin); + } + + if (rising) + { + regval &= ~(PWR_M7CTRLSTS_WKUP0POL << pin); /* WKUP0POL -> WKUP5POL */ + } + else + { + regval |= (PWR_M7CTRLSTS_WKUP0POL << pin); + } + + n32_pwr_putreg(N32_PWR_C1_PWR_CSR_OFFSET, regval); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: n32_pwr_setcorepwrsrc + ****************************************************************************/ + +void n32_pwr_setcorepwrsrc(pwr_vcoresrc_e src) +{ + switch (src) + { + case PWR_VCORESRC_EXT: + n32_pwr_modifyreg(N32_PWR_SYS_PWR_CR4_OFFSET, PWR_VCORESRC_MASK, + PWR_SYSCTRL4_VCORESRC); + break; + case PWR_VCORESRC_LDO: + n32_pwr_modifyreg(N32_PWR_SYS_PWR_CR4_OFFSET, PWR_VCORESRC_MASK, + PWR_SYSCTRL4_MLDOEN); + break; + case PWR_VCORESRC_SMPS: + n32_pwr_modifyreg(N32_PWR_SYS_PWR_CR4_OFFSET, PWR_VCORESRC_MASK, + PWR_SYSCTRL4_DCDEN); + break; + } +} + +#endif /* CONFIG_N32H7_PWR */ diff --git a/arch/arm/src/n32h7/n32_pwr.h b/arch/arm/src/n32h7/n32_pwr.h new file mode 100644 index 0000000000000..586412cec0866 --- /dev/null +++ b/arch/arm/src/n32h7/n32_pwr.h @@ -0,0 +1,141 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_pwr.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_PWR_H +#define __ARCH_ARM_SRC_N32H7_N32_PWR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "hardware/n32h7_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: n32_pwr_initbkp + * + * Description: + * Insures the referenced count access to the backup domain (RTC registers, + * RTC backup data registers and backup SRAM is consistent with the HW + * state without relying on a variable. + * + * NOTE: This function should only be called by SoC Start up code. + * + * Input Parameters: + * writable - set the initial state of the enable and the + * bkp_writable_counter + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_pwr_initbkp(bool writable); + +/**************************************************************************** + * Name: n32_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: + * none + * + ****************************************************************************/ + +void n32_pwr_enablebkp(bool writable); + +/**************************************************************************** + * Name: n32_pwr_configurewkup + * + * Description: + * Configures the external wakeup (WKUP) signals for wakeup from standby + * mode. + * Sets rising/falling edge sensitivity and pull state. + * + * + * Input Parameters: + * pin - WKUP pin number (0-5) to work on + * en - Enables the specified WKUP pin if true + * rising - If true, wakeup is triggered on rising edge, otherwise, + * it is triggered on the falling edge. + * pull - Specifies the WKUP pin pull resistor configuration + * (GPIO_FLOAT, GPIO_PULLUP, or GPIO_PULLDOWN) + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_pwr_configurewkup(uint32_t pin, bool en, + bool rising, uint32_t pull); + +/**************************************************************************** + * Name: n32_pwr_setcorepwrsrc + * + * Description: + * Sets the core power source. + * + * Input Parameters: + * src - The power source to set. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_pwr_setcorepwrsrc(pwr_vcoresrc_e src); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_PWR_H */ diff --git a/arch/arm/src/n32h7/n32_rcc.c b/arch/arm/src/n32h7/n32_rcc.c new file mode 100644 index 0000000000000..d1b8f0175d2ed --- /dev/null +++ b/arch/arm/src/n32h7/n32_rcc.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_rcc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "arm_internal.h" +#include "n32_gpio.h" +#include "n32_rcc.h" +#include "n32_pwr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include chip-specific clocking initialization logic */ + +#if defined(CONFIG_N32H7_N32H76X) +# include "n32h76x_rcc.c" +#else +# error "Unsupported N32H7 chip" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_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 peripherals enabled in the NuttX + * configuration file. + * + * If CONFIG_N32H7_CUSTOM_CLOCKCONFIG is defined, then clocking will be + * enabled by an externally provided, board-specific function called + * n32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_clockconfig(void) +{ +#ifndef CONFIG_N32H7_BYPASS_CLOCKCONFIG + /* Make sure that we are starting in the reset state */ + + rcc_reset(); + +# if defined(CONFIG_N32H7_PWR) + + /* Insure the bkp is initialized */ + + n32_pwr_initbkp(false); +# endif + +# if defined(CONFIG_N32H7_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + n32_board_clockconfig(); + +# else + + /* Invoke standard, fixed clock configuration based on definitions in + * board.h + */ + + n32_stdclockconfig(); + +# endif +#endif /* !CONFIG_N32H7_BYPASS_CLOCKCONFIG */ + + /* Enable peripheral clocking */ + + rcc_enableperipherals(); + +#ifdef CONFIG_N32H7_SYSCFG_IOCOMPENSATION + /* Enable I/O Compensation */ + + n32_iocompensation(); +#endif +} + +/**************************************************************************** + * Name: n32_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 functional performs a subset of the operations performed by + * n32_clockconfig(): It does not reset any devices, and it does not + * reset the currently enabled peripheral clocks. + * + * If CONFIG_N32H7_CUSTOM_CLOCKCONFIG is defined, then clocking will be + * enabled by an externally provided, board-specific function called + * n32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_PM +void n32_clockenable(void) +{ +#if defined(CONFIG_N32H7_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + n32_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in + * board.h + */ + + n32_stdclockconfig(); + +#endif +} +#endif diff --git a/arch/arm/src/n32h7/n32_rcc.h b/arch/arm/src/n32h7/n32_rcc.h new file mode 100644 index 0000000000000..d5b89e359bee7 --- /dev/null +++ b/arch/arm/src/n32h7/n32_rcc.h @@ -0,0 +1,174 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_rcc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_RCC_H +#define __ARCH_ARM_SRC_N32H7_N32_RCC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm_internal.h" +#include "hardware/n32h7_rcc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32h7_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 peripherals enabled in the NuttX + * configuration file. + * + * If CONFIG_N32H7_CUSTOM_CLOCKCONFIG is defined, then clocking will be + * enabled by an externally provided, board-specific function called + * n32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_clockconfig(void); + +/**************************************************************************** + * Name: n32_stdclockconfig + * + * Description: + * Setup the system using the "standard" clock configuration + * + ****************************************************************************/ + +void n32_stdclockconfig(void); + +/**************************************************************************** + * Name: n32_board_clockconfig + * + * Description: + * Any N32 board may replace the "standard" board clock configuration + * logic with its own, custom clock configuration logic. + * + ****************************************************************************/ + +#ifdef CONFIG_N32H7_CUSTOM_CLOCKCONFIG +void n32_board_clockconfig(void); +#endif + +/**************************************************************************** + * Name: n32_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 functional performs a subset of the operations performed by + * n32_clockconfig(): It does not reset any devices, and it does not + * reset the currently enabled peripheral clocks. + * + * If CONFIG_N32H7_CUSTOM_CLOCKCONFIG is defined, then clocking will be + * enabled by an externally provided, board-specific function called + * n32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_PM +void n32_clockenable(void); +#endif + +/**************************************************************************** + * Name: n32_rcc_enablelse + * + * Description: + * Enable the External Low-Speed (LSE) Oscillator. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void n32_rcc_enablelse(void); + +/**************************************************************************** + * Name: n32_rcc_enablelsi + * + * Description: + * Enable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void n32_rcc_enablelsi(void); + +/**************************************************************************** + * Name: n32_rcc_disablelsi + * + * Description: + * Disable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void n32_rcc_disablelsi(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_RCC_H */ diff --git a/arch/arm/src/n32h7/n32_sdmmc.c b/arch/arm/src/n32h7/n32_sdmmc.c new file mode 100644 index 0000000000000..578a275897545 --- /dev/null +++ b/arch/arm/src/n32h7/n32_sdmmc.c @@ -0,0 +1,2735 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_sdmmc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "arm_internal.h" +#include "hardware/n32h7_sdmmc.h" +#include "n32_gpio.h" +#include "n32_sdmmc.h" +#include "hardware/n32h76x_pwr.h" +#include "hardware/n32h76x_rcc.h" + +#if defined(CONFIG_N32H7_SDMMC1) || defined(CONFIG_N32H7_SDMMC2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Workqueue support required */ + +#if !defined(CONFIG_SCHED_WORKQUEUE) || !defined(CONFIG_SCHED_HPWORK) +# error "Callback support requires CONFIG_SCHED_WORKQUEUE and CONFIG_SCHED_HPWORK" +#endif + +/* DMA support (ADMA2) is optional but recommended */ + +#ifdef CONFIG_N32H7_SDMMC_ADMA +# define HAVE_ADMA2 1 +#else +# define HAVE_ADMA2 0 +#endif + +/* FIFO Size (4KB Block Buffer) */ + +#define N32_SDMMC_FIFO_SIZE (4096) + +/* Max Block Size (512 bytes for SD, 2048 for eMMC) */ + +#define N32_SDMMC_MAX_BLOCK_SIZE (512) + +/* Default Data Timeout (250 ms) */ + +#define N32_SDMMC_DATATIMEOUT_MS (250) + +/* Command Timeout Loops */ + +#define N32_SDMMC_CMDTIMEOUT (1000000) + +/* Event wait masks */ + +#define N32_WAIT_CMDDONE (N32_SDHOST_INTSTS_CMDC) +#define N32_WAIT_RESPDONE (N32_SDHOST_INTSTS_CMDC | N32_SDHOST_INTSTS_CTERR | N32_SDHOST_INTSTS_CCRCERR) +#define N32_WAIT_XFRDONE (N32_SDHOST_INTSTS_TC | N32_SDHOST_INTSTS_DTERR | N32_SDHOST_INTSTS_DCRERR | N32_SDHOST_INTSTS_ADMAERR) + +#define N32_WAIT_ALL (N32_SDHOST_INTSTS_CMDC | N32_SDHOST_INTSTS_TC | N32_SDHOST_INTSTS_BLKGAPE | N32_SDHOST_INTSTS_DMAINT |\ + N32_SDHOST_INTSTS_BUFWRDY | N32_SDHOST_INTSTS_BUFRRDY | N32_SDHOST_INTSTS_CINS | N32_SDHOST_INTSTS_CRMV |\ + N32_SDHOST_INTSTS_CINT | N32_SDHOST_INTSTS_RETUNE | N32_SDHOST_INTSTS_BOOTACKR | N32_SDHOST_INTSTS_BOOTTER |\ + N32_SDHOST_INTSTS_CTERR | N32_SDHOST_INTSTS_CCRCERR | N32_SDHOST_INTSTS_CENDBERR | N32_SDHOST_INTSTS_CINXERR |\ + N32_SDHOST_INTSTS_DTERR | N32_SDHOST_INTSTS_DCRERR | N32_SDHOST_INTSTS_DENDERR | N32_SDHOST_INTSTS_ACMDERR |\ + N32_SDHOST_INTSTS_ADMAERR | N32_SDHOST_INTSTS_TRGRERR) + +/* Helper: Get CFG and HOST base addresses */ + +#define N32_CFG_BASE(priv) ((priv)->cfg_base) +#define N32_HOST_BASE(priv) ((priv)->host_base) +#define N32_PUT_CFG(priv, off, val) putreg32((val), (priv)->cfg_base + (off)) +#define N32_GET_CFG(priv, off) getreg32((priv)->cfg_base + (off)) +#define N32_PUT_HOST(priv, off, val) putreg32((val), (priv)->host_base + (off)) +#define N32_GET_HOST(priv, off) getreg32((priv)->host_base + (off)) + +/* Clock calculation: SDCLK = BCLKF / (2 * SDCLKSEL), BCLKF in MHz */ + +#define N32_BCLKF_FREQ (N32_PLL1B_FREQUENCY / 1000000) /* 100 MHz */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* ADMA2 Descriptor List (for scatter-gather) */ + +struct n32_sdmmc_adma_list_s +{ + struct n32_sdmmc_adma_desc_s *desc; /* Pointer to descriptor array */ + int count; /* Number of descriptors */ + uint32_t total_len; +}; + +/* N32 SDMMC Device State */ + +struct n32_sdmmc_s +{ + struct sdio_dev_s dev; /* Standard SDIO interface */ + + uint32_t cfg_base; /* SDMMC_CFG base address */ + uint32_t host_base; /* SDHOST base address */ + int irq; /* Interrupt number */ + + /* Clock */ + + uint32_t clock; /* Current SDCLK frequency in Hz */ + + /* Event support */ + + sem_t waitsem; /* Event wait semaphore */ + sdio_eventset_t waitevents; /* Events to wait for */ + uint32_t waitmask; /* Interrupt mask for waiting */ + volatile sdio_eventset_t wkupevent; /* Wakeup event */ + struct wdog_s waitwdog; /* Timeout watchdog */ + + /* Callback support */ + + sdio_statset_t cdstatus; /* Card status */ + sdio_eventset_t cbevents; /* Callback events */ + worker_t callback; /* Callback function */ + void *cbarg; /* Callback argument */ + struct work_s cbwork; /* Callback work */ + + /* Transfer state (PIO / DMA) */ + + uint32_t *buffer; /* Current buffer pointer */ + size_t remaining; /* Bytes remaining */ + uint32_t blocksize; /* Current block size */ + uint32_t nblocks; /* Number of blocks */ + bool is_read; /* true=read, false=write */ + bool using_dma; /* true if using ADMA */ + + /* ADMA2 state */ + +#if HAVE_ADMA2 + struct n32_sdmmc_adma_list_s adma_list; + bool adma_in_progress; +#endif + + /* Misc */ + + bool widebus; /* 4-bit bus mode */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register access helpers */ + +static inline void n32_sdmmc_putreg(struct n32_sdmmc_s *priv, + uint32_t value, int offset); +static inline uint32_t n32_sdmmc_getreg(struct n32_sdmmc_s *priv, + int offset); +static inline void n32_sdmmc_modifyreg(struct n32_sdmmc_s *priv, + int offset, uint32_t clr, + uint32_t set); + +/* Interrupt control */ + +static void n32_sdmmc_configints(struct n32_sdmmc_s *priv); +static void n32_sdmmc_configsts(struct n32_sdmmc_s *priv, uint32_t mask); + +/* Clock / Power */ + +static int n32_sdmmc_enable_clock(struct n32_sdmmc_s *priv, + uint32_t freq_hz); +static void n32_sdmmc_power_on(struct n32_sdmmc_s *priv); +static void n32_sdmmc_power_off(struct n32_sdmmc_s *priv); + +/* Command & Response */ + +static int n32_sdmmc_send_cmd(struct n32_sdmmc_s *priv, + uint32_t cmd, uint32_t arg); +static int n32_sdmmc_wait_cmd_done(struct n32_sdmmc_s *priv, + uint32_t cmd); +static void n32_sdmmc_get_response(struct n32_sdmmc_s *priv, + uint32_t cmd, uint32_t *resp); + +/* Data transfer (PIO) */ + +static void n32_sdmmc_setup_data(struct n32_sdmmc_s *priv); +static void n32_sdmmc_send_fifo(struct n32_sdmmc_s *priv); +static void n32_sdmmc_recv_fifo(struct n32_sdmmc_s *priv); +static void n32_sdmmc_datadisable(struct n32_sdmmc_s *priv); + +/* ADMA2 */ + +#if HAVE_ADMA2 +static int n32_sdmmc_build_adma_desc(struct n32_sdmmc_s *priv, + uint8_t *buffer, size_t len); +static void n32_sdmmc_start_adma(struct n32_sdmmc_s *priv); +static void n32_sdmmc_stop_adma(struct n32_sdmmc_s *priv); +#endif + +/* Event handling */ + +static void n32_sdmmc_endwait(struct n32_sdmmc_s *priv, + sdio_eventset_t wkupevent); +static void n32_sdmmc_eventtimeout(wdparm_t arg); + +/* Interrupt handler */ + +static int n32_sdmmc_interrupt(int irq, void *context, void *arg); + +/* SDIO interface methods */ + +#ifdef CONFIG_SDIO_MUXBUS +static int n32_sdmmc_lock(struct sdio_dev_s *dev, bool lock); +#endif /* CONFIG_SDIO_MUXBUS */ +static void n32_sdmmc_reset(struct sdio_dev_s *dev); +static sdio_capset_t n32_sdmmc_capabilities(struct sdio_dev_s *dev); +static sdio_statset_t n32_sdmmc_status(struct sdio_dev_s *dev); +static void n32_sdmmc_widebus(struct sdio_dev_s *dev, bool enable); +static void n32_sdmmc_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate); +static int n32_sdmmc_attach(struct sdio_dev_s *dev); +static int n32_sdmmc_sendcmd(struct sdio_dev_s *dev, uint32_t cmd, + uint32_t arg); +static void n32_sdmmc_blocksetup(struct sdio_dev_s *dev, + unsigned int blocksize, + unsigned int nblocks); +static int n32_sdmmc_recvsetup(struct sdio_dev_s *dev, uint8_t *buffer, + size_t nbytes); +static int n32_sdmmc_sendsetup(struct sdio_dev_s *dev, + const uint8_t *buffer, size_t nbytes); +static int n32_sdmmc_cancel(struct sdio_dev_s *dev); +static int n32_sdmmc_waitresponse(struct sdio_dev_s *dev, uint32_t cmd); +static int n32_sdmmc_recvshortcrc(struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int n32_sdmmc_recvlong(struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]); +static int n32_sdmmc_recvshort(struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static void n32_sdmmc_waitenable(struct sdio_dev_s *dev, + sdio_eventset_t eventset, + uint32_t timeout); +static sdio_eventset_t n32_sdmmc_eventwait(struct sdio_dev_s *dev); +static void n32_sdmmc_callbackenable(struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static int n32_sdmmc_registercallback(struct sdio_dev_s *dev, + worker_t callback, void *arg); +#ifdef CONFIG_SDIO_DMA +# if HAVE_ADMA2 +static int n32_sdmmc_dmarecvsetup(struct sdio_dev_s *dev, + uint8_t *buffer, size_t buflen); +static int n32_sdmmc_dmasendsetup(struct sdio_dev_s *dev, + const uint8_t *buffer, size_t buflen); +# else +# error "CONFIG_SDIO_DMA requires HAVE_ADMA2" +# endif /* HAVE_ADMA2 */ +#endif /* CONFIG_SDIO_DMA */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* SDMMC1 and SDMMC2 device instances */ + +#if defined(CONFIG_N32H7_SDMMC1) +static struct n32_sdmmc_s g_sdmmc1_dev = +{ + .dev = + { +#ifdef CONFIG_SDIO_MUXBUS + .lock = n32_sdmmc_lock, +#endif /* CONFIG_SDIO_MUXBUS */ + .reset = n32_sdmmc_reset, + .capabilities = n32_sdmmc_capabilities, + .status = n32_sdmmc_status, + .widebus = n32_sdmmc_widebus, + .clock = n32_sdmmc_clock, + .attach = n32_sdmmc_attach, + .sendcmd = n32_sdmmc_sendcmd, + .blocksetup = n32_sdmmc_blocksetup, + .recvsetup = n32_sdmmc_recvsetup, + .sendsetup = n32_sdmmc_sendsetup, + .cancel = n32_sdmmc_cancel, + .waitresponse = n32_sdmmc_waitresponse, + .recv_r1 = n32_sdmmc_recvshortcrc, + .recv_r2 = n32_sdmmc_recvlong, + .recv_r3 = n32_sdmmc_recvshort, + .recv_r4 = n32_sdmmc_recvshort, + .recv_r5 = n32_sdmmc_recvshortcrc, + .recv_r6 = n32_sdmmc_recvshortcrc, + .recv_r7 = n32_sdmmc_recvshort, + .waitenable = n32_sdmmc_waitenable, + .eventwait = n32_sdmmc_eventwait, + .callbackenable = n32_sdmmc_callbackenable, + .registercallback = n32_sdmmc_registercallback, +#ifdef CONFIG_SDIO_DMA +# if HAVE_ADMA2 + .dmarecvsetup = n32_sdmmc_dmarecvsetup, + .dmasendsetup = n32_sdmmc_dmasendsetup, +# else +# error "CONFIG_SDIO_DMA requires HAVE_ADMA2" +# endif /* HAVE_ADMA2 */ +#endif /* CONFIG_SDIO_DMA */ + }, + .cfg_base = N32_SDMMC1_CFG_BASE, + .host_base = N32_SDHOST1_BASE, + .irq = N32_IRQ_SDMMC1, + .waitsem = SEM_INITIALIZER(0), +}; +#endif + +#if defined(CONFIG_N32H7_SDMMC2) +static struct n32_sdmmc_s g_sdmmc2_dev = +{ + .dev = + { +#ifdef CONFIG_SDIO_MUXBUS + .lock = n32_sdmmc_lock, +#endif /* CONFIG_SDIO_MUXBUS */ + .reset = n32_sdmmc_reset, + .capabilities = n32_sdmmc_capabilities, + .status = n32_sdmmc_status, + .widebus = n32_sdmmc_widebus, + .clock = n32_sdmmc_clock, + .attach = n32_sdmmc_attach, + .sendcmd = n32_sdmmc_sendcmd, + .blocksetup = n32_sdmmc_blocksetup, + .recvsetup = n32_sdmmc_recvsetup, + .sendsetup = n32_sdmmc_sendsetup, + .cancel = n32_sdmmc_cancel, + .waitresponse = n32_sdmmc_waitresponse, + .recv_r1 = n32_sdmmc_recvshortcrc, + .recv_r2 = n32_sdmmc_recvlong, + .recv_r3 = n32_sdmmc_recvshort, + .recv_r4 = n32_sdmmc_recvshort, + .recv_r5 = n32_sdmmc_recvshortcrc, + .recv_r6 = n32_sdmmc_recvshortcrc, + .recv_r7 = n32_sdmmc_recvshort, + .waitenable = n32_sdmmc_waitenable, + .eventwait = n32_sdmmc_eventwait, + .callbackenable = n32_sdmmc_callbackenable, + .registercallback = n32_sdmmc_registercallback, +#ifdef CONFIG_SDIO_DMA +# if HAVE_ADMA2 + .dmarecvsetup = n32_sdmmc_dmarecvsetup, + .dmasendsetup = n32_sdmmc_dmasendsetup, +# else +# error "CONFIG_SDIO_DMA requires HAVE_ADMA2" +# endif /* HAVE_ADMA2 */ +#endif /* CONFIG_SDIO_DMA */ + }, + .cfg_base = N32_SDMMC2_CFG_BASE, + .host_base = N32_SDHOST2_BASE, + .irq = N32_IRQ_SDMMC2, + .waitsem = SEM_INITIALIZER(0), +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* ========================================================================== + * Register Access Helpers + * ========================================================================== + */ + +/**************************************************************************** + * Name: n32_sdmmc_putreg + * + * Description: + * Write a 32-bit value to a SDHOST register. + * + * Input Parameters: + * priv - SDMMC device instance + * value - Value to write + * offset - Register offset from SDHOST base + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void n32_sdmmc_putreg(struct n32_sdmmc_s *priv, + uint32_t value, int offset) +{ + putreg32(value, priv->host_base + offset); +} + +/**************************************************************************** + * Name: n32_sdmmc_getreg + * + * Description: + * Read a 32-bit value from a SDHOST register. + * + * Input Parameters: + * priv - SDMMC device instance + * offset - Register offset from SDHOST base + * + * Returned Value: + * Register value + * + ****************************************************************************/ + +static inline uint32_t n32_sdmmc_getreg(struct n32_sdmmc_s *priv, + int offset) +{ + return getreg32(priv->host_base + offset); +} + +/**************************************************************************** + * Name: n32_sdmmc_modifyreg + * + * Description: + * Atomically modify a SDHOST register (clear and set bits). + * + * Input Parameters: + * priv - SDMMC device instance + * offset - Register offset + * clr - Bits to clear + * set - Bits to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void n32_sdmmc_modifyreg(struct n32_sdmmc_s *priv, + int offset, uint32_t clr, + uint32_t set) +{ + uint32_t reg = n32_sdmmc_getreg(priv, offset); + + reg &= ~clr; + reg |= set; + n32_sdmmc_putreg(priv, reg, offset); +} + +/* ========================================================================== + * Interrupt Configuration + * ========================================================================== + */ + +/**************************************************************************** + * Name: n32_sdmmc_configints + * + * Description: + * Enable/disable SDHOST interrupts and set waiting events. + * + * Input Parameters: + * priv - SDMMC device instance + * mask - Interrupt mask to write to ISE + * events - Events to be waited for (SDIOWAIT_*) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_configints(struct n32_sdmmc_s *priv) +{ + irqstate_t flags = enter_critical_section(); + + /* Enable interrupts at the signal level (ISE) */ + + n32_sdmmc_putreg(priv, priv->waitmask, N32_SDHOST_ISE_OFFSET); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: n32_sdmmc_configsts + * + * Description: + * Enable/disable SDHOST status signal and set waiting events. + * + * Input Parameters: + * priv - SDMMC device instance + * mask - Interrupt mask to write to IE + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_configsts(struct n32_sdmmc_s *priv, uint32_t mask) +{ + irqstate_t flags = enter_critical_section(); + + /* Enable interrupts at the SDHOST level (IE) */ + + n32_sdmmc_putreg(priv, mask, N32_SDHOST_IE_OFFSET); + + leave_critical_section(flags); +} + +/* ========================================================================== + * Clock & Power Control + * ========================================================================== + */ + +/**************************************************************************** + * Name: n32_sdmmc_enable_clock + * + * Description: + * Enable or disable SD clock with the desired frequency. + * + * Input Parameters: + * priv - SDMMC device instance + * freq_hz - Desired SD clock frequency in Hz (0 to disable) + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_enable_clock(struct n32_sdmmc_s *priv, uint32_t freq_hz) +{ + uint32_t regval; + uint32_t div; + int timeout = 10000; + + /* If freq_hz is 0, disable clock */ + + if (freq_hz == 0) + { + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL2_OFFSET, + N32_SDHOST_CTRL2_INCLKE | + N32_SDHOST_CTRL2_SDCLKE, + 0); + priv->clock = 0; + return OK; + } + + /* Calculate SDCLKSEL divider: freq = BCLKF / (2 * div) */ + + /* BCLKF is in MHz, freq_hz in Hz */ + + uint32_t bclk_hz = N32_BCLKF_FREQ * 1000000UL; + + div = bclk_hz / (2 * freq_hz); + + if (div > 0x3ff) + { + div = 0x3ff; /* Max divider */ + } + + priv->clock = freq_hz; + + /* 1. Disable clock */ + + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL2_OFFSET, + N32_SDHOST_CTRL2_INCLKE | N32_SDHOST_CTRL2_SDCLKE, 0); + + /* 2. Set divider */ + + regval = n32_sdmmc_getreg(priv, N32_SDHOST_CTRL2_OFFSET); + regval &= ~(N32_SDHOST_CTRL2_SDCLKSEL70_MASK | + N32_SDHOST_CTRL2_SDCLKSEL98_MASK); + regval |= N32_SDHOST_CTRL2_SDCLKSEL(div); + n32_sdmmc_putreg(priv, regval, N32_SDHOST_CTRL2_OFFSET); + + /* 3. Enable clock */ + + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL2_OFFSET, 0, + N32_SDHOST_CTRL2_INCLKE | N32_SDHOST_CTRL2_SDCLKE); + + /* 4. Wait for stable */ + + do + { + regval = n32_sdmmc_getreg(priv, N32_SDHOST_CTRL2_OFFSET); + if (regval & N32_SDHOST_CTRL2_INCLKSTS) + { + break; + } + + up_udelay(10); + } + while (--timeout > 0); + + if (timeout == 0) + { + mcerr("ERROR: Internal clock not stable\n"); + return -ETIMEDOUT; + } + + mcinfo("SDCLK enabled: freq=%lu Hz, div=%lu\n", (unsigned long)freq_hz, + (unsigned long)div); + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_power_on + * + * Description: + * Turn on SD bus power (3.3V). + * + * Input Parameters: + * priv - SDMMC device instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_power_on(struct n32_sdmmc_s *priv) +{ + uint32_t regval; + + /* Set voltage to 3.3V and enable power */ + + regval = n32_sdmmc_getreg(priv, N32_SDHOST_CTRL1_OFFSET); + regval &= ~(N32_SDHOST_CTRL1_SDBVSEL_MASK | N32_SDHOST_CTRL1_SDPWR); + regval |= N32_SDHOST_CTRL1_SDBVSEL_3V3; + n32_sdmmc_putreg(priv, regval, N32_SDHOST_CTRL1_OFFSET); + + /* Power up delay */ + + nxsched_msleep(10); + regval |= N32_SDHOST_CTRL1_SDPWR; + n32_sdmmc_putreg(priv, regval, N32_SDHOST_CTRL1_OFFSET); +} + +/**************************************************************************** + * Name: n32_sdmmc_power_off + * + * Description: + * Turn off SD bus power. + * + * Input Parameters: + * priv - SDMMC device instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_power_off(struct n32_sdmmc_s *priv) +{ + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL1_OFFSET, + N32_SDHOST_CTRL1_SDPWR, 0); +} + +/* ========================================================================== + * Command & Response + * ========================================================================== + */ + +/**************************************************************************** + * Name: n32_sdmmc_send_cmd + * + * Description: + * Format and send an SD command. + * + * Input Parameters: + * priv - SDMMC device instance + * cmd - Command word (including flags) + * arg - 32-bit argument + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_send_cmd(struct n32_sdmmc_s *priv, + uint32_t cmd, uint32_t arg) +{ + uint32_t regval = 0; + uint32_t cmdidx; + + /* Clear previous command status */ + + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_CMDC | N32_SDHOST_INTSTS_CTERR | + N32_SDHOST_INTSTS_CCRCERR | N32_SDHOST_INTSTS_CINXERR | + N32_SDHOST_INTSTS_CENDBERR, + N32_SDHOST_INTSTS_OFFSET); + + /* Set argument */ + + n32_sdmmc_putreg(priv, arg, N32_SDHOST_CMDARG1_OFFSET); + + /* Build TMODE register */ + + cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; + regval |= (cmdidx << N32_SDHOST_TMODE_CMDINDEX_SHIFT); + + /* Response type */ + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: + regval |= N32_SDHOST_TMODE_RTYPES_NONE; + break; + case MMCSD_R1_RESPONSE: + case MMCSD_R5_RESPONSE: + case MMCSD_R6_RESPONSE: + case MMCSD_R7_RESPONSE: + regval |= N32_SDHOST_TMODE_RTYPES_48 | N32_SDHOST_TMODE_CRCCK | + N32_SDHOST_TMODE_CMDXCK; + break; + case MMCSD_R1B_RESPONSE: + regval |= N32_SDHOST_TMODE_RTYPES_48_BUSY | N32_SDHOST_TMODE_CRCCK | + N32_SDHOST_TMODE_CMDXCK; + break; + case MMCSD_R2_RESPONSE: + regval |= N32_SDHOST_TMODE_RTYPES_136 | N32_SDHOST_TMODE_CRCCK; + break; + case MMCSD_R3_RESPONSE: + case MMCSD_R4_RESPONSE: + regval |= N32_SDHOST_TMODE_RTYPES_48; + break; + default: + return -EINVAL; + } + + /* Data transfer */ + + if ((cmd & MMCSD_DATAXFR_MASK) != MMCSD_NODATAXFR) + { + regval |= N32_SDHOST_TMODE_DPSEL; + if ((cmd & MMCSD_DATAXFR_MASK) == MMCSD_RDDATAXFR) + { + regval |= N32_SDHOST_TMODE_DATDIR; /* Read */ + priv->is_read = true; + } + else + { + priv->is_read = false; /* Write */ + } + + n32_sdmmc_setup_data(priv); + } + + /* Multi-block */ + + if (priv->nblocks > 1) + { + regval |= N32_SDHOST_TMODE_BLKSEL | N32_SDHOST_TMODE_BCNTE; + } + + /* DMA enable if using ADMA */ + + if (priv->using_dma) + { + regval |= N32_SDHOST_TMODE_DMAE; + } + + /* Write TMODE to trigger command */ + + n32_sdmmc_putreg(priv, regval, N32_SDHOST_TMODE_OFFSET); + + mcinfo("CMD: 0x%08lx ARG: 0x%08lx TMODE: 0x%08lx\n", + (unsigned long)cmd, (unsigned long)arg, + (unsigned long)regval); + + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_wait_cmd_done + * + * Description: + * Poll-wait for command completion or error. + * + * Input Parameters: + * priv - SDMMC device instance + * cmd - Command word (for debugging) + * + * Returned Value: + * OK on success, -ETIMEDOUT or -EIO on error. + * + ****************************************************************************/ + +static int n32_sdmmc_wait_cmd_done(struct n32_sdmmc_s *priv, uint32_t cmd) +{ + uint32_t regval; + int32_t timeout = N32_SDMMC_CMDTIMEOUT; + + /* Wait for command complete or error */ + + while (--timeout > 0) + { + regval = n32_sdmmc_getreg(priv, N32_SDHOST_INTSTS_OFFSET); + if (regval & N32_SDHOST_INTSTS_CMDC) + { + /* Clear it */ + + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_CMDC, + N32_SDHOST_INTSTS_OFFSET); + return OK; + } + + if (regval & (N32_SDHOST_INTSTS_CTERR | N32_SDHOST_INTSTS_CCRCERR)) + { + mcerr("CMD error: Istatus=0x%08lx\n", (unsigned long)regval); + + /* Reset command line */ + + regval = n32_sdmmc_getreg(priv, N32_SDHOST_CTRL2_OFFSET); + regval |= N32_SDHOST_CTRL2_SWRSTCMD; + n32_sdmmc_putreg(priv, regval, N32_SDHOST_CTRL2_OFFSET); + return -EIO; + } + + up_udelay(1); + } + + mcerr("CMD timeout: status=0x%08lx\n", + (unsigned long)n32_sdmmc_getreg(priv, N32_SDHOST_INTSTS_OFFSET)); + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: n32_sdmmc_get_response + * + * Description: + * Read command response from response registers. + * + * Input Parameters: + * priv - SDMMC device instance + * cmd - Command word (to determine response length) + * resp - Pointer to store response (if R2, points to 4-word array) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_get_response(struct n32_sdmmc_s *priv, + uint32_t cmd, uint32_t *resp) +{ + int rtype = cmd & MMCSD_RESPONSE_MASK; + + if (rtype == MMCSD_R2_RESPONSE) + { + if (resp) + { + resp[3] = n32_sdmmc_getreg(priv, N32_SDHOST_CMDRSP0_OFFSET) << 8; + resp[2] = (n32_sdmmc_getreg(priv, N32_SDHOST_CMDRSP1_OFFSET) << 8) + | (n32_sdmmc_getreg(priv, N32_SDHOST_CMDRSP0_OFFSET) >> 24); + resp[1] = (n32_sdmmc_getreg(priv, N32_SDHOST_CMDRSP2_OFFSET) << 8) + | (n32_sdmmc_getreg(priv, N32_SDHOST_CMDRSP1_OFFSET) >> 24); + resp[0] = (n32_sdmmc_getreg(priv, N32_SDHOST_CMDRSP3_OFFSET) << 8) + | (n32_sdmmc_getreg(priv, N32_SDHOST_CMDRSP2_OFFSET) >> 24); + } + } + else + { + if (resp) + { + *resp = n32_sdmmc_getreg(priv, N32_SDHOST_CMDRSP0_OFFSET); + } + } +} + +/* ========================================================================== + * Data Transfer (PIO) + * ========================================================================== + */ + +/**************************************************************************** + * Name: n32_sdmmc_setup_data + * + * Description: + * Configure BLKCFG for a data transfer. + * + * Input Parameters: + * priv - SDMMC device instance + * blocksize - Block size in bytes + * nblocks - Number of blocks + * read - true for read, false for write + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_setup_data(struct n32_sdmmc_s *priv) +{ + uint32_t regval; + uint32_t total_len = priv->blocksize * priv->nblocks; + + /* Set BLKCFG */ + + regval = ((priv->nblocks & 0xffff) << N32_SDHOST_BLKCFG_CNT_SHIFT) | + (priv->blocksize & N32_SDHOST_BLKCFG_SIZE_MASK); + n32_sdmmc_putreg(priv, regval, N32_SDHOST_BLKCFG_OFFSET); + + up_udelay(10); + + mcinfo("DATA: size=%lu, blocks=%lu, total=%lu, dir=%s\n", + (unsigned long)priv->blocksize, (unsigned long)priv->nblocks, + (unsigned long)total_len, priv->is_read ? "READ" : "WRITE"); +} + +/**************************************************************************** + * Name: n32_sdmmc_send_fifo + * + * Description: + * Write data from buffer to SDHOST FIFO (PIO write). + * + * Input Parameters: + * priv - SDMMC device instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_send_fifo(struct n32_sdmmc_s *priv) +{ + uint32_t data; + uint32_t status; + + while (priv->remaining > 0) + { + status = n32_sdmmc_getreg(priv, N32_SDHOST_PRESTS_OFFSET); + if (!(status & N32_SDHOST_PRESTS_BUFW)) + { + break; /* FIFO full */ + } + + if (priv->remaining >= 4) + { + data = *priv->buffer++; + priv->remaining -= 4; + } + else + { + /* Last fractional word */ + + uint8_t *ptr = (uint8_t *)priv->buffer; + + data = 0; + for (int i = 0; i < priv->remaining; i++) + { + ((uint8_t *)&data)[i] = ptr[i]; + } + + priv->remaining = 0; + } + + n32_sdmmc_putreg(priv, data, N32_SDHOST_BUFDAT_OFFSET); + } +} + +/**************************************************************************** + * Name: n32_sdmmc_recv_fifo + * + * Description: + * Read data from SDHOST FIFO to buffer (PIO read). + * + * Input Parameters: + * priv - SDMMC device instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_recv_fifo(struct n32_sdmmc_s *priv) +{ + uint32_t data; + uint32_t status; + + while (priv->remaining > 0) + { + status = n32_sdmmc_getreg(priv, N32_SDHOST_PRESTS_OFFSET); + if (!(status & N32_SDHOST_PRESTS_BUFR)) + { + break; /* No data */ + } + + data = n32_sdmmc_getreg(priv, N32_SDHOST_BUFDAT_OFFSET); + + if (priv->remaining >= 4) + { + *priv->buffer++ = data; + priv->remaining -= 4; + } + else + { + uint8_t *ptr = (uint8_t *)priv->buffer; + + for (int i = 0; i < priv->remaining; i++) + { + ptr[i] = ((uint8_t *)&data)[i]; + } + + priv->remaining = 0; + } + } +} + +/**************************************************************************** + * Name: n32_sdmmc_datadisable + * + * Description: + * Disable data path, stop DMA, and reset data state. + * + * Input Parameters: + * priv - SDMMC device instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_datadisable(struct n32_sdmmc_s *priv) +{ + /* Clear BLKCFG to prevent residual data */ + + n32_sdmmc_putreg(priv, 0, N32_SDHOST_BLKCFG_OFFSET); + + /* If in DMA mode, stop ADMA */ + +#if HAVE_ADMA2 + if (priv->adma_in_progress) + { + n32_sdmmc_stop_adma(priv); + } +#endif + + /* Software reset data line to flush FIFO */ + + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL2_OFFSET, + 0, N32_SDHOST_CTRL2_SWRSTDAT); + up_udelay(10); + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL2_OFFSET, + N32_SDHOST_CTRL2_SWRSTDAT, 0); + + /* Clear all data-related interrupt pending bits */ + + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_TC | N32_SDHOST_INTSTS_BUFWRDY | + N32_SDHOST_INTSTS_BUFRRDY | N32_SDHOST_INTSTS_DMAINT | + N32_SDHOST_INTSTS_DTERR | N32_SDHOST_INTSTS_DCRERR | + N32_SDHOST_INTSTS_ADMAERR, + N32_SDHOST_INTSTS_OFFSET); + + priv->remaining = 0; + priv->using_dma = false; +} + +/* ========================================================================== + * ADMA2 Support + * ========================================================================== + */ + +#if HAVE_ADMA2 + +/**************************************************************************** + * Name: n32_sdmmc_build_adma_desc + * + * Description: + * Build an ADMA2 descriptor table in system memory. + * + * Input Parameters: + * priv - SDMMC device instance + * buffer - Data buffer address + * len - Total data length in bytes + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +/* ADMA2 descriptor table in None-TCM memory */ +#ifdef CONFIG_N32H7_SDMMC1 +static struct n32_sdmmc_adma_desc_s locate_data(".axi_ram") + n32_sdmmc1_desc[CONFIG_N32H7_SDMMC_MAX_DESCS] aligned_data(4); +#endif /* CONFIG_N32H7_SDMMC1 */ +#ifdef CONFIG_N32H7_SDMMC2 +static struct n32_sdmmc_adma_desc_s locate_data(".axi_ram") + n32_sdmmc2_desc[CONFIG_N32H7_SDMMC_MAX_DESCS] aligned_data(4); +#endif /* CONFIG_N32H7_SDMMC2 */ +#if CONFIG_MMCSD_MULTIBLOCK_LIMIT <= 16 +# ifdef CONFIG_N32H7_SDMMC1 +static uint8_t locate_data(".axi_ram") + n32_sdmmc1_blk_buf + [N32_SDMMC_MAX_BLOCK_SIZE * CONFIG_MMCSD_MULTIBLOCK_LIMIT] + aligned_data(4); +# endif /* CONFIG_N32H7_SDMMC1 */ +# ifdef CONFIG_N32H7_SDMMC2 +static uint8_t locate_data(".axi_ram") + n32_sdmmc2_blk_buf + [N32_SDMMC_MAX_BLOCK_SIZE * CONFIG_MMCSD_MULTIBLOCK_LIMIT] + aligned_data(4); +# endif /* CONFIG_N32H7_SDMMC2 */ +#else +# error "CONFIG_MMCSD_MULTIBLOCK_LIMIT must be less than or equal to 16" +#endif /* CONFIG_MMCSD_MULTIBLOCK_LIMIT */ + +static int n32_sdmmc_build_adma_desc(struct n32_sdmmc_s *priv, + uint8_t *buffer, size_t len) +{ + uint32_t total_len = len; + uint32_t offset = 0; + uint32_t max_chunk = 65535; /* 64KB - 1 */ + struct n32_sdmmc_adma_desc_s *desc = NULL; + uint8_t desc_count = 0; + uint8_t *blk_buf = NULL; + +#ifdef CONFIG_N32H7_SDMMC1 + if (priv->irq == N32_IRQ_SDMMC1) + { + desc = n32_sdmmc1_desc; + blk_buf = n32_sdmmc1_blk_buf; + } +#endif /* CONFIG_N32H7_SDMMC1 */ + +#ifdef CONFIG_N32H7_SDMMC2 + if (priv->irq == N32_IRQ_SDMMC2) + { + desc = n32_sdmmc2_desc; + blk_buf = n32_sdmmc2_blk_buf; + } +#endif /* CONFIG_N32H7_SDMMC2 */ + + /* Calculate number of descriptors needed */ + + while (len > 0) + { + uint32_t chunk = (len > max_chunk) ? max_chunk : len; + + desc_count++; + len -= chunk; + } + + if (desc_count == 0 || desc_count > CONFIG_N32H7_SDMMC_MAX_DESCS) + { + return -EINVAL; + } + + priv->adma_list.desc = desc; + priv->adma_list.count = desc_count; + priv->adma_list.total_len = total_len; + + /* Fill descriptors */ + + len = total_len; + offset = 0; + for (uint8_t i = 0; i < desc_count; i++) + { + uint32_t chunk = (len > max_chunk) ? max_chunk : len; + + desc[i].addr = (uint32_t *)(blk_buf + offset); + desc[i].len = (uint16_t)chunk; + desc[i].attr = N32_ADMA_ENTRY_VALID | N32_ADMA_ACT_TRAN; + + /* Prepare block buffer in None-TCM memory */ + + if (!priv->is_read) + { + memcpy(desc[i].addr, buffer + offset, chunk); + } + + /* Invalidate D-Cache before DMA read from memory */ + + up_invalidate_dcache((uintptr_t)desc[i].addr, + (uintptr_t)desc[i].addr + chunk); + + if (i == desc_count - 1) + { + desc[i].attr |= N32_ADMA_ENTRY_END; + } + + /* Optionally set INT for every descriptor or at end */ + + /* desc[i].attr |= N32_ADMA_ENTRY_INT; */ + + offset += chunk; + len -= chunk; + } + + mcinfo("ADMA desc: count=%d, total_len=%lu\n", + desc_count, (unsigned long)total_len); + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_start_adma + * + * Description: + * Start ADMA2 transfer by setting descriptor address and enabling ADMA. + * + * Input Parameters: + * priv - SDMMC device instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_start_adma(struct n32_sdmmc_s *priv) +{ + /* Set ADMA descriptor address */ + + n32_sdmmc_putreg(priv, (uint32_t)priv->adma_list.desc, + N32_SDHOST_ASADD0_OFFSET); + + /* High 32 bits = 0 (32-bit addressing) */ + + n32_sdmmc_putreg(priv, 0, N32_SDHOST_ASADD1_OFFSET); + + /* Select ADMA2 in CTRL1 */ + + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL1_OFFSET, + N32_SDHOST_CTRL1_DMASEL_MASK, + N32_SDHOST_CTRL1_DMASEL_ADMA2); + + priv->adma_in_progress = true; + priv->using_dma = true; + + mcinfo("ADMA started, desc addr=0x%08lx\n", + (unsigned long)priv->adma_list.desc); +} + +/**************************************************************************** + * Name: n32_sdmmc_stop_adma + * + * Description: + * Stop ADMA2 and free descriptor table. + * + * Input Parameters: + * priv - SDMMC device instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_stop_adma(struct n32_sdmmc_s *priv) +{ + priv->adma_in_progress = false; + priv->using_dma = false; + + /* Disable ADMA */ + + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL1_OFFSET, + N32_SDHOST_CTRL1_DMASEL_MASK, 0); + + /* Free descriptor table */ + + if (priv->adma_list.desc) + { + priv->adma_list.desc = NULL; + priv->adma_list.count = 0; + priv->adma_list.total_len = 0; + } + + mcinfo("ADMA stopped\n"); +} + +#endif /* HAVE_ADMA2 */ + +/* ========================================================================== + * Event Handling + * ========================================================================== + */ + +/**************************************************************************** + * Name: n32_sdmmc_endwait + * + * Description: + * Wake up a waiting thread, cancel timeout, and clear events. + * + * Input Parameters: + * priv - SDMMC device instance + * wkupevent - Event that caused the wakeup + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_endwait(struct n32_sdmmc_s *priv, + sdio_eventset_t wkupevent) +{ + /* Cancel the watchdog timeout */ + + wd_cancel(&priv->waitwdog); + + /* Disable all waiting-related interrupts */ + + priv->waitmask = 0; + priv->waitevents = 0; + n32_sdmmc_configints(priv); + + /* Set wakeup event and post semaphore */ + + priv->wkupevent = wkupevent; + nxsem_post(&priv->waitsem); +} + +/**************************************************************************** + * Name: n32_sdmmc_eventtimeout + * + * Description: + * Watchdog timeout handler for event wait. + * + * Input Parameters: + * arg - Pointer to SDMMC device instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_eventtimeout(wdparm_t arg) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)arg; + + if (priv->waitevents & SDIOWAIT_TIMEOUT) + { + n32_sdmmc_endwait(priv, SDIOWAIT_TIMEOUT); + } +} + +/* ========================================================================== + * Interrupt Handler + * ========================================================================== + */ + +/**************************************************************************** + * Name: n32_sdmmc_interrupt + * + * Description: + * SDHOST interrupt handler. + * + * Input Parameters: + * irq - IRQ number + * context - Interrupt context + * arg - Pointer to SDMMC device instance + * + * Returned Value: + * Always returns OK. + * + ****************************************************************************/ + +static int n32_sdmmc_interrupt(int irq, void *context, void *arg) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)arg; + uint32_t status; + uint32_t enabled; + uint32_t error_mask; + + status = n32_sdmmc_getreg(priv, N32_SDHOST_INTSTS_OFFSET); + enabled = status & n32_sdmmc_getreg(priv, N32_SDHOST_ISE_OFFSET); + + if (enabled == 0) + { + return OK; + } + + /* Handle errors (all error bits) */ + + error_mask = enabled & (N32_SDHOST_INTSTS_CTERR | + N32_SDHOST_INTSTS_CCRCERR | + N32_SDHOST_INTSTS_CENDBERR | + N32_SDHOST_INTSTS_CINXERR | + N32_SDHOST_INTSTS_DTERR | + N32_SDHOST_INTSTS_DCRERR | + N32_SDHOST_INTSTS_DENDERR | + N32_SDHOST_INTSTS_ADMAERR | + N32_SDHOST_INTSTS_ACMDERR); + + if (error_mask) + { + mcerr("ERROR: status=0x%08lx mask=0x%08lx\n", + (unsigned long)status, (unsigned long)error_mask); + n32_sdmmc_putreg(priv, error_mask, N32_SDHOST_INTSTS_OFFSET); + + /* Disable data path on data errors */ + + if (error_mask & (N32_SDHOST_INTSTS_DTERR | + N32_SDHOST_INTSTS_DCRERR | + N32_SDHOST_INTSTS_DENDERR | + N32_SDHOST_INTSTS_ADMAERR)) + { + n32_sdmmc_datadisable(priv); + } + + if (priv->waitevents & SDIOWAIT_ERROR) + { + n32_sdmmc_endwait(priv, SDIOWAIT_ERROR); + } + + return OK; + } + + /* Command Complete */ + + if (enabled & N32_SDHOST_INTSTS_CMDC) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_CMDC, + N32_SDHOST_INTSTS_OFFSET); + if (priv->waitevents & SDIOWAIT_CMDDONE) + { + n32_sdmmc_endwait(priv, SDIOWAIT_CMDDONE); + } + } + + /* Transfer Complete */ + + if (enabled & N32_SDHOST_INTSTS_TC) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_TC, + N32_SDHOST_INTSTS_OFFSET); + + if (priv->waitevents & SDIOWAIT_TRANSFERDONE) + { + if (priv->using_dma) + { + priv->adma_in_progress = false; + if (priv->is_read) + { + uint32_t offset = 0; + + for (uint8_t i = 0; i < priv->adma_list.count; i++) + { + /* Invalidate D-Cache after DMA write to memory */ + + up_invalidate_dcache((uintptr_t) + priv->adma_list.desc[i].addr, + (uintptr_t)priv->adma_list.desc[i].addr + + priv->adma_list.desc[i].len); + + /* Copy data from None-TCM memory to buffer */ + + memcpy(priv->buffer + offset, + priv->adma_list.desc[i].addr, + priv->adma_list.desc[i].len); + priv->remaining -= priv->adma_list.desc[i].len; + offset += priv->adma_list.desc[i].len; + if (priv->adma_list.desc[i].attr & N32_ADMA_ENTRY_END) + { + break; + } + } + } + else + { + priv->remaining = 0; + } + } + + if (priv->remaining == 0) + { + n32_sdmmc_endwait(priv, SDIOWAIT_TRANSFERDONE); + } + } + } + + /* Buffer Write Ready (PIO) */ + + if (enabled & N32_SDHOST_INTSTS_BUFWRDY) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_BUFWRDY, + N32_SDHOST_INTSTS_OFFSET); + if (!priv->using_dma && !priv->is_read) + { + n32_sdmmc_send_fifo(priv); + if (priv->remaining == 0) + { + /* All data written, disable BUFWRDY interrupt */ + + priv->waitmask &= ~N32_SDHOST_INTSTS_BUFWRDY; + n32_sdmmc_configints(priv); + } + } + } + + /* Buffer Read Ready (PIO) */ + + if (enabled & N32_SDHOST_INTSTS_BUFRRDY) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_BUFRRDY, + N32_SDHOST_INTSTS_OFFSET); + if (!priv->using_dma && priv->is_read) + { + n32_sdmmc_recv_fifo(priv); + if (priv->remaining == 0) + { + /* All data read, disable BUFRRDY interrupt */ + + priv->waitmask &= ~N32_SDHOST_INTSTS_BUFRRDY; + n32_sdmmc_configints(priv); + } + } + } + + /* DMA Interrupt (for SDMA, not used by ADMA) */ + + if (enabled & N32_SDHOST_INTSTS_DMAINT) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_DMAINT, + N32_SDHOST_INTSTS_OFFSET); + } + + return OK; +} + +/* ========================================================================== + * SDIO Interface Methods + * ========================================================================== + */ + +/**************************************************************************** + * Name: n32_sdmmc_lock + * + * Description: + * Lock/unlock the SD bus (not implemented for single slot). + * + * Input Parameters: + * dev - SDIO device instance + * lock - true to lock, false to unlock + * + * Returned Value: + * Always OK. + * + ****************************************************************************/ +#ifdef CONFIG_SDIO_MUXBUS +static int n32_sdmmc_lock(struct sdio_dev_s *dev, bool lock) +{ + /* Not implemented for single slot */ + + return OK; +} +#endif /* CONFIG_SDIO_MUXBUS */ + +/**************************************************************************** + * Name: n32_sdmmc_reset + * + * Description: + * Reset the SDMMC controller to initial state. + * + * Input Parameters: + * dev - SDIO device instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_reset(struct sdio_dev_s *dev) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + uint32_t regval; + uint16_t timeout = 10000; + + /* 1. Software Reset All */ + + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL2_OFFSET, + 0, N32_SDHOST_CTRL2_SWRSTALL); + + /* Wait for reset to clear */ + + do + { + regval = n32_sdmmc_getreg(priv, N32_SDHOST_CTRL2_OFFSET); + if ((regval & N32_SDHOST_CTRL2_SWRSTALL) == 0) + { + break; + } + + up_udelay(10); + } + while (--timeout > 0); + + /* Disable all status word */ + + priv->waitmask = 0; + priv->waitevents = 0; + n32_sdmmc_configints(priv); + n32_sdmmc_configsts(priv, 0); + + /* 2. Soft CD enable */ + + regval = n32_sdmmc_getreg(priv, N32_SDHOST_CTRL1_OFFSET); + regval |= N32_SDHOST_CTRL1_CDSD; + n32_sdmmc_putreg(priv, regval, N32_SDHOST_CTRL1_OFFSET); + + /* 3. Configure CFG1 (BCLKF = 100 MHz, TCLKU = KHz) */ + + regval = (N32_BCLKF_FREQ << N32_SDMMC_CFG1_BCLKF_SHIFT) | 0; /* TCLKU=0 */ + N32_PUT_CFG(priv, N32_SDMMC_CFG1_OFFSET, regval); + + /* 4. Set capabilities (hardcoded) */ + + regval = N32_SDMMC_CFG2_VS33 | N32_SDMMC_CFG2_HS | N32_SDMMC_CFG2_ADMA2; + N32_PUT_CFG(priv, N32_SDMMC_CFG2_OFFSET, regval); + + /* 5. Reset state */ + + priv->clock = 0; + priv->remaining = 0; + priv->using_dma = false; + priv->widebus = false; + priv->waitevents = 0; + priv->wkupevent = 0; + priv->cdstatus = 0; + + wd_cancel(&priv->waitwdog); + + mcinfo("SDMMC reset completed\n"); +} + +/**************************************************************************** + * Name: n32_sdmmc_capabilities + * + * Description: + * Return SDIO capabilities (DMA supported if ADMA enabled). + * + * Input Parameters: + * dev - SDIO device instance + * + * Returned Value: + * Bitmask of capabilities (SDIO_CAPS_*). + * + ****************************************************************************/ + +static sdio_capset_t n32_sdmmc_capabilities(struct sdio_dev_s *dev) +{ + sdio_capset_t caps = SDIO_CAPS_4BIT | SDIO_CAPS_DMABEFOREWRITE; +#if HAVE_ADMA2 + caps |= (SDIO_CAPS_DMASUPPORTED/* | SDIO_CAPS_SD_HS_MODE */); +#endif + return caps; +} + +/**************************************************************************** + * Name: n32_sdmmc_status + * + * Description: + * Return current card status (present, write protected). + * + * Input Parameters: + * dev - SDIO device instance + * + * Returned Value: + * Bitmask of status flags (SDIO_STATUS_*). + * + ****************************************************************************/ + +static sdio_statset_t n32_sdmmc_status(struct sdio_dev_s *dev) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + return priv->cdstatus; +} + +/**************************************************************************** + * Name: n32_sdmmc_widebus + * + * Description: + * Enable/disable 4-bit wide bus mode. + * + * Input Parameters: + * dev - SDIO device instance + * enable - true for 4-bit, false for 1-bit + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_widebus(struct sdio_dev_s *dev, bool enable) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + priv->widebus = enable; + + if (enable) + { + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL1_OFFSET, + 0, N32_SDHOST_CTRL1_DTWIDTH); + } + else + { + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL1_OFFSET, + N32_SDHOST_CTRL1_DTWIDTH, 0); + } +} + +/**************************************************************************** + * Name: n32_sdmmc_clock + * + * Description: + * Set SD clock frequency based on the requested mode. + * + * Input Parameters: + * dev - SDIO device instance + * rate - Clock mode (CLOCK_*) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_clock(struct sdio_dev_s *dev, enum sdio_clock_e rate) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + uint32_t freq = 0, regval; + + switch (rate) + { + case CLOCK_SDIO_DISABLED: + freq = 0; + break; + case CLOCK_IDMODE: + freq = 400000; + break; + case CLOCK_MMC_TRANSFER: + case CLOCK_MMC_TRANSFER_4BIT: + freq = 25000000; + break; + case CLOCK_SD_TRANSFER_1BIT: + case CLOCK_SD_TRANSFER_4BIT: + freq = 25000000; + break; + case CLOCK_SD_TRANSFER_4BIT_HS: + regval = n32_sdmmc_getreg(priv, N32_SDHOST_CTRL1_OFFSET); + regval |= N32_SDHOST_CTRL1_HSEN; + n32_sdmmc_putreg(priv, regval, N32_SDHOST_CTRL1_OFFSET); + freq = 50000000; + break; + default: + freq = 400000; + break; + } + + n32_sdmmc_enable_clock(priv, freq); +} + +/**************************************************************************** + * Name: n32_sdmmc_attach + * + * Description: + * Attach interrupt handler and enable NVIC. + * + * Input Parameters: + * dev - SDIO device instance + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_attach(struct sdio_dev_s *dev) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + int ret; + + ret = irq_attach(priv->irq, n32_sdmmc_interrupt, priv); + if (ret == OK) + { + /* Disable all interrupts */ + + n32_sdmmc_putreg(priv, 0, N32_SDHOST_IE_OFFSET); + n32_sdmmc_putreg(priv, 0, N32_SDHOST_ISE_OFFSET); + + /* Clear pending */ + + n32_sdmmc_putreg(priv, 0xffffffff, N32_SDHOST_INTSTS_OFFSET); + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: n32_sdmmc_sendcmd + * + * Description: + * Send an SD command (wrapper for n32_sdmmc_send_cmd). + * + * Input Parameters: + * dev - SDIO device instance + * cmd - Command word + * arg - 32-bit argument + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_sendcmd(struct sdio_dev_s *dev, uint32_t cmd, + uint32_t arg) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + return n32_sdmmc_send_cmd(priv, cmd, arg); +} + +/**************************************************************************** + * Name: n32_sdmmc_blocksetup + * + * Description: + * Configure block size and number of blocks for next transfer. + * + * Input Parameters: + * dev - SDIO device instance + * blocksize - Block size in bytes + * nblocks - Number of blocks + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_blocksetup(struct sdio_dev_s *dev, + unsigned int blocksize, + unsigned int nblocks) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + + priv->blocksize = blocksize; + priv->nblocks = nblocks; +} + +/**************************************************************************** + * Name: n32_sdmmc_recvsetup + * + * Description: + * Setup for PIO read transfer. + * + * Input Parameters: + * dev - SDIO device instance + * buffer - Data buffer + * nbytes - Number of bytes to read + * + * Returned Value: + * OK on success. + * + ****************************************************************************/ + +static int n32_sdmmc_recvsetup(struct sdio_dev_s *dev, uint8_t *buffer, + size_t nbytes) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + + /* Reset data path state */ + + n32_sdmmc_datadisable(priv); + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; + priv->is_read = true; + priv->using_dma = false; + + /* Enable buffer read ready interrupt */ + + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_BUFRRDY, + N32_SDHOST_INTSTS_OFFSET); + priv->waitmask |= N32_SDHOST_INTSTS_BUFRRDY; + n32_sdmmc_configints(priv); + + mcinfo("PIO recv setup: buffer=%p, len=%zu\n", buffer, nbytes); + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_sendsetup + * + * Description: + * Setup for PIO write transfer. + * + * Input Parameters: + * dev - SDIO device instance + * buffer - Data buffer + * nbytes - Number of bytes to write + * + * Returned Value: + * OK on success. + * + ****************************************************************************/ + +static int n32_sdmmc_sendsetup(struct sdio_dev_s *dev, + const uint8_t *buffer, size_t nbytes) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + + /* Reset data path state */ + + n32_sdmmc_datadisable(priv); + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; + priv->is_read = false; + priv->using_dma = false; + + /* Enable buffer write ready interrupt */ + + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_BUFWRDY, + N32_SDHOST_INTSTS_OFFSET); + priv->waitmask |= N32_SDHOST_INTSTS_BUFWRDY; + n32_sdmmc_configints(priv); + + mcinfo("PIO send setup: buffer=%p, len=%zu\n", buffer, nbytes); + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_cancel + * + * Description: + * Cancel any ongoing data transfer and reset controller state. + * + * Input Parameters: + * dev - SDIO device instance + * + * Returned Value: + * OK on success. + * + ****************************************************************************/ + +static int n32_sdmmc_cancel(struct sdio_dev_s *dev) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + + /* Disable interrupts */ + + priv->waitmask = 0; + priv->waitevents = 0; + n32_sdmmc_configints(priv); + wd_cancel(&priv->waitwdog); + + /* Disable data path */ + + n32_sdmmc_datadisable(priv); + + /* Soft reset command line */ + + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL2_OFFSET, + 0, N32_SDHOST_CTRL2_SWRSTCMD); + up_udelay(10); + n32_sdmmc_modifyreg(priv, N32_SDHOST_CTRL2_OFFSET, + N32_SDHOST_CTRL2_SWRSTCMD, 0); + + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_waitresponse + * + * Description: + * Poll-wait for command response. + * + * Input Parameters: + * dev - SDIO device instance + * cmd - Command word + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_waitresponse(struct sdio_dev_s *dev, uint32_t cmd) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + return n32_sdmmc_wait_cmd_done(priv, cmd); +} + +/**************************************************************************** + * Name: n32_sdmmc_recvshortcrc + * + * Description: + * Receive short response with CRC (R1, R5, R6). + * + * Input Parameters: + * dev - SDIO device instance + * cmd - Command word + * rshort - Pointer to store response + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_recvshortcrc(struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + uint32_t status; + + status = n32_sdmmc_getreg(priv, N32_SDHOST_INTSTS_OFFSET); + if (status & N32_SDHOST_INTSTS_CTERR) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_CTERR, + N32_SDHOST_INTSTS_OFFSET); + return -ETIMEDOUT; + } + + if (status & N32_SDHOST_INTSTS_CCRCERR) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_CCRCERR, + N32_SDHOST_INTSTS_OFFSET); + return -EIO; + } + + n32_sdmmc_get_response(priv, cmd, rshort); + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_recvlong + * + * Description: + * Receive long response (R2). + * + * Input Parameters: + * dev - SDIO device instance + * cmd - Command word + * rlong - Pointer to 4-word array for response + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_recvlong(struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + uint32_t status; + + status = n32_sdmmc_getreg(priv, N32_SDHOST_INTSTS_OFFSET); + if (status & N32_SDHOST_INTSTS_CTERR) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_CTERR, + N32_SDHOST_INTSTS_OFFSET); + return -ETIMEDOUT; + } + + if (status & N32_SDHOST_INTSTS_CCRCERR) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_CCRCERR, + N32_SDHOST_INTSTS_OFFSET); + return -EIO; + } + + n32_sdmmc_get_response(priv, cmd, rlong); + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_recvshort + * + * Description: + * Receive short response without CRC (R3, R4, R7). + * + * Input Parameters: + * dev - SDIO device instance + * cmd - Command word + * rshort - Pointer to store response + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_recvshort(struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + uint32_t status; + + status = n32_sdmmc_getreg(priv, N32_SDHOST_INTSTS_OFFSET); + if (status & N32_SDHOST_INTSTS_CTERR) + { + n32_sdmmc_putreg(priv, N32_SDHOST_INTSTS_CTERR, + N32_SDHOST_INTSTS_OFFSET); + return -ETIMEDOUT; + } + + n32_sdmmc_get_response(priv, cmd, rshort); + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_waitenable + * + * Description: + * Enable waiting for a set of events. + * + * Input Parameters: + * dev - SDIO device instance + * eventset - Events to wait for (SDIOWAIT_*) + * timeout - Timeout in milliseconds + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_waitenable(struct sdio_dev_s *dev, + sdio_eventset_t eventset, + uint32_t timeout) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + uint32_t mask = priv->waitmask; + + if (eventset & SDIOWAIT_CMDDONE) + { + mask |= N32_SDHOST_INTSTS_CMDC; + } + + if (eventset & SDIOWAIT_TRANSFERDONE) + { + mask |= N32_SDHOST_INTSTS_TC | N32_SDHOST_INTSTS_DTERR | + N32_SDHOST_INTSTS_DCRERR; + } + + if (eventset & SDIOWAIT_ERROR) + { +#if HAVE_ADMA2 + mask |= N32_SDHOST_INTSTS_CTERR | N32_SDHOST_INTSTS_CCRCERR | + N32_SDHOST_INTSTS_ADMAERR; +#else + mask |= N32_SDHOST_INTSTS_CTERR | N32_SDHOST_INTSTS_CCRCERR; +#endif + } + + /* Clear interrupt status register */ + + n32_sdmmc_putreg(priv, mask, N32_SDHOST_INTSTS_OFFSET); + + /* Enable interrupts */ + + priv->waitmask = mask; + priv->waitevents = eventset; + n32_sdmmc_configints(priv); + + if (eventset & SDIOWAIT_TIMEOUT) + { + int delay = MSEC2TICK(timeout); + wd_start(&priv->waitwdog, delay, n32_sdmmc_eventtimeout, + (wdparm_t)priv); + } +} + +/**************************************************************************** + * Name: n32_sdmmc_eventwait + * + * Description: + * Wait for one of the enabled events to occur. + * + * Input Parameters: + * dev - SDIO device instance + * + * Returned Value: + * The event that occurred. + * + ****************************************************************************/ + +static sdio_eventset_t n32_sdmmc_eventwait(struct sdio_dev_s *dev) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + sdio_eventset_t wkupevent = 0; + int ret; + + while (1) + { + ret = nxsem_wait_uninterruptible(&priv->waitsem); + if (ret < 0) + { + wd_cancel(&priv->waitwdog); + return SDIOWAIT_ERROR; + } + + wkupevent = priv->wkupevent; + if (wkupevent != 0) + break; + } + + /* Disable interrupts after event */ + + priv->waitmask = 0; + priv->waitevents = 0; + n32_sdmmc_configints(priv); + return wkupevent; +} + +/**************************************************************************** + * Name: n32_sdmmc_callbackenable + * + * Description: + * Enable callback events (not fully implemented). + * + * Input Parameters: + * dev - SDIO device instance + * eventset - Events to enable for callback + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_sdmmc_callbackenable(struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + priv->cbevents = eventset; +} + +/**************************************************************************** + * Name: n32_sdmmc_registercallback + * + * Description: + * Register a callback function for card status changes. + * + * Input Parameters: + * dev - SDIO device instance + * callback - Callback function + * arg - Argument for callback + * + * Returned Value: + * OK on success. + * + ****************************************************************************/ + +static int n32_sdmmc_registercallback(struct sdio_dev_s *dev, + worker_t callback, void *arg) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + priv->callback = callback; + priv->cbarg = arg; + priv->cbevents = 0; + return OK; +} +#ifdef CONFIG_SDIO_DMA +# if HAVE_ADMA2 + +/**************************************************************************** + * Name: n32_sdmmc_dmarecvsetup + * + * Description: + * Setup for ADMA read transfer (with cache invalidation). + * + * Input Parameters: + * dev - SDIO device instance + * buffer - Data buffer + * buflen - Number of bytes to read + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_dmarecvsetup(struct sdio_dev_s *dev, + uint8_t *buffer, size_t buflen) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + int ret; + + /* Reset data path state */ + + n32_sdmmc_datadisable(priv); + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + priv->is_read = true; + priv->using_dma = true; + + ret = n32_sdmmc_build_adma_desc(priv, buffer, buflen); + if (ret < 0) + { + return ret; + } + + n32_sdmmc_start_adma(priv); + + return OK; +} + +/**************************************************************************** + * Name: n32_sdmmc_dmasendsetup + * + * Description: + * Setup for ADMA write transfer (with cache clean). + * + * Input Parameters: + * dev - SDIO device instance + * buffer - Data buffer + * buflen - Number of bytes to write + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +static int n32_sdmmc_dmasendsetup(struct sdio_dev_s *dev, + const uint8_t *buffer, size_t buflen) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + int ret; + + /* Reset data path state */ + + n32_sdmmc_datadisable(priv); + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + priv->is_read = false; + priv->using_dma = true; + + ret = n32_sdmmc_build_adma_desc(priv, (uint8_t *)buffer, buflen); + if (ret < 0) + { + return ret; + } + + n32_sdmmc_start_adma(priv); + + return OK; +} +# else + error "CONFIG_SDIO_DMA requires HAVE_ADMA2" +# endif /* HAVE_ADMA2 */ +#endif /* CONFIG_SDIO_DMA */ + +/**************************************************************************** + * Name: n32_sdmmc_callback + * + * Description: + * Perform callback. + * + * Assumptions: + * This function does not execute in the context of an interrupt handler. + * It may be invoked on any user thread or scheduled on the work thread + * from an interrupt handler. + * + ****************************************************************************/ + +static void n32_sdmmc_callback(void *arg) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)arg; + uint32_t regval; + uint8_t timeout = 100; + + /* Is a callback registered? */ + + DEBUGASSERT(priv != NULL); + + /* Wait for CD to settle */ + + if (priv->cdstatus & SDIO_STATUS_PRESENT) + { + regval = n32_sdmmc_getreg(priv, N32_SDHOST_CTRL1_OFFSET); + regval |= N32_SDHOST_CTRL1_CDTL; + n32_sdmmc_putreg(priv, regval, N32_SDHOST_CTRL1_OFFSET); + + do + { + nxsched_msleep(10); + regval = n32_sdmmc_getreg(priv, N32_SDHOST_PRESTS_OFFSET); + if ((regval & N32_SDHOST_PRESTS_CSTSL) == N32_SDHOST_PRESTS_CSTSL) + break; + } + while (--timeout > 0); + + n32_sdmmc_power_on(priv); + n32_sdmmc_configsts(priv, N32_WAIT_ALL); + } + else + { + regval = n32_sdmmc_getreg(priv, N32_SDHOST_CTRL1_OFFSET); + regval &= ~N32_SDHOST_CTRL1_CDTL; + n32_sdmmc_putreg(priv, regval, N32_SDHOST_CTRL1_OFFSET); + + do + { + nxsched_msleep(10); + regval = n32_sdmmc_getreg(priv, N32_SDHOST_PRESTS_OFFSET); + if ((regval & N32_SDHOST_PRESTS_CSTSL) == N32_SDHOST_PRESTS_CSTSL) + break; + } + while (--timeout > 0); + + n32_sdmmc_power_off(priv); + n32_sdmmc_configsts(priv, 0); + } + + mcinfo("Callback %p(%p) cbevents: %02" PRIx8 " cdstatus: %02" PRIx8 "\n", + priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus); + + if (priv->callback) + { + /* Yes.. Check for enabled callback events */ + + if ((priv->cdstatus & SDIO_STATUS_PRESENT) != 0) + { + /* Media is present. Is the media inserted event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_INSERTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + else + { + /* Media is not present. Is the media eject event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_EJECTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + + /* Perform the callback, disabling further callbacks. Of course, the + * the callback can (and probably should) re-enable callbacks. + */ + + priv->cbevents = 0; + + mcinfo("Callback to %p(%p)\n", priv->callback, priv->cbarg); + priv->callback(priv->cbarg); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - 0 for SDMMC1, 1 for SDMMC2 (depending on config). + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failure. + * + ****************************************************************************/ + +struct sdio_dev_s *sdio_initialize(int slotno) +{ + struct n32_sdmmc_s *priv = NULL; + uint32_t regval; + +#if defined(CONFIG_N32H7_SDMMC1) + if (slotno == 0) + { + priv = &g_sdmmc1_dev; + + /* Enable the HSC1 Power Gate */ + + regval = getreg32(N32_PWR_SYS_PWR_CR3); + regval |= PWR_SYSCTRL3_HSC1_PGEN; + putreg32(regval, N32_PWR_SYS_PWR_CR3); + + while ((getreg32(N32_PWR_SYS_PWR_CR3) & + PWR_SYSCTRL3_HSC1_PWRRDY) == 0); + + regval = getreg32(N32_PWR_SYS_PWR_CR3); + regval |= (PWR_SYSCTRL3_HSC1_FUCEN | PWR_SYSCTRL3_HSC1_ISNEN); + putreg32(regval, N32_PWR_SYS_PWR_CR3); + + /* Enable the SDMMC1 peripheral clock */ + + regval = getreg32(N32_RCC_AXIEN1); + regval |= RCC_AXIEN1_M7SDMMC1EN; + putreg32(regval, N32_RCC_AXIEN1); + + regval = getreg32(N32_PWR_IP_MEMPWR_CR); + regval &= ~PWR_IPMEMCTRL_SDMMC1_PGEN; + putreg32(regval, N32_PWR_IP_MEMPWR_CR); + + while ((getreg32(N32_PWR_IP_MEMPWR_CSR) & + PWR_IPMEMSTS_SDMMC1_PRDY) == 0); + + /* Configure sdmmc1_clk source is PLL1B */ + + regval = getreg32(N32_RCC_AXISEL1); + regval &= ~RCC_AXISEL1_SDMMC1KERSEL_MASK; + regval |= RCC_AXISEL1_SDMMC1KERSEL_PLL1B; + putreg32(regval, N32_RCC_AXISEL1); + + /* Enable clock and reset */ + + regval = getreg32(N32_RCC_AXIEN1); + regval |= RCC_AXIEN1_M7SDMMC1EN; + putreg32(regval, N32_RCC_AXIEN1); + regval = getreg32(N32_RCC_AXIRST1); + regval |= (RCC_AXIRST1_SDMMC1RST | RCC_AXIRST1_SDHOST1RST); + putreg32(regval, N32_RCC_AXIRST1); + up_udelay(10); + regval &= ~(RCC_AXIRST1_SDMMC1RST | RCC_AXIRST1_SDHOST1RST); + putreg32(regval, N32_RCC_AXIRST1); + + /* Configure GPIOs (must be defined in board.h) */ + +#ifndef CONFIG_SDIO_MUXBUS + n32_configgpio(GPIO_SDMMC1_CK); + n32_configgpio(GPIO_SDMMC1_CMD); + n32_configgpio(GPIO_SDMMC1_D0); +# ifndef CONFIG_SDMMC1_WIDTH_D1_ONLY + n32_configgpio(GPIO_SDMMC1_D1); + n32_configgpio(GPIO_SDMMC1_D2); + n32_configgpio(GPIO_SDMMC1_D3); +# endif + + /* Enable internal clock feedback */ + + regval = getreg32(N32_AFIO_RMP_CFG); + regval |= N32_AFIO_RMP_CFG_SDMMC1_CLKFB; + putreg32(regval, N32_AFIO_RMP_CFG); +#endif + } + else +#endif +#if defined(CONFIG_N32H7_SDMMC2) + if (slotno == 1) + { + priv = &g_sdmmc2_dev; + + /* Enable the HSC2 Power Gate */ + + regval = getreg32(N32_PWR_SYS_PWR_CR3); + regval |= PWR_SYSCTRL3_HSC2_PGEN; + putreg32(regval, N32_PWR_SYS_PWR_CR3); + + while ((getreg32(N32_PWR_SYS_PWR_CR3) & + PWR_SYSCTRL3_HSC2_PWRRDY) == 0); + + regval = getreg32(N32_PWR_SYS_PWR_CR3); + regval |= (PWR_SYSCTRL3_HSC2_FUCEN | PWR_SYSCTRL3_HSC2_ISNEN); + putreg32(regval, N32_PWR_SYS_PWR_CR3); + + /* Enable the USBHS2 peripheral clock */ + + regval = getreg32(N32_RCC_AHB1EN1); + regval |= RCC_AHB1EN1_M7SDMMC2EN; + putreg32(regval, N32_RCC_AHB1EN1); + + regval = getreg32(N32_PWR_IP_MEMPWR_CR); + regval &= ~PWR_IPMEMCTRL_SDMMC2_PGEN; + putreg32(regval, N32_PWR_IP_MEMPWR_CR); + + while ((getreg32(N32_PWR_IP_MEMPWR_CSR) & + PWR_IPMEMSTS_SDMMC2_PRDY) == 0); + + /* Configure sdmmc2_clk source is PLL1B */ + + regval = getreg32(N32_RCC_AHB1SEL1); + regval &= ~RCC_AHB1SEL1_SDMMC2KERSEL_MASK; + regval |= RCC_AHB1SEL1_SDMMC2KERSEL_PLL1B; + putreg32(regval, N32_RCC_AHB1SEL1); + + /* Enable clock and reset */ + + regval = getreg32(N32_RCC_AHB1EN1); + regval |= RCC_AHB1EN1_M7SDMMC2EN; + putreg32(regval, N32_RCC_AHB1EN1); + regval = getreg32(N32_RCC_AHB1RST1); + regval |= (RCC_AHB1RST1_SDMMC2RST | RCC_AHB1RST1_SDHOST2RST); + putreg32(regval, N32_RCC_AHB1RST1); + up_udelay(10); + regval &= ~(RCC_AHB1RST1_SDMMC2RST | RCC_AHB1RST1_SDHOST2RST); + putreg32(regval, N32_RCC_AHB1RST1); + +#ifndef CONFIG_SDIO_MUXBUS + n32_configgpio(GPIO_SDMMC2_CK); + n32_configgpio(GPIO_SDMMC2_CMD); + n32_configgpio(GPIO_SDMMC2_D0); +# ifndef CONFIG_SDMMC2_WIDTH_D1_ONLY + n32_configgpio(GPIO_SDMMC2_D1); + n32_configgpio(GPIO_SDMMC2_D2); + n32_configgpio(GPIO_SDMMC2_D3); +# endif + + /* Enable internal clock feedback */ + + regval = getreg32(N32_AFIO_RMP_CFG); + regval |= N32_AFIO_RMP_CFG_SDMMC2_CLKFB; + putreg32(regval, N32_AFIO_RMP_CFG); +#endif + } + else +#endif + { + mcerr("ERROR: Unsupported SDMMC slot: %d\n", slotno); + return NULL; + } + + if (priv) + { + n32_sdmmc_reset(&priv->dev); + } + + return &priv->dev; +} + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic to signal card insertion/removal. + * + * Input Parameters: + * dev - SDIO device instance + * cardinslot - true if card inserted, false otherwise + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sdio_mediachange(struct sdio_dev_s *dev, bool cardinslot) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + sdio_statset_t oldstatus; + irqstate_t flags; + + flags = enter_critical_section(); + + /* Save the old status for comparison */ + + oldstatus = priv->cdstatus; + + /* Update the card status */ + + if (cardinslot) + { + priv->cdstatus |= SDIO_STATUS_PRESENT; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_PRESENT; + } + + leave_critical_section(flags); + + /* If the status actually changed, schedule the callback to notify + * the upper MMC/SD layer. Note: This may be called from an interrupt + * context (EXTI), so we must use the high-priority work queue. + */ + + if (oldstatus != priv->cdstatus) + { + mcinfo("Media change: old=0x%02x, new=0x%02x, scheduling callback\n", + oldstatus, priv->cdstatus); + + /* Callbacks cannot be performed in the context of an interrupt + * handler. If we are in an interrupt handler, then queue the + * callback to be performed later on the work thread. + */ + + if (up_interrupt_context()) + { + /* Yes.. queue it */ + + work_queue(HPWORK, &priv->cbwork, n32_sdmmc_callback, + priv, 0); + } + + else + { + /* No.. then just call the callback here */ + + n32_sdmmc_callback(priv); + } + } +} + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report write protect status. + * + * Input Parameters: + * dev - SDIO device instance + * wrprotect - true if write protected, false otherwise + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(struct sdio_dev_s *dev, bool wrprotect) +{ + struct n32_sdmmc_s *priv = (struct n32_sdmmc_s *)dev; + irqstate_t flags = enter_critical_section(); + + if (wrprotect) + priv->cdstatus |= SDIO_STATUS_WRPROTECTED; + else + priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED; + + leave_critical_section(flags); +} + +#endif /* CONFIG_N32H7_SDMMC1 || CONFIG_N32H7_SDMMC2 */ diff --git a/arch/arm/src/n32h7/n32_sdmmc.h b/arch/arm/src/n32h7/n32_sdmmc.h new file mode 100644 index 0000000000000..616b3495879e3 --- /dev/null +++ b/arch/arm/src/n32h7/n32_sdmmc.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_sdmmc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * N32H7 SDMMC Driver Public Interface + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32H7_SDMMC_H +#define __ARCH_ARM_SRC_N32H7_N32H7_SDMMC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "chip.h" +#include "hardware/n32h7_sdmmc.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - 0 for SDMMC1, 1 for SDMMC2 (depending on config). + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failure. + * + ****************************************************************************/ + +struct sdio_dev_s *sdio_initialize(int slotno); + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic to signal card insertion/removal. + * + ****************************************************************************/ + +void sdio_mediachange(struct sdio_dev_s *dev, bool cardinslot); + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report write protect status. + * + ****************************************************************************/ + +void sdio_wrprotect(struct sdio_dev_s *dev, bool wrprotect); + +#if defined(CONFIG_SDMMC1_SDIO_MODE) || defined(CONFIG_SDMMC2_SDIO_MODE) +void sdio_set_sdio_card_isr(struct sdio_dev_s *dev, + int (*func)(void *), void *arg); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_SDMMC_H */ diff --git a/arch/arm/src/n32h7/n32_serial.c b/arch/arm/src/n32h7/n32_serial.c new file mode 100644 index 0000000000000..ae08ec5b4619e --- /dev/null +++ b/arch/arm/src/n32h7/n32_serial.c @@ -0,0 +1,2777 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_serial.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 "arm_internal.h" +#include "chip.h" +#include "n32_gpio.h" +#include "hardware/n32h7_uart.h" +#include "hardware/n32h76x_pinmap.h" +#include "n32_rcc.h" +#include "n32_dma.h" +#include "n32_uart.h" +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#ifdef HAVE_UART + +/* DMA Support */ +#ifdef CONFIG_ARCH_DMA +# define SERIAL_HAVE_DMA 1 +#else +# undef CONFIG_USART1_RXDMA +# undef CONFIG_USART1_TXDMA +# undef CONFIG_USART2_RXDMA +# undef CONFIG_USART2_TXDMA +# undef CONFIG_USART3_RXDMA +# undef CONFIG_USART3_TXDMA +# undef CONFIG_USART4_RXDMA +# undef CONFIG_USART4_TXDMA +# undef CONFIG_USART5_RXDMA +# undef CONFIG_USART5_TXDMA +# undef CONFIG_USART6_RXDMA +# undef CONFIG_USART6_TXDMA +# undef CONFIG_USART7_RXDMA +# undef CONFIG_USART7_TXDMA +# undef CONFIG_USART8_RXDMA +# undef CONFIG_USART8_TXDMA +# undef CONFIG_UART9_RXDMA +# undef CONFIG_UART9_TXDMA +# undef CONFIG_UART10_RXDMA +# undef CONFIG_UART10_TXDMA +# undef CONFIG_UART11_RXDMA +# undef CONFIG_UART11_TXDMA +# undef CONFIG_UART12_RXDMA +# undef CONFIG_UART12_TXDMA +# undef CONFIG_UART13_RXDMA +# undef CONFIG_UART13_TXDMA +# undef CONFIG_UART14_RXDMA +# undef CONFIG_UART14_TXDMA +# undef CONFIG_UART15_RXDMA +# undef CONFIG_UART15_TXDMA +#endif + +/* Detect which UARTs have DMA enabled */ +#undef SERIAL_HAVE_RXDMA +#if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \ + defined(CONFIG_USART3_RXDMA) || defined(CONFIG_USART4_RXDMA) || \ + defined(CONFIG_USART5_RXDMA) || defined(CONFIG_USART6_RXDMA) || \ + defined(CONFIG_USART7_RXDMA) || defined(CONFIG_USART8_RXDMA) || \ + defined(CONFIG_UART9_RXDMA) || defined(CONFIG_UART10_RXDMA) || \ + defined(CONFIG_UART11_RXDMA) || defined(CONFIG_UART12_RXDMA) || \ + defined(CONFIG_UART13_RXDMA) || defined(CONFIG_UART14_RXDMA) || \ + defined(CONFIG_UART15_RXDMA) +# define SERIAL_HAVE_RXDMA 1 +n32_dmacfg_t rxcfg = +{ + .src_addr = (uint32_t)NULL, + .dst_addr = (uint32_t)NULL, + .block_size = 0, + .ctrl = (DMA_CHCTRL_INTEN | + DMA_CHCTRL_DTW(DMA_WIDTH_8BITS) | + DMA_CHCTRL_STW(DMA_WIDTH_8BITS) | + DMA_CHCTRL_DINC(DMA_ADDR_INC) | + DMA_CHCTRL_SINC(DMA_ADDR_NOCHANGE) | + DMA_CHCTRL_DSTMSIZE(DMA_BURST_1) | + DMA_CHCTRL_SRCMSIZE(DMA_BURST_1) | + DMA_CHCTRL_SMS(DMA_MS_1) | + DMA_CHCTRL_DMS(DMA_MS_1) | + DMA_CHCTRL_TTFC(DMA_TTFC_PER_TO_MEM_DMA)), + .sg_cfg = 0, + .ds_cfg = 0, + .src_hs_if = 0, + .dst_hs_if = 0, + .priority = 7, + .src_hs_mode = 0, /* HW handshake */ + .dst_hs_mode = 0, + .link_list = NULL, +}; +#endif + +#undef SERIAL_HAVE_TXDMA +#if defined(CONFIG_USART1_TXDMA) || defined(CONFIG_USART2_TXDMA) || \ + defined(CONFIG_USART3_TXDMA) || defined(CONFIG_USART4_TXDMA) || \ + defined(CONFIG_USART5_TXDMA) || defined(CONFIG_USART6_TXDMA) || \ + defined(CONFIG_USART7_TXDMA) || defined(CONFIG_USART8_TXDMA) || \ + defined(CONFIG_UART9_TXDMA) || defined(CONFIG_UART10_TXDMA) || \ + defined(CONFIG_UART11_TXDMA) || defined(CONFIG_UART12_TXDMA) || \ + defined(CONFIG_UART13_TXDMA) || defined(CONFIG_UART14_TXDMA) || \ + defined(CONFIG_UART15_TXDMA) +# define SERIAL_HAVE_TXDMA 1 +n32_dmacfg_t txcfg = +{ + .src_addr = (uint32_t)NULL, + .dst_addr = (uint32_t)NULL, + .block_size = 0, + .ctrl = (DMA_CHCTRL_INTEN | + DMA_CHCTRL_DTW(DMA_WIDTH_8BITS) | + DMA_CHCTRL_STW(DMA_WIDTH_8BITS) | + DMA_CHCTRL_DINC(DMA_ADDR_NOCHANGE) | + DMA_CHCTRL_SINC(DMA_ADDR_INC) | + DMA_CHCTRL_DSTMSIZE(DMA_BURST_1) | + DMA_CHCTRL_SRCMSIZE(DMA_BURST_1) | + DMA_CHCTRL_SMS(DMA_MS_1) | + DMA_CHCTRL_DMS(DMA_MS_1) | + DMA_CHCTRL_TTFC(DMA_TTFC_MEM_TO_PER_DMA)), + .sg_cfg = 0, + .ds_cfg = 0, + .src_hs_if = 0, + .dst_hs_if = 0, + .priority = 7, + .src_hs_mode = 0, /* HW handshake */ + .dst_hs_mode = 0, + .link_list = NULL, +}; + +#endif + +#undef SERIAL_HAVE_RXDMA_TXDMA +#if defined(SERIAL_HAVE_RXDMA) && defined(SERIAL_HAVE_TXDMA) +# define SERIAL_HAVE_RXDMA_TXDMA 1 +#endif + +/* Interrupt masks for up_setusartint */ +#define USART_CTRL1_USED_INTS \ + (USART_CTRL1_RXDNEIEN | USART_CTRL1_TXDEIEN | USART_CTRL1_IDLEIEN | \ + USART_CTRL1_PEIEN | USART_CTRL1_TXCIEN) +#define USART_CTRL3_USED_INTS \ + (USART_CTRL3_CTSIEN | USART_CTRL3_ERRIEN) + +/* Power management activity count */ +#ifndef CONFIG_N32H7_PM_SERIAL_ACTIVITY +# define CONFIG_N32H7_PM_SERIAL_ACTIVITY 10 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + struct uart_dev_s dev; /* Generic UART device */ + uint16_t ie; /* Saved interrupt enable bits */ + uint16_t sr; /* Saved status (for ISR) */ + bool initialized; + +#ifdef CONFIG_PM + bool suspended; /* UART suspended for PM */ + uint16_t suspended_ie; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + uint8_t parity; + uint8_t bits; + bool stopbits2; +# ifdef CONFIG_SERIAL_IFLOWCONTROL + bool iflow; +# endif +# ifdef CONFIG_SERIAL_OFLOWCONTROL + bool oflow; +# endif + uint32_t baud; +#else + const uint8_t parity; + const uint8_t bits; + const bool stopbits2; +# ifdef CONFIG_SERIAL_IFLOWCONTROL + const bool iflow; +# endif +# ifdef CONFIG_SERIAL_OFLOWCONTROL + const bool oflow; +# endif + const uint32_t baud; +#endif + + const uint8_t irq; + const uint32_t apbclock; + const uint32_t usartbase; + const uint32_t tx_gpio; + const uint32_t rx_gpio; +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const uint32_t rts_gpio; +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const uint32_t cts_gpio; +#endif + +#ifdef SERIAL_HAVE_TXDMA + const unsigned int txdma_channel; + DMA_HANDLE txdma; +#endif +#ifdef SERIAL_HAVE_RXDMA + const unsigned int rxdma_channel; + DMA_HANDLE rxdma; +# ifdef CONFIG_PM + bool rxdmasusp; +# endif +#endif + + spinlock_t lock; +}; + +#ifdef CONFIG_PM +struct pm_config_s +{ + struct pm_callback_s pm_cb; + bool serial_suspended; +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void up_set_format(struct uart_dev_s *dev); +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context, void *arg); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); + +#if !defined(SERIAL_HAVE_ONLY_RXDMA) +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +#endif +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered, + bool upper); +#endif +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +#ifdef SERIAL_HAVE_TXDMA +static void up_dma_send(struct uart_dev_s *dev); +static void up_dma_txint(struct uart_dev_s *dev, bool enable); +static void up_dma_txavailable(struct uart_dev_s *dev); +static void up_dma_txcallback(DMA_HANDLE handle, uint8_t status, void *arg); +#endif + +#ifdef SERIAL_HAVE_RXDMA +static void up_dma_receive(struct uart_dev_s *dev); +static void up_dma_rxint(struct uart_dev_s *dev, bool enable); +static bool up_dma_rxavailable(struct uart_dev_s *dev); +static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg); +#endif + +#if defined(SERIAL_HAVE_RXDMA) || defined(SERIAL_HAVE_TXDMA) +static int up_dma_setup(struct uart_dev_s *dev); +static void up_dma_shutdown(struct uart_dev_s *dev); +#endif + +#ifdef CONFIG_PM +static void up_pm_setsuspend(bool suspend); +static void up_pm_notify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +static int up_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Ops tables: Different combinations of DMA usage */ +#ifdef SERIAL_HAVE_RXDMA +static const struct uart_ops_s g_uart_rxdma_ops = +{ + .setup = up_dma_setup, + .shutdown = up_dma_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .dmareceive = up_dma_receive, + .rxint = up_dma_rxint, + .rxavailable = up_dma_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; +#endif + +#ifdef SERIAL_HAVE_TXDMA +static const struct uart_ops_s g_uart_txdma_ops = +{ + .setup = up_dma_setup, + .shutdown = up_dma_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_dma_txint, + .txready = up_txready, + .txempty = up_txempty, + .dmatxavail = up_dma_txavailable, + .dmasend = up_dma_send, +}; +#endif + +#ifdef SERIAL_HAVE_RXDMA_TXDMA +static const struct uart_ops_s g_uart_rxtxdma_ops = +{ + .setup = up_dma_setup, + .shutdown = up_dma_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .dmareceive = up_dma_receive, + .rxint = up_dma_rxint, + .rxavailable = up_dma_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_dma_txint, + .txready = up_txready, + .txempty = up_txempty, + .dmatxavail = up_dma_txavailable, + .dmasend = up_dma_send, +}; +#endif + +/* Non-DMA ops */ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = up_rxflowcontrol, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* -------------------------------------------------------------------------- + * OPS macro definitions (choose correct ops based on DMA config) + * -------------------------------------------------------------------------- + */ +#if defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_TXDMA) +# define UART_USART1_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_USART1_RXDMA) +# define UART_USART1_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_USART1_TXDMA) +# define UART_USART1_OPS &g_uart_txdma_ops +#else +# define UART_USART1_OPS &g_uart_ops +#endif +#if defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_TXDMA) +# define UART_USART2_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_USART2_RXDMA) +# define UART_USART2_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_USART2_TXDMA) +# define UART_USART2_OPS &g_uart_txdma_ops +#else +# define UART_USART2_OPS &g_uart_ops +#endif +#if defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_TXDMA) +# define UART_USART3_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_USART3_RXDMA) +# define UART_USART3_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_USART3_TXDMA) +# define UART_USART3_OPS &g_uart_txdma_ops +#else +# define UART_USART3_OPS &g_uart_ops +#endif +#if defined(CONFIG_USART4_RXDMA) && defined(CONFIG_USART4_TXDMA) +# define UART_USART4_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_USART4_RXDMA) +# define UART_USART4_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_USART4_TXDMA) +# define UART_USART4_OPS &g_uart_txdma_ops +#else +# define UART_USART4_OPS &g_uart_ops +#endif +#if defined(CONFIG_USART5_RXDMA) && defined(CONFIG_USART5_TXDMA) +# define UART_USART5_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_USART5_RXDMA) +# define UART_USART5_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_USART5_TXDMA) +# define UART_USART5_OPS &g_uart_txdma_ops +#else +# define UART_USART5_OPS &g_uart_ops +#endif +#if defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_TXDMA) +# define UART_USART6_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_USART6_RXDMA) +# define UART_USART6_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_USART6_TXDMA) +# define UART_USART6_OPS &g_uart_txdma_ops +#else +# define UART_USART6_OPS &g_uart_ops +#endif +#if defined(CONFIG_USART7_RXDMA) && defined(CONFIG_USART7_TXDMA) +# define UART_USART7_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_USART7_RXDMA) +# define UART_USART7_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_USART7_TXDMA) +# define UART_USART7_OPS &g_uart_txdma_ops +#else +# define UART_USART7_OPS &g_uart_ops +#endif +#if defined(CONFIG_USART8_RXDMA) && defined(CONFIG_USART8_TXDMA) +# define UART_USART8_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_USART8_RXDMA) +# define UART_USART8_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_USART8_TXDMA) +# define UART_USART8_OPS &g_uart_txdma_ops +#else +# define UART_USART8_OPS &g_uart_ops +#endif +#if defined(CONFIG_UART9_RXDMA) && defined(CONFIG_UART9_TXDMA) +# define UART_UART9_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_UART9_RXDMA) +# define UART_UART9_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_UART9_TXDMA) +# define UART_UART9_OPS &g_uart_txdma_ops +#else +# define UART_UART9_OPS &g_uart_ops +#endif +#if defined(CONFIG_UART10_RXDMA) && defined(CONFIG_UART10_TXDMA) +# define UART_UART10_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_UART10_RXDMA) +# define UART_UART10_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_UART10_TXDMA) +# define UART_UART10_OPS &g_uart_txdma_ops +#else +# define UART_UART10_OPS &g_uart_ops +#endif +#if defined(CONFIG_UART11_RXDMA) && defined(CONFIG_UART11_TXDMA) +# define UART_UART11_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_UART11_RXDMA) +# define UART_UART11_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_UART11_TXDMA) +# define UART_UART11_OPS &g_uart_txdma_ops +#else +# define UART_UART11_OPS &g_uart_ops +#endif +#if defined(CONFIG_UART12_RXDMA) && defined(CONFIG_UART12_TXDMA) +# define UART_UART12_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_UART12_RXDMA) +# define UART_UART12_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_UART12_TXDMA) +# define UART_UART12_OPS &g_uart_txdma_ops +#else +# define UART_UART12_OPS &g_uart_ops +#endif +#if defined(CONFIG_UART13_RXDMA) && defined(CONFIG_UART13_TXDMA) +# define UART_UART13_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_UART13_RXDMA) +# define UART_UART13_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_UART13_TXDMA) +# define UART_UART13_OPS &g_uart_txdma_ops +#else +# define UART_UART13_OPS &g_uart_ops +#endif +#if defined(CONFIG_UART14_RXDMA) && defined(CONFIG_UART14_TXDMA) +# define UART_UART14_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_UART14_RXDMA) +# define UART_UART14_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_UART14_TXDMA) +# define UART_UART14_OPS &g_uart_txdma_ops +#else +# define UART_UART14_OPS &g_uart_ops +#endif +#if defined(CONFIG_UART15_RXDMA) && defined(CONFIG_UART15_TXDMA) +# define UART_UART15_OPS &g_uart_rxtxdma_ops +#elif defined(CONFIG_UART15_RXDMA) +# define UART_UART15_OPS &g_uart_rxdma_ops +#elif defined(CONFIG_UART15_TXDMA) +# define UART_UART15_OPS &g_uart_txdma_ops +#else +# define UART_UART15_OPS &g_uart_ops +#endif + +/* -------------------------------------------------------------------------- + * Instance data (generated by script) + * -------------------------------------------------------------------------- + */ +#ifdef CONFIG_N32H7_USART1 +static char locate_data(".axi_ram") g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_usart1priv = +{ + .dev = + { +#if CONSOLE_UART == 1 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_usart1rxbuffer), + .buffer = g_usart1rxbuffer + }, + .xmit = + { + .size = sizeof(g_usart1txbuffer), + .buffer = g_usart1txbuffer + }, + .ops = UART_USART1_OPS, + .priv = &g_usart1priv, + }, + .irq = N32_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, + .baud = CONFIG_USART1_BAUD, + .apbclock = N32_AHB_FREQUENCY, + .usartbase = N32_USART1_BASE, + .tx_gpio = GPIO_USART1_TX, + .rx_gpio = GPIO_USART1_RX, +#ifdef CONFIG_USART1_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_USART1_RTS, +#endif +#ifdef CONFIG_USART1_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_USART1_CTS, +#endif +#ifdef CONFIG_USART1_TXDMA + .txdma_channel = DMAMAP_USART1_TX, +#endif +#ifdef CONFIG_USART1_RXDMA + .rxdma_channel = DMAMAP_USART1_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_USART1 */ + +#ifdef CONFIG_N32H7_USART2 +static char locate_data(".axi_ram") g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_usart2priv = +{ + .dev = + { +#if CONSOLE_UART == 2 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_usart2rxbuffer), + .buffer = g_usart2rxbuffer + }, + .xmit = + { + .size = sizeof(g_usart2txbuffer), + .buffer = g_usart2txbuffer + }, + .ops = UART_USART2_OPS, + .priv = &g_usart2priv, + }, + .irq = N32_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, + .baud = CONFIG_USART2_BAUD, + .apbclock = N32_AHB_FREQUENCY, + .usartbase = N32_USART2_BASE, + .tx_gpio = GPIO_USART2_TX, + .rx_gpio = GPIO_USART2_RX, +#ifdef CONFIG_USART2_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_USART2_RTS, +#endif +#ifdef CONFIG_USART2_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_USART2_CTS, +#endif +#ifdef CONFIG_USART2_TXDMA + .txdma_channel = DMAMAP_USART2_TX, +#endif +#ifdef CONFIG_USART2_RXDMA + .rxdma_channel = DMAMAP_USART2_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_USART2 */ + +#ifdef CONFIG_N32H7_USART3 +static char locate_data(".axi_ram") g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_usart3priv = +{ + .dev = + { +#if CONSOLE_UART == 3 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_usart3rxbuffer), + .buffer = g_usart3rxbuffer + }, + .xmit = + { + .size = sizeof(g_usart3txbuffer), + .buffer = g_usart3txbuffer + }, + .ops = UART_USART3_OPS, + .priv = &g_usart3priv, + }, + .irq = N32_IRQ_USART3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, + .baud = CONFIG_USART3_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_USART3_BASE, + .tx_gpio = GPIO_USART3_TX, + .rx_gpio = GPIO_USART3_RX, +#ifdef CONFIG_USART3_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_USART3_RTS, +#endif +#ifdef CONFIG_USART3_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_USART3_CTS, +#endif +#ifdef CONFIG_USART3_TXDMA + .txdma_channel = DMAMAP_USART3_TX, +#endif +#ifdef CONFIG_USART3_RXDMA + .rxdma_channel = DMAMAP_USART3_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_USART3 */ + +#ifdef CONFIG_N32H7_USART4 +static char locate_data(".axi_ram") g_usart4rxbuffer[CONFIG_USART4_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_usart4txbuffer[CONFIG_USART4_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_usart4priv = +{ + .dev = + { +#if CONSOLE_UART == 4 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_usart4rxbuffer), + .buffer = g_usart4rxbuffer + }, + .xmit = + { + .size = sizeof(g_usart4txbuffer), + .buffer = g_usart4txbuffer + }, + .ops = UART_USART4_OPS, + .priv = &g_usart4priv, + }, + .irq = N32_IRQ_USART4, + .parity = CONFIG_USART4_PARITY, + .bits = CONFIG_USART4_BITS, + .stopbits2 = CONFIG_USART4_2STOP, + .baud = CONFIG_USART4_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_USART4_BASE, + .tx_gpio = GPIO_USART4_TX, + .rx_gpio = GPIO_USART4_RX, +#ifdef CONFIG_USART4_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_USART4_RTS, +#endif +#ifdef CONFIG_USART4_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_USART4_CTS, +#endif +#ifdef CONFIG_USART4_TXDMA + .txdma_channel = DMAMAP_USART4_TX, +#endif +#ifdef CONFIG_USART4_RXDMA + .rxdma_channel = DMAMAP_USART4_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_USART4 */ + +#ifdef CONFIG_N32H7_USART5 +static char locate_data(".axi_ram") g_usart5rxbuffer[CONFIG_USART5_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_usart5txbuffer[CONFIG_USART5_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_usart5priv = +{ + .dev = + { +#if CONSOLE_UART == 5 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_usart5rxbuffer), + .buffer = g_usart5rxbuffer + }, + .xmit = + { + .size = sizeof(g_usart5txbuffer), + .buffer = g_usart5txbuffer + }, + .ops = UART_USART5_OPS, + .priv = &g_usart5priv, + }, + .irq = N32_IRQ_USART5, + .parity = CONFIG_USART5_PARITY, + .bits = CONFIG_USART5_BITS, + .stopbits2 = CONFIG_USART5_2STOP, + .baud = CONFIG_USART5_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_USART5_BASE, + .tx_gpio = GPIO_USART5_TX, + .rx_gpio = GPIO_USART5_RX, +#ifdef CONFIG_USART5_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_USART5_RTS, +#endif +#ifdef CONFIG_USART5_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_USART5_CTS, +#endif +#ifdef CONFIG_USART5_TXDMA + .txdma_channel = DMAMAP_USART5_TX, +#endif +#ifdef CONFIG_USART5_RXDMA + .rxdma_channel = DMAMAP_USART5_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_USART5 */ + +#ifdef CONFIG_N32H7_USART6 +static char locate_data(".axi_ram") g_usart6rxbuffer[CONFIG_USART6_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_usart6txbuffer[CONFIG_USART6_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_usart6priv = +{ + .dev = + { +#if CONSOLE_UART == 6 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_usart6rxbuffer), + .buffer = g_usart6rxbuffer + }, + .xmit = + { + .size = sizeof(g_usart6txbuffer), + .buffer = g_usart6txbuffer + }, + .ops = UART_USART6_OPS, + .priv = &g_usart6priv, + }, + .irq = N32_IRQ_USART6, + .parity = CONFIG_USART6_PARITY, + .bits = CONFIG_USART6_BITS, + .stopbits2 = CONFIG_USART6_2STOP, + .baud = CONFIG_USART6_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_USART6_BASE, + .tx_gpio = GPIO_USART6_TX, + .rx_gpio = GPIO_USART6_RX, +#ifdef CONFIG_USART6_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_USART6_RTS, +#endif +#ifdef CONFIG_USART6_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_USART6_CTS, +#endif +#ifdef CONFIG_USART6_TXDMA + .txdma_channel = DMAMAP_USART6_TX, +#endif +#ifdef CONFIG_USART6_RXDMA + .rxdma_channel = DMAMAP_USART6_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_USART6 */ + +#ifdef CONFIG_N32H7_USART7 +static char locate_data(".axi_ram") g_usart7rxbuffer[CONFIG_USART7_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_usart7txbuffer[CONFIG_USART7_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_usart7priv = +{ + .dev = + { +#if CONSOLE_UART == 7 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_usart7rxbuffer), + .buffer = g_usart7rxbuffer + }, + .xmit = + { + .size = sizeof(g_usart7txbuffer), + .buffer = g_usart7txbuffer + }, + .ops = UART_USART7_OPS, + .priv = &g_usart7priv, + }, + .irq = N32_IRQ_USART7, + .parity = CONFIG_USART7_PARITY, + .bits = CONFIG_USART7_BITS, + .stopbits2 = CONFIG_USART7_2STOP, + .baud = CONFIG_USART7_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_USART7_BASE, + .tx_gpio = GPIO_USART7_TX, + .rx_gpio = GPIO_USART7_RX, +#ifdef CONFIG_USART7_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_USART7_RTS, +#endif +#ifdef CONFIG_USART7_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_USART7_CTS, +#endif +#ifdef CONFIG_USART7_TXDMA + .txdma_channel = DMAMAP_USART7_TX, +#endif +#ifdef CONFIG_USART7_RXDMA + .rxdma_channel = DMAMAP_USART7_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_USART7 */ + +#ifdef CONFIG_N32H7_USART8 +static char locate_data(".axi_ram") g_usart8rxbuffer[CONFIG_USART8_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_usart8txbuffer[CONFIG_USART8_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_usart8priv = +{ + .dev = + { +#if CONSOLE_UART == 8 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_usart8rxbuffer), + .buffer = g_usart8rxbuffer + }, + .xmit = + { + .size = sizeof(g_usart8txbuffer), + .buffer = g_usart8txbuffer + }, + .ops = UART_USART8_OPS, + .priv = &g_usart8priv, + }, + .irq = N32_IRQ_USART8, + .parity = CONFIG_USART8_PARITY, + .bits = CONFIG_USART8_BITS, + .stopbits2 = CONFIG_USART8_2STOP, + .baud = CONFIG_USART8_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_USART8_BASE, + .tx_gpio = GPIO_USART8_TX, + .rx_gpio = GPIO_USART8_RX, +#ifdef CONFIG_USART8_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_USART8_RTS, +#endif +#ifdef CONFIG_USART8_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_USART8_CTS, +#endif +#ifdef CONFIG_USART8_TXDMA + .txdma_channel = DMAMAP_USART8_TX, +#endif +#ifdef CONFIG_USART8_RXDMA + .rxdma_channel = DMAMAP_USART8_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_USART8 */ + +#ifdef CONFIG_N32H7_UART9 +static char locate_data(".axi_ram") g_uart9rxbuffer[CONFIG_UART9_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_uart9txbuffer[CONFIG_UART9_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_uart9priv = +{ + .dev = + { +#if CONSOLE_UART == 9 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_uart9rxbuffer), + .buffer = g_uart9rxbuffer + }, + .xmit = + { + .size = sizeof(g_uart9txbuffer), + .buffer = g_uart9txbuffer + }, + .ops = UART_UART9_OPS, + .priv = &g_uart9priv, + }, + .irq = N32_IRQ_UART9, + .parity = CONFIG_UART9_PARITY, + .bits = CONFIG_UART9_BITS, + .stopbits2 = CONFIG_UART9_2STOP, + .baud = CONFIG_UART9_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_UART9_BASE, + .tx_gpio = GPIO_UART9_TX, + .rx_gpio = GPIO_UART9_RX, +#ifdef CONFIG_UART9_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_UART9_RTS, +#endif +#ifdef CONFIG_UART9_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_UART9_CTS, +#endif +#ifdef CONFIG_UART9_TXDMA + .txdma_channel = DMAMAP_UART9_TX, +#endif +#ifdef CONFIG_UART9_RXDMA + .rxdma_channel = DMAMAP_UART9_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_UART9 */ + +#ifdef CONFIG_N32H7_UART10 +static char locate_data(".axi_ram") g_uart10rxbuffer[CONFIG_UART10_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_uart10txbuffer[CONFIG_UART10_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_uart10priv = +{ + .dev = + { +#if CONSOLE_UART == 10 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_uart10rxbuffer), + .buffer = g_uart10rxbuffer + }, + .xmit = + { + .size = sizeof(g_uart10txbuffer), + .buffer = g_uart10txbuffer + }, + .ops = UART_UART10_OPS, + .priv = &g_uart10priv, + }, + .irq = N32_IRQ_UART10, + .parity = CONFIG_UART10_PARITY, + .bits = CONFIG_UART10_BITS, + .stopbits2 = CONFIG_UART10_2STOP, + .baud = CONFIG_UART10_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_UART10_BASE, + .tx_gpio = GPIO_UART10_TX, + .rx_gpio = GPIO_UART10_RX, +#ifdef CONFIG_UART10_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_UART10_RTS, +#endif +#ifdef CONFIG_UART10_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_UART10_CTS, +#endif +#ifdef CONFIG_UART10_TXDMA + .txdma_channel = DMAMAP_UART10_TX, +#endif +#ifdef CONFIG_UART10_RXDMA + .rxdma_channel = DMAMAP_UART10_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_UART10 */ + +#ifdef CONFIG_N32H7_UART11 +static char locate_data(".axi_ram") g_uart11rxbuffer[CONFIG_UART11_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_uart11txbuffer[CONFIG_UART11_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_uart11priv = +{ + .dev = + { +#if CONSOLE_UART == 11 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_uart11rxbuffer), + .buffer = g_uart11rxbuffer + }, + .xmit = + { + .size = sizeof(g_uart11txbuffer), + .buffer = g_uart11txbuffer + }, + .ops = UART_UART11_OPS, + .priv = &g_uart11priv, + }, + .irq = N32_IRQ_UART11, + .parity = CONFIG_UART11_PARITY, + .bits = CONFIG_UART11_BITS, + .stopbits2 = CONFIG_UART11_2STOP, + .baud = CONFIG_UART11_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_UART11_BASE, + .tx_gpio = GPIO_UART11_TX, + .rx_gpio = GPIO_UART11_RX, +#ifdef CONFIG_UART11_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_UART11_RTS, +#endif +#ifdef CONFIG_UART11_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_UART11_CTS, +#endif +#ifdef CONFIG_UART11_TXDMA + .txdma_channel = DMAMAP_UART11_TX, +#endif +#ifdef CONFIG_UART11_RXDMA + .rxdma_channel = DMAMAP_UART11_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_UART11 */ + +#ifdef CONFIG_N32H7_UART12 +static char locate_data(".axi_ram") g_uart12rxbuffer[CONFIG_UART12_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_uart12txbuffer[CONFIG_UART12_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_uart12priv = +{ + .dev = + { +#if CONSOLE_UART == 12 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_uart12rxbuffer), + .buffer = g_uart12rxbuffer + }, + .xmit = + { + .size = sizeof(g_uart12txbuffer), + .buffer = g_uart12txbuffer + }, + .ops = UART_UART12_OPS, + .priv = &g_uart12priv, + }, + .irq = N32_IRQ_UART12, + .parity = CONFIG_UART12_PARITY, + .bits = CONFIG_UART12_BITS, + .stopbits2 = CONFIG_UART12_2STOP, + .baud = CONFIG_UART12_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_UART12_BASE, + .tx_gpio = GPIO_UART12_TX, + .rx_gpio = GPIO_UART12_RX, +#ifdef CONFIG_UART12_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_UART12_RTS, +#endif +#ifdef CONFIG_UART12_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_UART12_CTS, +#endif +#ifdef CONFIG_UART12_TXDMA + .txdma_channel = DMAMAP_UART12_TX, +#endif +#ifdef CONFIG_UART12_RXDMA + .rxdma_channel = DMAMAP_UART12_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_UART12 */ + +#ifdef CONFIG_N32H7_UART13 +static char locate_data(".axi_ram") g_uart13rxbuffer[CONFIG_UART13_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_uart13txbuffer[CONFIG_UART13_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_uart13priv = +{ + .dev = + { +#if CONSOLE_UART == 13 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_uart13rxbuffer), + .buffer = g_uart13rxbuffer + }, + .xmit = + { + .size = sizeof(g_uart13txbuffer), + .buffer = g_uart13txbuffer + }, + .ops = UART_UART13_OPS, + .priv = &g_uart13priv, + }, + .irq = N32_IRQ_UART13, + .parity = CONFIG_UART13_PARITY, + .bits = CONFIG_UART13_BITS, + .stopbits2 = CONFIG_UART13_2STOP, + .baud = CONFIG_UART13_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_UART13_BASE, + .tx_gpio = GPIO_UART13_TX, + .rx_gpio = GPIO_UART13_RX, +#ifdef CONFIG_UART13_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_UART13_RTS, +#endif +#ifdef CONFIG_UART13_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_UART13_CTS, +#endif +#ifdef CONFIG_UART13_TXDMA + .txdma_channel = DMAMAP_UART13_TX, +#endif +#ifdef CONFIG_UART13_RXDMA + .rxdma_channel = DMAMAP_UART13_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_UART13 */ + +#ifdef CONFIG_N32H7_UART14 +static char locate_data(".axi_ram") g_uart14rxbuffer[CONFIG_UART14_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_uart14txbuffer[CONFIG_UART14_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_uart14priv = +{ + .dev = + { +#if CONSOLE_UART == 14 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_uart14rxbuffer), + .buffer = g_uart14rxbuffer + }, + .xmit = + { + .size = sizeof(g_uart14txbuffer), + .buffer = g_uart14txbuffer + }, + .ops = UART_UART14_OPS, + .priv = &g_uart14priv, + }, + .irq = N32_IRQ_UART14, + .parity = CONFIG_UART14_PARITY, + .bits = CONFIG_UART14_BITS, + .stopbits2 = CONFIG_UART14_2STOP, + .baud = CONFIG_UART14_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_UART14_BASE, + .tx_gpio = GPIO_UART14_TX, + .rx_gpio = GPIO_UART14_RX, +#ifdef CONFIG_UART14_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_UART14_RTS, +#endif +#ifdef CONFIG_UART14_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_UART14_CTS, +#endif +#ifdef CONFIG_UART14_TXDMA + .txdma_channel = DMAMAP_UART14_TX, +#endif +#ifdef CONFIG_UART14_RXDMA + .rxdma_channel = DMAMAP_UART14_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_UART14 */ + +#ifdef CONFIG_N32H7_UART15 +static char locate_data(".axi_ram") g_uart15rxbuffer[CONFIG_UART15_RXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); +static char locate_data(".axi_ram") g_uart15txbuffer[CONFIG_UART15_TXBUFSIZE] + aligned_data(ARMV7M_DCACHE_LINESIZE); + +static struct up_dev_s g_uart15priv = +{ + .dev = + { +#if CONSOLE_UART == 15 + .isconsole = true, +#endif + .recv = + { + .size = sizeof(g_uart15rxbuffer), + .buffer = g_uart15rxbuffer + }, + .xmit = + { + .size = sizeof(g_uart15txbuffer), + .buffer = g_uart15txbuffer + }, + .ops = UART_UART15_OPS, + .priv = &g_uart15priv, + }, + .irq = N32_IRQ_UART15, + .parity = CONFIG_UART15_PARITY, + .bits = CONFIG_UART15_BITS, + .stopbits2 = CONFIG_UART15_2STOP, + .baud = CONFIG_UART15_BAUD, + .apbclock = N32_APB_FREQUENCY, + .usartbase = N32_UART15_BASE, + .tx_gpio = GPIO_UART15_TX, + .rx_gpio = GPIO_UART15_RX, +#ifdef CONFIG_UART15_IFLOWCONTROL + .iflow = true, + .rts_gpio = GPIO_UART15_RTS, +#endif +#ifdef CONFIG_UART15_OFLOWCONTROL + .oflow = true, + .cts_gpio = GPIO_UART15_CTS, +#endif +#ifdef CONFIG_UART15_TXDMA + .txdma_channel = DMAMAP_UART15_TX, +#endif +#ifdef CONFIG_UART15_RXDMA + .rxdma_channel = DMAMAP_UART15_RX, +#endif + .lock = SP_UNLOCKED, +}; +#endif /* CONFIG_N32H7_UART15 */ + +/* Device pointer array */ + +static struct up_dev_s * const g_uart_devs[] = +{ +#ifdef CONFIG_N32H7_USART1 + [0] = &g_usart1priv, +#endif +#ifdef CONFIG_N32H7_USART2 + [1] = &g_usart2priv, +#endif +#ifdef CONFIG_N32H7_USART3 + [2] = &g_usart3priv, +#endif +#ifdef CONFIG_N32H7_USART4 + [3] = &g_usart4priv, +#endif +#ifdef CONFIG_N32H7_USART5 + [4] = &g_usart5priv, +#endif +#ifdef CONFIG_N32H7_USART6 + [5] = &g_usart6priv, +#endif +#ifdef CONFIG_N32H7_USART7 + [6] = &g_usart7priv, +#endif +#ifdef CONFIG_N32H7_USART8 + [7] = &g_usart8priv, +#endif +#ifdef CONFIG_N32H7_UART9 + [8] = &g_uart9priv, +#endif +#ifdef CONFIG_N32H7_UART10 + [9] = &g_uart10priv, +#endif +#ifdef CONFIG_N32H7_UART11 + [10] = &g_uart11priv, +#endif +#ifdef CONFIG_N32H7_UART12 + [11] = &g_uart12priv, +#endif +#ifdef CONFIG_N32H7_UART13 + [12] = &g_uart13priv, +#endif +#ifdef CONFIG_N32H7_UART14 + [13] = &g_uart14priv, +#endif +#ifdef CONFIG_N32H7_UART15 + [14] = &g_uart15priv, +#endif +}; + +#ifdef CONFIG_PM +static struct pm_config_s g_serialpm = +{ + .pm_cb.notify = up_pm_notify, + .pm_cb.prepare = up_pm_prepare, + .serial_suspended = false +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +static inline void up_serialout(struct up_dev_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_setusartint + ****************************************************************************/ + +static inline void up_setusartint(struct up_dev_s *priv, uint16_t ie) +{ + uint32_t cr1; + uint32_t cr3; + irqstate_t flags = spin_lock_irqsave(&priv->lock); + + priv->ie = ie; + + cr1 = up_serialin(priv, N32_USART_CTRL1_OFFSET); + cr1 &= ~USART_CTRL1_USED_INTS; + cr1 |= (ie & USART_CTRL1_USED_INTS); + up_serialout(priv, N32_USART_CTRL1_OFFSET, cr1); + + cr3 = up_serialin(priv, N32_USART_CTRL3_OFFSET); + cr3 &= ~USART_CTRL3_USED_INTS; + cr3 |= (ie & USART_CTRL3_USED_INTS); + up_serialout(priv, N32_USART_CTRL3_OFFSET, cr3); + + spin_unlock_irqrestore(&priv->lock, flags); +} + +/**************************************************************************** + * Name: up_disableusartint + ****************************************************************************/ + +static void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) +{ + irqstate_t flags = spin_lock_irqsave(&priv->lock); + + if (ie) + { + uint32_t cr1 = up_serialin(priv, N32_USART_CTRL1_OFFSET); + uint32_t cr3 = up_serialin(priv, N32_USART_CTRL3_OFFSET); + + *ie = (cr1 & USART_CTRL1_USED_INTS) | (cr3 & USART_CTRL3_USED_INTS); + } + + up_setusartint(priv, 0); + spin_unlock_irqrestore(&priv->lock, flags); +} + +/**************************************************************************** + * Name: up_set_format + ****************************************************************************/ + +#ifndef CONFIG_SUPPRESS_UART_CONFIG +static void up_set_format(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t cr1; + uint32_t cr2; + uint32_t cr3; + uint32_t brcf; + uint32_t usartdiv; + irqstate_t flags = enter_critical_section(); + + /* Disable UE */ + + cr1 = up_serialin(priv, N32_USART_CTRL1_OFFSET); + cr1 &= ~USART_CTRL1_UEN; + up_serialout(priv, N32_USART_CTRL1_OFFSET, cr1); + + /* Calculate baud rate */ + + bool over8 = false; + uint32_t tmp = (25 * (priv->apbclock / 2)) / priv->baud; + + if (tmp < 100) /* Empirical threshold for using 8x oversampling */ + { + over8 = true; + usartdiv = (tmp & 0xfff0) | ((tmp & 0x000f) >> 1); + } + else + { + usartdiv = (25 * (priv->apbclock / 4)) / priv->baud; + } + + /* Convert to 12.4 format (integer part 12 bits, fractional 4 bits) */ + + brcf = (usartdiv / 100) << 4; + tmp = usartdiv - ((brcf >> 4) * 100); + if (over8) + { + tmp = ((((tmp * 8) + 50) / 100)) & ((uint8_t)0x0f); + if (tmp == 0x08) + { + brcf = brcf + 0x10; + } + else + { + brcf |= tmp; + } + } + else + { + /* Oversampling mode is 16 Samples */ + + brcf += ((((tmp * 16) + 50) / 100)) & ((uint8_t)0x1f); + } + + up_serialout(priv, N32_USART_BRCF_OFFSET, brcf); + + /* Oversampling mode */ + + cr1 = up_serialin(priv, N32_USART_CTRL1_OFFSET); + if (over8) + { + cr1 |= USART_CTRL1_OSPM; + } + else + { + cr1 &= ~USART_CTRL1_OSPM; + } + + /* Word length and parity */ + + cr1 &= ~(USART_CTRL1_WL | USART_CTRL1_PCEN | USART_CTRL1_PSEL); + if (priv->bits == 8 && priv->parity != 0) + { + cr1 |= USART_CTRL1_WL; + } + + if (priv->parity == 1) /* Odd parity */ + { + cr1 |= (USART_CTRL1_PCEN | USART_CTRL1_PSEL); + } + else if (priv->parity == 2) /* Even parity */ + { + cr1 |= USART_CTRL1_PCEN; + } + + /* Stop bits */ + + cr2 = up_serialin(priv, N32_USART_CTRL2_OFFSET); + cr2 &= ~USART_CTRL2_STPB_MASK; + if (priv->stopbits2) + { + cr2 |= USART_CTRL2_STPB(2); /* 2 stop bits */ + } + else + { + cr2 |= USART_CTRL2_STPB(0); /* 1 stop bit */ + } + + up_serialout(priv, N32_USART_CTRL2_OFFSET, cr2); + + /* Hardware flow control (RTSE/CTSE) */ + + cr3 = up_serialin(priv, N32_USART_CTRL3_OFFSET); + cr3 &= ~(USART_CTRL3_CTSEN | USART_CTRL3_RTSEN); +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + cr3 |= USART_CTRL3_RTSEN; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow) + { + cr3 |= USART_CTRL3_CTSEN; + } +#endif + + up_serialout(priv, N32_USART_CTRL3_OFFSET, cr3); + + /* Re-enable UE */ + + cr1 |= USART_CTRL1_UEN; + up_serialout(priv, N32_USART_CTRL1_OFFSET, cr1); + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_set_apb_clock + ****************************************************************************/ + +static void up_set_apb_clock(struct up_dev_s *priv, bool on) +{ + uint32_t regaddr = 0; + uint32_t en_bit = 0; + + switch (priv->usartbase) + { + #ifdef CONFIG_N32H7_USART1 + case N32_USART1_BASE: + regaddr = N32_RCC_APB1EN3; + en_bit = RCC_APB1EN3_M7USART1EN; + break; + #endif + #ifdef CONFIG_N32H7_USART2 + case N32_USART2_BASE: + regaddr = N32_RCC_APB1EN3; + en_bit = RCC_APB1EN3_M7USART2EN; + break; + #endif + #ifdef CONFIG_N32H7_USART3 + case N32_USART3_BASE: + regaddr = N32_RCC_APB1EN3; + en_bit = RCC_APB1EN3_M7USART3EN; + break; + #endif + #ifdef CONFIG_N32H7_USART4 + case N32_USART4_BASE: + regaddr = N32_RCC_APB1EN3; + en_bit = RCC_APB1EN3_M7USART4EN; + break; + #endif + #ifdef CONFIG_N32H7_USART5 + case N32_USART5_BASE: + regaddr = N32_RCC_APB2EN3; + en_bit = RCC_APB2EN3_M7USART5EN; + break; + #endif + #ifdef CONFIG_N32H7_USART6 + case N32_USART6_BASE: + regaddr = N32_RCC_APB2EN3; + en_bit = RCC_APB2EN3_M7USART6EN; + break; + #endif + #ifdef CONFIG_N32H7_USART7 + case N32_USART7_BASE: + regaddr = N32_RCC_APB2EN3; + en_bit = RCC_APB2EN3_M7USART7EN; + break; + #endif + #ifdef CONFIG_N32H7_USART8 + case N32_USART8_BASE: + regaddr = N32_RCC_APB2EN3; + en_bit = RCC_APB2EN3_M7USART8EN; + break; + #endif + #ifdef CONFIG_N32H7_UART9 + case N32_UART9_BASE: + regaddr = N32_RCC_APB1EN3; + en_bit = RCC_APB1EN3_M7UART9EN; + break; + #endif + #ifdef CONFIG_N32H7_UART10 + case N32_UART10_BASE: + regaddr = N32_RCC_APB1EN3; + en_bit = RCC_APB1EN3_M7UART10EN; + break; + #endif + #ifdef CONFIG_N32H7_UART11 + case N32_UART11_BASE: + regaddr = N32_RCC_APB1EN3; + en_bit = RCC_APB1EN3_M7UART11EN; + break; + #endif + #ifdef CONFIG_N32H7_UART12 + case N32_UART12_BASE: + regaddr = N32_RCC_APB1EN3; + en_bit = RCC_APB1EN3_M7UART12EN; + break; + #endif + #ifdef CONFIG_N32H7_UART13 + case N32_UART13_BASE: + regaddr = N32_RCC_APB2EN3; + en_bit = RCC_APB2EN3_M7UART13EN; + break; + #endif + #ifdef CONFIG_N32H7_UART14 + case N32_UART14_BASE: + regaddr = N32_RCC_APB2EN3; + en_bit = RCC_APB2EN3_M7UART14EN; + break; + #endif + #ifdef CONFIG_N32H7_UART15 + case N32_UART15_BASE: + regaddr = N32_RCC_APB2EN3; + en_bit = RCC_APB2EN3_M7UART15EN; + break; + #endif + default: + return; + } + + if (on) + { + modifyreg32(regaddr, 0, en_bit); + } + else + { + modifyreg32(regaddr, en_bit, 0); + } +} + +/**************************************************************************** + * Name: up_setup (non-DMA) + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t cr1; + uint32_t cr2; + uint32_t cr3; + + /* Enable clock */ + + up_set_apb_clock(priv, true); + + /* Configure GPIOs */ + + n32_configgpio(priv->tx_gpio); + n32_configgpio(priv->rx_gpio); +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio) + { + n32_configgpio(priv->rts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio) + { + n32_configgpio(priv->cts_gpio); + } +#endif + + /* Disable USART for configuration */ + + cr1 = up_serialin(priv, N32_USART_CTRL1_OFFSET); + cr1 &= ~USART_CTRL1_UEN; + up_serialout(priv, N32_USART_CTRL1_OFFSET, cr1); + + /* Configure CR2 (stop bits) */ + + cr2 = up_serialin(priv, N32_USART_CTRL2_OFFSET); + cr2 &= ~(USART_CTRL2_STPB_MASK | USART_CTRL2_CLKEN | USART_CTRL2_LINMEN); + if (priv->stopbits2) + { + cr2 |= USART_CTRL2_STPB(2); + } + + up_serialout(priv, N32_USART_CTRL2_OFFSET, cr2); + + /* Configure CR3 (flow control, DMA, etc.) */ + + cr3 = up_serialin(priv, N32_USART_CTRL3_OFFSET); + cr3 &= ~(USART_CTRL3_CTSEN | USART_CTRL3_RTSEN | + USART_CTRL3_DMARXEN | USART_CTRL3_DMATXEN | + USART_CTRL3_HDMEN | USART_CTRL3_SCMEN | USART_CTRL3_IRDAMEN); +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + cr3 |= USART_CTRL3_RTSEN; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow) + { + cr3 |= USART_CTRL3_CTSEN; + } +#endif + + up_serialout(priv, N32_USART_CTRL3_OFFSET, cr3); + + /* Call up_set_format to set baud rate, word length, parity, etc. */ + + up_set_format(dev); + + /* Disable FIFO */ + + uint32_t fifo = up_serialin(priv, N32_USART_FIFO_OFFSET); + + fifo &= ~USART_FIFO_EN; + up_serialout(priv, N32_USART_FIFO_OFFSET, fifo); + + /* Enable USART (UE, TE, RE) */ + + cr1 = up_serialin(priv, N32_USART_CTRL1_OFFSET); + cr1 |= (USART_CTRL1_UEN | USART_CTRL1_TXEN | USART_CTRL1_RXEN); + up_serialout(priv, N32_USART_CTRL1_OFFSET, cr1); + + priv->initialized = true; + return OK; +} + +/**************************************************************************** + * Name: up_shutdown (non-DMA) + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + priv->initialized = false; + + /* Disable interrupts */ + + up_disableusartint(priv, NULL); + + /* Disable USART */ + + uint32_t cr1 = up_serialin(priv, N32_USART_CTRL1_OFFSET); + + cr1 &= ~(USART_CTRL1_UEN | USART_CTRL1_TXEN | USART_CTRL1_RXEN); + up_serialout(priv, N32_USART_CTRL1_OFFSET, cr1); + + /* Disable clock */ + + up_set_apb_clock(priv, false); + + /* Release GPIOs (optional) */ + + n32_unconfiggpio(priv->tx_gpio); + n32_unconfiggpio(priv->rx_gpio); +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio) + { + n32_unconfiggpio(priv->rts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio) + { + n32_unconfiggpio(priv->cts_gpio); + } +#endif +} + +/**************************************************************************** + * Name: up_dma_setup / up_dma_shutdown + ****************************************************************************/ + +#if defined(SERIAL_HAVE_RXDMA) || defined(SERIAL_HAVE_TXDMA) +static int up_dma_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Perform basic setup first */ + + ret = up_setup(dev); + if (ret < 0) + { + return ret; + } + + /* Configure TX DMA */ + +#ifdef SERIAL_HAVE_TXDMA + if (priv->txdma_channel != 0) + { + priv->txdma = n32_dmachannel(priv->txdma_channel); + if (!priv->txdma) + { + return -ENODEV; + } + + /* Enable USART DMA transmission */ + + uint32_t cr3 = up_serialin(priv, N32_USART_CTRL3_OFFSET); + + cr3 |= USART_CTRL3_DMATXEN; + up_serialout(priv, N32_USART_CTRL3_OFFSET, cr3); + } +#endif + + /* Configure RX DMA */ + +#ifdef SERIAL_HAVE_RXDMA + if (priv->rxdma_channel != 0) + { + uart_recvchars_dma(&priv->dev); + priv->rxdma = n32_dmachannel(priv->rxdma_channel); + if (!priv->rxdma) + { + return -ENODEV; + } + + /* Configure DMA for circular reception */ + + rxcfg.src_addr = priv->usartbase + N32_USART_DAT_OFFSET; + rxcfg.dst_addr = (uint32_t)priv->dev.dmarx.buffer; + rxcfg.block_size = priv->dev.dmarx.length; + rxcfg.src_hs_if = n32_getchannel(priv->rxdma); + rxcfg.dst_hs_if = n32_getchannel(priv->rxdma); + + n32_dmasetup(priv->rxdma, &rxcfg); + n32_dmastart(priv->rxdma, up_dma_rxcallback, priv); + + /* Enable USART DMA reception */ + + uint32_t cr3 = up_serialin(priv, N32_USART_CTRL3_OFFSET); + + cr3 |= USART_CTRL3_DMARXEN; + up_serialout(priv, N32_USART_CTRL3_OFFSET, cr3); + } +#endif + + return OK; +} + +static void up_dma_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Stop DMA */ + +#ifdef SERIAL_HAVE_RXDMA + if (priv->rxdma) + { + n32_dmastop(priv->rxdma); + n32_dmafree(priv->rxdma); + priv->rxdma = NULL; + } +#endif + +#ifdef SERIAL_HAVE_TXDMA + if (priv->txdma) + { + n32_dmastop(priv->txdma); + n32_dmafree(priv->txdma); + priv->txdma = NULL; + } +#endif + + up_shutdown(dev); +} +#endif + +/**************************************************************************** + * Name: up_attach / up_detach + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = irq_attach(priv->irq, up_interrupt, priv); + + if (ret == OK) + { + up_enable_irq(priv->irq); + } + + return ret; +} + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + ****************************************************************************/ + +static int up_interrupt(int irq, void *context, void *arg) +{ + struct up_dev_s *priv = (struct up_dev_s *)arg; + uint32_t sts = up_serialin(priv, N32_USART_STS_OFFSET); + + /* Report activity to PM */ + +#ifdef CONFIG_PM + pm_activity(PM_IDLE_DOMAIN, CONFIG_N32H7_PM_SERIAL_ACTIVITY); +#endif + + /* Handle errors */ + + if (sts & (USART_STS_OREF | USART_STS_FEF | USART_STS_NEF)) + { + /* Clear error by reading STS then DAT */ + + uint32_t dat = up_serialin(priv, N32_USART_DAT_OFFSET); + + UNUSED(dat); + } + + /* Handle IDLE interrupt (DMA reception complete) */ + + if ((sts & USART_STS_IDLEF) && (priv->rxdma) && + (priv->ie & USART_CTRL1_IDLEIEN)) + { + if (up_dma_rxavailable(&priv->dev)) + { + /* Clear error by reading STS then DAT */ + + uint32_t dat = up_serialin(priv, N32_USART_DAT_OFFSET); + + UNUSED(dat); + + n32_dmastop(priv->rxdma); + priv->dev.dmarx.nbytes = n32_getcount(priv->rxdma); + uart_recvchars_done(&priv->dev); + uart_recvchars_dma(&priv->dev); + + rxcfg.src_addr = priv->usartbase + N32_USART_DAT_OFFSET; + rxcfg.dst_addr = (uint32_t)priv->dev.dmarx.buffer; + rxcfg.block_size = priv->dev.dmarx.length; + rxcfg.src_hs_if = n32_getchannel(priv->rxdma); + rxcfg.dst_hs_if = n32_getchannel(priv->rxdma); + + n32_dmasetup(priv->rxdma, &rxcfg); + n32_dmastart(priv->rxdma, up_dma_rxcallback, priv); + + return OK; + } + } + + /* Non-DMA reception */ + + if ((sts & USART_STS_RXDNE) && (priv->ie & USART_CTRL1_RXDNEIEN)) + { + uart_recvchars(&priv->dev); + } + + /* Transmit by interrupt */ + + if ((sts & USART_STS_TXDE) && (priv->ie & USART_CTRL1_TXDEIEN)) + { + uart_xmitchars(&priv->dev); + } + + return OK; +} + +/**************************************************************************** + * Name: up_receive (non-DMA) + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_RXDMA +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t dat = up_serialin(priv, N32_USART_DAT_OFFSET); + + *status = 0; + return dat & 0xff; +} +#endif + +/**************************************************************************** + * Name: up_rxint + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_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 Error + * " " 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_CTRL1_RXDNEIEN | USART_CTRL1_PEIEN | USART_CTRL3_ERRIEN); +#else + ie |= USART_CTRL1_RXDNEIEN; +#endif +#endif + } + else + { + ie &= ~(USART_CTRL1_RXDNEIEN | USART_CTRL1_PEIEN | USART_CTRL3_ERRIEN); + } + + /* Then set the new interrupt state */ + + up_setusartint(priv, ie); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + return (up_serialin(priv, N32_USART_STS_OFFSET) & USART_STS_RXDNE) != 0; +} + +/**************************************************************************** + * Name: up_rxflowcontrol + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered, + bool upper) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + if (priv->iflow) + { + /* Simple flow control: disable RX interrupt when buffer full */ + + if (upper) + { + uart_disablerxint(dev); + return true; + } + else + { + uart_enablerxint(dev); + } + } + + return false; +} +#endif + +/**************************************************************************** + * Name: up_send + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + up_serialout(priv, N32_USART_DAT_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + /* USART transmit interrupts: + * + * Enable Status Meaning Usage + * --------------- -------------- --------------------- ---------- + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (used only + * for 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_CTRL1_TXDEIEN; + +# ifdef CONFIG_STM32_SERIALBRK_BSDCOMPAT + if (priv->ie & USART_CR1_IE_BREAK_INPROGRESS) + { + leave_critical_section(flags); + return; + } +# endif + + up_setusartint(priv, ie); +#else + /* 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 */ + + up_setusartint(priv, priv->ie & ~USART_CTRL1_TXDEIEN); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready / up_txempty + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + return (up_serialin(priv, N32_USART_STS_OFFSET) & USART_STS_TXDE) != 0; +} + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + return (up_serialin(priv, N32_USART_STS_OFFSET) & USART_STS_TXC) != 0; +} + +/**************************************************************************** + * Name: up_dma_rxcallback + ****************************************************************************/ + +#ifdef SERIAL_HAVE_RXDMA +static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + struct up_dev_s *priv = arg; + + uart_recvchars_dma(&priv->dev); +} +#endif + +/**************************************************************************** + * Name: up_dma_receive / up_dma_rxint / up_dma_rxavailable + ****************************************************************************/ + +#ifdef SERIAL_HAVE_RXDMA +static void up_dma_receive(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t nextrx = n32_getcount(priv->rxdma); + + /* Check if more data is available */ + + if (nextrx != 0) + { +#ifdef CONFIG_ARMV7M_DCACHE + /* If the data cache is enabled, then we will also need to manage + * cache coherency. Are any bytes available in the currently coherent + * region of the data cache? + */ + + uintptr_t addr; + + /* Invalidate the DMA buffer range */ + + addr = (uintptr_t)&dev->recv.buffer[dev->recv.tail]; + up_invalidate_dcache(addr, addr + nextrx); +#endif + } +} + +static void up_dma_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + /* Check if DMA handle is valid */ + + if (!priv->rxdma) + { + return; + } + + flags = enter_critical_section(); + if (enable) + { + uint16_t ie = priv->ie | USART_CTRL1_IDLEIEN; + + up_setusartint(priv, ie); + } + else + { + uint16_t ie = priv->ie & ~USART_CTRL1_IDLEIEN; + + up_setusartint(priv, ie); + } + + leave_critical_section(flags); +} + +static bool up_dma_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + return n32_getcount(priv->rxdma) != 0; +} +#endif + +/**************************************************************************** + * Name: up_dma_txcallback / up_dma_txavailable / up_dma_send / up_dma_txint + ****************************************************************************/ + +#ifdef SERIAL_HAVE_TXDMA +static void up_dma_txcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + struct up_dev_s *priv = arg; + + if (status == DMA_INT_TFR) + { + priv->dev.dmatx.nbytes += priv->dev.dmatx.length; + if (priv->dev.dmatx.nlength) + { + /* Set up DMA on next buffer */ + + txcfg.src_addr = (uint32_t)priv->dev.dmatx.nbuffer; + txcfg.dst_addr = (uint32_t)priv->usartbase | N32_USART_DAT_OFFSET; + txcfg.block_size = priv->dev.dmatx.nlength; + txcfg.src_hs_if = n32_getchannel(priv->txdma); + txcfg.dst_hs_if = n32_getchannel(priv->txdma); + n32_dmasetup(priv->txdma, &txcfg); + + /* Set length for the next completion */ + + priv->dev.dmatx.length = priv->dev.dmatx.nlength; + priv->dev.dmatx.nlength = 0; + + /* Start transmission with the callback on DMA completion */ + + n32_dmastart(priv->txdma, up_dma_txcallback, priv); + + return; + } + } + else if(status == DMA_INT_ERROR) + { + PANIC(); + } + + /* Adjust the pointers */ + + uart_xmitchars_done(&priv->dev); + + /* Send more if available */ + + up_dma_txavailable(&priv->dev); +} + +static void up_dma_txavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags = enter_critical_section(); + + if (priv->dev.dmatx.length == 0 && priv->dev.dmatx.nlength == 0) + { + uart_xmitchars_dma(dev); + } + + leave_critical_section(flags); +} + +static void up_dma_send(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* We need to stop DMA before reconfiguration */ + + n32_dmastop(priv->txdma); + + /* Reset the number sent */ + + dev->dmatx.nbytes = 0; + + /* Flush the contents of the TX buffer into physical memory */ + + up_clean_dcache((uintptr_t)dev->dmatx.buffer, + (uintptr_t)dev->dmatx.buffer + dev->dmatx.length); + + /* Is this a split transfer */ + + if (dev->dmatx.nbuffer) + { + /* Flush the contents of the next TX buffer into physical memory */ + + up_clean_dcache((uintptr_t)dev->dmatx.nbuffer, + (uintptr_t)dev->dmatx.nbuffer + dev->dmatx.nlength); + } + + /* Configure TX DMA */ + + txcfg.src_addr = (uint32_t)priv->dev.dmatx.buffer; + txcfg.dst_addr = (uint32_t)priv->usartbase | N32_USART_DAT_OFFSET; + txcfg.block_size = priv->dev.dmatx.length; + txcfg.src_hs_if = n32_getchannel(priv->txdma); + txcfg.dst_hs_if = n32_getchannel(priv->txdma); + + n32_dmasetup(priv->txdma, &txcfg); + n32_dmastart(priv->txdma, up_dma_txcallback, priv); +} + +static void up_dma_txint(struct uart_dev_s *dev, bool enable) +{ + /* DMA TX doesn't use interrupts, driven by DMA callback */ +} +#endif + +/**************************************************************************** + * Name: up_ioctl + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret = OK; +#endif + + switch (cmd) + { + #ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + struct up_dev_s *user = (struct up_dev_s *)arg; + + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, priv, sizeof(struct up_dev_s)); + } + } + break; + #endif + + #ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *t = (struct termios *)arg; + + if (!t) + { + ret = -EINVAL; + } + + t->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 + ((priv->bits == 8 && priv->parity != 0) ? CS7 : CS8); + cfsetispeed(t, priv->baud); + cfsetospeed(t, priv->baud); + } + break; + + case TCSETS: + { + struct termios *t = (struct termios *)arg; + + if (!t) + { + return -EINVAL; + } + + if ((t->c_cflag & (CS8 | CS7)) == 0) + { + return -EINVAL; + } + + if ((t->c_cflag & CSIZE) == CS7 && (t->c_cflag & PARENB) == 0) + { + return -EINVAL; + } + + priv->parity = (t->c_cflag & PARENB) ? + ((t->c_cflag & PARODD) ? 1 : 2) : 0; + priv->stopbits2 = (t->c_cflag & CSTOPB) != 0; + #ifdef CONFIG_SERIAL_OFLOWCONTROL + priv->oflow = (t->c_cflag & CCTS_OFLOW) != 0; + #endif + #ifdef CONFIG_SERIAL_IFLOWCONTROL + priv->iflow = (t->c_cflag & CRTS_IFLOW) != 0; + #endif + priv->baud = cfgetispeed(t); + up_set_format(dev); + } + + break; + #endif + + case TIOCSSWAP: + { + uint32_t cr1 = up_serialin(priv, N32_USART_CTRL1_OFFSET); + uint32_t tmp = cr1 & USART_CTRL1_UEN; + + cr1 &= ~USART_CTRL1_UEN; + up_serialout(priv, N32_USART_CTRL1_OFFSET, cr1); + if (arg) + { + cr1 |= USART_CTRL1_SWAP; + } + else + { + cr1 &= ~USART_CTRL1_SWAP; + } + + cr1 |= tmp; + up_serialout(priv, N32_USART_CTRL1_OFFSET, cr1); + } + + break; + + case TIOCSBRK: + { + uint32_t cr1 = up_serialin(priv, N32_USART_CTRL1_OFFSET); + + cr1 |= USART_CTRL1_SDBRK; + up_serialout(priv, N32_USART_CTRL1_OFFSET, cr1); + + /* Wait for break to be sent (hardware clears it automatically) */ + + while (up_serialin(priv, N32_USART_CTRL1_OFFSET) & + USART_CTRL1_SDBRK); + } + + break; + case TIOCCBRK: + + /* No operation needed */ + + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_pm_* (Power Management) + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_pm_setsuspend(bool suspend) +{ + /* Iterate all UARTs to suspend/resume */ + + for (int i = 0; i < sizeof(g_uart_devs) / sizeof(g_uart_devs[0]); i++) + { + struct up_dev_s *priv = g_uart_devs[i]; + + if (!priv || !priv->initialized) + { + continue; + } + + if (suspend) + { + /* Save and disable interrupts */ + + up_disableusartint(priv, &priv->suspended_ie); + priv->suspended = true; + } + else + { + up_setusartint(priv, priv->suspended_ie); + priv->suspended = false; + } + } +} + +static void up_pm_notify(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + if (pmstate == PM_NORMAL || pmstate == PM_IDLE) + { + up_pm_setsuspend(false); + } + else + { + up_pm_setsuspend(true); + } +} + +static int up_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate) +{ + /* Check if there is pending data, prevent low-power if so */ + + if (pmstate == PM_SLEEP || pmstate == PM_STANDBY) + { + for (int i = 0; i < sizeof(g_uart_devs) / sizeof(g_uart_devs[0]); i++) + { + struct up_dev_s *priv = g_uart_devs[i]; + + if (!priv || !priv->initialized) + { + continue; + } + + if (priv->dev.xmit.head != priv->dev.xmit.tail) + { + return -EBUSY; + } + + if (priv->dev.recv.head != priv->dev.recv.tail) + { + return -EBUSY; + } + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_serial_get_uart + ****************************************************************************/ + +uart_dev_t *n32_serial_get_uart(int uart_num) +{ + int idx = uart_num - 1; + + if (idx < 0 || idx >= (int)(sizeof(g_uart_devs) / sizeof(g_uart_devs[0]))) + { + return NULL; + } + + struct up_dev_s *priv = g_uart_devs[idx]; + + if (!priv || !priv->initialized) + { + return NULL; + } + + return &priv->dev; +} + +/**************************************************************************** + * Name: arm_earlyserialinit + ****************************************************************************/ + +void arm_earlyserialinit(void) +{ +#ifdef HAVE_UART + /* Disable all UART interrupts */ + + for (int i = 0; i < sizeof(g_uart_devs) / sizeof(g_uart_devs[0]); i++) + { + if (g_uart_devs[i]) + { + up_disableusartint(g_uart_devs[i], NULL); + } + } +#endif +} + +/**************************************************************************** + * Name: arm_serialinit + ****************************************************************************/ + +void arm_serialinit(void) +{ +#ifdef HAVE_UART + char devname[32]; + int minor = 0; + + UNUSED(g_uart_rxdma_ops); + UNUSED(g_uart_txdma_ops); + UNUSED(g_uart_rxtxdma_ops); + UNUSED(g_uart_ops); + + /* Configure console */ + +#if CONSOLE_UART > 0 +#if defined(SERIAL_HAVE_TXDMA) || defined(SERIAL_HAVE_RXDMA) + up_dma_setup(&g_uart_devs[CONSOLE_UART - 1]->dev); +#else + up_setup(&g_uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif + +#ifdef CONFIG_PM + pm_register(&g_serialpm.pm_cb); +#endif + + /* Register console */ + +#if CONSOLE_UART > 0 + uart_register("/dev/console", &g_uart_devs[CONSOLE_UART - 1]->dev); + + /* Register as ttyS0 first, skip console in later loop */ + + uart_register("/dev/ttyS0", &g_uart_devs[CONSOLE_UART - 1]->dev); + minor = 1; +#endif + + /* Register remaining UARTs */ + + for (int i = 0; i < sizeof(g_uart_devs) / sizeof(g_uart_devs[0]); i++) + { + if (!g_uart_devs[i]) + { + continue; + } + + if (g_uart_devs[i]->dev.isconsole) + { + continue; + } + + snprintf(devname, sizeof(devname), "/dev/ttyS%d", minor++); + uart_register(devname, &g_uart_devs[i]->dev); + } +#endif +} + +/**************************************************************************** + * Name: up_putc + ****************************************************************************/ + +void up_putc(int ch) +{ +#if CONSOLE_UART > 0 + struct up_dev_s *priv = g_uart_devs[CONSOLE_UART - 1]; + uint16_t ie; + + up_disableusartint(priv, &ie); + arm_lowputc(ch); + up_setusartint(priv, ie); +#endif +} + +#endif /* HAVE_UART */ diff --git a/arch/arm/src/n32h7/n32_start.c b/arch/arm/src/n32h7/n32_start.c new file mode 100644 index 0000000000000..bdf783b9652f1 --- /dev/null +++ b/arch/arm/src/n32h7/n32_start.c @@ -0,0 +1,397 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_start.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "arm_internal.h" +#include "nvic.h" +#include "mpu.h" +#ifdef CONFIG_ARM_MPU +# include "n32_mpuinit.h" +#endif + +#include "n32_rcc.h" +#include "n32_lowputc.h" +#include "n32_start.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Memory Map ***************************************************************/ + +extern const uint32_t _sbss_rel[]; +extern const uint32_t _ebss_rel[]; +extern const uint32_t _sivectors[]; +extern const uint32_t _svectors[]; +extern const uint32_t _evectors[]; +extern const uint32_t _sitext[]; +extern const uint32_t __extab_start[]; +extern const uint32_t __extab_end[]; +extern const uint32_t __exidx_start[]; +extern const uint32_t __exidx_end[]; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* 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 = (uintptr_t)_ebss_rel + + CONFIG_IDLETHREAD_STACKSIZE; + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +void up_lowputc(int ch) +{ + arm_lowputc(ch); +} +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) arm_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_STACKCHECK +/* we need to get r10 set before we can allow instrumentation calls */ + +void __start(void) noinstrument_function; +#endif + +#ifdef CONFIG_ARCH_CHIP_N32H7_CORTEXM7 +/**************************************************************************** + * Name: n32_tcmenable + * + * Description: + * Enable/disable tightly coupled memories. Size of tightly coupled + * memory regions is controlled by GPNVM Bits 7-8. + * + ****************************************************************************/ + +static inline no_builtin("memcpy") no_builtin("memset") + void n32_tcmenable(void) +{ + uint32_t regval; + + UP_MB(); + + /* Enabled/disabled ITCM */ + +#ifdef CONFIG_ARMV7M_ITCM + regval = NVIC_TCMCR_EN | NVIC_TCMCR_RMW | NVIC_TCMCR_RETEN; +#else + regval = getreg32(NVIC_ITCMCR); + regval &= ~NVIC_TCMCR_EN; +#endif + putreg32(regval, NVIC_ITCMCR); + + /* Enabled/disabled DTCM */ + +#ifdef CONFIG_ARMV7M_DTCM + + regval = NVIC_TCMCR_EN | NVIC_TCMCR_RMW | NVIC_TCMCR_RETEN; +#else + regval = getreg32(NVIC_DTCMCR); + regval &= ~NVIC_TCMCR_EN; +#endif + putreg32(regval, NVIC_DTCMCR); + + UP_MB(); + +#ifdef CONFIG_ARMV7M_ITCM + const uint32_t *src; + uint32_t *dest; + + /* Copy TCM code from flash to ITCM */ + + for (src = _sivectors, dest = (uint32_t *)_svectors; dest < _evectors; ) + { + *dest++ = *src++; + } + + for (src = _sitext, dest = (uint32_t *)_stext; dest < (uint32_t *)_etext; ) + { + *dest++ = *src++; + } + + for (dest = (uint32_t *)_sinit; dest < (uint32_t *)_einit; ) + { + *dest++ = *src++; + } + + for (dest = (uint32_t *)__extab_start; dest < __extab_end; ) + { + *dest++ = *src++; + } + + for (dest = (uint32_t *)__exidx_start; dest < __exidx_end; ) + { + *dest++ = *src++; + } +#endif +} +#endif + +/**************************************************************************** + * Name: n32_tcm_init + * + * Description: + * Initialize the TCM Controller. + * No Memory Access, only register access. + * + * Input Parameters: + * tcm_size - TCM size config code + * + ****************************************************************************/ + +static inline void n32_tcm_init(uint32_t tcm_size) +{ + __asm__ volatile ("ldr r3, =0x1ff00f01\n\t" + "push {r0, lr}\n\t" + "blx r3\n\t" + "mov r3, r0\n\t" + "pop {r0, lr}\n\t" + "cmp r3, r0\n\t" + "beq tcm_ok\n\t" + "ldr r3, =0x51105280\n\t" + "mov r2, r0\n\t" + "str r2, [r3]\n\t" + "ldr r3, =0xE000ED0C\n\t" + "ldr r3, [r3]\n\t" + "and r2, r3, #0x0700\n\t" + "ldr r1, =0xE000ED0C\n\t" + "ldr r3, =0x05FA0004\n\t" + "orrs r3, r2\n\t" + "str r3, [r1]\n\t" + "dsb\n\t" + "loop:\n\t" + "nop\n\t" + "b loop\n\t" + "tcm_ok:\n\t" + "ldr r3, =g_idle_topstack\n\t" + "ldr r3, [r3]\n\t" + "mov sp, r3\n\t": : "r"(tcm_size) : "r3", "r1", "r2", + "memory"); +} + +/**************************************************************************** + * Name: n32_startup_m7 + * + * Description: + * Startup function. + * No Flash access. + * + ****************************************************************************/ + +static noinline_function void n32_startup_m7(void) +{ + const uint32_t *src; + uint32_t *dest; + +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit before we attempt to call any functions */ + + __asm__ volatile("sub r10, sp, %0" : : + "r"(CONFIG_IDLETHREAD_STACKSIZE - 64) :); +#endif + + /* If enabled reset the MPU */ + + mpu_early_reset(); + + /* In case of TCM configuration can be changed after POR, + * we use AXI_RAM as .bss section before TCM configuration is initialized, + * so we need to clear .bss_rel instead after TCM configuration has been + * done. + */ + + for (dest = (uint32_t *)_sbss_rel; dest < (uint32_t *)_ebss_rel; ) + { + *dest++ = 0; + } + + /* 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 = (const uint32_t *)_eronly, + dest = (uint32_t *)_sdata; dest < (uint32_t *)_edata; + ) + { + *dest++ = *src++; + } + + /* Copy any necessary code sections from FLASH to RAM. The correct + * destination in SRAM is given by _sramfuncs and _eramfuncs. The + * temporary location is in flash after the data initialization code + * at _framfuncs. This should be done before n32_clockconfig() is + * called (in case it has some dependency on initialized C variables). + */ + +#ifdef CONFIG_ARCH_RAMFUNCS + for (src = (const uint32_t *)_framfuncs, + dest = (uint32_t *)_sramfuncs; dest < (uint32_t *)_eramfuncs; + ) + { + *dest++ = *src++; + } +#endif + +#ifdef CONFIG_ARMV7M_STACKCHECK + arm_stack_check_init(); +#endif + /* Configure the UART so that we can get debug output as soon as possible */ + + n32_clockconfig(); + arm_fpuconfig(); + n32_lowsetup(); + syslog(LOG_INFO, "\033[2J\033[0m"); + showprogress('A'); + + /* Initialize onboard resources */ + + n32_boardinitialize(); + showprogress('B'); + +#ifdef CONFIG_ARCH_CHIP_N32H7_CORTEXM7 + /* Enable I- and D-Caches */ + + up_enable_icache(); + up_enable_dcache(); +#endif + showprogress('C'); + +#ifdef CONFIG_ARCH_PERF_EVENTS + up_perf_init((void *)N32_M7CPU_FREQUENCY); +#endif + + /* 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 + n32_userspace(); +#endif + showprogress('E'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + +#ifdef CONFIG_ARM_MPU + /* Configure the MPU */ + + n32_mpuinitialize(); +#endif + + nx_start(); + + /* Shouldn't get here */ + + board_autoled_off(LED_STACKCREATED); + for (; ; ) + { + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +osentry_function +void __start(void) +{ +#ifdef CONFIG_ARCH_CHIP_N32H7_CORTEXM7 + /* Initialize TCM */ + + n32_tcm_init(TCM_SIZE_VALUE); + + /* Enable/disable tightly coupled memories */ + + n32_tcmenable(); + + /* CM7 Startup function */ + + n32_startup_m7(); +#else +# error "N32H7_CORTEXM4 is not supported" +#endif +} diff --git a/arch/arm/src/n32h7/n32_start.h b/arch/arm/src/n32h7/n32_start.h new file mode 100644 index 0000000000000..a48dbef00d23c --- /dev/null +++ b/arch/arm/src/n32h7/n32_start.h @@ -0,0 +1,74 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_start.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_START_H +#define __ARCH_ARM_SRC_N32H7_N32_START_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "arm_internal.h" +#include "chip.h" + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_boardinitialize + * + * Description: + * All SAMV7 architectures must provide the following entry point. + * This entry point is called early in the initialization -- after clocking + * and memory have been configured but before caches have been enabled and + * before any devices have been initialized. + * + ****************************************************************************/ + +void n32_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_START_H */ diff --git a/arch/arm/src/n32h7/n32_systemreset.c b/arch/arm/src/n32h7/n32_systemreset.c new file mode 100644 index 0000000000000..9fbed874dba4c --- /dev/null +++ b/arch/arm/src/n32h7/n32_systemreset.c @@ -0,0 +1,95 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_systemreset.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "arm_internal.h" +#include "hardware/n32h7_rcc.h" +#include "n32_systemreset.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_get_reset_cause + * + * Description: + * Get cause of the last CPU reset. This is done by reading reset status + * registger. + * + * Returned Value: + * CPU reset cause in form of macros defined in sam_systemreset.h. This is + * to avoid passing boardctl dependent structure to architecture layer. + * Board level specific code should include sam_systemreset.h and set + * boardctl result according to that. -1 is returned in case of invalid + * value in status register. + * + ****************************************************************************/ + +int n32_get_reset_cause(void) +{ + int ret = -1; + static uint32_t rstsr = 0; + + if (rstsr == 0) + { + rstsr = getreg32(N32_RCC_CTRLSTS); + putreg32(RCC_CTRLSTS_RMRSTF, N32_RCC_CTRLSTS); + putreg32(~RCC_CTRLSTS_RMRSTF, N32_RCC_CTRLSTS); + } + + if (rstsr & RCC_CTRLSTS_PORRSTF) + { + ret = N32H7_RESET_PWRUP; + } + else if (rstsr & RCC_CTRLSTS_BORRSTF) + { + ret = N32H7_RESET_BOR; + } + else if (rstsr & (RCC_CTRLSTS_WWDG1RSTF | RCC_CTRLSTS_WWDG2RSTF | + RCC_CTRLSTS_IWDG1RSTF | RCC_CTRLSTS_IWDG2RSTF)) + { + ret = N32H7_RESET_WDOG; + } + else if (rstsr & RCC_CTRLSTS_CM7SFTRSTF) + { + ret = N32H7_RESET_SWRST; + } + else if (rstsr & RCC_CTRLSTS_PINRSTF) + { + ret = N32H7_RESET_NRST; + } + + return ret; +} diff --git a/arch/arm/src/n32h7/n32_systemreset.h b/arch/arm/src/n32h7/n32_systemreset.h new file mode 100644 index 0000000000000..3af9879f0ff86 --- /dev/null +++ b/arch/arm/src/n32h7/n32_systemreset.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_systemreset.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_SYSTEMRESET_H +#define __ARCH_ARM_SRC_N32H7_N32_SYSTEMRESET_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define N32H7_RESET_PWRUP 1 +#define N32H7_RESET_BOR 2 +#define N32H7_RESET_WDOG 3 +#define N32H7_RESET_SWRST 4 +#define N32H7_RESET_NRST 5 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_get_reset_cause + * + * Description: + * Get cause of the last CPU reset. This is done by reading reset status + * registger. + * + * Returned Value: + * CPU reset cause in form of macros defined in sam_systemreset.h. This is + * to avoid passing boardctl dependent structure to architecture layer. + * Board level specific code should include sam_systemreset.h and set + * boardctl result according to that. -1 is returned in case of invalid + * value in status register. + * + ****************************************************************************/ + +int n32_get_reset_cause(void); + +#endif /* __ARCH_ARM_SRC_N32H7_N32_SYSTEMRESET_H */ diff --git a/arch/arm/src/n32h7/n32_tickless.c b/arch/arm/src/n32h7/n32_tickless.c new file mode 100644 index 0000000000000..8c33ef191efdb --- /dev/null +++ b/arch/arm/src/n32h7/n32_tickless.c @@ -0,0 +1,821 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_tickless.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Tickless OS Support. + * + * When CONFIG_SCHED_TICKLESS is enabled, all support for timer interrupts + * is suppressed and the platform specific code is expected to provide the + * following custom functions. + * + * void up_timer_initialize(void): Initializes the timer facilities. + * Called early in the initialization sequence (by up_initialize()). + * int up_timer_gettime(struct timespec *ts): Returns the current + * time from the platform specific time source. + * int up_timer_cancel(void): Cancels the interval timer. + * int up_timer_start(const struct timespec *ts): Start (or re-starts) + * the interval timer. + * + * The RTOS will provide the following interfaces for use by the platform- + * specific interval timer implementation: + * + * void nxsched_timer_expiration(void): Called by the platform-specific + * logic when the interval timer expires. + * + ****************************************************************************/ + +/**************************************************************************** + * N32H7 Timer Usage + * + * This implementation uses one timer: A free running timer to provide + * the current time and a capture/compare channel for timed-events. + * + * Basic timers (BTIM) are incompatible because they don't have + * capture/compare channels. Use ATIM or GTIMA instead. + * + * There are two interrupts generated from our timer: + * - overflow interrupt -> update 64-bit counter + * - compare interrupt -> interval expiration + * + * Some low-level register operations are done directly because the + * n32_tim.c API does not expose all needed controls. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "arm_internal.h" +#include "n32_tim.h" +#include "n32_dbgmcu.h" + +#ifdef CONFIG_SCHED_TICKLESS + +/* Timer is always 16-bit on N32H7 for tickless (we use ATIM/GTIMA) */ + +/* No 32-bit tickless support on N32H7 because BTIM lacks CC channel */ + +#define HAVE_16BIT_TICKLESS 1 + +#if CONFIG_N32H7_TICKLESS_CHANNEL == 1 +# define DIER_CAPT_IE N32_ATIM_DINTEN_CC1IEN +# define SR_CAPT_IF N32_ATIM_STS_CC1ITF +#elif CONFIG_N32H7_TICKLESS_CHANNEL == 2 +# define DIER_CAPT_IE N32_ATIM_DINTEN_CC2IEN +# define SR_CAPT_IF N32_ATIM_STS_CC2ITF +#elif CONFIG_N32H7_TICKLESS_CHANNEL == 3 +# define DIER_CAPT_IE N32_ATIM_DINTEN_CC3IEN +# define SR_CAPT_IF N32_ATIM_STS_CC3ITF +#elif CONFIG_N32H7_TICKLESS_CHANNEL == 4 +# define DIER_CAPT_IE N32_ATIM_DINTEN_CC4IEN +# define SR_CAPT_IF N32_ATIM_STS_CC4ITF +#else +# error "Invalid tickless channel" +#endif + +/* Note: N32H7 ATIM STS and DINTEN are 32-bit registers */ + +#define N32_STS_OFFSET N32_ATIM_STS_OFFSET +#define N32_DINTEN_OFFSET N32_ATIM_DINTEN_OFFSET + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct n32_tickless_s +{ + uint8_t timer; /* Timer number (1-18) */ + uint8_t channel; /* Capture/compare channel (1-4) */ + uint32_t base; /* Timer base address */ + struct n32_tim_dev_s *tch; /* Timer device handle */ + uint32_t frequency; /* Timer clock frequency (AHB) */ + volatile uint32_t overflow; /* Number of overflows (16-bit counter) */ + volatile bool pending; /* True: interval timer is pending */ + uint32_t period; /* Interval compare value */ +#ifdef CONFIG_SCHED_TICKLESS_ALARM + uint64_t last_alrm; /* Last alarm time (alarm mode) */ +#endif +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct n32_tickless_s g_tickless; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_getreg16/n32_putreg16 (for 16-bit registers like CNT, PSC, ARR) + * Name: n32_getreg32/n32_putreg32/n32_modreg32 (for 32-bit registers) + ****************************************************************************/ + +static inline uint16_t n32_getreg16(uint32_t offset) +{ + return getreg16(g_tickless.base + offset); +} + +static inline void n32_putreg16(uint32_t offset, uint16_t value) +{ + putreg16(value, g_tickless.base + offset); +} + +static inline uint32_t n32_getreg32(uint32_t offset) +{ + return getreg32(g_tickless.base + offset); +} + +static inline void n32_putreg32(uint32_t offset, uint32_t value) +{ + putreg32(value, g_tickless.base + offset); +} + +static inline void n32_modreg32(uint32_t offset, uint32_t clearbits, + uint32_t setbits) +{ + modifyreg32(g_tickless.base + offset, clearbits, setbits); +} + +/**************************************************************************** + * Name: n32_tickless_enableint/n32_tickless_disableint/n32_tickless_ackint + ****************************************************************************/ + +static inline void n32_tickless_enableint(void) +{ + n32_modreg32(N32_DINTEN_OFFSET, 0, DIER_CAPT_IE); +} + +static inline void n32_tickless_disableint(void) +{ + n32_modreg32(N32_DINTEN_OFFSET, DIER_CAPT_IE, 0); +} + +static inline void n32_tickless_ackint(void) +{ + n32_putreg32(N32_STS_OFFSET, ~SR_CAPT_IF); +} + +static inline uint32_t n32_tickless_getint(void) +{ + return n32_getreg32(N32_STS_OFFSET); +} + +/**************************************************************************** + * Name: n32_tickless_setchannel + * + * Description: + * Configure the timer channel as output compare (frozen mode) for interval + * timing. This is similar to n32_tim_setchannel but hard-coded for the + * tickless timer. + * + ****************************************************************************/ + +static int n32_tickless_setchannel(uint8_t channel) +{ + uint32_t ccmr_orig; + uint32_t ccmr_val; + uint32_t ccmr_mask; + uint32_t ccmr_offset; + uint32_t ccer_val; + uint32_t ccer_shift; + uint32_t ccmr_mode_shift; + uint32_t ccen_bit; + + if (channel < 1 || channel > 4) + { + return -EINVAL; + } + + ccer_val = n32_getreg16(N32_ATIM_CCEN_OFFSET); + ccer_shift = (uint32_t)(channel - 1) * 4; + ccen_bit = N32_ATIM_CCEN_CC1EN << ccer_shift; + + /* Determine CCMOD register and shift */ + + if (channel <= 2) + { + ccmr_offset = N32_ATIM_CCMOD1_OFFSET; + ccmr_mode_shift = (channel == 1) ? 0 : (N32_ATIM_CCMOD1_OC2MD_SHIFT - + N32_ATIM_CCMOD1_OC1MD_SHIFT); + } + else + { + ccmr_offset = N32_ATIM_CCMOD2_OFFSET; + ccmr_mode_shift = (channel == 3) ? 0 : (N32_ATIM_CCMOD2_OC4MD_SHIFT - + N32_ATIM_CCMOD2_OC3MD_SHIFT); + } + + /* Clear channel enable bit */ + + ccer_val &= ~ccen_bit; + ccer_val &= ~(N32_ATIM_CCEN_CC1P << ccer_shift); + + /* Frozen mode, no preload */ + + ccmr_val = (N32_ATIM_CCMOD1_OCMODE_FRZN << ccmr_mode_shift); + ccmr_mask = 0xff << ccmr_mode_shift; + + /* Clear polarity (active high) and enable output */ + + ccer_val &= ~(N32_ATIM_CCEN_CC1P << ccer_shift); + ccer_val |= ccen_bit; + + /* Write CCMOD */ + + ccmr_orig = n32_getreg16(ccmr_offset); + ccmr_orig &= ~ccmr_mask; + ccmr_orig |= ccmr_val; + n32_putreg16(ccmr_offset, ccmr_orig); + + /* Write CCEN */ + + n32_putreg16(N32_ATIM_CCEN_OFFSET, ccer_val); + + return OK; +} + +/**************************************************************************** + * Name: n32_interval_handler + * + * Description: + * Called when the timer counter matches the compare register. + * + ****************************************************************************/ + +static void n32_interval_handler(void) +{ + tmrinfo("Expired...\n"); + + /* Disable the compare interrupt now. */ + + n32_tickless_disableint(); + n32_tickless_ackint(); + + g_tickless.pending = false; + + nxsched_process_timer(); +} + +/**************************************************************************** + * Name: n32_timing_handler + * + * Description: + * Timer overflow interrupt handler. Increment the overflow counter. + * + ****************************************************************************/ + +static void n32_timing_handler(void) +{ + g_tickless.overflow++; + n32_putreg32(N32_STS_OFFSET, ~N32_ATIM_STS_UDITF); +} + +/**************************************************************************** + * Name: n32_tickless_handler + * + * Description: + * Generic interrupt handler for this timer. Checks the source of the + * interrupt and fires the appropriate handler. + * + ****************************************************************************/ + +static int n32_tickless_handler(int irq, void *context, void *arg) +{ + uint32_t sr = n32_tickless_getint(); + + if (sr & N32_ATIM_STS_UDITF) + { + n32_timing_handler(); + } + + if (sr & SR_CAPT_IF) + { + n32_interval_handler(); + } + + return OK; +} + +/**************************************************************************** + * Name: n32_tickless_get_counter64 + * + * Description: + * Read the 64-bit counter value (overflow + current counter). + * + ****************************************************************************/ + +static uint64_t n32_tickless_get_counter64(void) +{ + irqstate_t flags; + uint32_t overflow; + uint32_t counter; + uint32_t verify; + int pending; + + flags = enter_critical_section(); + + overflow = g_tickless.overflow; + counter = n32_getreg16(N32_ATIM_CNT_OFFSET); + pending = (n32_tickless_getint() & N32_ATIM_STS_UDITF) ? 1 : 0; + verify = n32_getreg16(N32_ATIM_CNT_OFFSET); + + if (pending) + { + /* Acknowledge the overflow interrupt and increment */ + + n32_putreg32(N32_STS_OFFSET, N32_ATIM_STS_UDITF); + overflow++; + counter = verify; + g_tickless.overflow = overflow; + } + + leave_critical_section(flags); + + return ((uint64_t)overflow << 16) | (uint64_t)counter; +} + +/**************************************************************************** + * Name: n32_tickless_dbgmcu_freeze + * + * Description: + * Configure the timer to stop in debug mode. + * + ****************************************************************************/ + +static void n32_tickless_dbgmcu_freeze(uint32_t base) +{ + switch (base) + { +#ifdef CONFIG_N32H7_ATIM3 + case N32_ATIMER3_BASE: + modifyreg32(N32_DBG_M7APB5FZ, 0, DBG_M7APB5FZ_ATIM3_STOP); + break; +#endif +#ifdef CONFIG_N32H7_ATIM4 + case N32_ATIMER4_BASE: + modifyreg32(N32_DBG_M7APB5FZ, 0, DBG_M7APB5FZ_ATIM4_STOP); + break; +#endif + default: + tmrerr("ERROR: Unsupported tickless timer!\n"); + PANIC(); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * Initializes all platform-specific timer facilities. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + int timer = CONFIG_N32H7_TICKLESS_TIMER; + int channel = CONFIG_N32H7_TICKLESS_CHANNEL; + + tmrinfo("timer=%d channel=%d\n", timer, channel); + + /* Set base address and frequency based on selected timer */ + + switch (timer) + { +#ifdef CONFIG_N32H7_ATIM3 + case 6: + g_tickless.base = N32_ATIMER3_BASE; + break; +#endif +#ifdef CONFIG_N32H7_ATIM4 + case 7: + g_tickless.base = N32_ATIMER4_BASE; + break; +#endif + default: + tmrerr("ERROR: Unsupported tickless timer %d\n", timer); + PANIC(); + } + + g_tickless.timer = timer; + g_tickless.channel = channel; + g_tickless.frequency = USEC_PER_SEC / (uint32_t)CONFIG_USEC_PER_TICK; + g_tickless.overflow = 0; + g_tickless.pending = false; + g_tickless.period = 0; + + tmrinfo("base=0x%08lx frequency=%lu Hz\n", + (unsigned long)g_tickless.base, g_tickless.frequency); + + /* Initialize the timer hardware */ + + g_tickless.tch = n32_tim_init(timer); + if (g_tickless.tch == NULL) + { + tmrerr("ERROR: Failed to initialize TIM%d\n", timer); + PANIC(); + } + + /* Set timer clock and period (max for 16-bit) */ + + N32_TIM_SETCLOCK(g_tickless.tch, g_tickless.frequency); + + /* Set up interrupt handler (both update and CC) */ + + N32_TIM_SETISR(g_tickless.tch, n32_tickless_handler, NULL, + N32_TIM_ISR_UPDATE); + N32_TIM_SETISR(g_tickless.tch, n32_tickless_handler, NULL, + N32_TIM_ISR_CC); + + /* Initialize interval to zero */ + + N32_TIM_SETCOMPARE(g_tickless.tch, channel, 0); + + /* Configure compare channel for interval timing */ + + n32_tickless_setchannel(channel); + + /* Set timer period */ + + N32_TIM_SETPERIOD(g_tickless.tch, UINT16_MAX); + + /* Initialize the counter */ + + N32_TIM_SETMODE(g_tickless.tch, N32_TIM_MODE_UP); + + /* Acknowledge any pending interrupts and enable update interrupt */ + + n32_putreg32(N32_STS_OFFSET, N32_ATIM_STS_UDITF | SR_CAPT_IF); + N32_TIM_ENABLEINT(g_tickless.tch, N32_ATIM_DINTEN_UIEN); + + /* Configure debug freeze (stop timer when core halted) */ + + n32_tickless_dbgmcu_freeze(g_tickless.base); + + tmrinfo("Tickless timer initialized\n"); + +#if defined(CONFIG_ARMV7M_SYSTICK) && defined(CONFIG_CPULOAD_PERIOD) + nxsched_period_extclk(systick_initialize(true, N32_M7CPU_FREQUENCY, -1)); +#endif +} + +/**************************************************************************** + * Name: up_timer_gettime + * + * Description: + * Return the elapsed time since power-up. + * + ****************************************************************************/ + +int up_timer_gettime(struct timespec *ts) +{ + uint64_t ticks; + uint64_t usec; + uint64_t sec; + + DEBUGASSERT(ts != NULL); + + if (g_tickless.tch == NULL) + { + ts->tv_sec = 0; + ts->tv_nsec = 0; + return OK; + } + + ticks = n32_tickless_get_counter64(); + + usec = (ticks * USEC_PER_SEC) / g_tickless.frequency; + + sec = usec / USEC_PER_SEC; + ts->tv_sec = (time_t)sec; + ts->tv_nsec = (long)((usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC); + + tmrinfo("ticks=%llu usec=%llu ts=(%lu, %lu)\n", + ticks, usec, (unsigned long)ts->tv_sec, + (unsigned long)ts->tv_nsec); + + return OK; +} + +#ifdef CONFIG_CLOCK_TIMEKEEPING + +/**************************************************************************** + * Name: up_timer_gettick + ****************************************************************************/ + +int up_timer_gettick(clock_t *ticks) +{ + if (ticks == NULL) + { + return -EINVAL; + } + + *ticks = (clock_t)n32_tickless_get_counter64(); + return OK; +} + +/**************************************************************************** + * Name: up_timer_getmask + ****************************************************************************/ + +void up_timer_getmask(clock_t *mask) +{ + DEBUGASSERT(mask != NULL); + *mask = 0xffff; /* 16-bit timer */ +} + +#endif /* CONFIG_CLOCK_TIMEKEEPING */ + +/**************************************************************************** + * Name: up_timer_cancel + * + * Description: + * Cancel the interval timer and return the time remaining. + * + ****************************************************************************/ + +#ifndef CONFIG_SCHED_TICKLESS_ALARM +int up_timer_cancel(struct timespec *ts) +{ + irqstate_t flags; + uint64_t usec; + uint32_t count; + uint32_t period; + + flags = enter_critical_section(); + + if (!g_tickless.pending) + { + if (ts != NULL) + { + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + + leave_critical_section(flags); + return OK; + } + + tmrinfo("Cancelling...\n"); + + /* Disable the compare interrupt */ + + n32_tickless_disableint(); + + count = n32_getreg16(N32_ATIM_CNT_OFFSET); + period = g_tickless.period; + + g_tickless.pending = false; + + leave_critical_section(flags); + + if (ts != NULL) + { + /* Calculate remaining time */ + + if (count < period) + { + usec = ((uint64_t)(period - count) * USEC_PER_SEC) / + g_tickless.frequency; + } + else + { + usec = 0; + } + + ts->tv_sec = (time_t)(usec / USEC_PER_SEC); + ts->tv_nsec = (long)((usec - (uint64_t)(ts->tv_sec * USEC_PER_SEC)) * + NSEC_PER_USEC); + + tmrinfo("Remaining: %lu sec, %lu nsec\n", + (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + } + + return OK; +} +#endif /* !CONFIG_SCHED_TICKLESS_ALARM */ + +/**************************************************************************** + * Name: up_timer_start + * + * Description: + * Start the interval timer. + * + ****************************************************************************/ + +#ifndef CONFIG_SCHED_TICKLESS_ALARM +int up_timer_start(const struct timespec *ts) +{ + uint64_t usec; + uint64_t period_ticks; + uint32_t count; + uint32_t compare; + irqstate_t flags; + + DEBUGASSERT(ts != NULL); + + tmrinfo("ts=(%lu, %lu)\n", + (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec); + + flags = enter_critical_section(); + + if (g_tickless.pending) + { + up_timer_cancel(NULL); + } + + usec = (uint64_t)ts->tv_sec * USEC_PER_SEC + + (uint64_t)(ts->tv_nsec / NSEC_PER_USEC); + + period_ticks = (usec * g_tickless.frequency) / USEC_PER_SEC; + + if (period_ticks == 0) + { + period_ticks = 1; + } + + count = n32_getreg16(N32_ATIM_CNT_OFFSET); + compare = count + (uint32_t)period_ticks; + + if (compare > 0xffff) + { + /* Wrap around: set compare to count - (0xffff - period) */ + + compare = count - (0xffff - (uint32_t)period_ticks); + } + + g_tickless.period = compare; + n32_putreg16(N32_ATIM_CCDAT1_OFFSET + (g_tickless.channel - 1) * 4, + compare); + + n32_tickless_ackint(); + n32_tickless_enableint(); + + g_tickless.pending = true; + + leave_critical_section(flags); + + tmrinfo("Started: count=%lu compare=%lu\n", count, compare); + + return OK; +} +#endif /* !CONFIG_SCHED_TICKLESS_ALARM */ + +#ifdef CONFIG_SCHED_TICKLESS_ALARM + +/**************************************************************************** + * Name: up_alarm_start + * + * Description: + * Start the alarm timer (absolute time). + * + ****************************************************************************/ + +int up_alarm_start(const struct timespec *ts) +{ + uint64_t target_ticks; + uint64_t current_ticks; + uint32_t compare; + uint32_t current_low; + uint64_t diff; + irqstate_t flags; + + DEBUGASSERT(ts != NULL); + + target_ticks = ((uint64_t)ts->tv_sec * NSEC_PER_SEC + ts->tv_nsec) / + NSEC_PER_TICK; + + flags = enter_critical_section(); + + if (g_tickless.pending) + { + n32_tickless_disableint(); + g_tickless.pending = false; + } + + current_ticks = n32_tickless_get_counter64(); + current_low = n32_getreg16(N32_ATIM_CNT_OFFSET); + diff = target_ticks - current_ticks; + + if (diff <= 0xffff) + { + compare = current_low + (uint32_t)diff; + } + else + { + compare = 0xffff; + } + + if (compare > 0xffff) + { + compare -= 0x10000; + } + + g_tickless.period = compare; + n32_putreg16(N32_ATIM_CCDAT1_OFFSET + (g_tickless.channel - 1) * 4, + compare); + + n32_tickless_ackint(); + n32_tickless_enableint(); + + g_tickless.pending = true; + g_tickless.last_alrm = target_ticks; + + leave_critical_section(flags); + + tmrinfo("Alarm started: current=%llu target=%llu compare=%lu\n", + current_ticks, target_ticks, compare); + + return OK; +} + +/**************************************************************************** + * Name: up_alarm_cancel + ****************************************************************************/ + +int up_alarm_cancel(struct timespec *ts) +{ + irqstate_t flags; + uint64_t nsec; + + flags = enter_critical_section(); + + if (!g_tickless.pending) + { + if (ts != NULL) + { + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + + leave_critical_section(flags); + return OK; + } + + n32_tickless_disableint(); + g_tickless.pending = false; + + uint64_t current_ticks = n32_tickless_get_counter64(); + + leave_critical_section(flags); + + if (ts != NULL) + { + if (g_tickless.last_alrm > current_ticks) + { + uint64_t diff = g_tickless.last_alrm - current_ticks; + + nsec = (diff * NSEC_PER_SEC) / g_tickless.frequency; + } + else + { + nsec = 0; + } + + ts->tv_sec = (time_t)(nsec / NSEC_PER_SEC); + ts->tv_nsec = (long)(nsec % NSEC_PER_SEC); + } + + return OK; +} + +#endif /* CONFIG_SCHED_TICKLESS_ALARM */ + +#endif /* CONFIG_SCHED_TICKLESS */ diff --git a/arch/arm/src/n32h7/n32_tim.c b/arch/arm/src/n32h7/n32_tim.c new file mode 100644 index 0000000000000..9132a5e33dae7 --- /dev/null +++ b/arch/arm/src/n32h7/n32_tim.c @@ -0,0 +1,2358 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_tim.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "arm_internal.h" +#include "n32_rcc.h" +#include "n32_gpio.h" +#include "n32_tim.h" +#include "hardware/n32h7_rcc.h" +#include "hardware/n32h76x_pinmap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Timer devices may be used for different purposes. Such special purposes + * include: + * + * - To generate modulated outputs for such things as motor control. If + * CONFIG_N32H7_TIMn_PWM is defined then the timer is intended to be used + * for pulsed output modulation. + * + * - To control periodic ADC input sampling. If CONFIG_N32H7_TIMn_ADC is + * defined then timer "n" is intended to be used for that purpose. + * + * - To control periodic DAC outputs. If CONFIG_N32H7_TIMn_DAC is defined + * then timer "n" is intended to be used for that purpose. + * + * - To use a Quadrature Encoder. If CONFIG_N32H7_TIMn_QE is defined then + * 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. + */ + +/* ATIM1 */ +#if defined(CONFIG_N32H7_ATIM1_PWM) || defined(CONFIG_N32H7_ATIM1_ADC) || \ + defined(CONFIG_N32H7_ATIM1_DAC) || defined(CONFIG_N32H7_ATIM1_QE) +# undef CONFIG_N32H7_ATIM1 +#endif + +/* ATIM2 */ +#if defined(CONFIG_N32H7_ATIM2_PWM) || defined(CONFIG_N32H7_ATIM2_ADC) || \ + defined(CONFIG_N32H7_ATIM2_DAC) || defined(CONFIG_N32H7_ATIM2_QE) +# undef CONFIG_N32H7_ATIM2 +#endif + +/* ATIM3 */ +#if defined(CONFIG_N32H7_ATIM3_PWM) || defined(CONFIG_N32H7_ATIM3_ADC) || \ + defined(CONFIG_N32H7_ATIM3_DAC) || defined(CONFIG_N32H7_ATIM3_QE) +# undef CONFIG_N32H7_ATIM3 +#endif + +/* ATIM4 */ +#if defined(CONFIG_N32H7_ATIM4_PWM) || defined(CONFIG_N32H7_ATIM4_ADC) || \ + defined(CONFIG_N32H7_ATIM4_DAC) || defined(CONFIG_N32H7_ATIM4_QE) +# undef CONFIG_N32H7_ATIM4 +#endif + +/* GTIMA1 */ +#if defined(CONFIG_N32H7_GTIMA1_PWM) || defined(CONFIG_N32H7_GTIMA1_ADC) || \ + defined(CONFIG_N32H7_GTIMA1_DAC) || defined(CONFIG_N32H7_GTIMA1_QE) +# undef CONFIG_N32H7_GTIMA1 +#endif + +/* GTIMA2 */ +#if defined(CONFIG_N32H7_GTIMA2_PWM) || defined(CONFIG_N32H7_GTIMA2_ADC) || \ + defined(CONFIG_N32H7_GTIMA2_DAC) || defined(CONFIG_N32H7_GTIMA2_QE) +# undef CONFIG_N32H7_GTIMA2 +#endif + +/* GTIMA3 */ +#if defined(CONFIG_N32H7_GTIMA3_PWM) || defined(CONFIG_N32H7_GTIMA3_ADC) || \ + defined(CONFIG_N32H7_GTIMA3_DAC) || defined(CONFIG_N32H7_GTIMA3_QE) +# undef CONFIG_N32H7_GTIMA3 +#endif + +/* GTIMA4 */ +#if defined(CONFIG_N32H7_GTIMA4_PWM) || defined(CONFIG_N32H7_GTIMA4_ADC) || \ + defined(CONFIG_N32H7_GTIMA4_DAC) || defined(CONFIG_N32H7_GTIMA4_QE) +# undef CONFIG_N32H7_GTIMA4 +#endif + +/* GTIMA5 */ +#if defined(CONFIG_N32H7_GTIMA5_PWM) || defined(CONFIG_N32H7_GTIMA5_ADC) || \ + defined(CONFIG_N32H7_GTIMA5_DAC) || defined(CONFIG_N32H7_GTIMA5_QE) +# undef CONFIG_N32H7_GTIMA5 +#endif + +/* GTIMA6 */ +#if defined(CONFIG_N32H7_GTIMA6_PWM) || defined(CONFIG_N32H7_GTIMA6_ADC) || \ + defined(CONFIG_N32H7_GTIMA6_DAC) || defined(CONFIG_N32H7_GTIMA6_QE) +# undef CONFIG_N32H7_GTIMA6 +#endif + +/* GTIMA7 */ +#if defined(CONFIG_N32H7_GTIMA7_PWM) || defined(CONFIG_N32H7_GTIMA7_ADC) || \ + defined(CONFIG_N32H7_GTIMA7_DAC) || defined(CONFIG_N32H7_GTIMA7_QE) +# undef CONFIG_N32H7_GTIMA7 +#endif + +/* GTIMB1 */ +#if defined(CONFIG_N32H7_GTIMB1_PWM) || defined(CONFIG_N32H7_GTIMB1_ADC) || \ + defined(CONFIG_N32H7_GTIMB1_DAC) || defined(CONFIG_N32H7_GTIMB1_QE) +# undef CONFIG_N32H7_GTIMB1 +#endif + +/* GTIMB2 */ +#if defined(CONFIG_N32H7_GTIMB2_PWM) || defined(CONFIG_N32H7_GTIMB2_ADC) || \ + defined(CONFIG_N32H7_GTIMB2_DAC) || defined(CONFIG_N32H7_GTIMB2_QE) +# undef CONFIG_N32H7_GTIMB2 +#endif + +/* GTIMB3 */ +#if defined(CONFIG_N32H7_GTIMB3_PWM) || defined(CONFIG_N32H7_GTIMB3_ADC) || \ + defined(CONFIG_N32H7_GTIMB3_DAC) || defined(CONFIG_N32H7_GTIMB3_QE) +# undef CONFIG_N32H7_GTIMB3 +#endif + +/* BTIM1 */ +#if defined(CONFIG_N32H7_BTIM1_PWM) || defined(CONFIG_N32H7_BTIM1_ADC) || \ + defined(CONFIG_N32H7_BTIM1_DAC) || defined(CONFIG_N32H7_BTIM1_QE) +# undef CONFIG_N32H7_BTIM1 +#endif + +/* BTIM2 */ +#if defined(CONFIG_N32H7_BTIM2_PWM) || defined(CONFIG_N32H7_BTIM2_ADC) || \ + defined(CONFIG_N32H7_BTIM2_DAC) || defined(CONFIG_N32H7_BTIM2_QE) +# undef CONFIG_N32H7_BTIM2 +#endif + +/* BTIM3 */ +#if defined(CONFIG_N32H7_BTIM3_PWM) || defined(CONFIG_N32H7_BTIM3_ADC) || \ + defined(CONFIG_N32H7_BTIM3_DAC) || defined(CONFIG_N32H7_BTIM3_QE) +# undef CONFIG_N32H7_BTIM3 +#endif + +/* BTIM4 */ +#if defined(CONFIG_N32H7_BTIM4_PWM) || defined(CONFIG_N32H7_BTIM4_ADC) || \ + defined(CONFIG_N32H7_BTIM4_DAC) || defined(CONFIG_N32H7_BTIM4_QE) +# undef CONFIG_N32H7_BTIM4 +#endif + +/* GPIO output pin configuration support */ + +#if defined(CONFIG_N32H7_ATIM1) +# if defined(GPIO_ATIM1_CH1OUT) || defined(GPIO_ATIM1_CH2OUT) || \ + defined(GPIO_ATIM1_CH3OUT) || defined(GPIO_ATIM1_CH4OUT) +# define HAVE_ATIM1_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_ATIM2) +# if defined(GPIO_ATIM2_CH1OUT) || defined(GPIO_ATIM2_CH2OUT) || \ + defined(GPIO_ATIM2_CH3OUT) || defined(GPIO_ATIM2_CH4OUT) +# define HAVE_ATIM2_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_ATIM3) +# if defined(GPIO_ATIM3_CH1OUT) || defined(GPIO_ATIM3_CH2OUT) || \ + defined(GPIO_ATIM3_CH3OUT) || defined(GPIO_ATIM3_CH4OUT) +# define HAVE_ATIM3_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_ATIM4) +# if defined(GPIO_ATIM4_CH1OUT) || defined(GPIO_ATIM4_CH2OUT) || \ + defined(GPIO_ATIM4_CH3OUT) || defined(GPIO_ATIM4_CH4OUT) +# define HAVE_ATIM4_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMA1) +# if defined(GPIO_GTIMA1_CH1OUT) || defined(GPIO_GTIMA1_CH2OUT) || \ + defined(GPIO_GTIMA1_CH3OUT) || defined(GPIO_GTIMA1_CH4OUT) +# define HAVE_GTIMA1_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMA2) +# if defined(GPIO_GTIMA2_CH1OUT) || defined(GPIO_GTIMA2_CH2OUT) || \ + defined(GPIO_GTIMA2_CH3OUT) || defined(GPIO_GTIMA2_CH4OUT) +# define HAVE_GTIMA2_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMA3) +# if defined(GPIO_GTIMA3_CH1OUT) || defined(GPIO_GTIMA3_CH2OUT) || \ + defined(GPIO_GTIMA3_CH3OUT) || defined(GPIO_GTIMA3_CH4OUT) +# define HAVE_GTIMA3_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMA4) +# if defined(GPIO_GTIMA4_CH1OUT) || defined(GPIO_GTIMA4_CH2OUT) || \ + defined(GPIO_GTIMA4_CH3OUT) || defined(GPIO_GTIMA4_CH4OUT) +# define HAVE_GTIMA4_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMA5) +# if defined(GPIO_GTIMA5_CH1OUT) || defined(GPIO_GTIMA5_CH2OUT) || \ + defined(GPIO_GTIMA5_CH3OUT) || defined(GPIO_GTIMA5_CH4OUT) +# define HAVE_GTIMA5_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMA6) +# if defined(GPIO_GTIMA6_CH1OUT) || defined(GPIO_GTIMA6_CH2OUT) || \ + defined(GPIO_GTIMA6_CH3OUT) || defined(GPIO_GTIMA6_CH4OUT) +# define HAVE_GTIMA6_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMA7) +# if defined(GPIO_GTIMA7_CH1OUT) || defined(GPIO_GTIMA7_CH2OUT) || \ + defined(GPIO_GTIMA7_CH3OUT) || defined(GPIO_GTIMA7_CH4OUT) +# define HAVE_GTIMA7_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMB1) +# if defined(GPIO_GTIMB1_CH1POUT) || defined(GPIO_GTIMB1_CH2OUT) || \ + defined(GPIO_GTIMB1_CH3OUT) || defined(GPIO_GTIMB1_CH4OUT) +# define HAVE_GTIMB1_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMB2) +# if defined(GPIO_GTIMB2_CH1POUT) || defined(GPIO_GTIMB2_CH2OUT) || \ + defined(GPIO_GTIMB2_CH3OUT) || defined(GPIO_GTIMB2_CH4OUT) +# define HAVE_GTIMB2_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_N32H7_GTIMB3) +# if defined(GPIO_GTIMB3_CH1POUT) || defined(GPIO_GTIMB3_CH2OUT) || \ + defined(GPIO_GTIMB3_CH3OUT) || defined(GPIO_GTIMB3_CH4OUT) +# define HAVE_GTIMB3_GPIOCONFIG 1 +# endif +#endif + +/* This module compiles only if there are enabled timers not intended for + * some other purpose. + */ + +#if defined(CONFIG_N32H7_ATIM1) || defined(CONFIG_N32H7_ATIM2) || \ + defined(CONFIG_N32H7_ATIM3) || defined(CONFIG_N32H7_ATIM4) || \ + defined(CONFIG_N32H7_GTIMA1) || defined(CONFIG_N32H7_GTIMA2) || \ + defined(CONFIG_N32H7_GTIMA3) || defined(CONFIG_N32H7_GTIMA4) || \ + defined(CONFIG_N32H7_GTIMA5) || defined(CONFIG_N32H7_GTIMA6) || \ + defined(CONFIG_N32H7_GTIMA7) || defined(CONFIG_N32H7_GTIMB1) || \ + defined(CONFIG_N32H7_GTIMB2) || defined(CONFIG_N32H7_GTIMB3) || \ + defined(CONFIG_N32H7_BTIM1) || defined(CONFIG_N32H7_BTIM2) || \ + defined(CONFIG_N32H7_BTIM3) || defined(CONFIG_N32H7_BTIM4) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Timer type enumeration */ + +enum n32_tim_type_e +{ + TIM_TYPE_ATIM, /* Advanced timer (ATIM1-4) */ + TIM_TYPE_GTIMA, /* General-purpose timer A (GTIMA1-7) */ + TIM_TYPE_GTIMB, /* General-purpose timer B (GTIMB1-3) */ + TIM_TYPE_BTIM /* Basic timer (BTIM1-4) */ +}; + +/* Timer device private structure */ + +struct n32_tim_priv_s +{ + const struct n32_tim_ops_s *ops; + enum n32_tim_type_e type; + uint32_t base; /* Timer base address */ + uint32_t freqin; /* Input clock frequency (for setclock) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Timer helpers */ + +static void n32_tim_reload_counter(struct n32_tim_dev_s *dev); +static void n32_tim_enable(struct n32_tim_dev_s *dev); +static void n32_tim_disable(struct n32_tim_dev_s *dev); +static void n32_tim_reset(struct n32_tim_dev_s *dev); + +/* Timer methods */ + +static int n32_tim_setmode(struct n32_tim_dev_s *dev, + n32_tim_mode_t mode); +static int n32_tim_setclock(struct n32_tim_dev_s *dev, + uint32_t freq); +static void n32_tim_setperiod(struct n32_tim_dev_s *dev, + uint32_t period); +static uint32_t n32_tim_getperiod(struct n32_tim_dev_s *dev); +static uint32_t n32_tim_getcounter(struct n32_tim_dev_s *dev); +static void n32_tim_setcounter(struct n32_tim_dev_s *dev, + uint32_t count); +static int n32_tim_getwidth(struct n32_tim_dev_s *dev); +static int n32_tim_setchannel(struct n32_tim_dev_s *dev, + uint8_t channel, + n32_tim_channel_t mode); +static int n32_tim_setcompare(struct n32_tim_dev_s *dev, + uint8_t channel, uint32_t compare); +static int n32_tim_getcapture(struct n32_tim_dev_s *dev, + uint8_t channel); +static int n32_tim_setisr(struct n32_tim_dev_s *dev, + xcpt_t handler, void *arg, int source); +static void n32_tim_enableint(struct n32_tim_dev_s *dev, int source); +static void n32_tim_disableint(struct n32_tim_dev_s *dev, int source); +static void n32_tim_ackint(struct n32_tim_dev_s *dev, int source); +static int n32_tim_checkint(struct n32_tim_dev_s *dev, int source); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct n32_tim_ops_s n32_tim_ops = +{ + .enable = &n32_tim_enable, + .disable = &n32_tim_disable, + .setmode = &n32_tim_setmode, + .setclock = &n32_tim_setclock, + .setperiod = &n32_tim_setperiod, + .getperiod = &n32_tim_getperiod, + .getcounter = &n32_tim_getcounter, + .setcounter = &n32_tim_setcounter, + .getwidth = &n32_tim_getwidth, + .setchannel = &n32_tim_setchannel, + .setcompare = &n32_tim_setcompare, + .getcapture = &n32_tim_getcapture, + .setisr = &n32_tim_setisr, + .enableint = &n32_tim_enableint, + .disableint = &n32_tim_disableint, + .ackint = &n32_tim_ackint, + .checkint = &n32_tim_checkint, +}; + +/* Timer private structures - ATIM1-4 */ + +#ifdef CONFIG_N32H7_ATIM1 +static struct n32_tim_priv_s n32_tim1_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_ATIM, + .base = N32_ATIMER1_BASE, + .freqin = N32_AHB_FREQUENCY, /* 300 MHz */ +}; +#endif + +#ifdef CONFIG_N32H7_ATIM2 +static struct n32_tim_priv_s n32_tim2_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_ATIM, + .base = N32_ATIMER2_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM3 +static struct n32_tim_priv_s n32_tim3_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_ATIM, + .base = N32_ATIMER3_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM4 +static struct n32_tim_priv_s n32_tim4_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_ATIM, + .base = N32_ATIMER4_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +/* Timer private structures - GTIMA1-7 */ + +#ifdef CONFIG_N32H7_GTIMA1 +static struct n32_tim_priv_s n32_gtima1_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMA, + .base = N32_GTIMERA1_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA2 +static struct n32_tim_priv_s n32_gtima2_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMA, + .base = N32_GTIMERA2_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA3 +static struct n32_tim_priv_s n32_gtima3_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMA, + .base = N32_GTIMERA3_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA4 +static struct n32_tim_priv_s n32_gtima4_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMA, + .base = N32_GTIMERA4_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA5 +static struct n32_tim_priv_s n32_gtima5_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMA, + .base = N32_GTIMERA5_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA6 +static struct n32_tim_priv_s n32_gtima6_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMA, + .base = N32_GTIMERA6_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA7 +static struct n32_tim_priv_s n32_gtima7_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMA, + .base = N32_GTIMERA7_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +/* Timer private structures - GTIMB1-3 */ + +#ifdef CONFIG_N32H7_GTIMB1 +static struct n32_tim_priv_s n32_gtimb1_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMB, + .base = N32_GTIMERB1_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB2 +static struct n32_tim_priv_s n32_gtimb2_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMB, + .base = N32_GTIMERB2_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB3 +static struct n32_tim_priv_s n32_gtimb3_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_GTIMB, + .base = N32_GTIMERB3_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +/* Timer private structures - BTIM1-4 */ + +#ifdef CONFIG_N32H7_BTIM1 +static struct n32_tim_priv_s n32_btim1_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_BTIM, + .base = N32_BTIMER1_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_BTIM2 +static struct n32_tim_priv_s n32_btim2_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_BTIM, + .base = N32_BTIMER2_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_BTIM3 +static struct n32_tim_priv_s n32_btim3_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_BTIM, + .base = N32_BTIMER3_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +#ifdef CONFIG_N32H7_BTIM4 +static struct n32_tim_priv_s n32_btim4_priv = +{ + .ops = &n32_tim_ops, + .type = TIM_TYPE_BTIM, + .base = N32_BTIMER4_BASE, + .freqin = N32_AHB_FREQUENCY, +}; +#endif + +/* Unified register offsets (same for all timer types) */ + +#define N32_TIM_CTRL1_OFFSET 0x0000 /* Control register 1 */ +#define N32_TIM_CTRL2_OFFSET 0x0004 /* Control register 2 */ +#define N32_TIM_STS_OFFSET 0x0008 /* Status register */ +#define N32_TIM_ETGEN_OFFSET 0x000c /* Event generation register */ +#define N32_TIM_SMCTRL_OFFSET 0x0010 /* Slave mode control (not for BTIM) */ +#define N32_TIM_DINTEN_OFFSET 0x0014 /* DMA/Interrupt enable register */ +#define N32_TIM_CCMOD1_OFFSET 0x0018 /* Capture/compare mode 1 (not for BTIM) */ +#define N32_TIM_CCMOD2_OFFSET 0x001c /* Capture/compare mode 2 (not for BTIM) */ +#define N32_TIM_CCMOD3_OFFSET 0x0020 /* Capture/compare mode 3 (ATIM/GTIMB only) */ +#define N32_TIM_CCEN_OFFSET 0x0024 /* Capture/compare enable (not for BTIM) */ +#define N32_TIM_CCDAT1_OFFSET 0x0028 /* Capture/compare reg 1 (not for BTIM) */ +#define N32_TIM_CCDAT2_OFFSET 0x002c /* Capture/compare reg 2 (not for BTIM) */ +#define N32_TIM_CCDAT3_OFFSET 0x0030 /* Capture/compare reg 3 (not for BTIM) */ +#define N32_TIM_CCDAT4_OFFSET 0x0034 /* Capture/compare reg 4 (not for BTIM) */ +#define N32_TIM_PSC_OFFSET 0x0040 /* Prescaler */ +#define N32_TIM_AR_OFFSET 0x0044 /* Auto-reload register */ +#define N32_TIM_CNT_OFFSET 0x0048 /* Counter */ +#define N32_TIM_BKDT_OFFSET 0x0050 /* Break/dead-time (ATIM/GTIMB only) */ + +/* Helper macros for register access */ + +#define n32_getreg16(dev, off) getreg16(((struct n32_tim_priv_s *)dev)->base + (off)) +#define n32_putreg16(dev, off, v) putreg16((v), ((struct n32_tim_priv_s *)dev)->base + (off)) +#define n32_modreg16(dev, off, c, s) modifyreg16(((struct n32_tim_priv_s *)dev)->base + (off), (c), (s)) + +#define n32_getreg32(dev, off) getreg32(((struct n32_tim_priv_s *)dev)->base + (off)) +#define n32_putreg32(dev, off, v) putreg32((v), ((struct n32_tim_priv_s *)dev)->base + (off)) +#define n32_modreg32(dev, off, c, s) modifyreg32(((struct n32_tim_priv_s *)dev)->base + (off), (c), (s)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_tim_is_btim + * + * Description: + * Check if the timer is a basic timer (BTIM). + * + ****************************************************************************/ + +static inline bool n32_tim_is_btim(struct n32_tim_dev_s *dev) +{ + return ((struct n32_tim_priv_s *)dev)->type == TIM_TYPE_BTIM; +} + +/**************************************************************************** + * Name: n32_tim_is_atim + * + * Description: + * Check if the timer is an advanced timer (ATIM). + * + ****************************************************************************/ + +static inline bool n32_tim_is_atim(struct n32_tim_dev_s *dev) +{ + return ((struct n32_tim_priv_s *)dev)->type == TIM_TYPE_ATIM; +} + +/**************************************************************************** + * Name: n32_tim_is_gtimb + * + * Description: + * Check if the timer is a GTIMB timer. + * + ****************************************************************************/ + +static inline bool n32_tim_is_gtimb(struct n32_tim_dev_s *dev) +{ + return ((struct n32_tim_priv_s *)dev)->type == TIM_TYPE_GTIMB; +} + +/**************************************************************************** + * Name: n32_tim_get_width + * + * Description: + * Determine the counter width (16 or 32 bits) for the timer. + * + ****************************************************************************/ + +static inline int n32_tim_get_width(struct n32_tim_dev_s *dev) +{ + /* Only BTIM timers are 32-bit */ + + if (n32_tim_is_btim(dev)) + { + return 32; + } + + return 16; +} + +/**************************************************************************** + * Name: n32_tim_reload_counter + * + * Description: + * Generate an update event to reload the counter. + * + ****************************************************************************/ + +static void n32_tim_reload_counter(struct n32_tim_dev_s *dev) +{ + n32_putreg16(dev, N32_TIM_ETGEN_OFFSET, N32_ATIM_ETGEN_UDGN); +} + +/**************************************************************************** + * Name: n32_tim_enable + * + * Description: + * Enable the timer counter. + * + ****************************************************************************/ + +static void n32_tim_enable(struct n32_tim_dev_s *dev) +{ + uint32_t regval; + + regval = n32_getreg32(dev, N32_TIM_CTRL1_OFFSET); + regval |= N32_ATIM_CTRL1_CNTEN; + + /* For ATIM, also set MOE (Main Output Enable) */ + + if (n32_tim_is_atim(dev)) + { + n32_modreg32(dev, N32_TIM_BKDT_OFFSET, 0, N32_ATIM_BKDT_MOEN); + } + + n32_tim_reload_counter(dev); + n32_putreg32(dev, N32_TIM_CTRL1_OFFSET, regval); +} + +/**************************************************************************** + * Name: n32_tim_disable + * + * Description: + * Disable the timer counter. + * + ****************************************************************************/ + +static void n32_tim_disable(struct n32_tim_dev_s *dev) +{ + uint32_t regval; + + regval = n32_getreg32(dev, N32_TIM_CTRL1_OFFSET); + regval &= ~N32_ATIM_CTRL1_CNTEN; + n32_putreg32(dev, N32_TIM_CTRL1_OFFSET, regval); + + /* For ATIM, clear MOE as well */ + + if (n32_tim_is_atim(dev)) + { + n32_modreg32(dev, N32_TIM_BKDT_OFFSET, N32_ATIM_BKDT_MOEN, 0); + } +} + +/**************************************************************************** + * Name: n32_tim_reset + * + * Description: + * Reset the timer to its default state (all relevant registers cleared). + * + ****************************************************************************/ + +static void n32_tim_reset(struct n32_tim_dev_s *dev) +{ + bool is_btim = n32_tim_is_btim(dev); + bool is_atim = n32_tim_is_atim(dev); + + /* Disable counter */ + + n32_tim_disable(dev); + + /* Reset CTRL1: clear all bits except ARPE */ + + n32_putreg32(dev, N32_TIM_CTRL1_OFFSET, N32_ATIM_CTRL1_ARPEN); + + /* Reset CTRL2 */ + + n32_putreg32(dev, N32_TIM_CTRL2_OFFSET, 0); + + /* Clear status register */ + + n32_putreg32(dev, N32_TIM_STS_OFFSET, 0); + + /* Clear event generation register */ + + n32_putreg32(dev, N32_TIM_ETGEN_OFFSET, 0); + + /* Reset DIER (all interrupts/DMA disabled) */ + + n32_putreg32(dev, N32_TIM_DINTEN_OFFSET, 0); + + if (!is_btim) + { + /* Reset CCMOD1 and CCMOD2 */ + + n32_putreg32(dev, N32_TIM_CCMOD1_OFFSET, 0); + n32_putreg32(dev, N32_TIM_CCMOD2_OFFSET, 0); + + /* Reset CCEN */ + + n32_putreg32(dev, N32_TIM_CCEN_OFFSET, 0); + + /* Reset CCR1-4 */ + + n32_putreg32(dev, N32_TIM_CCDAT1_OFFSET, 0); + n32_putreg32(dev, N32_TIM_CCDAT2_OFFSET, 0); + n32_putreg32(dev, N32_TIM_CCDAT3_OFFSET, 0); + n32_putreg32(dev, N32_TIM_CCDAT4_OFFSET, 0); + + /* Reset SMCTRL */ + + n32_putreg32(dev, N32_TIM_SMCTRL_OFFSET, 0); + + /* CCMOD3 exists for ATIM and GTIMB */ + + if (is_atim || n32_tim_is_gtimb(dev)) + { + n32_putreg32(dev, N32_TIM_CCMOD3_OFFSET, 0); + } + + /* BKDT exists for ATIM and GTIMB */ + + if (is_atim || n32_tim_is_gtimb(dev)) + { + n32_putreg32(dev, N32_TIM_BKDT_OFFSET, 0); + } + } + + /* Reset prescaler */ + + n32_putreg32(dev, N32_TIM_PSC_OFFSET, 0); + + /* Reset ARR to max value (16-bit or 32-bit) */ + + if (is_btim) + { + n32_putreg32(dev, N32_TIM_AR_OFFSET, 0xffffffff); + } + else + { + n32_putreg32(dev, N32_TIM_AR_OFFSET, 0xffff); + } + + /* Reset counter */ + + n32_putreg32(dev, N32_TIM_CNT_OFFSET, 0); + + /* For BTIM, PSC and ARR are 32-bit registers */ + + if (is_btim) + { + /* BTIM PSC is 16-bit, ARR is 32-bit, CNT is 32-bit */ + } +} + +/**************************************************************************** + * Name: n32_tim_setmode + * + * Description: + * Set the timer counting mode. + * + ****************************************************************************/ + +static int n32_tim_setmode(struct n32_tim_dev_s *dev, n32_tim_mode_t mode) +{ + uint32_t val = N32_ATIM_CTRL1_CNTEN | N32_ATIM_CTRL1_ARPEN; + + DEBUGASSERT(dev != NULL); + + /* BTIM does not support mode setting */ + + if (n32_tim_is_btim(dev) && (mode & ~N32_TIM_MODE_UP)) + { + return -EINVAL; + } + + switch (mode & N32_TIM_MODE_MASK) + { + case N32_TIM_MODE_DISABLED: + val &= ~N32_ATIM_CTRL1_CNTEN; + break; + + case N32_TIM_MODE_DOWN: + val |= N32_ATIM_CTRL1_DIR; + + /* Fall through */ + + case N32_TIM_MODE_UP: + break; + + case N32_TIM_MODE_UPDOWN: + val |= N32_ATIM_CTRL1_CENTER1; + break; + + case N32_TIM_MODE_PULSE: + val |= N32_ATIM_CTRL1_ONEPM; + break; + + default: + return -EINVAL; + } + + n32_tim_reload_counter(dev); + n32_tim_ackint(dev, N32_ATIM_STS_UDITF); + n32_putreg32(dev, N32_TIM_CTRL1_OFFSET, val); + + /* For ATIM, ensure MOE is set when counter is enabled */ + + if (n32_tim_is_atim(dev)) + { + n32_modreg32(dev, N32_TIM_BKDT_OFFSET, 0, N32_ATIM_BKDT_MOEN); + } + + return OK; +} + +/**************************************************************************** + * Name: n32_tim_setclock + * + * Description: + * Set the timer clock frequency by configuring the prescaler. + * + * Timer core clock is AHB frequency (300 MHz) for all timers. + * + ****************************************************************************/ + +static int n32_tim_setclock(struct n32_tim_dev_s *dev, uint32_t freq) +{ + struct n32_tim_priv_s *priv = (struct n32_tim_priv_s *)dev; + uint32_t freqin; + uint32_t prescaler; + uint32_t psc_mask; + + DEBUGASSERT(dev != NULL); + + /* If frequency is 0, disable the timer */ + + if (freq == 0) + { + n32_tim_disable(dev); + return 0; + } + + /* All timers use AHB clock as their core clock */ + + freqin = priv->freqin; + + /* Calculate prescaler value */ + + prescaler = freqin / freq; + + /* Decrement by 1 (pre-scaler value is PSC+1) */ + + if (prescaler > 0) + { + prescaler--; + } + + /* Check for overflow (16-bit prescaler for all timer types) */ + + psc_mask = 0xffff; + if (prescaler > psc_mask) + { + prescaler = psc_mask; + } + + n32_putreg32(dev, N32_TIM_PSC_OFFSET, prescaler); + + return prescaler; +} + +/**************************************************************************** + * Name: n32_tim_setperiod + * + * Description: + * Set the auto-reload value (period). + * + ****************************************************************************/ + +static void n32_tim_setperiod(struct n32_tim_dev_s *dev, uint32_t period) +{ + bool is_btim = n32_tim_is_btim(dev); + uint32_t max_period; + + DEBUGASSERT(dev != NULL); + + max_period = is_btim ? 0xffffffff : 0xffff; + + if (period > max_period) + { + period = max_period; + } + + n32_putreg32(dev, N32_TIM_AR_OFFSET, period); +} + +/**************************************************************************** + * Name: n32_tim_getperiod + * + * Description: + * Get the current period value. + * + ****************************************************************************/ + +static uint32_t n32_tim_getperiod(struct n32_tim_dev_s *dev) +{ + DEBUGASSERT(dev != NULL); + + return n32_getreg32(dev, N32_TIM_AR_OFFSET); +} + +/**************************************************************************** + * Name: n32_tim_getcounter + * + * Description: + * Read the current counter value. + * + ****************************************************************************/ + +static uint32_t n32_tim_getcounter(struct n32_tim_dev_s *dev) +{ + DEBUGASSERT(dev != NULL); + + if (n32_tim_is_btim(dev)) + { + return n32_getreg32(dev, N32_TIM_CNT_OFFSET); + } + else + { + return n32_getreg16(dev, N32_TIM_CNT_OFFSET); + } +} + +/**************************************************************************** + * Name: n32_tim_setcounter + * + * Description: + * Set the counter value. + * + ****************************************************************************/ + +static void n32_tim_setcounter(struct n32_tim_dev_s *dev, uint32_t count) +{ + DEBUGASSERT(dev != NULL); + + if (n32_tim_is_btim(dev)) + { + n32_putreg32(dev, N32_TIM_CNT_OFFSET, count); + } + else + { + n32_putreg16(dev, N32_TIM_CNT_OFFSET, (uint16_t)count); + } +} + +/**************************************************************************** + * Name: n32_tim_getwidth + * + * Description: + * Get the counter width in bits. + * + ****************************************************************************/ + +static int n32_tim_getwidth(struct n32_tim_dev_s *dev) +{ + return n32_tim_get_width(dev); +} + +/**************************************************************************** + * Name: n32_tim_gpioconfig + * + * Description: + * Configure or unconfigure a GPIO pin for timer output. + * + ****************************************************************************/ + +#if defined(HAVE_ATIM1_GPIOCONFIG) || defined(HAVE_ATIM2_GPIOCONFIG) || \ + defined(HAVE_ATIM3_GPIOCONFIG) || defined(HAVE_ATIM4_GPIOCONFIG) || \ + defined(HAVE_GTIMA1_GPIOCONFIG) || defined(HAVE_GTIMA2_GPIOCONFIG) || \ + defined(HAVE_GTIMA3_GPIOCONFIG) || defined(HAVE_GTIMA4_GPIOCONFIG) || \ + defined(HAVE_GTIMA5_GPIOCONFIG) || defined(HAVE_GTIMA6_GPIOCONFIG) || \ + defined(HAVE_GTIMA7_GPIOCONFIG) || defined(HAVE_GTIMB1_GPIOCONFIG) || \ + defined(HAVE_GTIMB2_GPIOCONFIG) || defined(HAVE_GTIMB3_GPIOCONFIG) + +static void n32_tim_gpioconfig(uint32_t cfg, n32_tim_channel_t mode) +{ + if (mode & N32_TIM_CH_MODE_MASK) + { + n32_configgpio(cfg); + } + else + { + n32_unconfiggpio(cfg); + } +} +#endif + +/**************************************************************************** + * Name: n32_tim_setchannel + * + * Description: + * Configure a timer channel for output or input. + * + ****************************************************************************/ + +static int n32_tim_setchannel(struct n32_tim_dev_s *dev, + uint8_t channel, n32_tim_channel_t mode) +{ + struct n32_tim_priv_s *priv = (struct n32_tim_priv_s *)dev; + uint32_t ccmr_orig; + uint32_t ccmr_val; + uint32_t ccmr_mask; + uint32_t ccmr_offset; + uint32_t ccer_val; + uint32_t ccer_shift; + uint32_t ccmr_mode_shift; + uint32_t oc_pe_bit; + uint32_t ccen_bit; + + DEBUGASSERT(dev != NULL); + + /* BTIM does not support channels */ + + if (n32_tim_is_btim(dev)) + { + return -EINVAL; + } + + /* Channel numbering: 1..4 (or more for ATIM/GTIMB) */ + + if (channel < 1 || channel > 4) + { + /* For now, only support channels 1-4 */ + + return -EINVAL; + } + + ccer_val = n32_getreg32(dev, N32_TIM_CCEN_OFFSET); + ccer_shift = (uint32_t)(channel - 1) * 4; + ccen_bit = N32_ATIM_CCEN_CC1EN << ccer_shift; + + /* Determine CCMOD register and shift */ + + if (channel <= 2) + { + ccmr_offset = N32_TIM_CCMOD1_OFFSET; + ccmr_mode_shift = (channel == 1) ? 0 : (N32_ATIM_CCMOD1_OC2MD_SHIFT - + N32_ATIM_CCMOD1_OC1MD_SHIFT); + oc_pe_bit = (channel == 1) ? N32_ATIM_CCMOD1_OC1PEN : + N32_ATIM_CCMOD1_OC2PEN; + } + else + { + ccmr_offset = N32_TIM_CCMOD2_OFFSET; + ccmr_mode_shift = (channel == 3) ? 0 : (N32_ATIM_CCMOD2_OC4MD_SHIFT - + N32_ATIM_CCMOD2_OC3MD_SHIFT); + oc_pe_bit = (channel == 3) ? N32_ATIM_CCMOD2_OC3PEN : + N32_ATIM_CCMOD2_OC4PEN; + } + + /* Clear channel enable bit */ + + ccer_val &= ~ccen_bit; + ccer_val &= ~(N32_ATIM_CCEN_CC1P << ccer_shift); + + /* Default: channel disabled */ + + ccmr_val = 0; + ccmr_mask = 0xff << ccmr_mode_shift; + + /* Decode channel mode */ + + switch (mode & N32_TIM_CH_MODE_MASK) + { + case N32_TIM_CH_DISABLED: + break; + + case N32_TIM_CH_OUTTOGGLE: + ccmr_val = (N32_ATIM_CCMOD1_OCMODE_TOGGLE << ccmr_mode_shift) | + oc_pe_bit; + ccer_val |= ccen_bit; + break; + + case N32_TIM_CH_OUTPWM: + ccmr_val = (N32_ATIM_CCMOD1_OCMODE_PWM1 << ccmr_mode_shift) | + oc_pe_bit; + ccer_val |= ccen_bit; + break; + + default: + return -EINVAL; + } + + /* Set polarity (negative if requested) */ + + if (mode & N32_TIM_CH_POLARITY_NEG) + { + ccer_val |= (N32_ATIM_CCEN_CC1P << ccer_shift); + } + + /* Write CCMOD */ + + ccmr_orig = n32_getreg32(dev, ccmr_offset); + ccmr_orig &= ~ccmr_mask; + ccmr_orig |= ccmr_val; + n32_putreg32(dev, ccmr_offset, ccmr_orig); + + /* Write CCEN */ + + n32_putreg32(dev, N32_TIM_CCEN_OFFSET, ccer_val); + + /* Configure GPIO */ + + switch (priv->base) + { +#ifdef CONFIG_N32H7_ATIM1 + case N32_ATIMER1_BASE: + switch (channel) + { +# if defined(GPIO_ATIM1_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_ATIM1_CH1OUT, mode); + break; +# endif +# if defined(GPIO_ATIM1_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_ATIM1_CH2OUT, mode); + break; +# endif +# if defined(GPIO_ATIM1_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_ATIM1_CH3OUT, mode); + break; +# endif +# if defined(GPIO_ATIM1_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_ATIM1_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_ATIM2 + case N32_ATIMER2_BASE: + switch (channel) + { +# if defined(GPIO_ATIM2_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_ATIM2_CH1OUT, mode); + break; +# endif +# if defined(GPIO_ATIM2_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_ATIM2_CH2OUT, mode); + break; +# endif +# if defined(GPIO_ATIM2_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_ATIM2_CH3OUT, mode); + break; +# endif +# if defined(GPIO_ATIM2_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_ATIM2_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_ATIM3 + case N32_ATIMER3_BASE: + switch (channel) + { +# if defined(GPIO_ATIM3_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_ATIM3_CH1OUT, mode); + break; +# endif +# if defined(GPIO_ATIM3_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_ATIM3_CH2OUT, mode); + break; +# endif +# if defined(GPIO_ATIM3_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_ATIM3_CH3OUT, mode); + break; +# endif +# if defined(GPIO_ATIM3_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_ATIM3_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_ATIM4 + case N32_ATIMER4_BASE: + switch (channel) + { +# if defined(GPIO_ATIM4_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_ATIM4_CH1OUT, mode); + break; +# endif +# if defined(GPIO_ATIM4_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_ATIM4_CH2OUT, mode); + break; +# endif +# if defined(GPIO_ATIM4_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_ATIM4_CH3OUT, mode); + break; +# endif +# if defined(GPIO_ATIM4_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_ATIM4_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA1 + case N32_GTIMERA1_BASE: + switch (channel) + { +# if defined(GPIO_GTIMA1_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMA1_CH1OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA1_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMA1_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA1_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMA1_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA1_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMA1_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA2 + case N32_GTIMERA2_BASE: + switch (channel) + { +# if defined(GPIO_GTIMA2_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMA2_CH1OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA2_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMA2_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA2_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMA2_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA2_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMA2_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA3 + case N32_GTIMERA3_BASE: + switch (channel) + { +# if defined(GPIO_GTIMA3_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMA3_CH1OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA3_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMA3_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA3_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMA3_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA3_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMA3_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA4 + case N32_GTIMERA4_BASE: + switch (channel) + { +# if defined(GPIO_GTIMA4_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMA4_CH1OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA4_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMA4_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA4_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMA4_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA4_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMA4_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA5 + case N32_GTIMERA5_BASE: + switch (channel) + { +# if defined(GPIO_GTIMA5_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMA5_CH1OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA5_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMA5_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA5_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMA5_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA5_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMA5_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA6 + case N32_GTIMERA6_BASE: + switch (channel) + { +# if defined(GPIO_GTIMA6_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMA6_CH1OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA6_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMA6_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA6_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMA6_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA6_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMA6_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA7 + case N32_GTIMERA7_BASE: + switch (channel) + { +# if defined(GPIO_GTIMA7_CH1OUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMA7_CH1OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA7_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMA7_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA7_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMA7_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMA7_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMA7_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMB1 + case N32_GTIMERB1_BASE: + switch (channel) + { +# if defined(GPIO_GTIMB1_CH1POUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMB1_CH1POUT, mode); + break; +# endif +# if defined(GPIO_GTIMB1_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMB1_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMB1_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMB1_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMB1_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMB1_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMB2 + case N32_GTIMERB2_BASE: + switch (channel) + { +# if defined(GPIO_GTIMB2_CH1POUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMB2_CH1POUT, mode); + break; +# endif +# if defined(GPIO_GTIMB2_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMB2_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMB2_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMB2_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMB2_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMB2_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMB3 + case N32_GTIMERB3_BASE: + switch (channel) + { +# if defined(GPIO_GTIMB3_CH1POUT) + case 1: + n32_tim_gpioconfig(GPIO_GTIMB3_CH1POUT, mode); + break; +# endif +# if defined(GPIO_GTIMB3_CH2OUT) + case 2: + n32_tim_gpioconfig(GPIO_GTIMB3_CH2OUT, mode); + break; +# endif +# if defined(GPIO_GTIMB3_CH3OUT) + case 3: + n32_tim_gpioconfig(GPIO_GTIMB3_CH3OUT, mode); + break; +# endif +# if defined(GPIO_GTIMB3_CH4OUT) + case 4: + n32_tim_gpioconfig(GPIO_GTIMB3_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + + default: + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: n32_tim_setcompare + * + * Description: + * Set the compare value for a channel. + * + ****************************************************************************/ + +static int n32_tim_setcompare(struct n32_tim_dev_s *dev, + uint8_t channel, uint32_t compare) +{ + uint32_t max_val; + + DEBUGASSERT(dev != NULL); + + /* BTIM does not support channels */ + + if (n32_tim_is_btim(dev)) + { + return -EINVAL; + } + + max_val = n32_tim_get_width(dev) > 16 ? 0xffffffff : 0xffff; + if (compare > max_val) + { + compare = max_val; + } + + switch (channel) + { + case 1: + n32_putreg32(dev, N32_TIM_CCDAT1_OFFSET, compare); + break; + case 2: + n32_putreg32(dev, N32_TIM_CCDAT2_OFFSET, compare); + break; + case 3: + n32_putreg32(dev, N32_TIM_CCDAT3_OFFSET, compare); + break; + case 4: + n32_putreg32(dev, N32_TIM_CCDAT4_OFFSET, compare); + break; + default: + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: n32_tim_getcapture + * + * Description: + * Get the captured value for a channel (input capture mode). + * + ****************************************************************************/ + +static int n32_tim_getcapture(struct n32_tim_dev_s *dev, uint8_t channel) +{ + DEBUGASSERT(dev != NULL); + + /* BTIM does not support capture */ + + if (n32_tim_is_btim(dev)) + { + return -EINVAL; + } + + switch (channel) + { + case 1: + return n32_getreg32(dev, N32_TIM_CCDAT1_OFFSET); + case 2: + return n32_getreg32(dev, N32_TIM_CCDAT2_OFFSET); + case 3: + return n32_getreg32(dev, N32_TIM_CCDAT3_OFFSET); + case 4: + return n32_getreg32(dev, N32_TIM_CCDAT4_OFFSET); + default: + return -EINVAL; + } +} + +/**************************************************************************** + * Name: n32_tim_setisr + * + * Description: + * Attach an interrupt handler to the timer based on the source. + * + * Supported sources (see N32_TIM_ISR_* definitions): + * N32_TIM_ISR_UPDATE - Update event (overflow/underflow) + * N32_TIM_ISR_CC - Capture/Compare event (CC1-CC4) + * N32_TIM_ISR_TRG_COM - Trigger or COM event + * N32_TIM_ISR_BRK - Break event (advanced timers only) + * + * Input Parameters: + * dev - Timer device handle + * handler - Interrupt handler (NULL to detach) + * arg - Argument passed to handler + * source - Bitmask of desired interrupt sources + * (only one bit should be set) + * + * Returned Value: + * OK on success; negated errno on failure. + * + ****************************************************************************/ + +static int n32_tim_setisr(struct n32_tim_dev_s *dev, + xcpt_t handler, void *arg, int source) +{ + struct n32_tim_priv_s *priv = (struct n32_tim_priv_s *)dev; + int irqno = -1; + bool valid_source = false; + + DEBUGASSERT(dev != NULL); + + /* Determine which IRQ number corresponds to the requested source + * based on the timer type and hardware capabilities. + */ + + switch (priv->base) + { +#ifdef CONFIG_N32H7_ATIM1 + case N32_ATIMER1_BASE: + if (source & N32_TIM_ISR_UPDATE) + { + irqno = N32_IRQ_ATIM1_UP; + valid_source = true; + } + else if (source & N32_TIM_ISR_CC) + { + irqno = N32_IRQ_ATIM1_CC; + valid_source = true; + } + else if (source & N32_TIM_ISR_TRG_COM) + { + irqno = N32_IRQ_ATIM1_TRG_COM; + valid_source = true; + } + else if (source & N32_TIM_ISR_BRK) + { + irqno = N32_IRQ_ATIM1_BRK; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_ATIM2 + case N32_ATIMER2_BASE: + if (source & N32_TIM_ISR_UPDATE) + { + irqno = N32_IRQ_ATIM2_UP; + valid_source = true; + } + else if (source & N32_TIM_ISR_CC) + { + irqno = N32_IRQ_ATIM2_CC; + valid_source = true; + } + else if (source & N32_TIM_ISR_TRG_COM) + { + irqno = N32_IRQ_ATIM2_TRG_COM; + valid_source = true; + } + else if (source & N32_TIM_ISR_BRK) + { + irqno = N32_IRQ_ATIM2_BRK; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_ATIM3 + case N32_ATIMER3_BASE: + if (source & N32_TIM_ISR_UPDATE) + { + irqno = N32_IRQ_ATIM3_UP; + valid_source = true; + } + else if (source & N32_TIM_ISR_CC) + { + irqno = N32_IRQ_ATIM3_CC; + valid_source = true; + } + else if (source & N32_TIM_ISR_TRG_COM) + { + irqno = N32_IRQ_ATIM3_TRG_COM; + valid_source = true; + } + else if (source & N32_TIM_ISR_BRK) + { + irqno = N32_IRQ_ATIM3_BRK; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_ATIM4 + case N32_ATIMER4_BASE: + if (source & N32_TIM_ISR_UPDATE) + { + irqno = N32_IRQ_ATIM4_UP; + valid_source = true; + } + else if (source & N32_TIM_ISR_CC) + { + irqno = N32_IRQ_ATIM4_CC; + valid_source = true; + } + else if (source & N32_TIM_ISR_TRG_COM) + { + irqno = N32_IRQ_ATIM4_TRG_COM; + valid_source = true; + } + else if (source & N32_TIM_ISR_BRK) + { + irqno = N32_IRQ_ATIM4_BRK; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA1 + case N32_GTIMERA1_BASE: + + /* GTIMA timers have only one combined interrupt vector */ + + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GTIMA1; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA2 + case N32_GTIMERA2_BASE: + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GTIMA2; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA3 + case N32_GTIMERA3_BASE: + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GIIMA3; /* Note: typo in original */ + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA4 + case N32_GTIMERA4_BASE: + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GTIMA4; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA5 + case N32_GTIMERA5_BASE: + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GTIMA5; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA6 + case N32_GTIMERA6_BASE: + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GTIMA6; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMA7 + case N32_GTIMERA7_BASE: + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GTIMA7; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMB1 + case N32_GTIMERB1_BASE: + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GTIMB1; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMB2 + case N32_GTIMERB2_BASE: + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GTIMB2; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_GTIMB3 + case N32_GTIMERB3_BASE: + if (source & (N32_TIM_ISR_UPDATE | N32_TIM_ISR_CC | + N32_TIM_ISR_TRG_COM | N32_TIM_ISR_BRK)) + { + irqno = N32_IRQ_GTIMB3; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_BTIM1 + case N32_BTIMER1_BASE: + + /* BTIM timers only support update interrupt */ + + if (source & N32_TIM_ISR_UPDATE) + { + irqno = N32_IRQ_BTIM1; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_BTIM2 + case N32_BTIMER2_BASE: + if (source & N32_TIM_ISR_UPDATE) + { + irqno = N32_IRQ_BTIM2; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_BTIM3 + case N32_BTIMER3_BASE: + if (source & N32_TIM_ISR_UPDATE) + { + irqno = N32_IRQ_BTIM3; + valid_source = true; + } + break; +#endif + +#ifdef CONFIG_N32H7_BTIM4 + case N32_BTIMER4_BASE: + if (source & N32_TIM_ISR_UPDATE) + { + irqno = N32_IRQ_BTIM4; + valid_source = true; + } + break; +#endif + + default: + break; + } + + if (!valid_source || irqno < 0) + { + return -EINVAL; + } + + /* If handler is NULL, detach and disable IRQ */ + + if (handler == NULL) + { + up_disable_irq(irqno); + irq_detach(irqno); + return OK; + } + + /* Attach handler and enable IRQ */ + + irq_attach(irqno, handler, arg); + up_enable_irq(irqno); + +#ifdef CONFIG_ARCH_IRQPRIO + up_prioritize_irq(irqno, NVIC_SYSH_HIGH_PRIORITY); +#endif + + return OK; +} + +/**************************************************************************** + * Name: n32_tim_enableint + * + * Description: + * Enable the specified interrupt source. + * + ****************************************************************************/ + +static void n32_tim_enableint(struct n32_tim_dev_s *dev, int source) +{ + DEBUGASSERT(dev != NULL); + n32_modreg32(dev, N32_TIM_DINTEN_OFFSET, 0, source); +} + +/**************************************************************************** + * Name: n32_tim_disableint + * + * Description: + * Disable the specified interrupt source. + * + ****************************************************************************/ + +static void n32_tim_disableint(struct n32_tim_dev_s *dev, int source) +{ + DEBUGASSERT(dev != NULL); + n32_modreg32(dev, N32_TIM_DINTEN_OFFSET, source, 0); +} + +/**************************************************************************** + * Name: n32_tim_checkint + * + * Description: + * Check if the specified interrupt source is pending. + * + ****************************************************************************/ + +static int n32_tim_checkint(struct n32_tim_dev_s *dev, int source) +{ + uint32_t regval; + + DEBUGASSERT(dev != NULL); + regval = n32_getreg32(dev, N32_TIM_STS_OFFSET); + return (regval & source) ? 1 : 0; +} + +/**************************************************************************** + * Name: n32_tim_ackint + * + * Description: + * Acknowledge the specified interrupt source. + * + ****************************************************************************/ + +static void n32_tim_ackint(struct n32_tim_dev_s *dev, int source) +{ + DEBUGASSERT(dev != NULL); + n32_putreg32(dev, N32_TIM_STS_OFFSET, ~source); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_tim_init + * + * Description: + * Initialize a timer device. + * + * Input Parameters: + * timer - Timer number (1-4 for ATIM, 1-7 for GTIMA, etc.) + * Determined by CONFIG_N32H7_TIMx definitions. + * + * Returned Value: + * Pointer to timer device structure, or NULL on failure. + * + ****************************************************************************/ + +struct n32_tim_dev_s *n32_tim_init(int timer) +{ + struct n32_tim_dev_s *dev = NULL; + + /* Select the timer private structure and enable its clock */ + + switch (timer) + { +#ifdef CONFIG_N32H7_ATIM1 + case 1: + dev = (struct n32_tim_dev_s *)&n32_tim1_priv; + modifyreg32(N32_RCC_APB2EN1, 0, RCC_APB2EN1_M7ATIM1EN); + break; +#endif +#ifdef CONFIG_N32H7_ATIM2 + case 2: + dev = (struct n32_tim_dev_s *)&n32_tim2_priv; + modifyreg32(N32_RCC_APB2EN1, 0, RCC_APB2EN1_M7ATIM2EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA1 + case 3: + dev = (struct n32_tim_dev_s *)&n32_gtima1_priv; + modifyreg32(N32_RCC_APB2EN1, 0, RCC_APB2EN1_M7GTIMA1EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA2 + case 4: + dev = (struct n32_tim_dev_s *)&n32_gtima2_priv; + modifyreg32(N32_RCC_APB2EN1, 0, RCC_APB2EN1_M7GTIMA2EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA3 + case 5: + dev = (struct n32_tim_dev_s *)&n32_gtima3_priv; + modifyreg32(N32_RCC_APB2EN1, 0, RCC_APB2EN1_M7GTIMA3EN); + break; +#endif +#ifdef CONFIG_N32H7_ATIM3 + case 6: + dev = (struct n32_tim_dev_s *)&n32_tim3_priv; + modifyreg32(N32_RCC_APB5EN1, 0, RCC_APB5EN1_M7ATIM3EN); + break; +#endif +#ifdef CONFIG_N32H7_ATIM4 + case 7: + dev = (struct n32_tim_dev_s *)&n32_tim4_priv; + modifyreg32(N32_RCC_APB5EN1, 0, RCC_APB5EN1_M7ATIM4EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA4 + case 8: + dev = (struct n32_tim_dev_s *)&n32_gtima4_priv; + modifyreg32(N32_RCC_APB1EN1, 0, RCC_APB1EN1_M7GTIMA4EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA5 + case 9: + dev = (struct n32_tim_dev_s *)&n32_gtima5_priv; + modifyreg32(N32_RCC_APB1EN2, 0, RCC_APB1EN2_M7GTIMA5EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA6 + case 10: + dev = (struct n32_tim_dev_s *)&n32_gtima6_priv; + modifyreg32(N32_RCC_APB1EN2, 0, RCC_APB1EN2_M7GTIMA6EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA7 + case 11: + dev = (struct n32_tim_dev_s *)&n32_gtima7_priv; + modifyreg32(N32_RCC_APB1EN2, 0, RCC_APB1EN2_M7GTIMA7EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMB1 + case 12: + dev = (struct n32_tim_dev_s *)&n32_gtimb1_priv; + modifyreg32(N32_RCC_APB1EN1, 0, RCC_APB1EN1_M7GTIMB1EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMB2 + case 13: + dev = (struct n32_tim_dev_s *)&n32_gtimb2_priv; + modifyreg32(N32_RCC_APB1EN1, 0, RCC_APB1EN1_M7GTIMB2EN); + break; +#endif +#ifdef CONFIG_N32H7_GTIMB3 + case 14: + dev = (struct n32_tim_dev_s *)&n32_gtimb3_priv; + modifyreg32(N32_RCC_APB1EN1, 0, RCC_APB1EN1_M7GTIMB3EN); + break; +#endif +#ifdef CONFIG_N32H7_BTIM1 + case 15: + dev = (struct n32_tim_dev_s *)&n32_btim1_priv; + modifyreg32(N32_RCC_APB1EN1, 0, RCC_APB1EN1_M7BTIM1EN); + break; +#endif +#ifdef CONFIG_N32H7_BTIM2 + case 16: + dev = (struct n32_tim_dev_s *)&n32_btim2_priv; + modifyreg32(N32_RCC_APB1EN1, 0, RCC_APB1EN1_M7BTIM2EN); + break; +#endif +#ifdef CONFIG_N32H7_BTIM3 + case 17: + dev = (struct n32_tim_dev_s *)&n32_btim3_priv; + modifyreg32(N32_RCC_APB1EN1, 0, RCC_APB1EN1_M7BTIM3EN); + break; +#endif +#ifdef CONFIG_N32H7_BTIM4 + case 18: + dev = (struct n32_tim_dev_s *)&n32_btim4_priv; + modifyreg32(N32_RCC_APB1EN1, 0, RCC_APB1EN1_M7BTIM4EN); + break; +#endif + default: + return NULL; + } + + /* Reset the timer to a known state */ + + n32_tim_reset(dev); + + return dev; +} + +/**************************************************************************** + * Name: n32_tim_deinit + * + * Description: + * De-initialize a timer device. + * + * Input Parameters: + * dev - Timer device structure. + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +int n32_tim_deinit(struct n32_tim_dev_s *dev) +{ + struct n32_tim_priv_s *priv = (struct n32_tim_priv_s *)dev; + uint32_t base; + + DEBUGASSERT(dev != NULL); + + base = priv->base; + + /* Disable the timer */ + + n32_tim_disable(dev); + + /* Reset to default state */ + + n32_tim_reset(dev); + + /* Disable the clock */ + + switch (base) + { +#ifdef CONFIG_N32H7_ATIM1 + case N32_ATIMER1_BASE: + modifyreg32(N32_RCC_APB2EN1, RCC_APB2EN1_M7ATIM1EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_ATIM2 + case N32_ATIMER2_BASE: + modifyreg32(N32_RCC_APB2EN1, RCC_APB2EN1_M7ATIM2EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_ATIM3 + case N32_ATIMER3_BASE: + modifyreg32(N32_RCC_APB5EN1, RCC_APB5EN1_M7ATIM3EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_ATIM4 + case N32_ATIMER4_BASE: + modifyreg32(N32_RCC_APB5EN1, RCC_APB5EN1_M7ATIM4EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA1 + case N32_GTIMERA1_BASE: + modifyreg32(N32_RCC_APB2EN1, RCC_APB2EN1_M7GTIMA1EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA2 + case N32_GTIMERA2_BASE: + modifyreg32(N32_RCC_APB2EN1, RCC_APB2EN1_M7GTIMA2EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA3 + case N32_GTIMERA3_BASE: + modifyreg32(N32_RCC_APB2EN1, RCC_APB2EN1_M7GTIMA3EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA4 + case N32_GTIMERA4_BASE: + modifyreg32(N32_RCC_APB1EN1, RCC_APB1EN1_M7GTIMA4EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA5 + case N32_GTIMERA5_BASE: + modifyreg32(N32_RCC_APB1EN2, RCC_APB1EN2_M7GTIMA5EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA6 + case N32_GTIMERA6_BASE: + modifyreg32(N32_RCC_APB1EN2, RCC_APB1EN2_M7GTIMA6EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMA7 + case N32_GTIMERA7_BASE: + modifyreg32(N32_RCC_APB1EN2, RCC_APB1EN2_M7GTIMA7EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMB1 + case N32_GTIMERB1_BASE: + modifyreg32(N32_RCC_APB1EN1, RCC_APB1EN1_M7GTIMB1EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMB2 + case N32_GTIMERB2_BASE: + modifyreg32(N32_RCC_APB1EN1, RCC_APB1EN1_M7GTIMB2EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_GTIMB3 + case N32_GTIMERB3_BASE: + modifyreg32(N32_RCC_APB1EN1, RCC_APB1EN1_M7GTIMB3EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_BTIM1 + case N32_BTIMER1_BASE: + modifyreg32(N32_RCC_APB1EN1, RCC_APB1EN1_M7BTIM1EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_BTIM2 + case N32_BTIMER2_BASE: + modifyreg32(N32_RCC_APB1EN1, RCC_APB1EN1_M7BTIM2EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_BTIM3 + case N32_BTIMER3_BASE: + modifyreg32(N32_RCC_APB1EN1, RCC_APB1EN1_M7BTIM3EN, 0); + break; +#endif +#ifdef CONFIG_N32H7_BTIM4 + case N32_BTIMER4_BASE: + modifyreg32(N32_RCC_APB1EN1, RCC_APB1EN1_M7BTIM4EN, 0); + break; +#endif + default: + return -EINVAL; + } + + return OK; +} + +#endif /* defined(CONFIG_N32H7_ATIM1 || ... || CONFIG_N32H7_BTIM4) */ diff --git a/arch/arm/src/n32h7/n32_tim.h b/arch/arm/src/n32h7/n32_tim.h new file mode 100644 index 0000000000000..da0c71249183b --- /dev/null +++ b/arch/arm/src/n32h7/n32_tim.h @@ -0,0 +1,232 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_tim.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_TIM_H +#define __ARCH_ARM_SRC_N32H7_N32_TIM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "hardware/n32h7_tim.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Helpers for timer driver operations **************************************/ + +#define N32_TIM_SETMODE(d, mode) ((d)->ops->setmode(d, mode)) +#define N32_TIM_SETCLOCK(d, freq) ((d)->ops->setclock(d, freq)) +#define N32_TIM_SETPERIOD(d, period) ((d)->ops->setperiod(d, period)) +#define N32_TIM_GETPERIOD(d) ((d)->ops->getperiod(d)) +#define N32_TIM_GETCOUNTER(d) ((d)->ops->getcounter(d)) +#define N32_TIM_SETCOUNTER(d, c) ((d)->ops->setcounter(d, c)) +#define N32_TIM_GETWIDTH(d) ((d)->ops->getwidth(d)) +#define N32_TIM_SETCHANNEL(d, ch, m) ((d)->ops->setchannel(d, ch, m)) +#define N32_TIM_SETCOMPARE(d, ch, c) ((d)->ops->setcompare(d, ch, c)) +#define N32_TIM_GETCAPTURE(d, ch) ((d)->ops->getcapture(d, ch)) +#define N32_TIM_SETISR(d, h, a, s) ((d)->ops->setisr(d, h, a, s)) +#define N32_TIM_ENABLEINT(d, s) ((d)->ops->enableint(d, s)) +#define N32_TIM_DISABLEINT(d, s) ((d)->ops->disableint(d, s)) +#define N32_TIM_ACKINT(d, s) ((d)->ops->ackint(d, s)) +#define N32_TIM_CHECKINT(d, s) ((d)->ops->checkint(d, s)) +#define N32_TIM_ENABLE(d) ((d)->ops->enable(d)) +#define N32_TIM_DISABLE(d) ((d)->ops->disable(d)) + +/* Timer interrupt sources for use with N32_TIM_SETISR */ +#define N32_TIM_ISR_UPDATE (1 << 0) /* Update interrupt (overflow/underflow) */ +#define N32_TIM_ISR_CC (1 << 1) /* Capture/Compare interrupt (CC1-CC4) */ +#define N32_TIM_ISR_TRG_COM (1 << 2) /* Trigger and COM interrupt */ +#define N32_TIM_ISR_BRK (1 << 3) /* Break interrupt (only ATIM) */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Forward reference */ + +struct n32_tim_dev_s; + +/* Timer modes of operation */ + +typedef enum +{ + N32_TIM_MODE_UNUSED = -1, + + /* One of the following */ + + N32_TIM_MODE_MASK = 0x0310, + N32_TIM_MODE_DISABLED = 0x0000, + N32_TIM_MODE_UP = 0x0100, + N32_TIM_MODE_DOWN = 0x0110, + N32_TIM_MODE_UPDOWN = 0x0200, + N32_TIM_MODE_PULSE = 0x0300, + + /* Clock source options (not fully supported in this version) */ + + N32_TIM_MODE_CK_INT = 0x0000, +} n32_tim_mode_t; + +/* Timer channel modes */ + +typedef enum +{ + N32_TIM_CH_DISABLED = 0x00, + + /* Common configuration */ + + N32_TIM_CH_POLARITY_POS = 0x00, + N32_TIM_CH_POLARITY_NEG = 0x01, + + /* MODES: */ + + N32_TIM_CH_MODE_MASK = 0x0e, + + /* Output compare modes */ + + N32_TIM_CH_OUTPWM = 0x04, /* PWM mode 1 (active high) */ + N32_TIM_CH_OUTTOGGLE = 0x08, /* Toggle on match */ +} n32_tim_channel_t; + +/* Timer operations structure */ + +struct n32_tim_ops_s +{ + /* Basic timer operations */ + + void (*enable)(struct n32_tim_dev_s *dev); + void (*disable)(struct n32_tim_dev_s *dev); + int (*setmode)(struct n32_tim_dev_s *dev, n32_tim_mode_t mode); + int (*setclock)(struct n32_tim_dev_s *dev, uint32_t freq); + void (*setperiod)(struct n32_tim_dev_s *dev, uint32_t period); + uint32_t (*getperiod)(struct n32_tim_dev_s *dev); + uint32_t (*getcounter)(struct n32_tim_dev_s *dev); + void (*setcounter)(struct n32_tim_dev_s *dev, uint32_t count); + + /* General and advanced timers */ + + int (*getwidth)(struct n32_tim_dev_s *dev); + int (*setchannel)(struct n32_tim_dev_s *dev, uint8_t channel, + n32_tim_channel_t mode); + int (*setcompare)(struct n32_tim_dev_s *dev, uint8_t channel, + uint32_t compare); + int (*getcapture)(struct n32_tim_dev_s *dev, uint8_t channel); + + /* Timer interrupts */ + + int (*setisr)(struct n32_tim_dev_s *dev, xcpt_t handler, void *arg, + int source); + void (*enableint)(struct n32_tim_dev_s *dev, int source); + void (*disableint)(struct n32_tim_dev_s *dev, int source); + void (*ackint)(struct n32_tim_dev_s *dev, int source); + int (*checkint)(struct n32_tim_dev_s *dev, int source); +}; + +/* Timer device structure (public) */ + +struct n32_tim_dev_s +{ + const struct n32_tim_ops_s *ops; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_tim_init + * + * Description: + * Initialize a timer device and enable its clock. + * + * Input Parameters: + * timer - Timer number (1-18, as defined by the configuration). + * The mapping is determined by CONFIG_N32H7_ATIMx, + * CONFIG_N32H7_GTIMAx, CONFIG_N32H7_GTIMBx, CONFIG_N32H7_BTIMx. + * + * Returned Value: + * Pointer to the timer device structure, or NULL on failure. + * + ****************************************************************************/ + +struct n32_tim_dev_s *n32_tim_init(int timer); + +/**************************************************************************** + * Name: n32_tim_deinit + * + * Description: + * De-initialize a timer device, disable its clock, and reset it. + * + * Input Parameters: + * dev - Timer device structure. + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +int n32_tim_deinit(struct n32_tim_dev_s *dev); + +/**************************************************************************** + * Name: n32_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 Values: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_TIMER +int n32_timer_initialize(const char *devpath, int timer); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_TIM_H */ diff --git a/arch/arm/src/n32h7/n32_tim_lowerhalf.c b/arch/arm/src/n32h7/n32_tim_lowerhalf.c new file mode 100644 index 0000000000000..2de01ad7335a2 --- /dev/null +++ b/arch/arm/src/n32h7/n32_tim_lowerhalf.c @@ -0,0 +1,621 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_tim_lowerhalf.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include +#include + +#include + +#include "n32_tim.h" + +#if defined(CONFIG_TIMER) && \ + (defined(CONFIG_N32H7_ATIM1) || defined(CONFIG_N32H7_ATIM2) || \ + defined(CONFIG_N32H7_ATIM3) || defined(CONFIG_N32H7_ATIM4) || \ + defined(CONFIG_N32H7_GTIMA1) || defined(CONFIG_N32H7_GTIMA2) || \ + defined(CONFIG_N32H7_GTIMA3) || defined(CONFIG_N32H7_GTIMA4) || \ + defined(CONFIG_N32H7_GTIMA5) || defined(CONFIG_N32H7_GTIMA6) || \ + defined(CONFIG_N32H7_GTIMA7) || defined(CONFIG_N32H7_GTIMB1) || \ + defined(CONFIG_N32H7_GTIMB2) || defined(CONFIG_N32H7_GTIMB3) || \ + defined(CONFIG_N32H7_BTIM1) || defined(CONFIG_N32H7_BTIM2) || \ + defined(CONFIG_N32H7_BTIM3) || defined(CONFIG_N32H7_BTIM4)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Interrupt source for timer upper half (update interrupt) */ + +#define N32_TIM_UIE N32_ATIM_DINTEN_UIEN +#define N32_TIM_UIF N32_ATIM_STS_UDITF + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure provides the private representation of the "lower-half" + * driver state structure. + */ + +struct n32_lowerhalf_s +{ + const struct timer_ops_s *ops; /* Lower half operations */ + struct n32_tim_dev_s *tim; /* N32 timer driver */ + tccb_t callback; /* Current user interrupt callback */ + 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 + ****************************************************************************/ + +static int n32_timer_handler(int irq, void *context, void *arg); + +/* "Lower half" driver methods **********************************************/ + +static int n32_start(struct timer_lowerhalf_s *lower); +static int n32_stop(struct timer_lowerhalf_s *lower); +static int n32_getstatus(struct timer_lowerhalf_s *lower, + struct timer_status_s *status); +static int n32_settimeout(struct timer_lowerhalf_s *lower, + uint32_t timeout); +static void n32_setcallback(struct timer_lowerhalf_s *lower, + tccb_t callback, void *arg); +static int n32_maxtimeout(struct timer_lowerhalf_s *lower, + uint32_t *maxtimeout); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* "Lower half" driver methods */ + +static const struct timer_ops_s g_timer_ops = +{ + .start = n32_start, + .stop = n32_stop, + .getstatus = n32_getstatus, + .settimeout = n32_settimeout, + .setcallback = n32_setcallback, + .ioctl = NULL, + .maxtimeout = n32_maxtimeout, + .tick_getstatus = NULL, + .tick_settimeout = NULL, + .tick_maxtimeout = NULL, +}; + +#ifdef CONFIG_N32H7_ATIM1 +static struct n32_lowerhalf_s g_tim1_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, /* ATIM1 is 16-bit */ +}; +#endif + +#ifdef CONFIG_N32H7_ATIM2 +static struct n32_lowerhalf_s g_tim2_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA1 +static struct n32_lowerhalf_s g_gtima1_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA2 +static struct n32_lowerhalf_s g_gtima2_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA3 +static struct n32_lowerhalf_s g_gtima3_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM3 +static struct n32_lowerhalf_s g_tim3_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_ATIM4 +static struct n32_lowerhalf_s g_tim4_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA4 +static struct n32_lowerhalf_s g_gtima4_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA5 +static struct n32_lowerhalf_s g_gtima5_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA6 +static struct n32_lowerhalf_s g_gtima6_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMA7 +static struct n32_lowerhalf_s g_gtima7_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB1 +static struct n32_lowerhalf_s g_gtimb1_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB2 +static struct n32_lowerhalf_s g_gtimb2_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_GTIMB3 +static struct n32_lowerhalf_s g_gtimb3_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 16, +}; +#endif + +#ifdef CONFIG_N32H7_BTIM1 +static struct n32_lowerhalf_s g_btim1_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 32, +}; +#endif + +#ifdef CONFIG_N32H7_BTIM2 +static struct n32_lowerhalf_s g_btim2_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 32, +}; +#endif + +#ifdef CONFIG_N32H7_BTIM3 +static struct n32_lowerhalf_s g_btim3_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 32, +}; +#endif + +#ifdef CONFIG_N32H7_BTIM4 +static struct n32_lowerhalf_s g_btim4_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = 32, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_timer_handler + * + * Description: + * Timer interrupt handler + * + ****************************************************************************/ + +static int n32_timer_handler(int irq, void *context, void *arg) +{ + struct n32_lowerhalf_s *lower = (struct n32_lowerhalf_s *)arg; + uint32_t next_interval_us = 0; + + N32_TIM_ACKINT(lower->tim, N32_TIM_UIF); + + if (lower->callback(&next_interval_us, lower->arg)) + { + if (next_interval_us > 0) + { + N32_TIM_SETPERIOD(lower->tim, next_interval_us); + } + } + else + { + n32_stop((struct timer_lowerhalf_s *)lower); + } + + return OK; +} + +/**************************************************************************** + * Name: n32_start + * + * Description: + * Start the timer, resetting the time to the current timeout. + * + ****************************************************************************/ + +static int n32_start(struct timer_lowerhalf_s *lower) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + + if (!priv->started) + { + N32_TIM_SETMODE(priv->tim, N32_TIM_MODE_UP); + + if (priv->callback != NULL) + { + N32_TIM_SETISR(priv->tim, n32_timer_handler, priv, + N32_TIM_ISR_UPDATE); + N32_TIM_ENABLEINT(priv->tim, N32_TIM_UIE); + } + + priv->started = true; + return OK; + } + + return -EBUSY; +} + +/**************************************************************************** + * Name: n32_stop + * + * Description: + * Stop the timer + * + ****************************************************************************/ + +static int n32_stop(struct timer_lowerhalf_s *lower) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + + if (priv->started) + { + N32_TIM_SETMODE(priv->tim, N32_TIM_MODE_DISABLED); + N32_TIM_DISABLEINT(priv->tim, N32_TIM_UIE); + N32_TIM_SETISR(priv->tim, NULL, NULL, N32_TIM_ISR_UPDATE); + priv->started = false; + return OK; + } + + return -ENODEV; +} + +/**************************************************************************** + * Name: n32_getstatus + * + * Description: + * Get the current timer status. + * + ****************************************************************************/ + +static int n32_getstatus(struct timer_lowerhalf_s *lower, + struct timer_status_s *status) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + + if (status == NULL) + { + return -EINVAL; + } + + memset(status, 0, sizeof(*status)); + + if (priv->started) + { + status->flags |= TCFLAGS_ACTIVE; + } + + if (priv->callback != NULL) + { + status->flags |= TCFLAGS_HANDLER; + } + + status->timeout = N32_TIM_GETPERIOD(priv->tim); + status->timeleft = status->timeout - N32_TIM_GETCOUNTER(priv->tim); + + return OK; +} + +/**************************************************************************** + * Name: n32_settimeout + * + * Description: + * Set a new timeout value (and reset the timer) + * + ****************************************************************************/ + +static int n32_settimeout(struct timer_lowerhalf_s *lower, + uint32_t timeout) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + uint64_t maxtimeout; + + if (priv->started) + { + return -EPERM; + } + + maxtimeout = (1ULL << priv->resolution) - 1; + + /* If timeout exceeds the maximum counter value, scale the clock down */ + + if (timeout > maxtimeout) + { + uint64_t freq = (maxtimeout * 1000000ULL) / timeout; + + N32_TIM_SETCLOCK(priv->tim, (uint32_t)freq); + N32_TIM_SETPERIOD(priv->tim, (uint32_t)maxtimeout); + } + else + { + N32_TIM_SETCLOCK(priv->tim, 1000000); + N32_TIM_SETPERIOD(priv->tim, timeout); + } + + return OK; +} + +/**************************************************************************** + * Name: n32_setcallback + * + * Description: + * Call this user provided timeout callback. + * + ****************************************************************************/ + +static void n32_setcallback(struct timer_lowerhalf_s *lower, + tccb_t callback, void *arg) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + irqstate_t flags; + + flags = enter_critical_section(); + + /* Save the new callback */ + + priv->callback = callback; + priv->arg = arg; + + if (callback != NULL && priv->started) + { + N32_TIM_SETISR(priv->tim, n32_timer_handler, priv, N32_TIM_ISR_UPDATE); + N32_TIM_ENABLEINT(priv->tim, N32_TIM_UIE); + } + else + { + N32_TIM_DISABLEINT(priv->tim, N32_TIM_UIE); + N32_TIM_SETISR(priv->tim, NULL, NULL, N32_TIM_ISR_UPDATE); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: n32_maxtimeout + * + * Description: + * Return the maximum supported timeout value in microseconds. + * + ****************************************************************************/ + +static int n32_maxtimeout(struct timer_lowerhalf_s *lower, + uint32_t *maxtimeout) +{ + struct n32_lowerhalf_s *priv = (struct n32_lowerhalf_s *)lower; + + if (maxtimeout == NULL) + { + return -EINVAL; + } + + *maxtimeout = (1ULL << priv->resolution) - 1; + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + ****************************************************************************/ + +int n32_timer_initialize(const char *devpath, int timer) +{ + struct n32_lowerhalf_s *lower; + + switch (timer) + { +#ifdef CONFIG_N32H7_ATIM1 + case 1: + lower = &g_tim1_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_ATIM2 + case 2: + lower = &g_tim2_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMA1 + case 3: + lower = &g_gtima1_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMA2 + case 4: + lower = &g_gtima2_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMA3 + case 5: + lower = &g_gtima3_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_ATIM3 + case 6: + lower = &g_tim3_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_ATIM4 + case 7: + lower = &g_tim4_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMA4 + case 8: + lower = &g_gtima4_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMA5 + case 9: + lower = &g_gtima5_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMA6 + case 10: + lower = &g_gtima6_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMA7 + case 11: + lower = &g_gtima7_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMB1 + case 12: + lower = &g_gtimb1_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMB2 + case 13: + lower = &g_gtimb2_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_GTIMB3 + case 14: + lower = &g_gtimb3_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_BTIM1 + case 15: + lower = &g_btim1_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_BTIM2 + case 16: + lower = &g_btim2_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_BTIM3 + case 17: + lower = &g_btim3_lowerhalf; + break; +#endif +#ifdef CONFIG_N32H7_BTIM4 + case 18: + lower = &g_btim4_lowerhalf; + break; +#endif + default: + return -ENODEV; + } + + /* Initialize the elements of lower half state structure */ + + lower->started = false; + lower->callback = NULL; + lower->tim = n32_tim_init(timer); + + if (lower->tim == NULL) + { + return -EINVAL; + } + + /* Register the timer driver as /dev/timerX */ + + void *drvr = timer_register(devpath, + (struct timer_lowerhalf_s *)lower); + + if (drvr == NULL) + { + return -EEXIST; + } + + return OK; +} + +#endif /* CONFIG_TIMER && ... */ diff --git a/arch/arm/src/n32h7/n32_timerisr.c b/arch/arm/src/n32h7/n32_timerisr.c new file mode 100644 index 0000000000000..60be549d6fba5 --- /dev/null +++ b/arch/arm/src/n32h7/n32_timerisr.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_timerisr.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "arm_internal.h" +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select MCU-specific settings + * + * The RCC feeds the external clock of 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. + * + * The SysTick calibration value is fixed to 75000, which gives a reference + * time base of 1 ms with the SysTick clock set to 75 MHz (HCLK/8, with + * HCLK set to 600 MHz). + * + * REVISIT: Per ES0392 Rev 4: N32H743xI Errata sheet N32H743xI device + * limitations + * + * SysTick external clock is not HCLK/8 + * Description + * The SysTick external clock is the system clock, instead of the system + * clock divided by 8 (HCLK/8). + * Workaround + * Use the system clock (HCLK) as external clock and multiply the reload + * value by 8 in STK_LOAD register (take care that the maximum value is + * 224-1). + */ + +#undef CONFIG_N32H7_SYSTICK_HCLKd8 + +/* REVISIT: + * It looks like SYSTICK for H7 is always clocked from CPUCLK and doesn't + * depend on the SYSTICK_CTRL_CLKSOURCE bit settings. + */ + +#ifdef CONFIG_N32H7_SYSTICK_HCLKd8 +# define N32_SYSTICK_CLOCK (N32_M7CPU_FREQUENCY / 8) +#else +# define N32_SYSTICK_CLOCK (N32_M7CPU_FREQUENCY) +#endif + +/* 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 1000 (1000 ticks per second = 1 MS interval). + * + * For example, suppose HCLK = 600 MHz and CLK_TCK = 1000, then: + * + * N32_SYSTICK_CLOCK = 600 MHz + * SYSTICK_RELOAD = (600,000,000 / 1000) - 1 = 599,999 + */ + +#define SYSTICK_RELOAD ((N32_SYSTICK_CLOCK / CLK_TCK) - 1) + +/* 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: n32_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +static int n32_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; + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + putreg32(0, NVIC_SYSTICK_CURRENT); + + /* Attach the timer interrupt vector */ + + irq_attach(N32_IRQ_SYSTICK, (xcpt_t)n32_timerisr, NULL); + + /* Enable SysTick interrupts: + * + * NVIC_SYSTICK_CTRL_CLKSOURCE : Configurable, 0=HCLK/8, 1=CPU + * NVIC_SYSTICK_CTRL_TICKINT=1 : Generate interrupts + * NVIC_SYSTICK_CTRL_ENABLE : Enable the counter + */ + + regval = (NVIC_SYSTICK_CTRL_TICKINT | NVIC_SYSTICK_CTRL_ENABLE); +#ifndef CONFIG_N32H7_SYSTICK_HCLKd8 + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; +#else + regval &= ~NVIC_SYSTICK_CTRL_CLKSOURCE; +#endif + putreg32(regval, NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(N32_IRQ_SYSTICK); +} diff --git a/arch/arm/src/n32h7/n32_uart.h b/arch/arm/src/n32h7/n32_uart.h new file mode 100644 index 0000000000000..e542b3842edc1 --- /dev/null +++ b/arch/arm/src/n32h7/n32_uart.h @@ -0,0 +1,166 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_uart.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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_N32H7_N32H7_UART_H +#define __ARCH_ARM_SRC_N32H7_N32H7_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Disable UARTs not supported by the chip */ +#if N32H7_NUSART < 8 +# undef CONFIG_N32H7_USART8 +#endif +#if N32H7_NUSART < 7 +# undef CONFIG_N32H7_USART7 +#endif +#if N32H7_NUSART < 6 +# undef CONFIG_N32H7_USART6 +#endif +#if N32H7_NUSART < 5 +# undef CONFIG_N32H7_USART5 +#endif +#if N32H7_NUSART < 4 +# undef CONFIG_N32H7_USART4 +#endif +#if N32H7_NUSART < 3 +# undef CONFIG_N32H7_USART3 +#endif +#if N32H7_NUSART < 2 +# undef CONFIG_N32H7_USART2 +#endif +#if N32H7_NUSART < 1 +# undef CONFIG_N32H7_USART1 +#endif + +#if N32H7_NUART < 7 +# undef CONFIG_N32H7_UART15 +#endif +#if N32H7_NUART < 6 +# undef CONFIG_N32H7_UART14 +#endif +#if N32H7_NUART < 5 +# undef CONFIG_N32H7_UART13 +#endif +#if N32H7_NUART < 4 +# undef CONFIG_N32H7_UART12 +#endif +#if N32H7_NUART < 3 +# undef CONFIG_N32H7_UART11 +#endif +#if N32H7_NUART < 2 +# undef CONFIG_N32H7_UART10 +#endif +#if N32H7_NUART < 1 +# undef CONFIG_N32H7_UART9 +#endif + +/* Check if any UART is enabled */ +#if defined(CONFIG_N32H7_USART1) || defined(CONFIG_N32H7_USART2) || \ + defined(CONFIG_N32H7_USART3) || defined(CONFIG_N32H7_USART4) || \ + defined(CONFIG_N32H7_USART5) || defined(CONFIG_N32H7_USART6) || \ + defined(CONFIG_N32H7_USART7) || defined(CONFIG_N32H7_USART8) || \ + defined(CONFIG_N32H7_UART9) || defined(CONFIG_N32H7_UART10) || \ + defined(CONFIG_N32H7_UART11) || defined(CONFIG_N32H7_UART12) || \ + defined(CONFIG_N32H7_UART13) || defined(CONFIG_N32H7_UART14) || \ + defined(CONFIG_N32H7_UART15) +# define HAVE_UART 1 +#endif + +/* Console selection */ +#undef CONSOLE_UART +#undef HAVE_CONSOLE + +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_N32H7_USART1) +# define CONSOLE_UART 1 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_N32H7_USART2) +# define CONSOLE_UART 2 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_N32H7_USART3) +# define CONSOLE_UART 3 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART4_SERIAL_CONSOLE) && defined(CONFIG_N32H7_USART4) +# define CONSOLE_UART 4 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART5_SERIAL_CONSOLE) && defined(CONFIG_N32H7_USART5) +# define CONSOLE_UART 5 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_N32H7_USART6) +# define CONSOLE_UART 6 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART7_SERIAL_CONSOLE) && defined(CONFIG_N32H7_USART7) +# define CONSOLE_UART 7 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART8_SERIAL_CONSOLE) && defined(CONFIG_N32H7_USART8) +# define CONSOLE_UART 8 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART9_SERIAL_CONSOLE) && defined(CONFIG_N32H7_UART9) +# define CONSOLE_UART 9 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART10_SERIAL_CONSOLE) && defined(CONFIG_N32H7_UART10) +# define CONSOLE_UART 10 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART11_SERIAL_CONSOLE) && defined(CONFIG_N32H7_UART11) +# define CONSOLE_UART 11 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART12_SERIAL_CONSOLE) && defined(CONFIG_N32H7_UART12) +# define CONSOLE_UART 12 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART13_SERIAL_CONSOLE) && defined(CONFIG_N32H7_UART13) +# define CONSOLE_UART 13 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART14_SERIAL_CONSOLE) && defined(CONFIG_N32H7_UART14) +# define CONSOLE_UART 14 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART15_SERIAL_CONSOLE) && defined(CONFIG_N32H7_UART15) +# define CONSOLE_UART 15 +# define HAVE_CONSOLE 1 +#else +# define CONSOLE_UART 0 +# undef HAVE_CONSOLE +#endif + +#define CONFIG_N32H7_SERIAL_RXDMA_BUFFER_SIZE 64 + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +uart_dev_t *n32_serial_get_uart(int uart_num); +void n32_serial_dma_poll(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_ARM_SRC_N32H7_N32_UART_H */ diff --git a/arch/arm/src/n32h7/n32_uid.c b/arch/arm/src/n32h7/n32_uid.c new file mode 100644 index 0000000000000..6f545b048e2ca --- /dev/null +++ b/arch/arm/src/n32h7/n32_uid.c @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_uid.c + * + * SPDX-License-Identifier: BSD-3-Clause + * SPDX-FileCopyrightText: 2015 Marawan Ragab. All rights reserved. + * SPDX-FileContributor: Marawan Ragab + * SPDX-FileContributor: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "hardware/n32h7_memorymap.h" + +#include "n32_uid.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void n32_get_uniqueid(uint8_t uniqueid[16]) +{ + uint32_t otpc_tmp; + + for (int i = 0; i < 4; i++) + { + putreg32(N32_SYSMEM_UID + i, N32H7_OTPC_ADDR); + usleep(25000); + otpc_tmp = getreg32(N32H7_OTPC_DATA); + uniqueid[i * 4 + 0] = (otpc_tmp >> 0) & 0xff; + uniqueid[i * 4 + 1] = (otpc_tmp >> 8) & 0xff; + uniqueid[i * 4 + 2] = (otpc_tmp >> 16) & 0xff; + uniqueid[i * 4 + 3] = (otpc_tmp >> 24) & 0xff; + } +} diff --git a/arch/arm/src/n32h7/n32_uid.h b/arch/arm/src/n32h7/n32_uid.h new file mode 100644 index 0000000000000..d9128db8707d7 --- /dev/null +++ b/arch/arm/src/n32h7/n32_uid.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_uid.h + * + * SPDX-License-Identifier: BSD-3-Clause + * SPDX-FileCopyrightText: 2015 Marawan Ragab. All rights reserved. + * SPDX-FileContributor: Marawan Ragab + * SPDX-FileContributor: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_UID_H +#define __ARCH_ARM_SRC_N32H7_N32_UID_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "arm_internal.h" + +#define N32H7_OTPC_ADDR 0x51118010 +#define N32H7_OTPC_DATA 0x51118014 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void n32_get_uniqueid(uint8_t uniqueid[16]); + +#endif /* __ARCH_ARM_SRC_N32H7_N32_UID_H */ diff --git a/arch/arm/src/n32h7/n32_usbhs.h b/arch/arm/src/n32h7/n32_usbhs.h new file mode 100644 index 0000000000000..85919921caa3f --- /dev/null +++ b/arch/arm/src/n32h7/n32_usbhs.h @@ -0,0 +1,424 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_usbhs.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* N32H7 MOD: + * This file is the N32H76x counterpart of the STM32H7 stm32_otg.h driver + * common header. It provides the shared definitions used by the N32H7 + * USBHS device (n32_usbhsdev.c) and host (n32_usbhshost.c) drivers. + * + * Register offsets and bitfields are NOT duplicated here; they live in + * hardware/n32h7_usbhs.h. This header only composes the instance base + * address with the hardware offsets and supplies the small set of + * driver-local constants that the ported Synopsys OTG core logic needs. + */ + +#ifndef __ARCH_ARM_SRC_N32H7_N32_USBHS_H +#define __ARCH_ARM_SRC_N32H7_N32_USBHS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip.h" +#include "hardware/n32h7_usbhs.h" +#include "hardware/n32h76x_rcc.h" +#include "hardware/n32h76x_pwr.h" + +#if defined(CONFIG_N32H7_USBHS1_DEV) || defined(CONFIG_N32H7_USBHS2_DEV) || \ + defined(CONFIG_N32H7_USBHS1_HOST) || defined(CONFIG_N32H7_USBHS2_HOST) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Addresses *******************************************************/ + +/* Core global registers */ + +#define N32_USBHS_GCTRLSTS (N32_USBHS_BASE + N32_USBHS_GCTRLSTS_OFF) +#define N32_USBHS_GAHBCFG (N32_USBHS_BASE + N32_USBHS_GAHBCFG_OFF) +#define N32_USBHS_GCFG (N32_USBHS_BASE + N32_USBHS_GCFG_OFF) +#define N32_USBHS_GRSTCTRL (N32_USBHS_BASE + N32_USBHS_GRSTCTRL_OFF) +#define N32_USBHS_GINTSTS (N32_USBHS_BASE + N32_USBHS_GINTSTS_OFF) +#define N32_USBHS_GINTEN (N32_USBHS_BASE + N32_USBHS_GINTEN_OFF) +#define N32_USBHS_GRXSTS (N32_USBHS_BASE + N32_USBHS_GRXSTS_OFF) +#define N32_USBHS_GRXSTSP (N32_USBHS_BASE + N32_USBHS_GRXSTSP_OFF) +#define N32_USBHS_GRXFSIZ (N32_USBHS_BASE + N32_USBHS_GRXFSIZ_OFF) +#define N32_USBHS_GNPTXFSIZ (N32_USBHS_BASE + N32_USBHS_GNPTXFSIZ_OFF) +#define N32_USBHS_GNPTXFSTS (N32_USBHS_BASE + N32_USBHS_GNPTXFSTS_OFF) +#define N32_USBHS_CID (N32_USBHS_BASE + N32_USBHS_CID_OFF) +#define N32_USBHS_GPD (N32_USBHS_BASE + N32_USBHS_GPD_OFF) +#define N32_USBHS_HPTXFSIZ (N32_USBHS_BASE + N32_USBHS_HPTXFSIZ_OFF) + +#define N32_USBHS_DINEPPTXFSIZ(n) (N32_USBHS_BASE + \ + N32_USBHS_DINEPPTXFSIZ_OFF + (((n)-1) << 2)) + +/* N32H7 MOD: + * In device mode the IN EP0 TxFIFO size register shares the 0x028 offset + * with GNPTXFSIZ (same physical register, like DIEPTXF0/HNPTXFSIZ on the + * STM32H7 OTG core). + */ + +#define N32_USBHS_DINEPTXF0 (N32_USBHS_BASE + N32_USBHS_GNPTXFSIZ_OFF) + +/* Host mode registers */ + +#define N32_USBHS_HCFG (N32_USBHS_BASE + N32_USBHS_HCFG_OFF) +#define N32_USBHS_HFRI (N32_USBHS_BASE + N32_USBHS_HFRI_OFF) +#define N32_USBHS_HFNUM (N32_USBHS_BASE + N32_USBHS_HFNUM_OFF) +#define N32_USBHS_HPTXFQSTS (N32_USBHS_BASE + N32_USBHS_HPTXFQSTS_OFF) +#define N32_USBHS_HACHINT (N32_USBHS_BASE + N32_USBHS_HACHINT_OFF) +#define N32_USBHS_HACHINTEN (N32_USBHS_BASE + N32_USBHS_HACHINTEN_OFF) +#define N32_USBHS_HPCS (N32_USBHS_BASE + N32_USBHS_HPCS_OFF) + +/* Host channel registers */ + +#define N32_USBHS_HCHCTRL(n) (N32_USBHS_BASE + N32_USBHS_HCHCTRL_OFF(n)) +#define N32_USBHS_HCSCTRL(n) (N32_USBHS_BASE + N32_USBHS_HCSCTRL_OFF(n)) +#define N32_USBHS_HCHINTSTS(n) (N32_USBHS_BASE + N32_USBHS_HCHINTSTS_OFF(n)) +#define N32_USBHS_HCHINTEN(n) (N32_USBHS_BASE + N32_USBHS_HCHINTEN_OFF(n)) +#define N32_USBHS_HCHTXSIZ(n) (N32_USBHS_BASE + N32_USBHS_HCHTXSIZ_OFF(n)) +#define N32_USBHS_HCHDMADD(n) (N32_USBHS_BASE + N32_USBHS_HCHDMADD_OFF(n)) + +/* Device mode registers */ + +#define N32_USBHS_DCFG (N32_USBHS_BASE + N32_USBHS_DCFG_OFF) +#define N32_USBHS_DCTRL (N32_USBHS_BASE + N32_USBHS_DCTRL_OFF) +#define N32_USBHS_DSTS (N32_USBHS_BASE + N32_USBHS_DSTS_OFF) +#define N32_USBHS_DINEPINTEN (N32_USBHS_BASE + N32_USBHS_DINEPINTEN_OFF) +#define N32_USBHS_DOUTEPINTEN (N32_USBHS_BASE + N32_USBHS_DOUTEPINTEN_OFF) +#define N32_USBHS_DAEPINTSTS (N32_USBHS_BASE + N32_USBHS_DAEPINTSTS_OFF) +#define N32_USBHS_DAEPINTEN (N32_USBHS_BASE + N32_USBHS_DAEPINTEN_OFF) +#define N32_USBHS_DTHRCTRL (N32_USBHS_BASE + N32_USBHS_DTHRCTRL_OFF) +#define N32_USBHS_DINEPFEINTEN (N32_USBHS_BASE + N32_USBHS_DINEPFEINTEN_OFF) + +/* Device IN/OUT endpoint registers */ + +#define N32_USBHS_DINEPCTRL(n) (N32_USBHS_BASE + N32_USBHS_DINEPCTRL_OFF(n)) +#define N32_USBHS_DINEPINTSTS(n) (N32_USBHS_BASE + N32_USBHS_DINEPINTSTS_OFF(n)) +#define N32_USBHS_DINEPTXSIZ(n) (N32_USBHS_BASE + N32_USBHS_DINEPTXSIZ_OFF(n)) +#define N32_USBHS_DINEPTXFSTS(n) (N32_USBHS_BASE + N32_USBHS_DINEPTXFSTS_OFF(n)) +#define N32_USBHS_DOUTEPCTRL(n) (N32_USBHS_BASE + N32_USBHS_DOUTEPCTRL_OFF(n)) +#define N32_USBHS_DOUTEPINTSTS(n) (N32_USBHS_BASE + N32_USBHS_DOUTEPINTSTS_OFF(n)) +#define N32_USBHS_DOUTEPTXSIZ(n) (N32_USBHS_BASE + N32_USBHS_DOUTEPTXSIZ_OFF(n)) + +/* Power and clock gating control register */ + +#define N32_USBHS_PWRCTRL (N32_USBHS_BASE + N32_USBHS_PWRCTRL_OFF) +#define N32_USBHS_PWRCTRL1 (N32_USBHS_BASE + N32_USBHS_PWRCTRL1_OFF) + +/* Wrapper Registers */ +#define N32_USBHS_WRPCTRL (N32_USBHS_WRAPPER_BASE + N32_USBHS_WRPCTRL_OFF) +#define N32_USBHS_WRPCFG (N32_USBHS_WRAPPER_BASE + N32_USBHS_WRPCFG_OFF) + +/* N32H7 MOD: + * Data FIFO access (push/pop) addresses. The Synopsys-compatible core + * maps one 4Kb FIFO debug/push-pop region per endpoint (device mode) or + * per host channel starting at offset 0x1000. hardware/n32h7_usbhs.h + * does not carry FIFO window definitions, so they are provided here. + */ + +#define N32_USBHS_DFIFO_DEP(n) (N32_USBHS_BASE + 0x1000UL + \ + ((uint32_t)(n) << 12)) +#define N32_USBHS_DFIFO_HCH(n) (N32_USBHS_BASE + 0x1000UL + \ + ((uint32_t)(n) << 12)) + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: n32_usbhs_enableclock + * + * Description: + * Enable the AHB clock of the USBHS instance selected by the including + * driver file (via N32_USBHS_BASE) and un-gate the USBHS core memory + * power. + * + * N32H7 MOD: + * Replaces the STM32 RCC OTG clock enable. Per n32h76x_rcc.h the + * USBHS1 core clock is RCC_AHB2EN1_M7USB1EN and the USBHS2 core clock + * is RCC_AHB1EN1_M7USB2EN. The USBHS core memory power gate is + * controlled through N32_PWR_IP_MEMPWR_CR (PWR_IPMEMCTRL_USBx_PGEN); + * there is no USB voltage regulator / VDD33 detector as on STM32H7 + * (PWR_CR3_USBREGEN / PWR_CR3_USB33DEN do not exist on N32H76x). + * + * Defined static inline in this header so that both n32_usbhsdev.c and + * n32_usbhshost.c can use it without duplicate symbols when device and + * host roles are enabled on different instances in the same build. + * + ****************************************************************************/ + +static inline void n32_usbhs_enableclock(void) +{ + uint32_t regval; + + /* Enable the USBHS core memory power gate and wait until ready */ + + if (N32_USBHS_BASE == N32_USBCTRL1_BASE) + { + /* Enable the HSC1 Power Gate */ + + regval = getreg32(N32_PWR_SYS_PWR_CR3); + regval |= PWR_SYSCTRL3_HSC1_PGEN; + putreg32(regval, N32_PWR_SYS_PWR_CR3); + + while ((getreg32(N32_PWR_SYS_PWR_CR3) & + PWR_SYSCTRL3_HSC1_PWRRDY) == 0); + + regval = getreg32(N32_PWR_SYS_PWR_CR3); + regval |= (PWR_SYSCTRL3_HSC1_FUCEN | PWR_SYSCTRL3_HSC1_ISNEN); + putreg32(regval, N32_PWR_SYS_PWR_CR3); + + /* Enable the USBHS1 peripheral clock */ + + regval = getreg32(N32_RCC_AHB2EN1); + regval |= RCC_AHB2EN1_M7USB1EN; + putreg32(regval, N32_RCC_AHB2EN1); + + regval = getreg32(N32_PWR_IP_MEMPWR_CR); + regval &= ~PWR_IPMEMCTRL_USB1_PGEN; + putreg32(regval, N32_PWR_IP_MEMPWR_CR); + + while ((getreg32(N32_PWR_IP_MEMPWR_CSR) & + PWR_IPMEMSTS_USB1_PRDY) == 0); + + /* Reset the USBHS1 core */ + + regval = getreg32(N32_RCC_AHB2RST1); + regval |= RCC_AHB2RST1_USB1RST; + putreg32(regval, N32_RCC_AHB2RST1); + regval &= ~RCC_AHB2RST1_USB1RST; + putreg32(regval, N32_RCC_AHB2RST1); + } + else + { + /* Enable the HSC2 Power Gate */ + + regval = getreg32(N32_PWR_SYS_PWR_CR3); + regval |= PWR_SYSCTRL3_HSC2_PGEN; + putreg32(regval, N32_PWR_SYS_PWR_CR3); + + while ((getreg32(N32_PWR_SYS_PWR_CR3) & + PWR_SYSCTRL3_HSC2_PWRRDY) == 0); + + regval = getreg32(N32_PWR_SYS_PWR_CR3); + regval |= (PWR_SYSCTRL3_HSC2_FUCEN | PWR_SYSCTRL3_HSC2_ISNEN); + putreg32(regval, N32_PWR_SYS_PWR_CR3); + + /* Enable the USBHS2 peripheral clock */ + + regval = getreg32(N32_RCC_AHB1EN1); + regval |= RCC_AHB1EN1_M7USB2EN; + putreg32(regval, N32_RCC_AHB1EN1); + + regval = getreg32(N32_PWR_IP_MEMPWR_CR); + regval &= ~PWR_IPMEMCTRL_USB2_PGEN; + putreg32(regval, N32_PWR_IP_MEMPWR_CR); + + while ((getreg32(N32_PWR_IP_MEMPWR_CSR) & + PWR_IPMEMSTS_USB2_PRDY) == 0); + + /* Reset the USBHS2 core */ + + regval = getreg32(N32_RCC_AHB1RST1); + regval |= RCC_AHB1RST1_USB2RST; + putreg32(regval, N32_RCC_AHB1RST1); + regval &= ~RCC_AHB1RST1_USB2RST; + putreg32(regval, N32_RCC_AHB1RST1); + } +} + +/**************************************************************************** + * Name: n32_usbhs_disableclock + * + * Description: + * Disable the AHB clock of the USBHS instance selected by the including + * driver file and gate the USBHS core memory power. + ****************************************************************************/ + +static inline void n32_usbhs_disableclock(void) +{ + uint32_t regval; + + if (N32_USBHS_BASE == N32_USBCTRL1_BASE) + { + regval = getreg32(N32_RCC_AHB2EN1); + regval &= ~RCC_AHB2EN1_M7USB1EN; + putreg32(regval, N32_RCC_AHB2EN1); + + regval = getreg32(N32_PWR_IP_MEMPWR_CR); + regval |= PWR_IPMEMCTRL_USB1_PGEN; + putreg32(regval, N32_PWR_IP_MEMPWR_CR); + } + else + { + regval = getreg32(N32_RCC_AHB1EN1); + regval &= ~RCC_AHB1EN1_M7USB2EN; + putreg32(regval, N32_RCC_AHB1EN1); + + regval = getreg32(N32_PWR_IP_MEMPWR_CR); + regval |= PWR_IPMEMCTRL_USB2_PGEN; + putreg32(regval, N32_PWR_IP_MEMPWR_CR); + } +} + +/**************************************************************************** + * Name: n32_usbhs_phy_initialize + * + * Description: + * Initialize the USBHS PHY interface. + * + * N32H7 MOD: + * The N32H76x USBHS core has no on-chip HS PHY; an external ULPI PHY is + * used instead. The STM32H7 wrapper (WRPCTRL/WRPCFG) internal PHY PLL + * configuration is therefore not required and is intentionally skipped. + * The FS serial transceiver select (GCFG.PHYSEL) is only programmed by + * the drivers when the internal FS PHY configuration is selected + * (CONFIG_N32H7_USBHS_FS); for the default external ULPI configuration + * PHYSEL remains cleared. + ****************************************************************************/ + +static inline void n32_usbhs_phy_initialize(void) +{ + /* N32H7 MOD: + * External ULPI PHY is used. + * Skip internal PHY wrapper (WRPCTRL/WRPCFG) PLL configuration. + * Any board-level ULPI PHY reset is performed via n32_usbulpireset(). + */ +} + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: n32_usbhshost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initialized. Normally, + * this is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +struct usbhost_connection_s; +struct usbhost_connection_s *n32_usbhshost_initialize(int controller); +#endif + +/**************************************************************************** + * Name: n32_usbsuspend + * + * Description: + * Board logic must provide the n32_usbsuspend logic if the USBHS + * device driver is used. This function is called whenever the USB enters + * or leaves suspend mode. This is an opportunity for the board logic to + * shutdown clocks, power, etc. while the USB is suspended. + * + ****************************************************************************/ + +struct usbdev_s; +extern void n32_usbsuspend(struct usbdev_s *dev, bool resume); + +/**************************************************************************** + * Name: n32_usbulpireset + * + * Description: + * Reset external ULPI PHY. + * + ****************************************************************************/ + +#ifndef CONFIG_N32H7_USBHS_FS +struct usbdev_s; +void n32_usbulpireset(struct usbdev_s *dev); +#endif + +/**************************************************************************** + * Name: n32_usbhs_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be + * provided by each board that implements the N32H7 USBHS host interface. + * + * On-chip 5V VBUS generation is not supported. A charge pump or a basic + * power switch must be added externally to drive the 5V VBUS line; it + * can be driven by any GPIO output. When the application powers on + * VBUS using the chosen GPIO, it must also set the port power bit + * (HPCS.PPWR). + * + * Input Parameters: + * iface - For future growth to handle multiple USB host interfaces. + * Should be zero. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +extern void n32_usbhs_vbusdrive(int iface, bool enable); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_N32H7_USBHS1_DEV || CONFIG_N32H7_USBHS2_DEV || ... */ +#endif /* __ARCH_ARM_SRC_N32H7_N32_USBHS_H */ diff --git a/arch/arm/src/n32h7/n32_usbhsdev.c b/arch/arm/src/n32h7/n32_usbhsdev.c new file mode 100644 index 0000000000000..4e0dc0afda104 --- /dev/null +++ b/arch/arm/src/n32h7/n32_usbhsdev.c @@ -0,0 +1,6009 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_usbhsdev.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "n32_gpio.h" +#include "arm_internal.h" + +#if defined(CONFIG_USBDEV) && (defined(CONFIG_N32H7_USBHS1_DEV) || \ + defined(CONFIG_N32H7_USBHS2_DEV)) + +/* N32_USBHS_BASE and N32_IRQ_USBHS are defined before n32_usbhs.h is + * included so that the register address macros and the static inline + * clock/PHY helpers in that header expand for the correct instance. + * The USBHS GPIO pin definitions (GPIO_USBHS_*) are provided by board.h. + */ + +#if defined(CONFIG_N32H7_USBHS1_DEV) +# define N32_IRQ_USBHS N32_IRQ_USBHS1_HS +# define N32_USBHS_BASE N32_USBCTRL1_BASE +# define N32_USBHS_WRAPPER_BASE N32_USBCTRL1_WRAPPER_BASE +# define GPIO_USBHS_DM GPIO_USBHS1_DM +# define GPIO_USBHS_DP GPIO_USBHS1_DP +#elif defined(CONFIG_N32H7_USBHS2_DEV) +# define N32_IRQ_USBHS N32_IRQ_USBHS2_HS +# define N32_USBHS_BASE N32_USBCTRL2_BASE +# define N32_USBHS_WRAPPER_BASE N32_USBCTRL2_WRAPPER_BASE +# define GPIO_USBHS_DM GPIO_USBHS2_DM +# define GPIO_USBHS_DP GPIO_USBHS2_DP +#else +# error Not selected USBDEV peripheral +#endif + +#if defined(CONFIG_N32H7_USBHS1_DEV) && defined(CONFIG_N32H7_USBHS2_DEV) +# error Only one USBDEV role supported +#endif + +/* N32H7 MOD: + * The N32H76x USBHS core has no on-chip HS PHY; an external ULPI PHY is + * the default configuration. Define CONFIG_N32H7_USBHS_FS to select the + * FS serial transceiver (GCFG.PHYSEL) instead. + */ + +#include "n32_usbhs.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_SETUP_MAXDATASIZE +# define CONFIG_USBDEV_SETUP_MAXDATASIZE CONFIG_USBDEV_EP0_MAXSIZE +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +/* There is 4Kb of FIFO memory. The default partitions this memory + * so that there is a TxFIFO allocated for each endpoint and with more + * memory provided for the common RxFIFO. A more knowledge-able + * configuration would not allocate any TxFIFO space to OUT endpoints. + */ + +#ifndef CONFIG_USBDEV_RXFIFO_SIZE +# define CONFIG_USBDEV_RXFIFO_SIZE 512 +#endif + +#if N32_USBHS_NENDPOINTS > 0 +# ifndef CONFIG_USBDEV_EP0_TXFIFO_SIZE +# define CONFIG_USBDEV_EP0_TXFIFO_SIZE 64 +# endif +#else +# define CONFIG_USBDEV_EP0_TXFIFO_SIZE 0 +#endif + +#if N32_USBHS_NENDPOINTS > 1 +# ifndef CONFIG_USBDEV_EP1_TXFIFO_SIZE +# define CONFIG_USBDEV_EP1_TXFIFO_SIZE ((N32_USBHS_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE - CONFIG_USBDEV_EP0_TXFIFO_SIZE)/(N32_USBHS_NENDPOINTS-1)) +# endif +#else +# define CONFIG_USBDEV_EP1_TXFIFO_SIZE 0 +#endif + +#if N32_USBHS_NENDPOINTS > 2 +# ifndef CONFIG_USBDEV_EP2_TXFIFO_SIZE +# define CONFIG_USBDEV_EP2_TXFIFO_SIZE ((N32_USBHS_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE - CONFIG_USBDEV_EP0_TXFIFO_SIZE)/(N32_USBHS_NENDPOINTS-1)) +# endif +#else +# define CONFIG_USBDEV_EP2_TXFIFO_SIZE 0 +#endif + +#if N32_USBHS_NENDPOINTS > 3 +# ifndef CONFIG_USBDEV_EP3_TXFIFO_SIZE +# define CONFIG_USBDEV_EP3_TXFIFO_SIZE ((N32_USBHS_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE - CONFIG_USBDEV_EP0_TXFIFO_SIZE)/(N32_USBHS_NENDPOINTS-1)) +# endif +#else +# define CONFIG_USBDEV_EP3_TXFIFO_SIZE 0 +#endif + +#if N32_USBHS_NENDPOINTS > 4 +# ifndef CONFIG_USBDEV_EP4_TXFIFO_SIZE +# define CONFIG_USBDEV_EP4_TXFIFO_SIZE ((N32_USBHS_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE - CONFIG_USBDEV_EP0_TXFIFO_SIZE)/(N32_USBHS_NENDPOINTS-1)) +# endif +#else +# define CONFIG_USBDEV_EP4_TXFIFO_SIZE 0 +#endif + +#if N32_USBHS_NENDPOINTS > 5 +# ifndef CONFIG_USBDEV_EP5_TXFIFO_SIZE +# define CONFIG_USBDEV_EP5_TXFIFO_SIZE ((N32_USBHS_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE - CONFIG_USBDEV_EP0_TXFIFO_SIZE)/(N32_USBHS_NENDPOINTS-1)) +# endif +#else +# define CONFIG_USBDEV_EP5_TXFIFO_SIZE 0 +#endif + +#if N32_USBHS_NENDPOINTS > 6 +# ifndef CONFIG_USBDEV_EP6_TXFIFO_SIZE +# define CONFIG_USBDEV_EP6_TXFIFO_SIZE ((N32_USBHS_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE - CONFIG_USBDEV_EP0_TXFIFO_SIZE)/(N32_USBHS_NENDPOINTS-1)) +# endif +#else +# define CONFIG_USBDEV_EP6_TXFIFO_SIZE 0 +#endif + +#if N32_USBHS_NENDPOINTS > 7 +# ifndef CONFIG_USBDEV_EP7_TXFIFO_SIZE +# define CONFIG_USBDEV_EP7_TXFIFO_SIZE ((N32_USBHS_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE - CONFIG_USBDEV_EP0_TXFIFO_SIZE)/(N32_USBHS_NENDPOINTS-1)) +# endif +#else +# define CONFIG_USBDEV_EP7_TXFIFO_SIZE 0 +#endif + +#if N32_USBHS_NENDPOINTS > 8 +# ifndef CONFIG_USBDEV_EP8_TXFIFO_SIZE +# define CONFIG_USBDEV_EP8_TXFIFO_SIZE ((N32_USBHS_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE - CONFIG_USBDEV_EP0_TXFIFO_SIZE)/(N32_USBHS_NENDPOINTS-1)) +# endif +#else +# define CONFIG_USBDEV_EP8_TXFIFO_SIZE 0 +#endif + +/* The actual FIFO addresses that we use must be aligned to 4-byte + * boundaries; FIFO sizes must be provided in units of 32-bit words. + */ + +#define N32_RXFIFO_BYTES ((CONFIG_USBDEV_RXFIFO_SIZE + 3) & ~3) +#define N32_RXFIFO_WORDS ((CONFIG_USBDEV_RXFIFO_SIZE + 3) >> 2) + +#define N32_EP0_TXFIFO_BYTES ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) & ~3) +#define N32_EP0_TXFIFO_WORDS ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) >> 2) + +#define N32_EP1_TXFIFO_BYTES ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) & ~3) +#define N32_EP1_TXFIFO_WORDS ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) >> 2) + +#define N32_EP2_TXFIFO_BYTES ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) & ~3) +#define N32_EP2_TXFIFO_WORDS ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) >> 2) + +#define N32_EP3_TXFIFO_BYTES ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) & ~3) +#define N32_EP3_TXFIFO_WORDS ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) >> 2) + +#define N32_EP4_TXFIFO_BYTES ((CONFIG_USBDEV_EP4_TXFIFO_SIZE + 3) & ~3) +#define N32_EP4_TXFIFO_WORDS ((CONFIG_USBDEV_EP4_TXFIFO_SIZE + 3) >> 2) + +#define N32_EP5_TXFIFO_BYTES ((CONFIG_USBDEV_EP5_TXFIFO_SIZE + 3) & ~3) +#define N32_EP5_TXFIFO_WORDS ((CONFIG_USBDEV_EP5_TXFIFO_SIZE + 3) >> 2) + +#define N32_EP6_TXFIFO_BYTES ((CONFIG_USBDEV_EP6_TXFIFO_SIZE + 3) & ~3) +#define N32_EP6_TXFIFO_WORDS ((CONFIG_USBDEV_EP6_TXFIFO_SIZE + 3) >> 2) + +#define N32_EP7_TXFIFO_BYTES ((CONFIG_USBDEV_EP7_TXFIFO_SIZE + 3) & ~3) +#define N32_EP7_TXFIFO_WORDS ((CONFIG_USBDEV_EP7_TXFIFO_SIZE + 3) >> 2) + +#define N32_EP8_TXFIFO_BYTES ((CONFIG_USBDEV_EP8_TXFIFO_SIZE + 3) & ~3) +#define N32_EP8_TXFIFO_WORDS ((CONFIG_USBDEV_EP8_TXFIFO_SIZE + 3) >> 2) + +#if (N32_RXFIFO_BYTES + \ + N32_EP0_TXFIFO_BYTES + N32_EP1_TXFIFO_BYTES + N32_EP2_TXFIFO_BYTES + N32_EP3_TXFIFO_BYTES + \ + N32_EP4_TXFIFO_BYTES + N32_EP5_TXFIFO_BYTES + N32_EP6_TXFIFO_BYTES + N32_EP7_TXFIFO_BYTES + CONFIG_USBDEV_EP8_TXFIFO_SIZE \ + ) > N32_USBHS_FIFO_SIZE +# error "FIFO allocations exceed FIFO memory size" +#endif + +/* Driver-private constants ************************************************* + * + * N32H7 MOD: + * The following constants have no counterpart in hardware/n32h7_usbhs.h + * (the hardware header provides only the field SHIFT/MASK). They are + * driver-internal encodings used by the ported core logic, private to + * this file. + */ + +/* Device configuration (DCFG) device speed field values: + * 00: High speed (external ULPI HS PHY) + * 01: Full speed + */ + +#define N32_USBHS_DCFG_DEVSPD_HS (0UL << N32_USBHS_DCFG_DEVSPD_SHIFT) +#define N32_USBHS_DCFG_DEVSPD_FS (1UL << N32_USBHS_DCFG_DEVSPD_SHIFT) + +/* Endpoint type values (unshifted, driver-internal encoding; matches the + * DINEPCTRL/DOUTEPCTRL EPTYPE field encoding) + */ + +#define N32_USBHS_EPTYPE_CTRL 0 +#define N32_USBHS_EPTYPE_ISOC 1 +#define N32_USBHS_EPTYPE_BULK 2 +#define N32_USBHS_EPTYPE_INTR 3 + +/* Data PID values (unshifted; matches the DINEPTXSIZ PID field encoding) */ + +#define N32_USBHS_PID_DATA0 0 +#define N32_USBHS_PID_DATA1 2 +#define N32_USBHS_PID_SETUP 3 + +/* Test mode values (unshifted; matches the DCTRL test mode field encoding) */ + +#define N32_USBHS_TESTMODE_DISABLED 0 +#define N32_USBHS_TESTMODE_J 1 +#define N32_USBHS_TESTMODE_K 2 +#define N32_USBHS_TESTMODE_SE0_NAK 3 +#define N32_USBHS_TESTMODE_PACKET 4 +#define N32_USBHS_TESTMODE_FORCE 5 + +/* GCFG turnaround time helper (TRDTIM field, AHB clock turnaround) */ + +#define N32_USBHS_GCFG_TRDTIM(n) ((uint32_t)(n) << N32_USBHS_GCFG_TRDTIM_SHIFT) + +/* GRSTCTRL TxFIFO number helpers */ + +#define N32_USBHS_GRSTCTRL_TXFNUM_D(n) \ + ((uint32_t)(n) << N32_USBHS_GRSTCTRL_TXFNUM_SHIFT) +#define N32_USBHS_GRSTCTRL_TXFNUM_DALL \ + (0x10UL << N32_USBHS_GRSTCTRL_TXFNUM_SHIFT) + +/* Device all-endpoints interrupt helpers (DAEPINTSTS/DAEPINTEN) */ + +#define N32_USBHS_DAINT_IEP(n) (1UL << (n)) +#define N32_USBHS_DAINT_IEP_MASK N32_USBHS_DAEPINTSTS_INEPINT_MASK +#define N32_USBHS_DAINT_OEP(n) (1UL << ((n) + 16)) +#define N32_USBHS_DAINT_OEP_SHIFT N32_USBHS_DAEPINTSTS_OUTEPINT_SHIFT +#define N32_USBHS_DAINT_OEP_MASK N32_USBHS_DAEPINTSTS_OUTEPINT_MASK + +/* IN endpoint TxFIFO empty interrupt enable helper (DINEPFEINTEN) */ + +#define N32_USBHS_DINEPFEINTEN_IEP(n) (1UL << (n)) + +/* Device status (DSTS) frame number helpers */ + +#define N32_USBHS_DSTS_SOFFN0 (1UL << N32_USBHS_DSTS_SOFFN_SHIFT) +#define N32_USBHS_DSTS_SOFFN_EVEN (0) + +/* N32H7 MOD: + * The N32 USBHS core has no LPM interrupt; the corresponding bit was + * dropped from the read/clear-to-write-one mask. Bit 30 (VBUS valid / + * session request) is named only on the enable side in + * hardware/n32h7_usbhs.h; the same bit position in GINTSTS is + * write-1-to-clear. + */ + +#define N32_USBHS_GINT_RC_W1 (N32_USBHS_GINTSTS_MODMISIF | \ + N32_USBHS_GINTSTS_SOFIF | \ + N32_USBHS_GINTSTS_ESUSPIF | \ + N32_USBHS_GINTSTS_USBSUSPIF | \ + N32_USBHS_GINTSTS_USBRSTIF | \ + N32_USBHS_GINTSTS_ENUMDIF | \ + N32_USBHS_GINTSTS_ISOUTPDIF | \ + N32_USBHS_GINTSTS_EOPFIF | \ + N32_USBHS_GINTSTS_ISOINCIF | \ + N32_USBHS_GINTSTS_PTNCIF_ISOUTNCIF | \ + N32_USBHS_GINTSTS_RSTDIF | \ + N32_USBHS_GINTSTS_IDSTSCIF | \ + N32_USBHS_GINTSTS_DISCIF | \ + N32_USBHS_GINTEN_VBUSVIF | \ + N32_USBHS_GINTSTS_WKUPIF) + +/* Reserved (read-only / write-ignored) bits of GINTSTS that must be + * preserved when acknowledging interrupts. + */ + +#define N32_USBHS_GINT_RESERVED ((1UL << 8) | (1UL << 9) | \ + (1UL << 16) | (1UL << 17) | \ + (1UL << 27)) + +/* Debug ********************************************************************/ + +/* Trace error codes */ + +#define N32_TRACEERR_ALLOCFAIL 0x01 +#define N32_TRACEERR_BADCLEARFEATURE 0x02 +#define N32_TRACEERR_BADDEVGETSTATUS 0x03 +#define N32_TRACEERR_BADEPNO 0x04 +#define N32_TRACEERR_BADEPGETSTATUS 0x05 +#define N32_TRACEERR_BADGETCONFIG 0x06 +#define N32_TRACEERR_BADGETSETDESC 0x07 +#define N32_TRACEERR_BADGETSTATUS 0x08 +#define N32_TRACEERR_BADSETADDRESS 0x09 +#define N32_TRACEERR_BADSETCONFIG 0x0a +#define N32_TRACEERR_BADSETFEATURE 0x0b +#define N32_TRACEERR_BADTESTMODE 0x0c +#define N32_TRACEERR_BINDFAILED 0x0d +#define N32_TRACEERR_DISPATCHSTALL 0x0e +#define N32_TRACEERR_DRIVER 0x0f +#define N32_TRACEERR_DRIVERREGISTERED 0x10 +#define N32_TRACEERR_EP0NOSETUP 0x11 +#define N32_TRACEERR_EP0SETUPSTALLED 0x12 +#define N32_TRACEERR_EPINNULLPACKET 0x13 +#define N32_TRACEERR_EPINUNEXPECTED 0x14 +#define N32_TRACEERR_EPOUTNULLPACKET 0x15 +#define N32_TRACEERR_EPOUTUNEXPECTED 0x16 +#define N32_TRACEERR_INVALIDCTRLREQ 0x17 +#define N32_TRACEERR_INVALIDPARMS 0x18 +#define N32_TRACEERR_IRQREGISTRATION 0x19 +#define N32_TRACEERR_NOEP 0x1a +#define N32_TRACEERR_NOTCONFIGURED 0x1b +#define N32_TRACEERR_EPOUTQEMPTY 0x1c +#define N32_TRACEERR_EPINREQEMPTY 0x1d +#define N32_TRACEERR_NOOUTSETUP 0x1e +#define N32_TRACEERR_POLLTIMEOUT 0x1f + +/* Trace interrupt codes */ + +#define N32_TRACEINTID_USB 1 /* USB Interrupt entry/exit */ +#define N32_TRACEINTID_INTPENDING 2 /* On each pass through the loop */ + +#define N32_TRACEINTID_EPOUT (10 + 0) /* First level interrupt decode */ +#define N32_TRACEINTID_EPIN (10 + 1) +#define N32_TRACEINTID_MISMATCH (10 + 2) +#define N32_TRACEINTID_WAKEUP (10 + 3) +#define N32_TRACEINTID_SUSPEND (10 + 4) +#define N32_TRACEINTID_SOF (10 + 5) +#define N32_TRACEINTID_RXFIFO (10 + 6) +#define N32_TRACEINTID_DEVRESET (10 + 7) +#define N32_TRACEINTID_ENUMDNE (10 + 8) +#define N32_TRACEINTID_IISOIXFR (10 + 9) +#define N32_TRACEINTID_IISOOXFR (10 + 10) +#define N32_TRACEINTID_SRQ (10 + 11) +#define N32_TRACEINTID_OTG (10 + 12) + +#define N32_TRACEINTID_EPOUT_XFRC (40 + 0) /* EPOUT second level decode */ +#define N32_TRACEINTID_EPOUT_EPDISD (40 + 1) +#define N32_TRACEINTID_EPOUT_SETUP (40 + 2) +#define N32_TRACEINTID_DISPATCH (40 + 3) + +#define N32_TRACEINTID_GETSTATUS (50 + 0) /* EPOUT third level decode */ +#define N32_TRACEINTID_EPGETSTATUS (50 + 1) +#define N32_TRACEINTID_DEVGETSTATUS (50 + 2) +#define N32_TRACEINTID_IFGETSTATUS (50 + 3) +#define N32_TRACEINTID_CLEARFEATURE (50 + 4) +#define N32_TRACEINTID_SETFEATURE (50 + 5) +#define N32_TRACEINTID_SETADDRESS (50 + 6) +#define N32_TRACEINTID_GETSETDESC (50 + 7) +#define N32_TRACEINTID_GETCONFIG (50 + 8) +#define N32_TRACEINTID_SETCONFIG (50 + 9) +#define N32_TRACEINTID_GETSETIF (50 + 10) +#define N32_TRACEINTID_SYNCHFRAME (50 + 11) + +#define N32_TRACEINTID_EPIN_XFRC (70 + 0) /* EPIN second level decode */ +#define N32_TRACEINTID_EPIN_TOC (70 + 1) +#define N32_TRACEINTID_EPIN_ITTXFE (70 + 2) +#define N32_TRACEINTID_EPIN_EPDISD (70 + 3) +#define N32_TRACEINTID_EPIN_TXFE (70 + 4) + +#define N32_TRACEINTID_EPIN_EMPWAIT (80 + 0) /* EPIN second level decode */ + +#define N32_TRACEINTID_OUTNAK (90 + 0) /* RXFLVL second level decode */ +#define N32_TRACEINTID_OUTRECVD (90 + 1) +#define N32_TRACEINTID_OUTDONE (90 + 2) +#define N32_TRACEINTID_SETUPDONE (90 + 3) +#define N32_TRACEINTID_SETUPRECVD (90 + 4) + +/* Endpoints ****************************************************************/ + +/* Odd physical endpoint numbers are IN; even are OUT */ + +#define N32_EPPHYIN2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_IN) +#define N32_EPPHYOUT2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_OUT) + +/* Endpoint 0 */ + +#define EP0 (0) + +/* The set of all endpoints available to the class implementation (1-7) */ + +#define N32_EP_AVAILABLE (0xfe) /* All available endpoints */ + +/* Maximum packet sizes for full speed endpoints */ + +#define N32_MAXPACKET (64) /* Max packet size (1-64) */ + +/* Delays *******************************************************************/ + +#define N32_READY_DELAY 200000 +#define N32_FLUSH_DELAY 200000 + +/* Request queue operations *************************************************/ + +#define n32_rqempty(ep) ((ep)->head == NULL) +#define n32_rqpeek(ep) ((ep)->head) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Overall device state */ + +enum n32_devstate_e +{ + DEVSTATE_DEFAULT = 0, /* Power-up, unconfigured state. This state simply + * means that the device is not yet been given an + * address. + * SET: At initialization, uninitialization, + * reset, and whenever the device address + * is set to zero + * TESTED: Never + */ + DEVSTATE_ADDRESSED, /* Device address has been assigned, not no + * configuration has yet been selected. + * SET: When either a non-zero device address + * is first assigned or when the device + * is unconfigured (with configuration == 0) + * TESTED: never + */ + DEVSTATE_CONFIGURED, /* Address assigned and configured: + * SET: When the device has been addressed and + * an non-zero configuration has been selected. + * TESTED: In many places to assure that the USB device + * has been properly configured by the host. + */ +}; + +/* Endpoint 0 states */ + +enum n32_ep0state_e +{ + EP0STATE_IDLE = 0, /* Idle State, leave on receiving a SETUP packet or + * epsubmit: + * SET: In n32_epin() and n32_epout() when + * we revert from request processing to + * SETUP processing. + * TESTED: Never + */ + EP0STATE_SETUP_OUT, /* OUT SETUP packet received. Waiting for the DATA + * OUT phase of SETUP Packet to complete before + * processing a SETUP command (without a USB request): + * SET: Set in n32_rxinterrupt() when SETUP OUT + * packet is received. + * TESTED: In n32_ep0out_receive() + */ + EP0STATE_SETUP_READY, /* IN SETUP packet received -OR- OUT SETUP packet and + * accompanying data have been received. Processing + * of SETUP command will happen soon. + * SET: (1) n32_ep0out_receive() when the OUT + * SETUP data phase completes, or (2) + * n32_rxinterrupt() when an IN SETUP is + * packet received. + * TESTED: Tested in n32_epout_interrupt() when + * SETUP phase is done to see if the SETUP + * command is ready to be processed. Also + * tested in n32_ep0out_setup() just to + * double-check that we have a SETUP request + * and any accompanying data. + */ + EP0STATE_SETUP_PROCESS, /* SETUP Packet is being processed by n32_ep0out_setup(): + * SET: When SETUP packet received in EP0 OUT + * TESTED: Never + */ + EP0STATE_SETUPRESPONSE, /* Short SETUP response write (without a USB request): + * SET: When SETUP response is sent by + * n32_ep0in_setupresponse() + * TESTED: Never + */ + EP0STATE_DATA_IN, /* Waiting for data out stage (with a USB request): + * SET: In n32_epin_request() when a write + * request is processed on EP0. + * TESTED: In n32_epin() to see if we should + * revert to SETUP processing. + */ + EP0STATE_DATA_OUT /* Waiting for data in phase to complete ( with a + * USB request) + * SET: In n32_epout_request() when a read + * request is processed on EP0. + * TESTED: In n32_epout() to see if we should + * revert to SETUP processing + */ +}; + +/* Parsed control request */ + +struct n32_ctrlreq_s +{ + uint8_t type; + uint8_t req; + uint16_t value; + uint16_t index; + uint16_t len; +}; + +/* A container for a request so that the request may be retained in a list */ + +struct n32_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct n32_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct n32_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct n32_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* N32-specific fields */ + + struct n32_usbdev_s *dev; /* Reference to private driver data */ + struct n32_req_s *head; /* Request list for this endpoint */ + struct n32_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t eptype:2; /* Endpoint type */ + uint8_t active:1; /* 1: A request is being processed */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ + uint8_t isin:1; /* 1: IN Endpoint */ + uint8_t odd:1; /* 1: Odd frame */ + uint8_t zlp:1; /* 1: Transmit a zero-length-packet (IN EPs only) */ +}; + +/* This structure retains the state of the USB device controller */ + +struct n32_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to struct n32_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* N32-specific fields */ + + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t addressed:1; /* 1: Peripheral address has been set */ + uint8_t configured:1; /* 1: Class driver has been configured */ + uint8_t wakeup:1; /* 1: Device remote wake-up */ + uint8_t dotest:1; /* 1: Test mode selected */ + + uint8_t devstate:4; /* See enum n32_devstate_e */ + uint8_t ep0state:4; /* See enum n32_ep0state_e */ + uint8_t testmode:4; /* Selected test mode */ + uint8_t epavail[2]; /* Bitset of available OUT/IN endpoints */ + + /* E0 SETUP data buffering. + * + * ctrlreq: + * The 8-byte SETUP request is received on the EP0 OUT endpoint and is + * saved. + * + * ep0data + * For OUT SETUP requests, the SETUP data phase must also complete before + * the SETUP command can be processed. The pack receipt logic will save + * the accompanying EP0 IN data in ep0data[] before the SETUP command is + * processed. + * + * For IN SETUP requests, the DATA phase will occur AFTER the SETUP + * control request is processed. In that case, ep0data[] may be used as + * the response buffer. + * + * ep0datlen + * Length of OUT DATA received in ep0data[] (Not used with OUT data) + */ + + struct usb_ctrlreq_s ctrlreq; + uint8_t ep0data[CONFIG_USBDEV_SETUP_MAXDATASIZE]; + uint16_t ep0datlen; + + /* The endpoint lists */ + + struct n32_ep_s epin[N32_USBHS_NENDPOINTS]; + struct n32_ep_s epout[N32_USBHS_NENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ******************************************************/ + +#if defined(CONFIG_N32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) +static uint32_t n32_getreg(uint32_t addr); +static void n32_putreg(uint32_t val, uint32_t addr); +#else +# define n32_getreg(addr) getreg32(addr) +# define n32_putreg(val,addr) putreg32(val,addr) +#endif + +/* Request queue operations *************************************************/ + +static struct n32_req_s *n32_req_remfirst(struct n32_ep_s *privep); +static bool n32_req_addlast(struct n32_ep_s *privep, + struct n32_req_s *req); + +/* Low level data transfers and request operations **************************/ + +/* Special endpoint 0 data transfer logic */ + +static void n32_ep0in_setupresponse(struct n32_usbdev_s *priv, + uint8_t *data, uint32_t nbytes); +static inline void n32_ep0in_transmitzlp(struct n32_usbdev_s *priv); +static void n32_ep0in_activate(void); + +static void n32_ep0out_ctrlsetup(struct n32_usbdev_s *priv); + +/* IN request and TxFIFO handling */ + +static void n32_txfifo_write(struct n32_ep_s *privep, + uint8_t *buf, int nbytes); +static void n32_epin_transfer(struct n32_ep_s *privep, + uint8_t *buf, int nbytes); +static void n32_epin_request(struct n32_usbdev_s *priv, + struct n32_ep_s *privep); + +/* OUT request and RxFIFO handling */ + +static void n32_rxfifo_read(struct n32_ep_s *privep, + uint8_t *dest, uint16_t len); +static void n32_rxfifo_discard(struct n32_ep_s *privep, + int len); +static void n32_epout_complete(struct n32_usbdev_s *priv, + struct n32_ep_s *privep); +static inline void n32_ep0out_receive(struct n32_ep_s *privep, + int bcnt); +static inline void n32_epout_receive(struct n32_ep_s *privep, + int bcnt); +static void n32_epout_request(struct n32_usbdev_s *priv, + struct n32_ep_s *privep); + +/* General request handling */ + +static void n32_ep_flush(struct n32_ep_s *privep); +static void n32_req_complete(struct n32_ep_s *privep, + int16_t result); +static void n32_req_cancel(struct n32_ep_s *privep, + int16_t status); + +/* Interrupt handling *******************************************************/ + +static struct +n32_ep_s *n32_ep_findbyaddr(struct n32_usbdev_s *priv, + uint16_t eplog); +static int n32_req_dispatch(struct n32_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl); +static void n32_usbreset(struct n32_usbdev_s *priv); + +/* Second level OUT endpoint interrupt processing */ + +static inline void n32_ep0out_testmode(struct n32_usbdev_s *priv, + uint16_t index); +static inline void n32_ep0out_stdrequest(struct n32_usbdev_s *priv, + struct n32_ctrlreq_s *ctrlreq); +static inline void n32_ep0out_setup(struct n32_usbdev_s *priv); +static inline void n32_epout(struct n32_usbdev_s *priv, + uint8_t epno); +static inline void n32_epout_interrupt(struct n32_usbdev_s *priv); + +/* Second level IN endpoint interrupt processing */ + +static inline void n32_epin_runtestmode(struct n32_usbdev_s *priv); +static inline void n32_epin(struct n32_usbdev_s *priv, uint8_t epno); +static inline void n32_epin_txfifoempty(struct n32_usbdev_s *priv, + int epno); +static inline void n32_epin_interrupt(struct n32_usbdev_s *priv); + +/* Other second level interrupt processing */ + +static inline void n32_resumeinterrupt(struct n32_usbdev_s *priv); +static inline void n32_suspendinterrupt(struct n32_usbdev_s *priv); +static inline void n32_rxinterrupt(struct n32_usbdev_s *priv); +static inline void n32_enuminterrupt(struct n32_usbdev_s *priv); +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void n32_isocininterrupt(struct n32_usbdev_s *priv); +static inline void n32_isocoutinterrupt(struct n32_usbdev_s *priv); +#endif +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void n32_sessioninterrupt(struct n32_usbdev_s *priv); +static inline void n32_otginterrupt(struct n32_usbdev_s *priv); +#endif + +/* First level interrupt processing */ + +static int n32_usbinterrupt(int irq, void *context, + void *arg); + +/* Endpoint operations ******************************************************/ + +/* Global OUT NAK controls */ + +static void n32_enablegonak(struct n32_ep_s *privep); +static void n32_disablegonak(struct n32_ep_s *privep); + +/* Endpoint configuration */ + +static int n32_epout_configure(struct n32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int n32_epin_configure(struct n32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int n32_ep_configure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static void n32_ep0_configure(struct n32_usbdev_s *priv); + +/* Endpoint disable */ + +static void n32_epout_disable(struct n32_ep_s *privep); +static void n32_epin_disable(struct n32_ep_s *privep); +static int n32_ep_disable(struct usbdev_ep_s *ep); + +/* Endpoint request management */ + +static struct usbdev_req_s *n32_ep_allocreq(struct usbdev_ep_s *ep); +static void n32_ep_freereq(struct usbdev_ep_s *ep, + struct usbdev_req_s *); + +/* Endpoint buffer management */ + +#ifdef CONFIG_USBDEV_DMA +static void *n32_ep_allocbuffer(struct usbdev_ep_s *ep, + unsigned bytes); +static void n32_ep_freebuffer(struct usbdev_ep_s *ep, + void *buf); +#endif + +/* Endpoint request submission */ + +static int n32_ep_submit(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Endpoint request cancellation */ + +static int n32_ep_cancel(struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Stall handling */ + +static int n32_epout_setstall(struct n32_ep_s *privep); +static int n32_epin_setstall(struct n32_ep_s *privep); +static int n32_ep_setstall(struct n32_ep_s *privep); +static int n32_ep_clrstall(struct n32_ep_s *privep); +static int n32_ep_stall(struct usbdev_ep_s *ep, bool resume); +static void n32_ep0_stall(struct n32_usbdev_s *priv); + +/* Endpoint allocation */ + +static struct usbdev_ep_s *n32_ep_alloc(struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void n32_ep_free(struct usbdev_s *dev, + struct usbdev_ep_s *ep); + +/* USB device controller operations *****************************************/ + +static int n32_getframe(struct usbdev_s *dev); +static int n32_wakeup(struct usbdev_s *dev); +static int n32_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int n32_pullup(struct usbdev_s *dev, bool enable); +static void n32_setaddress(struct n32_usbdev_s *priv, + uint16_t address); +static int n32_txfifo_flush(uint32_t txfnum); +static int n32_rxfifo_flush(void); + +/* Initialization ***********************************************************/ + +static void n32_swinitialize(struct n32_usbdev_s *priv); +static void n32_hwinitialize(struct n32_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct n32_usbdev_s g_usbhsdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = n32_ep_configure, + .disable = n32_ep_disable, + .allocreq = n32_ep_allocreq, + .freereq = n32_ep_freereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = n32_ep_allocbuffer, + .freebuffer = n32_ep_freebuffer, +#endif + .submit = n32_ep_submit, + .cancel = n32_ep_cancel, + .stall = n32_ep_stall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = n32_ep_alloc, + .freeep = n32_ep_free, + .getframe = n32_getframe, + .wakeup = n32_wakeup, + .selfpowered = n32_selfpowered, + .pullup = n32_pullup, +}; + +/* Device error strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(N32_TRACEERR_ALLOCFAIL), + TRACE_STR(N32_TRACEERR_BADCLEARFEATURE), + TRACE_STR(N32_TRACEERR_BADDEVGETSTATUS), + TRACE_STR(N32_TRACEERR_BADEPNO), + TRACE_STR(N32_TRACEERR_BADEPGETSTATUS), + TRACE_STR(N32_TRACEERR_BADGETCONFIG), + TRACE_STR(N32_TRACEERR_BADGETSETDESC), + TRACE_STR(N32_TRACEERR_BADGETSTATUS), + TRACE_STR(N32_TRACEERR_BADSETADDRESS), + TRACE_STR(N32_TRACEERR_BADSETCONFIG), + TRACE_STR(N32_TRACEERR_BADSETFEATURE), + TRACE_STR(N32_TRACEERR_BADTESTMODE), + TRACE_STR(N32_TRACEERR_BINDFAILED), + TRACE_STR(N32_TRACEERR_DISPATCHSTALL), + TRACE_STR(N32_TRACEERR_DRIVER), + TRACE_STR(N32_TRACEERR_DRIVERREGISTERED), + TRACE_STR(N32_TRACEERR_EP0NOSETUP), + TRACE_STR(N32_TRACEERR_EP0SETUPSTALLED), + TRACE_STR(N32_TRACEERR_EPINNULLPACKET), + TRACE_STR(N32_TRACEERR_EPINUNEXPECTED), + TRACE_STR(N32_TRACEERR_EPOUTNULLPACKET), + TRACE_STR(N32_TRACEERR_EPOUTUNEXPECTED), + TRACE_STR(N32_TRACEERR_INVALIDCTRLREQ), + TRACE_STR(N32_TRACEERR_INVALIDPARMS), + TRACE_STR(N32_TRACEERR_IRQREGISTRATION), + TRACE_STR(N32_TRACEERR_NOEP), + TRACE_STR(N32_TRACEERR_NOTCONFIGURED), + TRACE_STR(N32_TRACEERR_EPOUTQEMPTY), + TRACE_STR(N32_TRACEERR_EPINREQEMPTY), + TRACE_STR(N32_TRACEERR_NOOUTSETUP), + TRACE_STR(N32_TRACEERR_POLLTIMEOUT), + TRACE_STR_END +}; +#endif + +/* Interrupt event strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(N32_TRACEINTID_USB), + TRACE_STR(N32_TRACEINTID_INTPENDING), + TRACE_STR(N32_TRACEINTID_EPOUT), + TRACE_STR(N32_TRACEINTID_EPIN), + TRACE_STR(N32_TRACEINTID_MISMATCH), + TRACE_STR(N32_TRACEINTID_WAKEUP), + TRACE_STR(N32_TRACEINTID_SUSPEND), + TRACE_STR(N32_TRACEINTID_SOF), + TRACE_STR(N32_TRACEINTID_RXFIFO), + TRACE_STR(N32_TRACEINTID_DEVRESET), + TRACE_STR(N32_TRACEINTID_ENUMDNE), + TRACE_STR(N32_TRACEINTID_IISOIXFR), + TRACE_STR(N32_TRACEINTID_IISOOXFR), + TRACE_STR(N32_TRACEINTID_SRQ), + TRACE_STR(N32_TRACEINTID_OTG), + TRACE_STR(N32_TRACEINTID_EPOUT_XFRC), + TRACE_STR(N32_TRACEINTID_EPOUT_EPDISD), + TRACE_STR(N32_TRACEINTID_EPOUT_SETUP), + TRACE_STR(N32_TRACEINTID_DISPATCH), + TRACE_STR(N32_TRACEINTID_GETSTATUS), + TRACE_STR(N32_TRACEINTID_EPGETSTATUS), + TRACE_STR(N32_TRACEINTID_DEVGETSTATUS), + TRACE_STR(N32_TRACEINTID_IFGETSTATUS), + TRACE_STR(N32_TRACEINTID_CLEARFEATURE), + TRACE_STR(N32_TRACEINTID_SETFEATURE), + TRACE_STR(N32_TRACEINTID_SETADDRESS), + TRACE_STR(N32_TRACEINTID_GETSETDESC), + TRACE_STR(N32_TRACEINTID_GETCONFIG), + TRACE_STR(N32_TRACEINTID_SETCONFIG), + TRACE_STR(N32_TRACEINTID_GETSETIF), + TRACE_STR(N32_TRACEINTID_SYNCHFRAME), + TRACE_STR(N32_TRACEINTID_EPIN_XFRC), + TRACE_STR(N32_TRACEINTID_EPIN_TOC), + TRACE_STR(N32_TRACEINTID_EPIN_ITTXFE), + TRACE_STR(N32_TRACEINTID_EPIN_EPDISD), + TRACE_STR(N32_TRACEINTID_EPIN_TXFE), + TRACE_STR(N32_TRACEINTID_EPIN_EMPWAIT), + TRACE_STR(N32_TRACEINTID_OUTNAK), + TRACE_STR(N32_TRACEINTID_OUTRECVD), + TRACE_STR(N32_TRACEINTID_OUTDONE), + TRACE_STR(N32_TRACEINTID_SETUPDONE), + TRACE_STR(N32_TRACEINTID_SETUPRECVD), + TRACE_STR_END +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_getreg + * + * Description: + * Get the contents of an N32 register + * + ****************************************************************************/ + +#if defined(CONFIG_N32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) +static uint32_t n32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + uinfo("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + uinfo("[repeats %" PRId32 " more times]\n", count - 3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + uinfo("%08" PRIx32 "->%08" PRIx32 "\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: n32_putreg + * + * Description: + * Set the contents of an N32 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_N32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) +static void n32_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + uinfo("%08" PRIx32 "->%08" PRIx32 "\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: n32_req_remfirst + * + * Description: + * Remove a request from the head of an endpoint request queue + * + ****************************************************************************/ + +static struct n32_req_s *n32_req_remfirst(struct n32_ep_s *privep) +{ + struct n32_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: n32_req_addlast + * + * Description: + * Add a request to the end of an endpoint request queue + * + ****************************************************************************/ + +static bool n32_req_addlast(struct n32_ep_s *privep, + struct n32_req_s *req) +{ + bool is_empty = !privep->head; + + req->flink = NULL; + if (is_empty) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } + + return is_empty; +} + +/**************************************************************************** + * Name: n32_ep0in_setupresponse + * + * Description: + * Schedule a short transfer on Endpoint 0 (IN or OUT) + * + ****************************************************************************/ + +static void n32_ep0in_setupresponse(struct n32_usbdev_s *priv, + uint8_t *buf, uint32_t nbytes) +{ + n32_epin_transfer(&priv->epin[EP0], buf, nbytes); + priv->ep0state = EP0STATE_SETUPRESPONSE; + n32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: n32_ep0in_transmitzlp + * + * Description: + * Send a zero length packet (ZLP) on endpoint 0 IN + * + ****************************************************************************/ + +static inline void n32_ep0in_transmitzlp(struct n32_usbdev_s *priv) +{ + n32_ep0in_setupresponse(priv, NULL, 0); +} + +/**************************************************************************** + * Name: n32_ep0in_activate + * + * Description: + * Activate the endpoint 0 IN endpoint. + * + ****************************************************************************/ + +static void n32_ep0in_activate(void) +{ + uint32_t regval; + + /* Set the max packet size of the IN EP. */ + + regval = n32_getreg(N32_USBHS_DINEPCTRL(0)); + regval &= ~N32_USBHS_DINEPCTRL_MPLEN_MASK; + + regval |= (CONFIG_USBDEV_EP0_MAXSIZE & N32_USBHS_DINEPCTRL_MPLEN_MASK); + + n32_putreg(regval, N32_USBHS_DINEPCTRL(0)); + + /* Clear global IN NAK */ + + regval = n32_getreg(N32_USBHS_DCTRL); + regval |= N32_USBHS_DCTRL_CGNPINAK; + n32_putreg(regval, N32_USBHS_DCTRL); +} + +/**************************************************************************** + * Name: n32_ep0out_ctrlsetup + * + * Description: + * Setup to receive a SETUP packet. + * + ****************************************************************************/ + +static void n32_ep0out_ctrlsetup(struct n32_usbdev_s *priv) +{ + uint32_t regval; + + /* Setup the hardware to perform the SETUP transfer */ + + regval = (USB_SIZEOF_CTRLREQ * 3 << N32_USBHS_DOUTEP0TXSIZ_TLEN_SHIFT) | + (1 << N32_USBHS_DOUTEP0TXSIZ_PKTCNT_SHIFT) | + (3 << N32_USBHS_DOUTEP0TXSIZ_STUPPCNT_SHIFT); + n32_putreg(regval, N32_USBHS_DOUTEPTXSIZ(0)); + + /* Then clear NAKing and enable the transfer */ + + regval = n32_getreg(N32_USBHS_DOUTEPCTRL(0)); + regval |= (N32_USBHS_DOUTEP0CTRL_CNAK | N32_USBHS_DOUTEP0CTRL_EPEN); + n32_putreg(regval, N32_USBHS_DOUTEPCTRL(0)); +} + +/**************************************************************************** + * Name: n32_txfifo_write + * + * Description: + * Send data to the endpoint's TxFIFO. + * + ****************************************************************************/ + +static void n32_txfifo_write(struct n32_ep_s *privep, + uint8_t *buf, int nbytes) +{ + uint32_t regaddr; + uint32_t regval; + int nwords; + int i; + + /* Convert the number of bytes to words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the TxFIFO for this endpoint (same as the endpoint number) */ + + regaddr = N32_USBHS_DFIFO_DEP(privep->epphy); + + /* Then transfer each word to the TxFIFO */ + + for (i = 0; i < nwords; i++) + { + /* Read four bytes from the source buffer (to avoid unaligned accesses) + * and pack these into one 32-bit word (little endian). + */ + + regval = (uint32_t)*buf++; + regval |= ((uint32_t)*buf++) << 8; + regval |= ((uint32_t)*buf++) << 16; + regval |= ((uint32_t)*buf++) << 24; + + /* Then write the packet data to the TxFIFO */ + + n32_putreg(regval, regaddr); + } +} + +/**************************************************************************** + * Name: n32_epin_transfer + * + * Description: + * Start the Tx data transfer + * + ****************************************************************************/ + +static void n32_epin_transfer(struct n32_ep_s *privep, + uint8_t *buf, int nbytes) +{ + uint32_t pktcnt; + uint32_t regval; + + /* Read the DIEPSIZx register */ + + regval = n32_getreg(N32_USBHS_DINEPTXSIZ(privep->epphy)); + + /* Clear the XFRSIZ, PKTCNT, and MCNT field of the DIEPSIZx register */ + + regval &= ~(N32_USBHS_DINEPTXSIZ_TLEN_MASK | + N32_USBHS_DINEPTXSIZ_PKTCNT_MASK | + N32_USBHS_DINEPTXSIZ_MCNT_MASK); + + /* Are we sending a zero length packet (ZLP) */ + + if (nbytes == 0) + { + /* Yes.. + * leave the transfer size at zero and set the packet count to 1 + */ + + pktcnt = 1; + } + else + { + /* No.. Program the transfer size and packet count. + * First calculate: + * + * xfrsize = The total number of bytes to be sent. + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + */ + + pktcnt = ((uint32_t)nbytes + (privep->ep.maxpacket - 1)) / + privep->ep.maxpacket; + } + + /* Set the XFRSIZ and PKTCNT */ + + regval |= (pktcnt << N32_USBHS_DINEPTXSIZ_PKTCNT_SHIFT); + regval |= ((uint32_t)nbytes << N32_USBHS_DINEPTXSIZ_TLEN_SHIFT); + + /* If this is an isochronous endpoint, then set the multi-count field to + * the PKTCNT as well. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + regval |= (pktcnt << N32_USBHS_DINEPTXSIZ_MCNT_SHIFT); + } + + /* Save DIEPSIZx register value */ + + n32_putreg(regval, N32_USBHS_DINEPTXSIZ(privep->epphy)); + + /* Read the DIEPCTLx register */ + + regval = n32_getreg(N32_USBHS_DINEPCTRL(privep->epphy)); + + /* If this is an isochronous endpoint, then set the even/odd frame bit + * the DIEPCTLx register. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + /* Check bit 0 of the frame number of the received SOF and set the + * even/odd frame to match. + */ + + uint32_t status = n32_getreg(N32_USBHS_DSTS); + + if ((status & N32_USBHS_DSTS_SOFFN0) == N32_USBHS_DSTS_SOFFN_EVEN) + { + regval |= N32_USBHS_DINEPCTRL_SD0PID_SEVNFRM; + } + else + { + regval |= N32_USBHS_DINEPCTRL_SD1PID_SODDFRM; + } + } + + /* EP enable, IN data in FIFO */ + + regval &= ~N32_USBHS_DINEPCTRL_EPDIS; + regval |= (N32_USBHS_DINEPCTRL_CNAK | N32_USBHS_DINEPCTRL_EPEN); + n32_putreg(regval, N32_USBHS_DINEPCTRL(privep->epphy)); + + /* Transfer the data to the TxFIFO. At this point, the caller has already + * assured that there is sufficient space in the TxFIFO to hold the + * transfer we can just blindly continue. + */ + + n32_txfifo_write(privep, buf, nbytes); +} + +/**************************************************************************** + * Name: n32_epin_request + * + * Description: + * Begin or continue write request processing. + * + ****************************************************************************/ + +static void n32_epin_request(struct n32_usbdev_s *priv, + struct n32_ep_s *privep) +{ + struct n32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint8_t *buf; + int nbytes; + int nwords; + int bytesleft; + + /* We get here in one of four possible ways. From three interrupting + * events: + * + * 1. From n32_epin as part of the transfer complete interrupt processing + * This interrupt indicates that the last transfer has completed. + * 2. As part of the ITTXFE interrupt processing. That interrupt indicates + * that an IN token was received when the associated TxFIFO was empty. + * 3. From n32_epin_txfifoempty as part of the TXFE interrupt processing. + * The TXFE interrupt is only enabled when the TxFIFO is full and the + * software must wait for space to become available in the TxFIFO. + * + * And this function may be called immediately when the write request is + * queue to start up the next transaction. + * + * 4. From n32_ep_submit when a new write request is received WHILE the + * endpoint is not active (privep->active == false). + */ + + /* Check the request from the head of the endpoint request queue */ + + privreq = n32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_EPINREQEMPTY), privep->epphy); + + /* There is no TX transfer in progress and no new pending TX + * requests to send. To stop transmitting any data on a particular + * IN endpoint, the application must set the IN NAK bit. To set this + * bit, the following field must be programmed. + */ + + regaddr = N32_USBHS_DINEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + regval |= N32_USBHS_DINEPCTRL_SNAK; + n32_putreg(regval, regaddr); + + /* The endpoint is no longer active */ + + privep->active = false; + return; + } + + uinfo("EP%" PRId8 " req=%p: len=%" PRId16 " xfrd=%" PRId16" zlp=%" + PRId8 "\n", privep->epphy, privreq, privreq->req.len, + privreq->req.xfrd, privep->zlp); + + /* Check for a special case: If we are just starting a request (xfrd==0) + * and the class driver is trying to send a zero-length packet (len==0). + * Then set the ZLP flag so that the packet will be sent. + */ + + if (privreq->req.len == 0) + { + /* The ZLP flag is set TRUE whenever we want to force the driver to + * send a zero-length-packet on the next pass through the loop (below). + * The flag is cleared whenever a packet is sent in the loop below. + */ + + privep->zlp = true; + } + + /* Add one more packet to the TxFIFO. We will wait for the transfer + * complete event before we add the next packet (or part of a packet + * to the TxFIFO). + * + * The documentation says that we can can multiple packets to the TxFIFO, + * but it seems that we need to get the transfer complete event before + * we can add the next (or maybe I have got something wrong?) + */ + +#if 0 + while (privreq->req.xfrd < privreq->req.len || privep->zlp) +#else + if (privreq->req.xfrd < privreq->req.len || privep->zlp) +#endif + { + /* Get the number of bytes left to be sent in the request */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + nbytes = bytesleft; + + /* Assume no zero-length-packet on the next pass through this loop */ + + privep->zlp = false; + + /* Limit the size of the transfer to one full packet and handle + * zero-length packets (ZLPs). + */ + + if (nbytes > 0) + { + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + if (nbytes >= privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + + /* Handle the case where this packet is exactly the + * maxpacketsize. Do we need to send a zero-length packet + * in this case? + */ + + if (bytesleft == privep->ep.maxpacket && + (privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + /* The ZLP flag is set TRUE whenever we want to force + * the driver to send a zero-length-packet on the next + * pass through this loop. The flag is cleared (above) + * whenever we are committed to sending any packet and + * set here when we want to force one more pass through + * the loop. + */ + + privep->zlp = true; + } + } + } + + /* Get the transfer size in 32-bit words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the number of 32-bit words available in the TxFIFO. The + * DXTFSTS indicates the amount of free space available in the + * endpoint TxFIFO. Values are in terms of 32-bit words: + * + * 0: Endpoint TxFIFO is full + * 1: 1 word available + * 2: 2 words available + * n: n words available + */ + + regaddr = N32_USBHS_DINEPTXFSTS(privep->epphy); + + /* Check for space in the TxFIFO. If space in the TxFIFO is not + * available, then set up an interrupt to resume the transfer when + * the TxFIFO is empty. + */ + + regval = n32_getreg(regaddr); + if ((int)(regval & N32_USBHS_DINEPTXFSTS_TXFSPCAVL_MASK) < nwords) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPIN_EMPWAIT), + (uint16_t)regval); + + /* There is insufficient space in the TxFIFO. Wait for a TxFIFO + * empty interrupt and try again. + */ + + uint32_t empmsk = n32_getreg(N32_USBHS_DINEPFEINTEN); + + empmsk |= N32_USBHS_DINEPFEINTEN_IEP(privep->epphy); + n32_putreg(empmsk, N32_USBHS_DINEPFEINTEN); + +#ifdef CONFIG_DEBUG_FEATURES + /* Check if the configured TXFIFO size is sufficient for a given + * request. If not, raise an assertion here. + */ + + regval = n32_getreg(N32_USBHS_DINEPPTXFSIZ(privep->epphy)); + regval &= N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_MASK; + regval >>= N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT; + uerr("EP%" PRId8 " TXLEN=%" PRId32 " nwords=%d\n", + privep->epphy, regval, nwords); + DEBUGASSERT(regval >= nwords); +#endif + + /* Terminate the transfer. We will try again when the TxFIFO empty + * interrupt is received. + */ + + return; + } + + /* Transfer data to the TxFIFO */ + + buf = privreq->req.buf + privreq->req.xfrd; + n32_epin_transfer(privep, buf, nbytes); + + /* If it was not before, the OUT endpoint is now actively transferring + * data. + */ + + privep->active = true; + + /* EP0 is a special case */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_IN; + } + + /* Update for the next time through the loop */ + + privreq->req.xfrd += nbytes; + } + + /* Note that the ZLP, if any, must be sent as a separate transfer. + * The need for a ZLP is indicated by privep->zlp. If all of the + * bytes were sent (including any final null packet) then we are + * finished with the transfer + */ + + if (privreq->req.xfrd >= privreq->req.len && !privep->zlp) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + + /* We are finished with the request (although the transfer has not + * yet completed). + */ + + n32_req_complete(privep, OK); + } +} + +/**************************************************************************** + * Name: n32_rxfifo_read + * + * Description: + * Read packet from the RxFIFO into a read request. + * + ****************************************************************************/ + +static void n32_rxfifo_read(struct n32_ep_s *privep, + uint8_t *dest, uint16_t len) +{ + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO. Note: there is only one RxFIFO so + * we might as well use the address associated with EP0. + */ + + regaddr = N32_USBHS_DFIFO_DEP(EP0); + + /* Read 32-bits and write 4 x 8-bits at time + * (to avoid unaligned accesses) + */ + + for (i = 0; i < len; i += 4) + { + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Read 1 x 32-bits of EP0 packet data */ + + data.w = n32_getreg(regaddr); + + /* Write 4 x 8-bits of EP0 packet data */ + + *dest++ = data.b[0]; + *dest++ = data.b[1]; + *dest++ = data.b[2]; + *dest++ = data.b[3]; + } +} + +/**************************************************************************** + * Name: n32_rxfifo_discard + * + * Description: + * Discard packet data from the RxFIFO. + * + ****************************************************************************/ + +static void n32_rxfifo_discard(struct n32_ep_s *privep, int len) +{ + if (len > 0) + { + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO Note: there is only one RxFIFO so + * we might as well use the address associated with EP0. + */ + + regaddr = N32_USBHS_DFIFO_DEP(EP0); + + /* Read 32-bits at time */ + + for (i = 0; i < len; i += 4) + { + volatile uint32_t data = n32_getreg(regaddr); + + UNUSED(data); + } + } +} + +/**************************************************************************** + * Name: n32_epout_complete + * + * Description: + * This function is called when an OUT transfer complete interrupt is + * received. It completes the read request at the head of the endpoint's + * request queue. + * + ****************************************************************************/ + +static void n32_epout_complete(struct n32_usbdev_s *priv, + struct n32_ep_s *privep) +{ + struct n32_req_s *privreq; + + /* Since a transfer just completed, there must be a read request at the + * head of the endpoint request queue. + */ + + privreq = n32_rqpeek(privep); + DEBUGASSERT(privreq); + + if (!privreq) + { + /* An OUT transfer completed, but no packet to receive the data. This + * should not happen. + */ + + usbtrace(TRACE_DEVERROR(N32_TRACEERR_EPOUTQEMPTY), + privep->epphy); + privep->active = false; + return; + } + + uinfo("EP%d: len=%zu xfrd=%zu\n", + privep->epphy, privreq->req.len, privreq->req.xfrd); + + /* Return the completed read request to the class driver and mark the + * state IDLE. + */ + + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + n32_req_complete(privep, OK); + privep->active = false; + + /* Now set up the next read request (if any) */ + + n32_epout_request(priv, privep); +} + +/**************************************************************************** + * Name: n32_ep0out_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new + * incoming data is available in the endpoint's RxFIFO. This function + * will simply copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void n32_ep0out_receive(struct n32_ep_s *privep, + int bcnt) +{ + struct n32_usbdev_s *priv; + + /* Sanity Checking */ + + DEBUGASSERT(privep && privep->dev); + priv = (struct n32_usbdev_s *)privep->dev; + + uinfo("EP0: bcnt=%d\n", bcnt); + usbtrace(TRACE_READ(EP0), bcnt); + + /* Verify that an OUT SETUP request as received before this data was + * received in the RxFIFO. + */ + + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Read the data into our special buffer for SETUP data */ + + int readlen = MIN(CONFIG_USBDEV_SETUP_MAXDATASIZE, bcnt); + + n32_rxfifo_read(privep, priv->ep0data, readlen); + + /* Do we have to discard any excess bytes? */ + + n32_rxfifo_discard(privep, bcnt - readlen); + + /* Now we can process the setup command */ + + privep->active = false; + priv->ep0state = EP0STATE_SETUP_READY; + priv->ep0datlen = readlen; + + n32_ep0out_setup(priv); + } + else + { + /* This is an error. We don't have any idea what to do with the EP0 + * data in this case. Just read and discard it so that the RxFIFO + * does not become constipated. + */ + + usbtrace(TRACE_DEVERROR(N32_TRACEERR_NOOUTSETUP), priv->ep0state); + n32_rxfifo_discard(privep, bcnt); + privep->active = false; + } +} + +/**************************************************************************** + * Name: n32_epout_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new + * incoming data is available in the endpoint's RxFIFO. This function + * will simply copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void n32_epout_receive(struct n32_ep_s *privep, + int bcnt) +{ + struct n32_req_s *privreq; + uint8_t *dest; + int buflen; + int readlen; + + /* Get a reference to the request at the head of the endpoint's request + * queue. + */ + + privreq = n32_rqpeek(privep); + if (!privreq) + { + /* Incoming data is available in the RxFIFO, but there is no read setup + * to receive the receive the data. This should not happen for data + * endpoints; those endpoints should have been NAKing any OUT data + * tokens. + * + * We should get here normally on OUT data phase following an OUT + * SETUP command. EP0 data will still receive data in this case and it + * should not be NAKing. + */ + + if (privep->epphy == 0) + { + n32_ep0out_receive(privep, bcnt); + } + else + { + /* Otherwise, the data is lost. This really should not happen if + * NAKing is working as expected. + */ + + usbtrace(TRACE_DEVERROR(N32_TRACEERR_EPOUTQEMPTY), + privep->epphy); + + /* Discard the data in the RxFIFO */ + + n32_rxfifo_discard(privep, bcnt); + } + + privep->active = false; + return; + } + + uinfo("EP%d: len=%zu xfrd=%zu\n", privep->epphy, + privreq->req.len, privreq->req.xfrd); + usbtrace(TRACE_READ(privep->epphy), bcnt); + + /* Get the number of bytes to transfer from the RxFIFO */ + + buflen = privreq->req.len - privreq->req.xfrd; + DEBUGASSERT(buflen > 0 && buflen >= bcnt); + readlen = MIN(buflen, bcnt); + + /* Get the destination of the data transfer */ + + dest = privreq->req.buf + privreq->req.xfrd; + + /* Transfer the data from the RxFIFO to the request's data buffer */ + + n32_rxfifo_read(privep, dest, readlen); + + /* If there were more bytes in the RxFIFO than could be held in the read + * request, then we will have to discard those. + */ + + n32_rxfifo_discard(privep, bcnt - readlen); + + /* Update the number of bytes transferred */ + + privreq->req.xfrd += readlen; +} + +/**************************************************************************** + * Name: n32_epout_request + * + * Description: + * This function is called when either + * (1) new read request is received, or + * (2) a pending receive request completes. If there is no read in + * pending, then this function will initiate the next OUT (read) operation. + * + ****************************************************************************/ + +static void n32_epout_request(struct n32_usbdev_s *priv, + struct n32_ep_s *privep) +{ + struct n32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint32_t xfrsize; + uint32_t pktcnt; + + /* Make sure that there is not already a pending request request. + * If there is, just return, leaving the newly received request + * in the request queue. + */ + + if (!privep->active) + { + /* Loop until a valid request is found (or the request queue is empty). + * The loop is only need to look at the request queue again is an + * invalid read request is encountered. + */ + + for (; ; ) + { + /* Get a reference to the request at the head of the endpoint's + * request queue + */ + + privreq = n32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_EPOUTQEMPTY), + privep->epphy); + + /* There are no read requests to be setup. Configure the + * hardware to NAK any incoming packets. (This should already + * be the case. I think that the hardware will automatically + * NAK after a transfer is completed until SNAK is cleared). + */ + + regaddr = N32_USBHS_DOUTEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + regval |= N32_USBHS_DOUTEPCTRL_SNAK; + n32_putreg(regval, regaddr); + + /* This endpoint is no longer actively transferring */ + + privep->active = false; + return; + } + + uinfo("EP%d: len=%d\n", privep->epphy, privreq->req.len); + + /* Ignore any attempt to receive a zero length packet (this really + * should not happen. + */ + + if (privreq->req.len <= 0) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_EPOUTNULLPACKET), 0); + n32_req_complete(privep, OK); + } + + /* Otherwise, we have a usable read request... + * break out of the loop + */ + + else + { + break; + } + } + + /* Setup the pending read into the request buffer. First calculate: + * + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + * xfrsize = The total number of bytes required (in units of + * maxpacket bytes). + */ + + pktcnt = (privreq->req.len + (privep->ep.maxpacket - 1)) / + privep->ep.maxpacket; + xfrsize = pktcnt * privep->ep.maxpacket; + + /* Then setup the hardware to perform this transfer */ + + regaddr = N32_USBHS_DOUTEPTXSIZ(privep->epphy); + regval = n32_getreg(regaddr); + regval &= ~(N32_USBHS_DOUTEPTXSIZ_TLEN_MASK | + N32_USBHS_DOUTEPTXSIZ_PKTCNT_MASK); + regval |= (xfrsize << N32_USBHS_DOUTEPTXSIZ_TLEN_SHIFT); + regval |= (pktcnt << N32_USBHS_DOUTEPTXSIZ_PKTCNT_SHIFT); + n32_putreg(regval, regaddr); + + /* Then enable the transfer */ + + regaddr = N32_USBHS_DOUTEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + + /* When an isochronous transfer is enabled the Even/Odd frame bit must + * also be set appropriately. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + if (privep->odd) + { + regval |= N32_USBHS_DOUTEPCTRL_SD1PID_SODDFRM; + } + else + { + regval |= N32_USBHS_DOUTEPCTRL_SD0PID_SEVNFRM; + } + } +#endif + + /* Clearing NAKing and enable the transfer. */ + + regval |= (N32_USBHS_DOUTEPCTRL_CNAK | N32_USBHS_DOUTEPCTRL_EPEN); + n32_putreg(regval, regaddr); + + /* A transfer is now active on this endpoint */ + + privep->active = true; + + /* EP0 is a special case. We need to know when to switch back to + * normal SETUP processing. + */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_OUT; + } + } +} + +/**************************************************************************** + * Name: n32_ep_flush + * + * Description: + * Flush any primed descriptors from this ep + * + ****************************************************************************/ + +static void n32_ep_flush(struct n32_ep_s *privep) +{ + if (privep->isin) + { + n32_txfifo_flush(N32_USBHS_GRSTCTRL_TXFNUM_D(privep->epphy)); + } + else + { + n32_rxfifo_flush(); + } +} + +/**************************************************************************** + * Name: n32_req_complete + * + * Description: + * Handle termination of the request at the head of the endpoint request + * queue. + * + ****************************************************************************/ + +static void n32_req_complete(struct n32_ep_s *privep, int16_t result) +{ + struct n32_req_s *privreq; + + /* Remove the request at the head of the request list */ + + privreq = n32_req_remfirst(privep); + DEBUGASSERT(privreq != NULL); + + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + + if (privep->epphy == EP0) + { + privep->stalled = privep->dev->stalled; + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: n32_req_cancel + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void n32_req_cancel(struct n32_ep_s *privep, int16_t status) +{ + if (!n32_rqempty(privep)) + { + n32_ep_flush(privep); + } + + while (!n32_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(privep->epphy), + (n32_rqpeek(privep))->req.xfrd); + n32_req_complete(privep, status); + } +} + +/**************************************************************************** + * Name: n32_ep_findbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct n32_ep_s *n32_ep_findbyaddr(struct n32_usbdev_s *priv, + uint16_t eplog) +{ + struct n32_ep_s *privep; + uint8_t epphy = USB_EPNO(eplog); + + if (epphy >= N32_USBHS_NENDPOINTS) + { + return NULL; + } + + /* Is this an IN or an OUT endpoint? */ + + if (USB_ISEPIN(eplog)) + { + privep = &priv->epin[epphy]; + } + else + { + privep = &priv->epout[epphy]; + } + + /* Return endpoint reference */ + + DEBUGASSERT(privep->epphy == epphy); + return privep; +} + +/**************************************************************************** + * Name: n32_req_dispatch + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically + * part of the USB interrupt handler. + * + ****************************************************************************/ + +static int n32_req_dispatch(struct n32_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret = -EIO; + + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_DISPATCH), 0); + if (priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, + priv->ep0data, priv->ep0datlen); + } + + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(N32_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = true; + } + + return ret; +} + +/**************************************************************************** + * Name: n32_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void n32_usbreset(struct n32_usbdev_s *priv) +{ + struct n32_ep_s *privep; + uint32_t regval; + int i; + + /* Clear the Remote Wake-up Signaling */ + + regval = n32_getreg(N32_USBHS_DCTRL); + regval &= ~N32_USBHS_DCTRL_RMWKUP; + n32_putreg(regval, N32_USBHS_DCTRL); + + /* Flush the EP0 Tx FIFO */ + + n32_txfifo_flush(N32_USBHS_GRSTCTRL_TXFNUM_D(EP0)); + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. + */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Mark all endpoints as available */ + + priv->epavail[0] = N32_EP_AVAILABLE; + priv->epavail[1] = N32_EP_AVAILABLE; + + /* Disable all end point interrupts */ + + for (i = 0; i < N32_USBHS_NENDPOINTS ; i++) + { + /* Disable endpoint interrupts */ + + n32_putreg(0xff, N32_USBHS_DINEPINTSTS(i)); + n32_putreg(0xff, N32_USBHS_DOUTEPINTSTS(i)); + + /* Return write requests to the class implementation */ + + privep = &priv->epin[i]; + n32_req_cancel(privep, -ESHUTDOWN); + + /* Reset IN endpoint status */ + + privep->stalled = false; + privep->active = false; + privep->zlp = false; + + /* Return read requests to the class implementation */ + + privep = &priv->epout[i]; + n32_req_cancel(privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + privep->active = false; + privep->zlp = false; + } + + n32_putreg(0xffffffff, N32_USBHS_DAEPINTSTS); + + /* Mask all device endpoint interrupts except EP0 */ + + regval = (N32_USBHS_DAINT_IEP(EP0) | N32_USBHS_DAINT_OEP(EP0)); + n32_putreg(regval, N32_USBHS_DAEPINTEN); + + /* Unmask OUT interrupts */ + + regval = (N32_USBHS_DOUTEPINTEN_TXCIEN | + N32_USBHS_DOUTEPINTEN_STUPDNEIEN | N32_USBHS_DOUTEPINTEN_EPDIEN); + n32_putreg(regval, N32_USBHS_DOUTEPINTEN); + + /* Unmask IN interrupts */ + + regval = (N32_USBHS_DINEPINTEN_TXCIEN | N32_USBHS_DINEPINTEN_EPDIEN | + N32_USBHS_DINEPINTEN_TOIEN); + n32_putreg(regval, N32_USBHS_DINEPINTEN); + + /* Reset device address to 0 */ + + n32_setaddress(priv, 0); + priv->devstate = DEVSTATE_DEFAULT; +#ifndef CONFIG_N32H7_USBHS_FS + priv->usbdev.speed = USB_SPEED_HIGH; +#else + priv->usbdev.speed = USB_SPEED_FULL; +#endif + + /* Re-configure EP0 */ + + n32_ep0_configure(priv); + + /* Setup EP0 to receive SETUP packets */ + + n32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: n32_ep0out_testmode + * + * Description: + * Select test mode + * + ****************************************************************************/ + +static inline void n32_ep0out_testmode(struct n32_usbdev_s *priv, + uint16_t index) +{ + uint8_t testmode; + + testmode = index >> 8; + switch (testmode) + { + case 1: + priv->testmode = N32_USBHS_TESTMODE_J; + break; + + case 2: + priv->testmode = N32_USBHS_TESTMODE_K; + break; + + case 3: + priv->testmode = N32_USBHS_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = N32_USBHS_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = N32_USBHS_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = N32_USBHS_TESTMODE_DISABLED; + priv->stalled = true; + } + + priv->dotest = true; + n32_ep0in_transmitzlp(priv); +} + +/**************************************************************************** + * Name: n32_ep0out_stdrequest + * + * Description: + * Handle a standard request on EP0. Pick off the things of interest to + * the USB device controller driver; pass what is left to the class driver. + * + ****************************************************************************/ + +static inline +void n32_ep0out_stdrequest(struct n32_usbdev_s *priv, + struct n32_ctrlreq_s *ctrlreq) +{ + struct n32_ep_s *privep; + + /* Handle standard request */ + + switch (ctrlreq->req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPGETSTATUS), + 0); + privep = n32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) + { + usbtrace(TRACE_DEVERROR( + N32_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0data[0] = + (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + n32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (ctrlreq->index == 0) + { + usbtrace(TRACE_INTDECODE( + N32_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup and self-powered */ + + priv->ep0data[0] = (priv->selfpowered << + USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << + USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + n32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + else + { + usbtrace(TRACE_DEVERROR( + N32_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_IFGETSTATUS), + 0); + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; + + n32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADGETSTATUS), 0); + priv->stalled = true; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = n32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + n32_ep_clrstall(privep); + n32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + n32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ + + n32_req_dispatch(priv, &priv->ctrlreq); + } + } + else + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = n32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + n32_ep_setstall(privep); + n32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + n32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + n32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ + + n32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + else + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_SETADDRESS), + ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. + * We cannot actually change to the next address until + * the completion of the status phase. + */ + + n32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + n32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) + { + n32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + n32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ + + int ret = n32_req_dispatch(priv, &priv->ctrlreq); + + /* If the class driver accepted the configuration, then mark + * the device state as configured (or not, depending on the + * configuration). + */ + + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_GETSETIF), 0); + n32_req_dispatch(priv, &priv->ctrlreq); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; + } +} + +/**************************************************************************** + * Name: n32_ep0out_setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void n32_ep0out_setup(struct n32_usbdev_s *priv) +{ + struct n32_ctrlreq_s ctrlreq; + + /* Verify that a SETUP was received */ + + if (priv->ep0state != EP0STATE_SETUP_READY) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_EP0NOSETUP), priv->ep0state); + return; + } + + /* Terminate any pending requests */ + + n32_req_cancel(&priv->epout[EP0], -EPROTO); + n32_req_cancel(&priv->epin[EP0], -EPROTO); + + /* Assume NOT stalled */ + + priv->epout[EP0].stalled = false; + priv->epin[EP0].stalled = false; + priv->stalled = false; + + /* Starting to process a control request - update state */ + + priv->ep0state = EP0STATE_SETUP_PROCESS; + + /* And extract the little-endian 16-bit values to host order */ + + ctrlreq.type = priv->ctrlreq.type; + ctrlreq.req = priv->ctrlreq.req; + ctrlreq.value = GETUINT16(priv->ctrlreq.value); + ctrlreq.index = GETUINT16(priv->ctrlreq.index); + ctrlreq.len = GETUINT16(priv->ctrlreq.len); + + uinfo("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrlreq.type, ctrlreq.req, ctrlreq.value, + ctrlreq.index, ctrlreq.len); + + /* Check for a standard request */ + + if ((ctrlreq.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + /* Dispatch any non-standard requests */ + + n32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + /* Handle standard requests. */ + + n32_ep0out_stdrequest(priv, &ctrlreq); + } + + /* Check if the setup processing resulted in a STALL */ + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_EP0SETUPSTALLED), + priv->ep0state); + n32_ep0_stall(priv); + } + + /* Reset state/data associated with the SETUP request */ + + priv->ep0datlen = 0; +} + +/**************************************************************************** + * Name: n32_epout + * + * Description: + * This is part of the OUT endpoint interrupt processing. This function + * handles the OUT event for a single endpoint. + * + ****************************************************************************/ + +static inline void n32_epout(struct n32_usbdev_s *priv, uint8_t epno) +{ + struct n32_ep_s *privep; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + privep = &priv->epout[EP0]; + + /* In the EP0STATE_DATA_OUT state, we are receiving data into the + * request buffer. In that case, we must continue the request + * processing. + */ + + if (priv->ep0state == EP0STATE_DATA_OUT) + { + /* Continue processing data from the EP0 OUT request queue */ + + n32_epout_complete(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + n32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an OUT request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + n32_epout_complete(priv, &priv->epout[epno]); + } +} + +/**************************************************************************** + * Name: n32_epout_interrupt + * + * Description: + * USB OUT endpoint interrupt handler. The core generates this interrupt + * when there is an interrupt is pending on one of the OUT endpoints of the + * core. The driver must read the OTG DAINT register to determine the exact + * number of the OUT endpoint on which the interrupt occurred, and then + * read the corresponding OTG DOEPINTx register to determine the exact + * cause of the interrupt. + * + ****************************************************************************/ + +static inline void n32_epout_interrupt(struct n32_usbdev_s *priv) +{ + uint32_t daint; + uint32_t regval; + uint32_t doepint; + int epno; + + /* Get the pending, enabled interrupts for the OUT endpoint from the + * endpoint interrupt status register. + */ + + regval = n32_getreg(N32_USBHS_DAEPINTSTS); + regval &= n32_getreg(N32_USBHS_DAEPINTEN); + daint = (regval & N32_USBHS_DAINT_OEP_MASK) >> N32_USBHS_DAINT_OEP_SHIFT; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + regval = n32_getreg(N32_USBHS_DAEPINTSTS); + daint = (regval & N32_USBHS_DAINT_OEP_MASK) >> + N32_USBHS_DAINT_OEP_SHIFT; + + usbtrace(TRACE_DEVERROR(N32_TRACEERR_EPOUTUNEXPECTED), + (uint16_t)regval); + + epno = 0; + while (daint) + { + if ((daint & 1) != 0) + { + regval = n32_getreg(N32_USBHS_DOUTEPINTSTS(epno)); + uerr("DOEPINT(%d) = %08" PRIx32 "\n", epno, regval); + n32_putreg(0xff, N32_USBHS_DOUTEPINTSTS(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an OUT interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Yes.. get the OUT endpoint interrupt status */ + + doepint = n32_getreg(N32_USBHS_DOUTEPINTSTS(epno)); + doepint &= n32_getreg(N32_USBHS_DOUTEPINTEN); + + /* Transfer completed interrupt. This interrupt is triggered when + * n32_rxinterrupt() removes the last packet data from the + * RxFIFO. In this case, core internally sets the NAK bit for this + * endpoint to prevent it from receiving any more packets. + */ + + if ((doepint & N32_USBHS_DOUTEPINTSTS_TXCIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPOUT_XFRC), + (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + n32_putreg(N32_USBHS_DOUTEPINTSTS_TXCIF, + N32_USBHS_DOUTEPINTSTS(epno)); + + /* Handle the RX transfer data ready event */ + + n32_epout(priv, epno); + } + + /* Endpoint disabled interrupt (ignored because this interrupt is + * used in polled mode by the endpoint disable logic). + */ +#if 1 + /* REVISIT: */ + + if ((doepint & N32_USBHS_DOUTEPINTSTS_EPDISIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPOUT_EPDISD), + (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + n32_putreg(N32_USBHS_DOUTEPINTSTS_EPDISIF, + N32_USBHS_DOUTEPINTSTS(epno)); + } +#endif + + /* Setup Phase Done (control EPs) */ + + if ((doepint & N32_USBHS_DOUTEPINTSTS_STUPPDNEIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPOUT_SETUP), + priv->ep0state); + + /* Handle the receipt of the IN SETUP packets now (OUT setup + * packet processing may be delayed until the accompanying + * OUT DATA is received) + */ + + if (priv->ep0state == EP0STATE_SETUP_READY) + { + n32_ep0out_setup(priv); + } + + n32_putreg(N32_USBHS_DOUTEPINTSTS_STUPPDNEIF, + N32_USBHS_DOUTEPINTSTS(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: n32_epin_runtestmode + * + * Description: + * Execute the test mode setup by the SET FEATURE request + * + ****************************************************************************/ + +static inline void n32_epin_runtestmode(struct n32_usbdev_s *priv) +{ + uint32_t regval = n32_getreg(N32_USBHS_DCTRL); + + regval &= N32_USBHS_DCTRL_TSCTRL_MASK; + regval |= (uint32_t)priv->testmode << N32_USBHS_DCTRL_TSCTRL_SHIFT; + n32_putreg(regval , N32_USBHS_DCTRL); + + priv->dotest = 0; + priv->testmode = N32_USBHS_TESTMODE_DISABLED; +} + +/**************************************************************************** + * Name: n32_epin + * + * Description: + * This is part of the IN endpoint interrupt processing. This function + * handles the IN event for a single endpoint. + * + ****************************************************************************/ + +static inline void n32_epin(struct n32_usbdev_s *priv, uint8_t epno) +{ + struct n32_ep_s *privep = &priv->epin[epno]; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + /* In the EP0STATE_DATA_IN state, we are sending data from request + * buffer. In that case, we must continue the request processing. + */ + + if (priv->ep0state == EP0STATE_DATA_IN) + { + /* Continue processing data from the EP0 OUT request queue */ + + n32_epin_request(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + n32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + + /* Test mode is another special case */ + + if (priv->dotest) + { + n32_epin_runtestmode(priv); + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an IN request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + /* Continue processing data from the endpoint write request queue */ + + n32_epin_request(priv, privep); + } +} + +/**************************************************************************** + * Name: n32_epin_txfifoempty + * + * Description: + * TxFIFO empty interrupt handling + * + ****************************************************************************/ + +static inline void n32_epin_txfifoempty(struct n32_usbdev_s *priv, + int epno) +{ + struct n32_ep_s *privep = &priv->epin[epno]; + + /* Continue processing the write request queue. This may mean sending + * more data from the existing request or terminating the current requests + * and (perhaps) starting the IN transfer from the next write request. + */ + + n32_epin_request(priv, privep); +} + +/**************************************************************************** + * Name: n32_epin_interrupt + * + * Description: + * USB IN endpoint interrupt handler. The core generates this interrupt + * when an interrupt is pending on one of the IN endpoints of the core. The + * driver must read the OTG DAINT register to determine the exact number of + * the IN endpoint on which the interrupt occurred, and then read the + * corresponding OTG DIEPINTx register to determine the exact cause of the + * interrupt. + * + ****************************************************************************/ + +static inline void n32_epin_interrupt(struct n32_usbdev_s *priv) +{ + uint32_t diepint; + uint32_t daint; + uint32_t mask; + uint32_t empty; + int epno; + + /* Get the pending, enabled interrupts for the IN endpoint from the + * endpoint interrupt status register. + */ + + daint = n32_getreg(N32_USBHS_DAEPINTSTS); + daint &= n32_getreg(N32_USBHS_DAEPINTEN); + daint &= N32_USBHS_DAINT_IEP_MASK; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + daint = n32_getreg(N32_USBHS_DAEPINTSTS); + usbtrace(TRACE_DEVERROR(N32_TRACEERR_EPINUNEXPECTED), + (uint16_t)daint); + + daint &= N32_USBHS_DAINT_IEP_MASK; + epno = 0; + + while (daint) + { + if ((daint & 1) != 0) + { + uerr("DIEPINT(%d) = %08" PRIx32 "\n", + epno, n32_getreg(N32_USBHS_DINEPINTSTS(epno))); + n32_putreg(0xff, N32_USBHS_DINEPINTSTS(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an IN interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Get IN interrupt mask register. Bits 0-6 correspond to enabled + * interrupts as will be found in the DIEPINT interrupt status + * register. + */ + + mask = n32_getreg(N32_USBHS_DINEPINTEN); + + /* Check if the TxFIFO not empty interrupt is enabled for this + * endpoint in the DIEPMSK register. Bits n corresponds to + * endpoint n in the register. That condition corresponds to + * bit 7 of the DIEPINT interrupt status register. There is + * no TXFE bit in the mask register, so we fake one here. + */ + + empty = n32_getreg(N32_USBHS_DINEPFEINTEN); + if ((empty & N32_USBHS_DINEPFEINTEN_IEP(epno)) != 0) + { + mask |= N32_USBHS_DINEPINTSTS_TXFEIF; + } + + /* Now, read the interrupt status and mask out all disabled + * interrupts. + */ + + diepint = n32_getreg(N32_USBHS_DINEPINTSTS(epno)) & mask; + + /* Decode and process the enabled, pending interrupts */ + + /* Transfer completed interrupt */ + + if ((diepint & N32_USBHS_DINEPINTSTS_TXCIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPIN_XFRC), + (uint16_t)diepint); + + /* It is possible that logic may be waiting for a the + * TxFIFO to become empty. We disable the TxFIFO empty + * interrupt here; it will be re-enabled if there is still + * insufficient space in the TxFIFO. + */ + + empty &= ~N32_USBHS_DINEPFEINTEN_IEP(epno); + n32_putreg(empty, N32_USBHS_DINEPFEINTEN); + n32_putreg(N32_USBHS_DINEPINTSTS_TXCIF, + N32_USBHS_DINEPINTSTS(epno)); + + /* IN transfer complete */ + + n32_epin(priv, epno); + } + + /* Timeout condition */ + + if ((diepint & N32_USBHS_DINEPINTSTS_TOUTIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPIN_TOC), + (uint16_t)diepint); + n32_putreg(N32_USBHS_DINEPINTSTS_TOUTIF, + N32_USBHS_DINEPINTSTS(epno)); + } + + /* IN token received when TxFIFO is empty. Applies to non-periodic + * IN endpoints only. This interrupt indicates that an IN token + * was received when the associated TxFIFO (periodic/non-periodic) + * was empty. This interrupt is asserted on the endpoint for which + * the IN token was received. + */ + + if ((diepint & N32_USBHS_DINEPINTSTS_TXFERINTIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPIN_ITTXFE), + (uint16_t)diepint); + n32_epin_request(priv, &priv->epin[epno]); + n32_putreg(N32_USBHS_DINEPINTSTS_TXFERINTIF, + N32_USBHS_DINEPINTSTS(epno)); + } + + /* IN endpoint NAK effective (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & N32_USBHS_DINEPINTSTS_INEPNAKEIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPIN_INEPNE), + (uint16_t)diepint); + n32_putreg(N32_USBHS_DINEPINTSTS_INEPNAKEIF, + N32_USBHS_DINEPINTSTS(epno)); + } +#endif + + /* Endpoint disabled interrupt (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & N32_USBHS_DINEPINTSTS_EPDISIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPIN_EPDISD), + (uint16_t)diepint); + n32_putreg(N32_USBHS_DINEPINTSTS_EPDISIF, + N32_USBHS_DINEPINTSTS(epno)); + } +#endif + + /* Transmit FIFO empty */ + + if ((diepint & N32_USBHS_DINEPINTSTS_TXFEIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPIN_TXFE), + (uint16_t)diepint); + + /* If we were waiting for TxFIFO to become empty, the we might + * have both XFRC and TXFE interrupts pending. Since we do the + * same thing for both cases, ignore the TXFE if we have + * already processed the XFRC. + */ + + if ((diepint & N32_USBHS_DINEPINTSTS_TXCIF) == 0) + { + /* Mask further FIFO empty interrupts. + * This will be re-enabled whenever we need to wait for a + * FIFO event. + */ + + empty &= ~N32_USBHS_DINEPFEINTEN_IEP(epno); + n32_putreg(empty, N32_USBHS_DINEPFEINTEN); + + /* Handle TxFIFO empty */ + + n32_epin_txfifoempty(priv, epno); + } + + /* Clear the pending TxFIFO empty interrupt */ + + n32_putreg(N32_USBHS_DINEPINTSTS_TXFEIF, + N32_USBHS_DINEPINTSTS(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: n32_resumeinterrupt + * + * Description: + * Resume/remote wakeup detected interrupt + * + ****************************************************************************/ + +static inline void n32_resumeinterrupt(struct n32_usbdev_s *priv) +{ + uint32_t regval; + + /* Restart the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = n32_getreg(N32_USBHS_PWRCTRL); + regval &= ~(N32_USBHS_PWRCTRL_PHYSTP | N32_USBHS_PWRCTRL_GATEHCLK); + n32_putreg(regval, N32_USBHS_PWRCTRL); +#endif + + /* Clear remote wake-up signaling */ + + regval = n32_getreg(N32_USBHS_DCTRL); + regval &= ~N32_USBHS_DCTRL_RMWKUP; + n32_putreg(regval, N32_USBHS_DCTRL); + + /* Restore full power -- whatever that means for this particular board */ + + n32_usbsuspend((struct usbdev_s *)priv, true); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } +} + +/**************************************************************************** + * Name: n32_suspendinterrupt + * + * Description: + * USB suspend interrupt + * + ****************************************************************************/ + +static inline void n32_suspendinterrupt(struct n32_usbdev_s *priv) +{ +#ifdef CONFIG_USBDEV_LOWPOWER + uint32_t regval; +#endif + + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + +#ifdef CONFIG_USBDEV_LOWPOWER + /* N32_USBHS_DSTS_SUSPF is set as long as the suspend condition is detected + * on USB. Check if we are still have the suspend condition, that we are + * connected to the host, and that we have been configured. + */ + + regval = n32_getreg(N32_USBHS_DSTS); + + if ((regval & N32_USBHS_DSTS_SUSPF) != 0 && devstate == + DEVSTATE_CONFIGURED) + { + /* Switch off OTG clocking. Setting N32_USBHS_PWRCTRL_PHYSTP stops the + * PHY clock. + */ + + regval = n32_getreg(N32_USBHS_PWRCTRL); + regval |= N32_USBHS_PWRCTRL_PHYSTP; + n32_putreg(regval, N32_USBHS_PWRCTRL); + + /* Setting N32_USBHS_PWRCTRL_GATEHCLK gate HCLK to modules other than + * the AHB Slave and Master and wakeup logic. + */ + + regval |= N32_USBHS_PWRCTRL_GATEHCLK; + n32_putreg(regval, N32_USBHS_PWRCTRL); + } +#endif + + /* Let the board-specific logic know that we have entered the suspend + * state + */ + + n32_usbsuspend((struct usbdev_s *)priv, false); +} + +/**************************************************************************** + * Name: n32_rxinterrupt + * + * Description: + * RxFIFO non-empty interrupt. This interrupt indicates that there is at + * least one packet pending to be read from the RxFIFO. + * + ****************************************************************************/ + +static inline void n32_rxinterrupt(struct n32_usbdev_s *priv) +{ + struct n32_ep_s *privep; + uint32_t regval; + int bcnt; + int epphy; + + /* Get the status from the top of the FIFO */ + + regval = n32_getreg(N32_USBHS_GRXSTSP); + + /* Decode status fields */ + + epphy = (regval & N32_USBHS_GRXSTS_CHEPNUM_MASK) >> + N32_USBHS_GRXSTS_CHEPNUM_SHIFT; + + if (epphy < N32_USBHS_NENDPOINTS) + { + privep = &priv->epout[epphy]; + + /* Handle the RX event according to the packet status field */ + + switch (regval & N32_USBHS_GRXSTS_PKTSTS_MASK) + { + /* Global OUT NAK. + * This indicate that the global OUT NAK bit + * has taken effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, + * DPID = Don'tCare. + */ + + case N32_USBHS_GRXSTS_OUT_NAK: + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_OUTNAK), 0); + } + break; + + /* OUT data packet received. + * + * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, + * EPNUM = EPNUM on which the packet was received, + * DPID = Actual Data PID. + */ + + case N32_USBHS_GRXSTS_OUT_RCVD: + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & N32_USBHS_GRXSTS_BCNT_MASK) >> + N32_USBHS_GRXSTS_BCNT_SHIFT; + if (bcnt > 0) + { + n32_epout_receive(privep, bcnt); + } + } + break; + + /* OUT transfer completed. + * This indicates that an OUT data transfer for the specified OUT + * endpoint has completed. After this entry is popped from the + * receive FIFO, the core asserts a Transfer Completed interrupt + * on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on + * which the data transfer is complete, DPID = Don't Care. + */ + + case N32_USBHS_GRXSTS_OUT_CPLT: + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_OUTDONE), epphy); + } + break; + + /* SETUP transaction completed. + * This indicates that the Setup stage for the specified endpoint + * has completed and the Data stage has started. + * After this entry is popped from the receive FIFO, the core + * asserts a Setup interrupt on the specified control OUT endpoint + * (triggers an interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ + + case N32_USBHS_GRXSTS_SETUP_DNE: + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_SETUPDONE), epphy); + + /* Now that the Setup Phase is complete if it was an OUT enable + * the endpoint + * (Doing this here prevents the loss of the first FIFO word) + */ + + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Clear NAKSTS so that we can receive the data */ + + regval = n32_getreg(N32_USBHS_DOUTEPCTRL(0)); + regval |= N32_USBHS_DOUTEP0CTRL_CNAK; + n32_putreg(regval, N32_USBHS_DOUTEPCTRL(0)); + } + } + break; + + /* SETUP data packet received. + * This indicates that a SETUP packet for the specified endpoint is + * now available for reading from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ + + case N32_USBHS_GRXSTS_SETUP_RCVD: + { + uint16_t datlen; + + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_SETUPRECVD), epphy); + + /* Read EP0 setup data. + * NOTE: If multiple SETUP packets are received, the last one + * overwrites the previous setup packets and only that last + * SETUP packet will be processed. + */ + + n32_rxfifo_read(&priv->epout[EP0], + (uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet.If it is an OUT SETUP, + * then we need to wait for the completion of the data phase to + * process the setup command. If it is an IN SETUP packet, then + * we must processing the command BEFORE we enter the DATA + * phase. + * + * If the data associated with the OUT SETUP packet is zero + * length, then, of course, we don't need to wait. + */ + + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word + * is popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDPARMS), + (regval & N32_USBHS_GRXSTS_PKTSTS_MASK) >> + N32_USBHS_GRXSTS_PKTSTS_SHIFT); + } + break; + } + } +} + +/**************************************************************************** + * Name: n32_enuminterrupt + * + * Description: + * Enumeration done interrupt + * + ****************************************************************************/ + +static inline void n32_enuminterrupt(struct n32_usbdev_s *priv) +{ + uint32_t regval; + + /* Activate EP0 */ + + n32_ep0in_activate(); + + regval = n32_getreg(N32_USBHS_GCFG); + regval &= ~N32_USBHS_GCFG_TRDTIM_MASK; +#ifdef CONFIG_N32H7_USBHS_FS + regval |= N32_USBHS_GCFG_TRDTIM(5); +#else + regval |= N32_USBHS_GCFG_TRDTIM(9); +#endif + n32_putreg(regval, N32_USBHS_GCFG); +} + +/**************************************************************************** + * Name: n32_isocininterrupt + * + * Description: + * Incomplete isochronous IN transfer interrupt. Assertion of the + * incomplete isochronous IN transfer interrupt indicates an incomplete + * isochronous IN transfer on at least one of the isochronous IN endpoints. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void n32_isocininterrupt(struct n32_usbdev_s *priv) +{ + int i; + + /* The application must read the endpoint control register for all + * isochronous IN endpoints to detect endpoints with incomplete IN data + * transfers. + */ + + for (i = 0; i < N32_USBHS_NENDPOINTS; i++) + { + /* Is this an isochronous IN endpoint? */ + + privep = &priv->epin[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = N32_USBHS_DINEPCTRL(privep->epphy); + doepctl = n32_getreg(regaddr); + dsts = n32_getreg(N32_USBHS_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & N32_USBHS_DINEPCTRL_EPDPID_EPEOFRM) != 0); + soffn = ((dsts & N32_USBHS_DSTS_SOFFN0) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous IN endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + n32_req_complete(privep, -EIO); +#warning "Will clear N32_USBHS_DINEPCTRL_EPACT too" + n32_epin_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: n32_isocoutinterrupt + * + * Description: + * Incomplete periodic transfer interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void n32_isocoutinterrupt(struct n32_usbdev_s *priv) +{ + struct n32_ep_s *privep; + struct n32_req_s *privreq; + uint32_t regaddr; + uint32_t doepctl; + uint32_t dsts; + bool eonum; + bool soffn; + + /* When it receives an IISOOXFR interrupt, the application must read the + * control registers of all isochronous OUT endpoints to determine which + * endpoints had an incomplete transfer in the current microframe. An + * endpoint transfer is incomplete if both the following conditions are + * true: + * + * DOEPCTLx:EONUM = DSTS:SOFFN[0], and + * DOEPCTLx:EPENA = 1 + */ + + for (i = 0; i < N32_USBHS_NENDPOINTS; i++) + { + /* Is this an isochronous OUT endpoint? */ + + privep = &priv->epout[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = N32_USBHS_DOUTEPCTRL(privep->epphy); + doepctl = n32_getreg(regaddr); + dsts = n32_getreg(N32_USBHS_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & N32_USBHS_DOUTEPCTRL_EPDPID_EPEOFRM) != 0); + soffn = ((dsts & N32_USBHS_DSTS_SOFFN0) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous OUT endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + n32_req_complete(privep, -EIO); +#warning "Will clear N32_USBHS_DOUTEPCTRL_EPACT too" + n32_epout_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: n32_sessioninterrupt + * + * Description: + * Session request/new session detected interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void n32_sessioninterrupt(struct n32_usbdev_s *priv) +{ +#warning "Missing logic" +} +#endif + +/**************************************************************************** + * Name: n32_otginterrupt + * + * Description: + * OTG interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void n32_otginterrupt(struct n32_usbdev_s *priv) +{ + uint32_t regval; + + regval = n32_getreg(N32_USBHS_GPD); + if ((regval & N32_USBHS_GPD_DISCONNDETSTS) != 0) + { +#warning "Missing logic" + } + + /* Clear the session change status */ + + n32_putreg(regval, N32_USBHS_GPD); +} +#endif + +/**************************************************************************** + * Name: n32_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int n32_usbinterrupt(int irq, void *context, void *arg) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_usbhsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple + * devices. + */ + + struct n32_usbdev_s *priv = &g_usbhsdev; + uint32_t regval; + uint32_t reserved; + + usbtrace(TRACE_INTENTRY(N32_TRACEINTID_USB), 0); + + /* Assure that we are in device mode */ + + DEBUGASSERT((n32_getreg(N32_USBHS_GINTSTS) & N32_USBHS_GINTSTS_CMODE) == + 0); + + /* Get the state of all enabled interrupts. We will do this repeatedly + * some interrupts (like RXFLVL) will generate additional interrupting + * events. + */ + + for (; ; ) + { + /* Get the set of pending, un-masked interrupts */ + + regval = n32_getreg(N32_USBHS_GINTSTS); + reserved = (regval & N32_USBHS_GINT_RESERVED); + regval &= n32_getreg(N32_USBHS_GINTEN); + + /* With out modifying the reserved bits, acknowledge all + * **Writable** pending irqs we will service below + */ + + n32_putreg(((regval | reserved) & N32_USBHS_GINT_RC_W1), + N32_USBHS_GINTSTS); + + /* Break out of the loop when there are no further pending (and + * unmasked) interrupts to be processes. + */ + + if (regval == 0) + { + break; + } + + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_INTPENDING), + (uint16_t)regval); + + /* OUT endpoint interrupt. The core sets this bit to indicate that an + * interrupt is pending on one of the OUT endpoints of the core. + */ + + if ((regval & N32_USBHS_GINTSTS_OUTEPIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPOUT), + (uint16_t)regval); + n32_epout_interrupt(priv); + } + + /* IN endpoint interrupt. The core sets this bit to indicate that + * an interrupt is pending on one of the IN endpoints of the core. + */ + + if ((regval & N32_USBHS_GINTSTS_INEPIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_EPIN), + (uint16_t)regval); + n32_epin_interrupt(priv); + } + + /* Host/device mode mismatch error interrupt */ + +#ifdef CONFIG_DEBUG_USB + if ((regval & N32_USBHS_GINTSTS_MODMISIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_MISMATCH), + (uint16_t)regval); + } +#endif + + /* Resume/remote wakeup detected interrupt */ + + if ((regval & N32_USBHS_GINTSTS_WKUPIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_WAKEUP), + (uint16_t)regval); + n32_resumeinterrupt(priv); + } + + /* USB suspend interrupt */ + + if ((regval & N32_USBHS_GINTSTS_USBSUSPIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_SUSPEND), + (uint16_t)regval); + n32_suspendinterrupt(priv); + } + + /* Start of frame interrupt */ + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + if ((regval & N32_USBHS_GINTSTS_SOFIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_SOF), + (uint16_t)regval); + usbdev_sof_irq(&priv->usbdev, n32_getframe(&priv->usbdev)); + } +#endif + + /* RxFIFO non-empty interrupt. Indicates that there is at least one + * packet pending to be read from the RxFIFO. + */ + + if ((regval & N32_USBHS_GINTSTS_RXFNEIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_RXFIFO), + (uint16_t)regval); + n32_rxinterrupt(priv); + } + + /* USB reset interrupt */ + + if ((regval & (N32_USBHS_GINTSTS_USBRSTIF | N32_USBHS_GINTSTS_RSTDIF)) + != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_DEVRESET), + (uint16_t)regval); + + /* Perform the device reset */ + + n32_usbreset(priv); + usbtrace(TRACE_INTEXIT(N32_TRACEINTID_USB), 0); + return OK; + } + + /* Enumeration done interrupt */ + + if ((regval & N32_USBHS_GINTSTS_ENUMDIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_ENUMDNE), + (uint16_t)regval); + n32_enuminterrupt(priv); + } + + /* Incomplete isochronous IN transfer interrupt. When the core finds + * non-empty any of the isochronous IN endpoint FIFOs scheduled for + * the current frame non-empty, the core generates an IISOIXFR + * interrupt. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if ((regval & N32_USBHS_GINTSTS_ISOINCIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_IISOIXFR), + (uint16_t)regval); + n32_isocininterrupt(priv); + } + + /* Incomplete isochronous OUT transfer. For isochronous OUT + * endpoints, the XFRC interrupt may not always be asserted. If the + * core drops isochronous OUT data packets, the application could fail + * to detect the XFRC interrupt. The incomplete Isochronous OUT data + * interrupt indicates that an XFRC interrupt was not asserted on at + * least one of the isochronous OUT endpoints. At this point, the + * endpoint with the incomplete transfer remains enabled, but no active + * transfers remain in progress on this endpoint on the USB. + */ + + if ((regval & N32_USBHS_GINTSTS_PTNCIF_ISOUTNCIF) != 0) + { + usbtrace(TRACE_INTDECODE(N32_TRACEINTID_IISOOXFR), + (uint16_t)regval); + n32_isocoutinterrupt(priv); + } +#endif + } + + usbtrace(TRACE_INTEXIT(N32_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_enablegonak + * + * Description: + * Enable global OUT NAK mode + * + ****************************************************************************/ + +static void n32_enablegonak(struct n32_ep_s *privep) +{ + uint32_t regval; + + /* First, make sure that there is no GNOAKEFF interrupt pending. */ + +#if 0 + n32_putreg(N32_USBHS_GINTSTS_GOUTNAKEIF, N32_USBHS_GINTSTS); +#endif + + /* Enable Global OUT NAK mode in the core. */ + + regval = n32_getreg(N32_USBHS_DCTRL); + regval |= N32_USBHS_DCTRL_SGONAK; + n32_putreg(regval, N32_USBHS_DCTRL); + +#if 0 + /* Wait for the GONAKEFF interrupt that indicates that the OUT NAK + * mode is in effect. When the interrupt handler pops the OUTNAK word + * from the RxFIFO, the core sets the GONAKEFF interrupt. + */ + + while ((n32_getreg(N32_USBHS_GINTSTS) & N32_USBHS_GINTSTS_GOUTNAKEIF) + == 0); + n32_putreg(N32_USBHS_GINTSTS_GOUTNAKEIF, N32_USBHS_GINTSTS); + +#else + /* Since we are in the interrupt handler, we cannot wait inline for the + * GONAKEFF because it cannot occur until service the RXFLVL global + * interrupt and pop the OUTNAK word from the RxFIFO. + * + * Perhaps it is sufficient to wait for Global OUT NAK status to be + * reported in OTG DCTL register? + */ + + while ((n32_getreg(N32_USBHS_DCTRL) & N32_USBHS_DCTRL_GONAKSTS) == 0); +#endif +} + +/**************************************************************************** + * Name: n32_disablegonak + * + * Description: + * Disable global OUT NAK mode + * + ****************************************************************************/ + +static void n32_disablegonak(struct n32_ep_s *privep) +{ + uint32_t regval; + + /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */ + + regval = n32_getreg(N32_USBHS_DCTRL); + regval |= N32_USBHS_DCTRL_CGONAK; + n32_putreg(regval, N32_USBHS_DCTRL); +} + +/**************************************************************************** + * Name: n32_epout_configure + * + * Description: + * Configure an OUT endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int n32_epout_configure(struct n32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t mpsiz_mask; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* The packet size is in bytes for all EP */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + if (maxpacket >= 64) + { + mpsiz = N32_USBHS_DOUTEP0CTRL_MPLEN_64; + } + else if(maxpacket >= 32) + { + mpsiz = N32_USBHS_DOUTEP0CTRL_MPLEN_32; + } + else if(maxpacket >= 16) + { + mpsiz = N32_USBHS_DOUTEP0CTRL_MPLEN_16; + } + else + { + mpsiz = N32_USBHS_DOUTEP0CTRL_MPLEN_8; + } + + mpsiz_mask = N32_USBHS_DOUTEP0CTRL_MPLEN_MASK; + } + else + { + mpsiz = (maxpacket << N32_USBHS_DOUTEPCTRL_MPLEN_SHIFT); + mpsiz_mask = N32_USBHS_DOUTEPCTRL_MPLEN_MASK; + } + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = N32_USBHS_DOUTEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + if ((regval & N32_USBHS_DOUTEPCTRL_EPACT) == 0) + { + if (regval & N32_USBHS_DOUTEPCTRL_NAKSTS) + { + regval |= N32_USBHS_DOUTEPCTRL_CNAK; + } + + regval &= ~(mpsiz_mask | N32_USBHS_DOUTEPCTRL_EPTYPE_MASK); + regval |= mpsiz; + regval |= (eptype << N32_USBHS_DOUTEPCTRL_EPTYPE_SHIFT); + regval |= (N32_USBHS_DOUTEPCTRL_SD0PID_SEVNFRM | + N32_USBHS_DOUTEPCTRL_EPACT); + n32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + privep->active = false; + privep->zlp = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = n32_getreg(N32_USBHS_DAEPINTEN); + regval |= N32_USBHS_DAINT_OEP(privep->epphy); + n32_putreg(regval, N32_USBHS_DAEPINTEN); + return OK; +} + +/**************************************************************************** + * Name: n32_epin_configure + * + * Description: + * Configure an IN endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int n32_epin_configure(struct n32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t mpsiz_mask; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* The packet size is in bytes for all EP */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + if (maxpacket >= 64) + { + mpsiz = N32_USBHS_DINEP0CTRL_MPLEN_64; + } + else if(maxpacket >= 32) + { + mpsiz = N32_USBHS_DINEP0CTRL_MPLEN_32; + } + else if(maxpacket >= 16) + { + mpsiz = N32_USBHS_DINEP0CTRL_MPLEN_16; + } + else + { + mpsiz = N32_USBHS_DINEP0CTRL_MPLEN_8; + } + + mpsiz_mask = N32_USBHS_DINEP0CTRL_MPLEN_MASK; + } + else + { + mpsiz = (maxpacket << N32_USBHS_DINEPCTRL_MPLEN_SHIFT); + mpsiz_mask = N32_USBHS_DINEPCTRL_MPLEN_MASK; + } + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = N32_USBHS_DINEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + if ((regval & N32_USBHS_DINEPCTRL_EPACT) == 0) + { + if (regval & N32_USBHS_DINEPCTRL_NAKSTS) + { + regval |= N32_USBHS_DINEPCTRL_CNAK; + } + + regval &= ~(mpsiz_mask | N32_USBHS_DINEPCTRL_EPTYPE_MASK | + N32_USBHS_DINEPCTRL_TXFNUM_MASK); + regval |= mpsiz; + regval |= (eptype << N32_USBHS_DINEPCTRL_EPTYPE_SHIFT); + regval |= (privep->epphy << N32_USBHS_DINEPCTRL_TXFNUM_SHIFT); + regval |= (N32_USBHS_DINEPCTRL_SD0PID_SEVNFRM | + N32_USBHS_DINEPCTRL_EPACT); + n32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + privep->active = false; + privep->zlp = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = n32_getreg(N32_USBHS_DAEPINTEN); + regval |= N32_USBHS_DAINT_IEP(privep->epphy); + n32_putreg(regval, N32_USBHS_DAEPINTEN); + + return OK; +} + +/**************************************************************************** + * Name: n32_ep_configure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int n32_ep_configure(struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, + bool last) +{ + struct n32_ep_s *privep = (struct n32_ep_s *)ep; + uint16_t maxpacket; + uint8_t eptype; + int ret; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Initialize EP capabilities */ + + maxpacket = GETUINT16(desc->mxpacketsize); + eptype = desc->attr & USB_EP_ATTR_XFERTYPE_MASK; + + /* Setup Endpoint Control Register */ + + if (privep->isin) + { + ret = n32_epin_configure(privep, eptype, maxpacket); + } + else + { + ret = n32_epout_configure(privep, eptype, maxpacket); + } + + return ret; +} + +/**************************************************************************** + * Name: n32_ep0_configure + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void n32_ep0_configure(struct n32_usbdev_s *priv) +{ + /* Enable EP0 IN and OUT */ + + n32_epin_configure(&priv->epin[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); + n32_epout_configure(&priv->epout[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); +} + +/**************************************************************************** + * Name: n32_epout_disable + * + * Description: + * Disable an OUT endpoint will no longer be used + * + ****************************************************************************/ + +static void n32_epout_disable(struct n32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + /* Before disabling any OUT endpoint, the application must enable + * Global OUT NAK mode in the core. + */ + + flags = enter_critical_section(); + n32_enablegonak(privep); + + /* Disable the required OUT endpoint by setting the EPDIS and SNAK bits + * int DOECPTL register. + */ + + regaddr = N32_USBHS_DOUTEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + regval &= ~N32_USBHS_DOUTEPCTRL_EPACT; + regval |= (N32_USBHS_DOUTEPCTRL_EPDIS | N32_USBHS_DOUTEPCTRL_SNAK); + n32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = N32_USBHS_DOUTEPINTSTS(privep->epphy); + while ((n32_getreg(regaddr) & N32_USBHS_DOUTEPINTSTS_EPDISIF) == 0); +#else + /* REVISIT: */ + + up_udelay(10); +#endif + + /* Clear the EPDISD interrupt indication */ + + n32_putreg(N32_USBHS_DOUTEPINTSTS_EPDISIF, + N32_USBHS_DOUTEPINTSTS(privep->epphy)); + + /* Then disable the Global OUT NAK mode to continue receiving data + * from other non-disabled OUT endpoints. + */ + + n32_disablegonak(privep); + + /* Disable endpoint interrupts */ + + regval = n32_getreg(N32_USBHS_DAEPINTEN); + regval &= ~N32_USBHS_DAINT_OEP(privep->epphy); + n32_putreg(regval, N32_USBHS_DAEPINTEN); + + /* Cancel any queued read requests */ + + n32_req_cancel(privep, -ESHUTDOWN); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: n32_epin_disable + * + * Description: + * Disable an IN endpoint when it will no longer be used + * + ****************************************************************************/ + +static void n32_epin_disable(struct n32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* After USB reset, the endpoint will already be deactivated by the + * hardware. Trying to disable again will just hang in the wait. + */ + + regaddr = N32_USBHS_DINEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + if ((regval & N32_USBHS_DINEPCTRL_EPACT) == 0) + { + return; + } + + /* This INEPNE wait logic is suggested by reference manual, but seems + * to get stuck to infinite loop. + */ + +#if 0 + /* Make sure that there is no pending IPEPNE interrupt (because we are + * to poll this bit below). + */ + + n32_putreg(N32_USBHS_DINEPINTSTS_INEPNAKEIF, + N32_USBHS_DINEPINTSTS(privep->epphy)); + + /* Set the endpoint in NAK mode */ + + regaddr = N32_USBHS_DINEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + regval &= ~N32_USBHS_DINEPCTRL_EPACT; + regval |= (N32_USBHS_DINEPCTRL_EPDIS | N32_USBHS_DINEPCTRL_SNAK); + n32_putreg(regval, regaddr); + + /* Wait for the INEPNE interrupt that indicates that we are now in + * NAK mode + */ + + regaddr = N32_USBHS_DINEPINTSTS(privep->epphy); + while ((n32_getreg(regaddr) & N32_USBHS_DINEPINTSTS_INEPNAKEIF) == 0); + + /* Clear the INEPNE interrupt indication */ + + n32_putreg(N32_USBHS_DINEPINTSTS_INEPNAKEIF, regaddr); +#endif + + /* Deactivate and disable the endpoint by setting the EPDIS and SNAK bits + * the DIEPCTLx register. + */ + + flags = enter_critical_section(); + regaddr = N32_USBHS_DINEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + regval &= ~N32_USBHS_DINEPCTRL_EPACT; + regval |= (N32_USBHS_DINEPCTRL_EPDIS | N32_USBHS_DINEPCTRL_SNAK); + n32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the IN + * endpoint is completely disabled. + */ + + regaddr = N32_USBHS_DINEPINTSTS(privep->epphy); + while ((n32_getreg(regaddr) & N32_USBHS_DINEPINTSTS_EPDISIF) == 0); + + /* Clear the EPDISD interrupt indication */ + + regval = n32_getreg(regaddr); + regval |= N32_USBHS_DINEPINTSTS_EPDISIF; + n32_putreg(regval, regaddr); + + /* Flush any data remaining in the TxFIFO */ + + n32_txfifo_flush(N32_USBHS_GRSTCTRL_TXFNUM_D(privep->epphy)); + + /* Disable endpoint interrupts */ + + regval = n32_getreg(N32_USBHS_DAEPINTEN); + regval &= ~N32_USBHS_DAINT_IEP(privep->epphy); + n32_putreg(regval, N32_USBHS_DAEPINTEN); + + /* Cancel any queued write requests */ + + n32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: n32_ep_disable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int n32_ep_disable(struct usbdev_ep_s *ep) +{ + struct n32_ep_s *privep = (struct n32_ep_s *)ep; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + if (privep->isin) + { + /* Disable the IN endpoint */ + + n32_epin_disable(privep); + } + else + { + /* Disable the OUT endpoint */ + + n32_epout_disable(privep); + } + + return OK; +} + +/**************************************************************************** + * Name: n32_ep_allocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static struct usbdev_req_s *n32_ep_allocreq(struct usbdev_ep_s *ep) +{ + struct n32_req_s *privreq; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + usbtrace(TRACE_EPALLOCREQ, ((struct n32_ep_s *)ep)->epphy); + + privreq = kmm_malloc(sizeof(struct n32_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct n32_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: n32_ep_freereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void n32_ep_freereq(struct usbdev_ep_s *ep, + struct usbdev_req_s *req) +{ + struct n32_req_s *privreq = (struct n32_req_s *)req; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((struct n32_ep_s *)ep)->epphy); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: n32_ep_allocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *n32_ep_allocbuffer(struct usbdev_ep_s *ep, unsigned bytes) +{ + usbtrace(TRACE_EPALLOCBUFFER, ((struct n32_ep_s *)ep)->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: n32_ep_freebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void n32_ep_freebuffer(struct usbdev_ep_s *ep, void *buf) +{ + usbtrace(TRACE_EPALLOCBUFFER, ((struct n32_ep_s *)ep)->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: n32_ep_submit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int n32_ep_submit(struct usbdev_ep_s *ep, + struct usbdev_req_s *req) +{ + struct n32_req_s *privreq = (struct n32_req_s *)req; + struct n32_ep_s *privep = (struct n32_ep_s *)ep; + struct n32_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + + /* Some sanity checking */ + +#ifdef CONFIG_DEBUG_FEATURES + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDPARMS), 0); + uinfo("req=%p callback=%p buf=%p ep=%p\n", + req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + +#ifdef CONFIG_DEBUG_FEATURES + if (!priv->driver) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_NOTCONFIGURED), + priv->usbdev.speed); + return -ESHUTDOWN; + } +#endif + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + + /* Disable Interrupts */ + + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + ret = -EBUSY; + } + else + { + /* Add the new request to the request queue for the endpoint. */ + + if (n32_req_addlast(privep, privreq) && !privep->active) + { + /* If a request was added to an IN endpoint, then attempt to send + * the request data buffer now. + */ + + if (privep->isin) + { + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + + /* If the endpoint is not busy with another write request, + * then process the newly received write request now. + */ + + if (!privep->active) + { + n32_epin_request(priv, privep); + } + } + + /* If the request was added to an OUT endpoint, then attempt to + * setup a read into the request data buffer now (this will, of + * course, fail if there is already a read in place). + */ + + else + { + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + n32_epout_request(priv, privep); + } + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: n32_ep_cancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int n32_ep_cancel(struct usbdev_ep_s *ep, + struct usbdev_req_s *req) +{ + struct n32_ep_s *privep = (struct n32_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + + /* FIXME: if the request is the first, then we need to flush the EP + * otherwise just remove it from the list + * + * but ... all other implementations cancel all requests ... + */ + + n32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: n32_epout_setstall + * + * Description: + * Stall an OUT endpoint + * + ****************************************************************************/ + +static int n32_epout_setstall(struct n32_ep_s *privep) +{ +#if 1 + /* This implementation follows the requirements from the USB OTG core + * reference manual. + */ + + uint32_t regaddr; + uint32_t regval; + + /* Put the core in the Global OUT NAK mode */ + + n32_enablegonak(privep); + + /* Disable and STALL the OUT endpoint by setting the EPDIS and STALL bits + * in the DOECPTL register. + */ + + regaddr = N32_USBHS_DOUTEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + regval |= (N32_USBHS_DOUTEPCTRL_EPDIS | N32_USBHS_DOUTEPCTRL_STALL); + n32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = N32_USBHS_DOUTEPINTSTS(privep->epphy); + while ((n32_getreg(regaddr) & N32_USBHS_DOUTEPINTSTS_EPDISIF) == 0); +#else + /* REVISIT: */ + + up_udelay(10); +#endif + + /* Disable Global OUT NAK mode */ + + n32_disablegonak(privep); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#else + /* This implementation follows the STMicro code example. */ + + /* REVISIT: */ + + uint32_t regaddr; + uint32_t regval; + + /* Stall the OUT endpoint by setting the STALL bit in the + * DOECPTL register. + */ + + regaddr = N32_USBHS_DOUTEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + regval |= N32_USBHS_DOUTEPCTRL_STALL; + n32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#endif +} + +/**************************************************************************** + * Name: n32_epin_setstall + * + * Description: + * Stall an IN endpoint + * + ****************************************************************************/ + +static int n32_epin_setstall(struct n32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + + /* Get the IN endpoint device control register */ + + regaddr = N32_USBHS_DINEPCTRL(privep->epphy); + regval = n32_getreg(regaddr); + + /* Then stall the endpoint */ + + regval |= N32_USBHS_DINEPCTRL_STALL; + n32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +} + +/**************************************************************************** + * Name: n32_ep_setstall + * + * Description: + * Stall an endpoint + * + ****************************************************************************/ + +static int n32_ep_setstall(struct n32_ep_s *privep) +{ + usbtrace(TRACE_EPSTALL, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + return n32_epin_setstall(privep); + } + else + { + return n32_epout_setstall(privep); + } +} + +/**************************************************************************** + * Name: n32_ep_clrstall + * + * Description: + * Resume a stalled endpoint + * + ****************************************************************************/ + +static int n32_ep_clrstall(struct n32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + uint32_t stallbit; + uint32_t data0bit; + + usbtrace(TRACE_EPRESUME, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = N32_USBHS_DINEPCTRL(privep->epphy); + stallbit = N32_USBHS_DINEPCTRL_STALL; + data0bit = N32_USBHS_DINEPCTRL_SD0PID_SEVNFRM; + } + else + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = N32_USBHS_DOUTEPCTRL(privep->epphy); + stallbit = N32_USBHS_DOUTEPCTRL_STALL; + data0bit = N32_USBHS_DOUTEPCTRL_SD0PID_SEVNFRM; + } + + /* Clear the stall bit */ + + regval = n32_getreg(regaddr); + regval &= ~stallbit; + + /* Set the DATA0 pid for interrupt and bulk endpoints */ + + if (privep->eptype == USB_EP_ATTR_XFER_INT || + privep->eptype == USB_EP_ATTR_XFER_BULK) + { + /* Writing this bit sets the DATA0 PID */ + + regval |= data0bit; + } + + n32_putreg(regval, regaddr); + + /* The endpoint is no longer stalled */ + + privep->stalled = false; + return OK; +} + +/**************************************************************************** + * Name: n32_ep_stall + * + * Description: + * Stall or resume an endpoint + * + ****************************************************************************/ + +static int n32_ep_stall(struct usbdev_ep_s *ep, bool resume) +{ + struct n32_ep_s *privep = (struct n32_ep_s *)ep; + irqstate_t flags; + int ret; + + /* Set or clear the stall condition as requested */ + + flags = enter_critical_section(); + if (resume) + { + ret = n32_ep_clrstall(privep); + } + else + { + ret = n32_ep_setstall(privep); + } + + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: n32_ep0_stall + * + * Description: + * Stall endpoint 0 + * + ****************************************************************************/ + +static void n32_ep0_stall(struct n32_usbdev_s *priv) +{ + n32_epin_setstall(&priv->epin[EP0]); + n32_epout_setstall(&priv->epout[EP0]); + priv->stalled = true; + n32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_ep_alloc + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). + * Zero means that any endpoint matching the other requirements + * will suffice. + * The assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, + * USB_EP_ATTR_XFER_BULK, USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static struct usbdev_ep_s *n32_ep_alloc(struct usbdev_s *dev, + uint8_t eplog, bool in, + uint8_t eptype) +{ + struct n32_usbdev_s *priv = (struct n32_usbdev_s *)dev; + uint8_t epavail; + irqstate_t flags; + int epphy; + int epno = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + epphy = USB_EPNO(eplog); + + /* Get the set of available endpoints depending on the direction */ + + flags = enter_critical_section(); + epavail = priv->epavail[in]; + + /* A physical address of 0 means that any endpoint will do */ + + if (epphy > 0) + { + /* Otherwise, we will return the endpoint structure only for the + * requested 'logical' endpoint. All of the other checks will + * still be performed. + * + * First, verify that the logical endpoint is in the range supported + * by by the hardware. + */ + + if (epphy >= N32_USBHS_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BADEPNO), (uint16_t)epphy); + return NULL; + } + + /* Remove all of the candidate endpoints from the bitset except for the + * this physical endpoint number. + */ + + epavail &= (1 << epphy); + } + + /* Is there an available endpoint? */ + + if (epavail) + { + /* Yes.. Select the lowest numbered endpoint in the set of available + * endpoints. + */ + + for (epno = 1; epno < N32_USBHS_NENDPOINTS; epno++) + { + uint8_t bit = 1 << epno; + + if ((epavail & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail[in] &= ~(1 << epno); + + /* And return the pointer to the standard endpoint structure */ + + leave_critical_section(flags); + return in ? &priv->epin[epno].ep : &priv->epout[epno].ep; + } + } + + /* We should not get here */ + } + + usbtrace(TRACE_DEVERROR(N32_TRACEERR_NOEP), (uint16_t)eplog); + leave_critical_section(flags); + return NULL; +} + +/**************************************************************************** + * Name: n32_ep_free + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void n32_ep_free(struct usbdev_s *dev, + struct usbdev_ep_s *ep) +{ + struct n32_usbdev_s *priv = (struct n32_usbdev_s *)dev; + struct n32_ep_s *privep = (struct n32_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail[privep->isin] |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: n32_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int n32_getframe(struct usbdev_s *dev) +{ + uint32_t regval; + + usbtrace(TRACE_DEVGETFRAME, 0); + + /* Return the last frame number of the last SOF detected by the hardware */ + + regval = n32_getreg(N32_USBHS_DSTS); + return (int)((regval & N32_USBHS_DSTS_SOFFN_MASK) >> + N32_USBHS_DSTS_SOFFN_SHIFT); +} + +/**************************************************************************** + * Name: n32_wakeup + * + * Description: + * Exit suspend mode. + * + ****************************************************************************/ + +static int n32_wakeup(struct usbdev_s *dev) +{ + struct n32_usbdev_s *priv = (struct n32_usbdev_s *)dev; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); + + /* Is wakeup enabled? */ + + flags = enter_critical_section(); + if (priv->wakeup) + { + /* Yes... is the core suspended? */ + + regval = n32_getreg(N32_USBHS_DSTS); + if ((regval & N32_USBHS_DSTS_SUSPF) != 0) + { + /* Re-start the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = n32_getreg(N32_USBHS_PWRCTRL); + regval &= ~(N32_USBHS_PWRCTRL_PHYSTP | N32_USBHS_PWRCTRL_GATEHCLK); + n32_putreg(regval, N32_USBHS_PWRCTRL); +#endif + /* Activate Remote wakeup signaling */ + + regval = n32_getreg(N32_USBHS_DCTRL); + regval |= N32_USBHS_DCTRL_RMWKUP; + n32_putreg(regval, N32_USBHS_DCTRL); + up_mdelay(5); + regval &= ~N32_USBHS_DCTRL_RMWKUP; + n32_putreg(regval, N32_USBHS_DCTRL); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: n32_selfpowered + * + * Description: + * Sets/clears the device self-powered feature + * + ****************************************************************************/ + +static int n32_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + struct n32_usbdev_s *priv = (struct n32_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG_FEATURES + if (!dev) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: n32_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int n32_pullup(struct usbdev_s *dev, bool enable) +{ + uint32_t regval; + + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + irqstate_t flags = enter_critical_section(); + + regval = n32_getreg(N32_USBHS_DCTRL); + if (enable) + { + /* Connect the device by clearing the soft disconnect bit in the DCTL + * register. + */ + + regval &= ~N32_USBHS_DCTRL_SFTDIS; + } + else + { + /* Disconnect the device by setting the soft disconnect bit in the DCTL + * register. + */ + + regval |= N32_USBHS_DCTRL_SFTDIS; + } + + n32_putreg(regval, N32_USBHS_DCTRL); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: n32_setaddress + * + * Description: + * Set the devices USB address + * + ****************************************************************************/ + +static void n32_setaddress(struct n32_usbdev_s *priv, uint16_t address) +{ + uint32_t regval; + + /* Set the device address in the DCFG register */ + + regval = n32_getreg(N32_USBHS_DCFG); + regval &= ~N32_USBHS_DCFG_DEVARR_MASK; + regval |= ((uint32_t)address << N32_USBHS_DCFG_DEVARR_SHIFT); + n32_putreg(regval, N32_USBHS_DCFG); + + /* Are we now addressed? (i.e., do we have a non-NULL device + * address?) + */ + + if (address != 0) + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->addressed = true; + } + else + { + priv->devstate = DEVSTATE_DEFAULT; + priv->addressed = false; + } +} + +/**************************************************************************** + * Name: n32_txfifo_flush + * + * Description: + * Flush the specific TX fifo. + * + ****************************************************************************/ + +static int n32_txfifo_flush(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = N32_USBHS_GRSTCTRL_TXFFLSH | txfnum; + n32_putreg(regval, N32_USBHS_GRSTCTRL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < N32_FLUSH_DELAY; timeout++) + { + regval = n32_getreg(N32_USBHS_GRSTCTRL); + if ((regval & N32_USBHS_GRSTCTRL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: n32_rxfifo_flush + * + * Description: + * Flush the RX fifo. + * + ****************************************************************************/ + +static int n32_rxfifo_flush(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + n32_putreg(N32_USBHS_GRSTCTRL_RXFFLSH, N32_USBHS_GRSTCTRL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < N32_FLUSH_DELAY; timeout++) + { + regval = n32_getreg(N32_USBHS_GRSTCTRL); + if ((regval & N32_USBHS_GRSTCTRL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: n32_swinitialize + * + * Description: + * Initialize all driver data structures. + * + ****************************************************************************/ + +static void n32_swinitialize(struct n32_usbdev_s *priv) +{ + struct n32_ep_s *privep; + int i; + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct n32_usbdev_s)); + + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->epin[EP0].ep; + + priv->epavail[0] = N32_EP_AVAILABLE; + priv->epavail[1] = N32_EP_AVAILABLE; + + /* Initialize the endpoint lists */ + + for (i = 0; i < N32_USBHS_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epin[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + privep->isin = 1; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = N32_EPPHYIN2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } + + /* Initialize the endpoint lists */ + + for (i = 0; i < N32_USBHS_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epout[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = N32_EPPHYOUT2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } +} + +/**************************************************************************** + * Name: n32_hwinitialize + * + * Description: + * Configure the OTG core for operation. + * + ****************************************************************************/ + +static void n32_hwinitialize(struct n32_usbdev_s *priv) +{ + uint32_t regval; + uint32_t timeout; + uint32_t address; + + /* Setup PHY PLL */ + + regval = n32_getreg(N32_USBHS_WRPCFG); + regval &= ~N32_USBHS_WRPCFG_PHYCLKSEL_MASK; + regval |= N32_USBHS_WRPCFG_PHYCLKSEL; + regval |= N32_USBHS_WRPCFG_PLLEN; + n32_putreg(regval, N32_USBHS_WRPCFG); + + /* Enable Host Pending */ + + regval = n32_getreg(N32_USBHS_WRPCTRL); + regval |= N32_USBHS_WRPCTRL_PINDETEN; + n32_putreg(regval, N32_USBHS_WRPCTRL); + + /* Reset the USBHS core */ + + if (N32_USBHS_BASE == N32_USBCTRL1_BASE) + { + /* Reset the USBHS1 core */ + + regval = n32_getreg(N32_RCC_AHB2RST1); + regval |= RCC_AHB2RST1_USB1PORRST; + n32_putreg(regval, N32_RCC_AHB2RST1); + regval &= ~RCC_AHB2RST1_USB1PORRST; + n32_putreg(regval, N32_RCC_AHB2RST1); + } + else + { + /* Reset the USBHS2 core */ + + regval = n32_getreg(N32_RCC_AHB1RST1); + regval |= RCC_AHB1RST1_USB2PORRST; + n32_putreg(regval, N32_RCC_AHB1RST1); + regval &= ~RCC_AHB1RST1_USB2PORRST; + n32_putreg(regval, N32_RCC_AHB1RST1); + } + + up_mdelay(1); + + n32_putreg(N32_USBHS_GAHBCFG_NPTXFETH, N32_USBHS_GAHBCFG); + + /* Disable global interrupts. */ + + regval = n32_getreg(N32_USBHS_GAHBCFG); + regval &= ~N32_USBHS_GAHBCFG_GINTEN; + n32_putreg(regval, N32_USBHS_GAHBCFG); + + /* At start-up the core is in FS/HS mode. */ + + regval = n32_getreg(N32_USBHS_GCFG); +#ifdef CONFIG_N32H7_USBHS_FS + /* Full speed serial transceiver select */ + + regval |= N32_USBHS_GCFG_PHYSEL; +#endif + regval |= N32_USBHS_GCFG_PHYIF; + n32_putreg(regval, N32_USBHS_GCFG); + + /* Common USB OTG core initialization */ + + /* Wait for AHB master IDLE state */ + + for (timeout = 0; timeout < N32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = n32_getreg(N32_USBHS_GRSTCTRL); + if ((regval & N32_USBHS_GRSTCTRL_AHBIDLE) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + regval = n32_getreg(N32_USBHS_GRSTCTRL); + regval |= N32_USBHS_GRSTCTRL_CSRST; + n32_putreg(regval, N32_USBHS_GRSTCTRL); + for (timeout = 0; timeout < N32_READY_DELAY; timeout++) + { + regval = n32_getreg(N32_USBHS_GRSTCTRL); + if ((regval & N32_USBHS_GRSTCTRL_SRSTDNE) != 0) + { + break; + } + } + + regval = n32_getreg(N32_USBHS_GRSTCTRL); + regval &= ~N32_USBHS_GRSTCTRL_CSRST; + n32_putreg(regval, N32_USBHS_GRSTCTRL); + + /* Wait for the PHY to settle */ + + up_udelay(3); + + /* Wait for the PHY to settle */ + + up_mdelay(20); + +#ifndef CONFIG_N32H7_USBHS_FS + regval = n32_getreg(N32_USBHS_DCFG); + regval |= N32_USBHS_DCFG_XCVDRLY; + n32_putreg(regval, N32_USBHS_DCFG); +#endif + + /* Force Device Mode */ + + regval = n32_getreg(N32_USBHS_GCFG); + regval &= ~N32_USBHS_GCFG_FHMODE; + regval |= N32_USBHS_GCFG_FDMODE; + n32_putreg(regval, N32_USBHS_GCFG); + up_mdelay(50); + + /* Initialize device mode */ + + n32_putreg(0, N32_USBHS_PWRCTRL); + + /* Device configuration register */ + + regval = n32_getreg(N32_USBHS_DCFG); + regval &= ~N32_USBHS_DCFG_PFRITVL_MASK; + regval |= N32_USBHS_DCFG_PFRITVL_80; + n32_putreg(regval, N32_USBHS_DCFG); + + /* Set device high or full speed */ + + regval = n32_getreg(N32_USBHS_DCFG); + regval &= ~N32_USBHS_DCFG_DEVSPD_MASK; +#ifdef CONFIG_N32H7_USBHS_FS + regval |= N32_USBHS_DCFG_DEVSPD_FS; +#else + regval |= N32_USBHS_DCFG_DEVSPD_HS; +#endif + n32_putreg(regval, N32_USBHS_DCFG); + + /* Set Rx FIFO size */ + + n32_putreg(N32_RXFIFO_WORDS, N32_USBHS_GRXFSIZ); + + address = N32_RXFIFO_WORDS; + regval = (address << N32_USBHS_GNPTXFSIZ_IEP0TXFRSADD_SHIFT) | + (N32_EP0_TXFIFO_WORDS << N32_USBHS_GNPTXFSIZ_IEP0TXFDEP_SHIFT); + n32_putreg(regval, N32_USBHS_DINEPTXF0); + + address += N32_EP0_TXFIFO_WORDS; + regval = (address << N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT) | + (N32_EP1_TXFIFO_WORDS << N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT); + n32_putreg(regval, N32_USBHS_DINEPPTXFSIZ(1)); + + address += N32_EP1_TXFIFO_WORDS; + regval = (address << N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT) | + (N32_EP2_TXFIFO_WORDS << N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT); + n32_putreg(regval, N32_USBHS_DINEPPTXFSIZ(2)); + + address += N32_EP2_TXFIFO_WORDS; + regval = (address << N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT) | + (N32_EP3_TXFIFO_WORDS << N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT); + n32_putreg(regval, N32_USBHS_DINEPPTXFSIZ(3)); + + address += N32_EP3_TXFIFO_WORDS; + regval = (address << N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT) | + (N32_EP4_TXFIFO_WORDS << N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT); + n32_putreg(regval, N32_USBHS_DINEPPTXFSIZ(4)); + + address += N32_EP4_TXFIFO_WORDS; + regval = (address << N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT) | + (N32_EP5_TXFIFO_WORDS << N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT); + n32_putreg(regval, N32_USBHS_DINEPPTXFSIZ(5)); + + address += N32_EP5_TXFIFO_WORDS; + regval = (address << N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT) | + (N32_EP6_TXFIFO_WORDS << N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT); + n32_putreg(regval, N32_USBHS_DINEPPTXFSIZ(6)); + + address += N32_EP6_TXFIFO_WORDS; + regval = (address << N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT) | + (N32_EP7_TXFIFO_WORDS << N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT); + n32_putreg(regval, N32_USBHS_DINEPPTXFSIZ(7)); + + address += N32_EP7_TXFIFO_WORDS; + regval = (address << N32_USBHS_DINEPPTXFSIZ_INEPTXSADD_SHIFT) | + (N32_EP8_TXFIFO_WORDS << N32_USBHS_DINEPPTXFSIZ_INEPTXFDEP_SHIFT); + n32_putreg(regval, N32_USBHS_DINEPPTXFSIZ(8)); + + /* Flush the FIFOs */ + + n32_txfifo_flush(N32_USBHS_GRSTCTRL_TXFNUM_DALL); + n32_rxfifo_flush(); + + /* Clear all pending Device Interrupts */ + + n32_putreg(0, N32_USBHS_DINEPINTEN); + n32_putreg(0, N32_USBHS_DOUTEPINTEN); + n32_putreg(0, N32_USBHS_DINEPFEINTEN); + n32_putreg(0xffffffff, N32_USBHS_DAEPINTSTS); + n32_putreg(0, N32_USBHS_DAEPINTEN); + + /* Configure all IN endpoints */ + + for (uint8_t i = 0; i < N32_USBHS_NENDPOINTS; i++) + { + regval = n32_getreg(N32_USBHS_DINEPCTRL(i)); + if ((regval & N32_USBHS_DINEPCTRL_EPEN) != 0) + { + /* The endpoint is already enabled */ + + regval = N32_USBHS_DINEPCTRL_EPDIS | N32_USBHS_DINEPCTRL_SNAK; + } + else + { + regval = 0; + } + + n32_putreg(regval, N32_USBHS_DINEPCTRL(i)); + n32_putreg(0, N32_USBHS_DINEPTXSIZ(i)); + n32_putreg(0xff, N32_USBHS_DINEPINTSTS(i)); + } + + /* Configure all OUT endpoints */ + + for (uint8_t i = 0; i < N32_USBHS_NENDPOINTS; i++) + { + regval = n32_getreg(N32_USBHS_DOUTEPCTRL(i)); + if ((regval & N32_USBHS_DOUTEPCTRL_EPEN) != 0) + { + /* The endpoint is already enabled */ + + regval = N32_USBHS_DOUTEPCTRL_EPDIS | N32_USBHS_DOUTEPCTRL_SNAK; + } + else + { + regval = 0; + } + + n32_putreg(regval, N32_USBHS_DOUTEPCTRL(i)); + n32_putreg(0, N32_USBHS_DOUTEPTXSIZ(i)); + n32_putreg(0xff, N32_USBHS_DOUTEPINTSTS(i)); + } + + /* Enable the Tx FIFO underrun interrupt */ + + regval = n32_getreg(N32_USBHS_DINEPINTEN); + regval |= N32_USBHS_DINEPINTEN_TXFUDIEN; + n32_putreg(regval, N32_USBHS_DINEPINTEN); + + /* Disable all interrupts. */ + + n32_putreg(0, N32_USBHS_GINTEN); + + /* Clear any pending interrupts */ + + regval = n32_getreg(N32_USBHS_GINTSTS); + regval &= N32_USBHS_GINT_RESERVED; + regval |= N32_USBHS_GINT_RC_W1; + n32_putreg(regval, N32_USBHS_GINTSTS); + + /* Enable the interrupts in the INTMSK */ + + regval = (N32_USBHS_GINTEN_RXFNEIEN | N32_USBHS_GINTEN_USBSUSPIEN | + N32_USBHS_GINTEN_ENUMDIEN | N32_USBHS_GINTEN_INEPIEN | + N32_USBHS_GINTEN_OUTEPIEN | N32_USBHS_GINTEN_USBRSTIEN | + N32_USBHS_GINTEN_WKUPIEN); + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + regval |= (N32_USBHS_GINTEN_ISOINCIEN | + N32_USBHS_GINTEN_PTNCIEN_ISOUTNCIEN); +#endif + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + regval |= N32_USBHS_GINTEN_SOFIEN; +#endif + +#ifdef CONFIG_USBDEV_VBUSSENSING + /* N32H7 MOD: bit 30 (VBUS valid/session request) + * are named only on the enable side in hardware/n32h7_usbhs.h. + */ + + regval |= N32_USBHS_GINTEN_VBUSVIF; +#endif + +#ifdef CONFIG_DEBUG_USB + regval |= N32_USBHS_GINTEN_MODMISIEN; +#endif + + /* Enable interrupts. */ + + n32_putreg(regval, N32_USBHS_GINTEN); + + /* Enable global interrupts. */ + + regval = n32_getreg(N32_USBHS_GAHBCFG); + regval |= N32_USBHS_GAHBCFG_GINTEN; + regval |= N32_USBHS_GAHBCFG_NPTXFETH; + n32_putreg(regval, N32_USBHS_GAHBCFG); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL and GIO pin initialization is not performed here but should been in + * the low-level boot logic: PLL1 must be configured for operation at + * 48MHz and P0.23 and PO.31 in PINSEL1 must be configured for Vbus and USB + * connect LED. + * + ****************************************************************************/ + +void arm_usbinitialize(void) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_usbhsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple + * devices. + */ + + struct n32_usbdev_s *priv = &g_usbhsdev; + int ret; + + usbtrace(TRACE_DEVINIT, 0); + + n32_usbhs_enableclock(); + n32_usbhs_phy_initialize(); + + /* Here we assume that: + * + * 1. GPIOA and OTG peripheral clocking has already been enabled as part + * of the boot sequence. + * 2. Board-specific logic has already enabled other board specific GPIOs + * for things like soft pull-up, VBUS sensing, power controls, and over- + * current detection. + */ + + /* Configure USBHS FS alternate function pins */ + + n32_configgpio(GPIO_USBHS_DM); + n32_configgpio(GPIO_USBHS_DP); + + /* Only needed for USBHS */ +#ifndef CONFIG_N32H7_USBHS_ID_DISABLE + n32_configgpio(GPIO_USBHS_ID); +#endif + + /* SOF output pin configuration is configurable. */ + +#ifdef CONFIG_N32H7_USBHS_SOFOUTPUT + n32_configgpio(GPIO_USBHS_SOF); +#endif + + /* Uninitialize the hardware so that we know that we are starting from a + * known state. + */ + + arm_usbuninitialize(); + + /* Initialize the driver data structure */ + + n32_swinitialize(priv); + + /* Initialize the USB OTG core */ + + n32_hwinitialize(priv); + + /* Attach the OTG interrupt handler */ + + ret = irq_attach(N32_IRQ_USBHS, n32_usbinterrupt, NULL); + if (ret < 0) + { + uerr("ERROR: irq_attach failed: %d\n", ret); + goto errout; + } + + /* Disconnect device */ + + n32_pullup(&priv->usbdev, false); + + /* Reset/Re-initialize the USB hardware */ + + n32_usbreset(priv); + + /* Enable USB controller interrupts at the NVIC */ + + up_enable_irq(N32_IRQ_USBHS); + return; + +errout: + arm_usbuninitialize(); +} + +/**************************************************************************** + * Name: arm_usbuninitialize + ****************************************************************************/ + +void arm_usbuninitialize(void) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_usbhsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple + * devices. + */ + + struct n32_usbdev_s *priv = &g_usbhsdev; + irqstate_t flags; + int i; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + n32_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable and detach IRQs */ + + up_disable_irq(N32_IRQ_USBHS); + irq_detach(N32_IRQ_USBHS); + + /* Disable all endpoint interrupts */ + + for (i = 0; i < N32_USBHS_NENDPOINTS; i++) + { + n32_putreg(0xff, N32_USBHS_DINEPINTSTS(i)); + n32_putreg(0xff, N32_USBHS_DOUTEPINTSTS(i)); + } + + n32_putreg(0, N32_USBHS_DINEPINTEN); + n32_putreg(0, N32_USBHS_DOUTEPINTEN); + n32_putreg(0, N32_USBHS_DINEPFEINTEN); + n32_putreg(0, N32_USBHS_DAEPINTEN); + n32_putreg(0xffffffff, N32_USBHS_DAEPINTSTS); + + /* Flush the FIFOs */ + + n32_txfifo_flush(N32_USBHS_GRSTCTRL_TXFNUM_DALL); + n32_rxfifo_flush(); + + /* TODO: Turn off USB power and clocking */ + + priv->devstate = DEVSTATE_DEFAULT; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method + * will be called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_usbhsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple + * devices. + */ + + struct n32_usbdev_s *priv = &g_usbhsdev; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG_FEATURES + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_BINDFAILED), (uint16_t)-ret); + priv->driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(N32_IRQ_USBHS); + + /* FIXME: nothing seems to call DEV_CONNECT(), but we need to set + * the RS bit to enable the controller. It kind of makes sense + * to do this after the class has bound to us... + * GEN: This bug is really in the class driver. It should make the + * soft connect when it is ready to be enumerated. I have added + * that logic to the class drivers but left this logic here. + */ + + n32_pullup(&priv->usbdev, true); + +#ifndef CONFIG_N32H7_USBHS_FS + priv->usbdev.speed = USB_SPEED_HIGH; +#else + priv->usbdev.speed = USB_SPEED_FULL; +#endif + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB + * host, it will first disconnect(). The driver is also requested to + * unbind() and clean up any device state, before this procedure finally + * returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_usbhsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple + * devices. + */ + + struct n32_usbdev_s *priv = &g_usbhsdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG_FEATURES + if (driver != priv->driver) + { + usbtrace(TRACE_DEVERROR(N32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. + */ + + flags = enter_critical_section(); + n32_usbreset(priv); + leave_critical_section(flags); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts */ + + flags = enter_critical_section(); + up_disable_irq(N32_IRQ_USBHS); + + /* Disconnect device */ + + n32_pullup(&priv->usbdev, false); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + + return OK; +} + +#endif /* CONFIG_USBDEV && (CONFIG_N32H7_USBHS1_DEV || CONFIG_N32H7_USBHS2_DEV) */ diff --git a/arch/arm/src/n32h7/n32_usbhshost.c b/arch/arm/src/n32h7/n32_usbhshost.c new file mode 100644 index 0000000000000..4997eb8ce092c --- /dev/null +++ b/arch/arm/src/n32h7/n32_usbhshost.c @@ -0,0 +1,5800 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32_usbhshost.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include + +#include "arm_internal.h" +#include "n32_gpio.h" + +#if defined(CONFIG_USBHOST) && (defined(CONFIG_N32H7_USBHS1_HOST) || \ + defined(CONFIG_N32H7_USBHS2_HOST)) + +/* N32_USBHS_BASE and N32_IRQ_USBHS are defined before n32_usbhs.h is + * included so that the register address macros and the static inline + * clock/PHY helpers in that header expand for the correct instance. + * The USBHS GPIO pin definitions (GPIO_USBHS_*) are provided by board.h. + */ + +#if defined(CONFIG_N32H7_USBHS1_HOST) +# define N32_IRQ_USBHS N32_IRQ_USBHS1_HS +# define N32_USBHS_BASE N32_USBCTRL1_BASE +# define N32_USBHS_WRAPPER_BASE N32_USBCTRL1_WRAPPER_BASE +# define GPIO_USBHS_DM GPIO_USBHS1_DM +# define GPIO_USBHS_DP GPIO_USBHS1_DP +#elif defined(CONFIG_N32H7_USBHS2_HOST) +# define N32_IRQ_USBHS N32_IRQ_USBHS2_HS +# define N32_USBHS_BASE N32_USBCTRL2_BASE +# define N32_USBHS_WRAPPER_BASE N32_USBCTRL2_WRAPPER_BASE +# define GPIO_USBHS_DM GPIO_USBHS2_DM +# define GPIO_USBHS_DP GPIO_USBHS2_DP +#else +# error Not selected USBHOST peripheral +#endif + +#if defined(CONFIG_N32H7_USBHS1_HOST) && defined(CONFIG_N32H7_USBHS2_HOST) +# error Only one HOST role supported +#endif + +/* N32H7 MOD: + * The N32H76x USBHS core has no on-chip HS PHY; an external ULPI PHY is + * the default configuration. Define CONFIG_N32H7_USBHS_FS to select the + * FS serial transceiver (GCFG.PHYSEL) instead. + */ + +#include "n32_usbhs.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* N32 USBHS Host Driver Support + * + * Pre-requisites + * + * CONFIG_USBHOST - Enable general USB host support + * CONFIG_N32H7_USBHS1_HOST or + * CONFIG_N32H7_USBHS2_HOST - Select the N32H7 USBHS instance + * + * Options: + * + * CONFIG_N32H7_USBHS_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words. + * Default 128 (512 bytes) + * CONFIG_N32H7_USBHS_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO + * in 32-bit words. Default 96 (384 bytes) + * CONFIG_N32H7_USBHS_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit + * words. Default 96 (384 bytes) + * CONFIG_N32H7_USBHS_DESCSIZE - Maximum size of a descriptor. Default: 128 + * CONFIG_N32H7_USBHS_SOFINTR - Enable SOF interrupts. Why would you ever + * want to do that? + * CONFIG_N32_USBHOST_REGDEBUG - Enable very low-level register access + * debug. Depends on CONFIG_DEBUG_FEATURES. + * CONFIG_N32_USBHOST_PKTDUMP - Dump all incoming and outgoing USB + * packets. Depends on CONFIG_DEBUG_FEATURES. + */ + +/* Default RxFIFO size */ + +#ifndef CONFIG_N32H7_USBHS_RXFIFO_SIZE +# define CONFIG_N32H7_USBHS_RXFIFO_SIZE 512 +#endif + +/* Default host non-periodic Tx FIFO size */ + +#ifndef CONFIG_N32H7_USBHS_NPTXFIFO_SIZE +# define CONFIG_N32H7_USBHS_NPTXFIFO_SIZE 256 +#endif + +/* Default host periodic Tx fifo size register */ + +#ifndef CONFIG_N32H7_USBHS_PTXFIFO_SIZE +# define CONFIG_N32H7_USBHS_PTXFIFO_SIZE 256 +#endif + +/* Maximum size of a descriptor */ + +#ifndef CONFIG_N32H7_USBHS_DESCSIZE +# define CONFIG_N32H7_USBHS_DESCSIZE 128 +#endif + +/* Register/packet debug depends on CONFIG_DEBUG_FEATURES */ + +#ifndef CONFIG_DEBUG_FEATURES +# undef CONFIG_N32_USBHOST_REGDEBUG +# undef CONFIG_N32_USBHOST_PKTDUMP +#endif + +/* Driver-private constants ************************************************ + * + * N32H7 MOD: + * The following constants have no counterpart in hardware/n32h7_usbhs.h + * (the hardware header provides only the field SHIFT/MASK). They are + * driver-internal encodings used by the ported core logic, private to + * this file. + */ + +/* Endpoint type values (unshifted, driver-internal encoding; matches the + * HCHCTRL EPTYPE field encoding) + */ + +#define N32_USBHS_EPTYPE_CTRL 0 +#define N32_USBHS_EPTYPE_ISOC 1 +#define N32_USBHS_EPTYPE_BULK 2 +#define N32_USBHS_EPTYPE_INTR 3 + +/* Data PID values (unshifted; matches the HCHTXSIZ PID field encoding) */ + +#define N32_USBHS_PID_DATA0 0 +#define N32_USBHS_PID_DATA1 2 +#define N32_USBHS_PID_SETUP 3 + +/* GRSTCTRL TxFIFO number helper (flush all host TxFIFOs) */ + +#define N32_USBHS_GRSTCTRL_TXFNUM_HALL \ + (0x10UL << N32_USBHS_GRSTCTRL_TXFNUM_SHIFT) + +/* Host all-channels interrupt helper (HACHINT/HACHINTEN) */ + +#define N32_USBHS_HACHINT_CH(n) (1UL << (n)) + +/**************************************************************************** + * Debug Trace Instrumentation + ****************************************************************************/ + +#ifdef HAVE_USBHOST_TRACE +enum usbhost_trace1codes_e +{ + __TRACE1_BASEVALUE = 0, /* This will force the first value to be 1 */ + + N32_USBHS_TRACE1_DEVDISCONN, /* USBHS ERROR: Host Port Device disconnected */ + N32_USBHS_TRACE1_IRQATTACH, /* USBHS ERROR: Failed to attach IRQ */ + N32_USBHS_TRACE1_TRNSFRFAILED, /* USBHS ERROR: Host Port Transfer Failed */ + N32_USBHS_TRACE1_SENDSETUP, /* USBHS ERROR: sendsetup() failed with: */ + N32_USBHS_TRACE1_SENDDATA, /* USBHS ERROR: senddata() failed with: */ + N32_USBHS_TRACE1_RECVDATA, /* USBHS ERROR: recvdata() failed with: */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + + N32_USBHS_VTRACE1_CONNECTED, /* USBHS Host Port connected */ + N32_USBHS_VTRACE1_DISCONNECTED, /* USBHS Host Port disconnected */ + N32_USBHS_VTRACE1_GINT, /* USBHS Handling Interrupt. Entry Point */ + N32_USBHS_VTRACE1_GINT_SOF, /* USBHS Handle the start of frame interrupt */ + N32_USBHS_VTRACE1_GINT_RXFLVL, /* USBHS Handle the RxFIFO non-empty interrupt */ + N32_USBHS_VTRACE1_GINT_NPTXFE, /* USBHS Handle the non-periodic TxFIFO empty interrupt */ + N32_USBHS_VTRACE1_GINT_PTXFE, /* USBHS Handle the periodic TxFIFO empty interrupt */ + N32_USBHS_VTRACE1_GINT_HC, /* USBHS Handle the host channels interrupt */ + N32_USBHS_VTRACE1_GINT_HPRT, /* USBHS Handle the host port interrupt */ + N32_USBHS_VTRACE1_GINT_HPRT_POCCHNG, /* USBHS HPRT: Port Over-Current Change */ + N32_USBHS_VTRACE1_GINT_HPRT_PCDET, /* USBHS HPRT: Port Connect Detect */ + N32_USBHS_VTRACE1_GINT_HPRT_PENCHNG, /* USBHS HPRT: Port Enable Changed */ + N32_USBHS_VTRACE1_GINT_HPRT_LSDEV, /* USBHS HPRT: Low Speed Device Connected */ + N32_USBHS_VTRACE1_GINT_HPRT_FSDEV, /* USBHS HPRT: Full Speed Device Connected */ + N32_USBHS_VTRACE1_GINT_HPRT_LSFSSW, /* USBHS HPRT: Host Switch: LS -> FS */ + N32_USBHS_VTRACE1_GINT_HPRT_FSLSSW, /* USBHS HPRT: Host Switch: FS -> LS */ + N32_USBHS_VTRACE1_GINT_DISC, /* USBHS Handle the disconnect detected interrupt */ + N32_USBHS_VTRACE1_GINT_IPXFR, /* USBHS Handle the incomplete periodic transfer */ + +#endif + + __TRACE1_NSTRINGS, /* Separates the format 1 from the format 2 strings */ + + N32_USBHS_TRACE2_CLIP, /* USBHS CLIP: chidx: buflen: */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + + N32_USBHS_VTRACE2_CHANWAKEUP_IN, /* USBHS IN Channel wake up with result */ + N32_USBHS_VTRACE2_CHANWAKEUP_OUT, /* USBHS OUT Channel wake up with result */ + N32_USBHS_VTRACE2_CTRLIN, /* USBHS CTRLIN */ + N32_USBHS_VTRACE2_CTRLOUT, /* USBHS CTRLOUT */ + N32_USBHS_VTRACE2_INTRIN, /* USBHS INTRIN */ + N32_USBHS_VTRACE2_INTROUT, /* USBHS INTROUT */ + N32_USBHS_VTRACE2_BULKIN, /* USBHS BULKIN */ + N32_USBHS_VTRACE2_BULKOUT, /* USBHS BULKOUT */ + N32_USBHS_VTRACE2_ISOCIN, /* USBHS ISOCIN */ + N32_USBHS_VTRACE2_ISOCOUT, /* USBHS ISOCOUT */ + N32_USBHS_VTRACE2_STARTTRANSFER, /* USBHS EP buflen */ + N32_USBHS_VTRACE2_CHANCONF_CTRL_IN, + N32_USBHS_VTRACE2_CHANCONF_CTRL_OUT, + N32_USBHS_VTRACE2_CHANCONF_INTR_IN, + N32_USBHS_VTRACE2_CHANCONF_INTR_OUT, + N32_USBHS_VTRACE2_CHANCONF_BULK_IN, + N32_USBHS_VTRACE2_CHANCONF_BULK_OUT, + N32_USBHS_VTRACE2_CHANCONF_ISOC_IN, + N32_USBHS_VTRACE2_CHANCONF_ISOC_OUT, + N32_USBHS_VTRACE2_CHANHALT, /* Channel halted. chidx: , reason: */ + +#endif + + __TRACE2_NSTRINGS /* Total number of enumeration values */ +}; + +# define TRACE1_FIRST ((int)__TRACE1_BASEVALUE + 1) +# define TRACE1_INDEX(id) ((int)(id) - TRACE1_FIRST) +# define TRACE1_NSTRINGS TRACE1_INDEX(__TRACE1_NSTRINGS + 1) + +# define TRACE2_FIRST ((int)__TRACE1_NSTRINGS + 1) +# define TRACE2_INDEX(id) ((int)(id) - TRACE2_FIRST) +# define TRACE2_NSTRINGS TRACE2_INDEX(__TRACE2_NSTRINGS) + +#endif /* HAVE_USBHOST_TRACE */ + +/* HCD Setup ****************************************************************/ + +/* Hardware capabilities */ + +#define N32_NHOST_CHANNELS 8 /* Number of host channels */ +#define N32_MAX_PACKET_SIZE 64 /* Full speed max packet size */ +#define N32_EP0_DEF_PACKET_SIZE 8 /* EP0 default packet size */ +#define N32_EP0_MAX_PACKET_SIZE 64 /* EP0 FS max packet size */ +#define N32_MAX_TX_FIFOS 15 /* Max number of TX FIFOs */ +#define N32_MAX_PKTCOUNT 256 /* Max packet count */ +#define N32_RETRY_COUNT 3 /* Number of ctrl transfer retries */ + +/* Delays *******************************************************************/ + +#define N32_READY_DELAY 200000 /* In loop counts */ +#define N32_FLUSH_DELAY 200000 /* In loop counts */ +#define N32_SETUP_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ +#define N32_DATANAK_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The following enumeration represents the various states of the USB host + * state machine (for debug purposes only) + */ + +enum n32_smstate_e +{ + SMSTATE_DETACHED = 0, /* Not attached to a device */ + SMSTATE_ATTACHED, /* Attached to a device */ + SMSTATE_ENUM, /* Attached, enumerating */ + SMSTATE_CLASS_BOUND, /* Enumeration complete, class bound */ +}; + +/* This enumeration provides the reason for the channel halt. */ + +enum n32_chreason_e +{ + CHREASON_IDLE = 0, /* Inactive (initial state) */ + CHREASON_FREED, /* Channel is no longer in use */ + CHREASON_XFRC, /* Transfer complete */ + CHREASON_NAK, /* NAK received */ + CHREASON_NYET, /* NotYet received */ + CHREASON_STALL, /* Endpoint stalled */ + CHREASON_TXERR, /* Transfer error received */ + CHREASON_DTERR, /* Data toggle error received */ + CHREASON_FRMOR, /* Frame overrun */ + CHREASON_CANCELLED /* Transfer cancelled */ +}; + +/* This structure retains the state of one host channel. NOTE: Since there + * is only one channel operation active at a time, some of the fields in + * in the structure could be moved in struct n32_ubhost_s to achieve + * some memory savings. + */ + +struct n32_chan_s +{ + sem_t waitsem; /* Channel wait semaphore */ + volatile uint8_t result; /* The result of the transfer */ + volatile uint8_t chreason; /* Channel halt reason. See enum n32_chreason_e */ + uint8_t chidx; /* Channel index */ + uint8_t epno; /* Device endpoint number (0-127) */ + uint8_t eptype; /* See N32_USBHS_EPTYPE_* definitions */ + uint8_t funcaddr; /* Device function address */ + uint8_t speed; /* Device speed */ + uint8_t interval; /* Interrupt/isochronous EP polling interval */ + uint8_t pid; /* Data PID */ + uint8_t npackets; /* Number of packets (for data toggle) */ + bool inuse; /* True: This channel is "in use" */ + volatile bool indata1; /* IN data toggle. True: DATA01 (Bulk and INTR only) */ + volatile bool outdata1; /* OUT data toggle. True: DATA01 */ + bool in; /* True: IN endpoint */ + volatile bool waiter; /* True: Thread is waiting for a channel event */ + uint16_t maxpacket; /* Max packet size */ + uint16_t buflen; /* Buffer length (at start of transfer) */ + volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */ + volatile uint16_t inflight; /* Number of Tx bytes "in-flight" */ + uint8_t *buffer; /* Transfer buffer pointer */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* A channel represents on uni-directional endpoint. So, in the case of the + * bi-directional, control endpoint, there must be two channels to represent + * the endpoint. + */ + +struct n32_ctrlinfo_s +{ + uint8_t inndx; /* EP0 IN control channel index */ + uint8_t outndx; /* EP0 OUT control channel index */ +}; + +/* This structure retains the state of the USB host controller */ + +struct n32_usbhost_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to struct n32_usbhost_s. + */ + + struct usbhost_driver_s drvr; + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s rhport; + + /* Overall driver status */ + + volatile uint8_t smstate; /* The state of the USB host state machine */ + uint8_t chidx; /* ID of channel waiting for space in Tx FIFO */ + volatile bool connected; /* Connected to device */ + volatile bool change; /* Connection change */ + volatile bool pscwait; /* True: Thread is waiting for a port event */ + mutex_t lock; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait for a port event */ + struct n32_ctrlinfo_s ep0; /* Root hub port EP0 description */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + struct usbhost_devaddr_s devgen; /* Address generation data */ + + /* The state of each host channel */ + + struct n32_chan_s chan[N32_MAX_TX_FIFOS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ******************************************************/ + +#ifdef CONFIG_N32_USBHOST_REGDEBUG +static void n32_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void n32_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t n32_getreg(uint32_t addr); +static void n32_putreg(uint32_t addr, uint32_t value); +#else +# define n32_getreg(addr) getreg32(addr) +# define n32_putreg(addr,val) putreg32(val,addr) +#endif + +static inline void n32_modifyreg(uint32_t addr, uint32_t clrbits, + uint32_t setbits); + +#ifdef CONFIG_N32_USBHOST_PKTDUMP +# define n32_pktdump(m,b,n) lib_dumpbuffer(m,b,n) +#else +# define n32_pktdump(m,b,n) +#endif + +/* Byte stream access helper functions **************************************/ + +static inline uint16_t n32_getle16(const uint8_t *val); + +/* Channel management *******************************************************/ + +static int n32_chan_alloc(struct n32_usbhost_s *priv); +static inline void n32_chan_free(struct n32_usbhost_s *priv, + int chidx); +static inline void n32_chan_freeall(struct n32_usbhost_s *priv); +static void n32_chan_configure(struct n32_usbhost_s *priv, + int chidx); +static void n32_chan_halt(struct n32_usbhost_s *priv, int chidx, + enum n32_chreason_e chreason); +static int n32_chan_waitsetup(struct n32_usbhost_s *priv, + struct n32_chan_s *chan); +#ifdef CONFIG_USBHOST_ASYNCH +static int n32_chan_asynchsetup(struct n32_usbhost_s *priv, + struct n32_chan_s *chan, + usbhost_asynch_t callback, void *arg); +#endif +static int n32_chan_wait(struct n32_usbhost_s *priv, + struct n32_chan_s *chan); +static void n32_chan_wakeup(struct n32_usbhost_s *priv, + struct n32_chan_s *chan); +static int n32_ctrlchan_alloc(struct n32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, + uint8_t speed, + struct n32_ctrlinfo_s *ctrlep); +static int n32_ctrlep_alloc(struct n32_usbhost_s *priv, + const struct usbhost_epdesc_s *epdesc, + usbhost_ep_t *ep); +static int n32_xfrep_alloc(struct n32_usbhost_s *priv, + const struct usbhost_epdesc_s *epdesc, + usbhost_ep_t *ep); + +/* Control/data transfer logic **********************************************/ + +static void n32_transfer_start(struct n32_usbhost_s *priv, + int chidx); +#if 0 /* Not used */ +static inline uint16_t n32_getframe(void); +#endif +static int n32_ctrl_sendsetup(struct n32_usbhost_s *priv, + struct n32_ctrlinfo_s *ep0, + const struct usb_ctrlreq_s *req); +static int n32_ctrl_senddata(struct n32_usbhost_s *priv, + struct n32_ctrlinfo_s *ep0, + uint8_t *buffer, unsigned int buflen); +static int n32_ctrl_recvdata(struct n32_usbhost_s *priv, + struct n32_ctrlinfo_s *ep0, + uint8_t *buffer, unsigned int buflen); +static int n32_in_setup(struct n32_usbhost_s *priv, int chidx); +static ssize_t n32_in_transfer(struct n32_usbhost_s *priv, int chidx, + uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void n32_in_next(struct n32_usbhost_s *priv, + struct n32_chan_s *chan); +static int n32_in_asynch(struct n32_usbhost_s *priv, int chidx, + uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, void *arg); +#endif +static int n32_out_setup(struct n32_usbhost_s *priv, int chidx); +static ssize_t n32_out_transfer(struct n32_usbhost_s *priv, + int chidx, uint8_t *buffer, + size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void n32_out_next(struct n32_usbhost_s *priv, + struct n32_chan_s *chan); +static int n32_out_asynch(struct n32_usbhost_s *priv, int chidx, + uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, void *arg); +#endif + +/* Interrupt handling *******************************************************/ + +/* Lower level interrupt handlers */ + +static void n32_gint_wrpacket(struct n32_usbhost_s *priv, + uint8_t *buffer, int chidx, int buflen); +static inline void n32_gint_hcinisr(struct n32_usbhost_s *priv, + int chidx); +static inline void n32_gint_hcoutisr(struct n32_usbhost_s *priv, + int chidx); +static void n32_gint_connected(struct n32_usbhost_s *priv); +static void n32_gint_disconnected(struct n32_usbhost_s *priv); + +/* Second level interrupt handlers */ + +#ifdef CONFIG_N32H7_USBHS_SOFINTR +static inline void n32_gint_sofisr(struct n32_usbhost_s *priv); +#endif +static inline void n32_gint_rxflvlisr(struct n32_usbhost_s *priv); +static inline void n32_gint_nptxfeisr(struct n32_usbhost_s *priv); +static inline void n32_gint_ptxfeisr(struct n32_usbhost_s *priv); +static inline void n32_gint_hcisr(struct n32_usbhost_s *priv); +static inline void n32_gint_hprtisr(struct n32_usbhost_s *priv); +static inline void n32_gint_discisr(struct n32_usbhost_s *priv); +static inline void n32_gint_ipxfrisr(struct n32_usbhost_s *priv); + +/* First level, global interrupt handler */ + +static int n32_gint_isr(int irq, void *context, void *arg); + +/* Interrupt controls */ + +static void n32_gint_enable(void); +static void n32_gint_disable(void); +static inline void n32_hostinit_enable(void); +static void n32_txfe_enable(struct n32_usbhost_s *priv, int chidx); + +/* USB host controller operations *******************************************/ + +static int n32_wait(struct usbhost_connection_s *conn, + struct usbhost_hubport_s **hport); +static int n32_rh_enumerate(struct n32_usbhost_s *priv, + struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport); +static int n32_enumerate(struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport); + +static int n32_ep0configure(struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, + uint8_t speed, uint16_t maxpacketsize); +static int n32_epalloc(struct usbhost_driver_s *drvr, + const struct usbhost_epdesc_s *epdesc, + usbhost_ep_t *ep); +static int n32_epfree(struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int n32_alloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t *maxlen); +static int n32_free(struct usbhost_driver_s *drvr, + uint8_t *buffer); +static int n32_ioalloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t buflen); +static int n32_iofree(struct usbhost_driver_s *drvr, + uint8_t *buffer); +static int n32_ctrlin(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + uint8_t *buffer); +static int n32_ctrlout(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + const uint8_t *buffer); +static ssize_t n32_transfer(struct usbhost_driver_s *drvr, + usbhost_ep_t ep, uint8_t *buffer, + size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int n32_asynch(struct usbhost_driver_s *drvr, usbhost_ep_t ep, + uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, void *arg); +#endif +static int n32_cancel(struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int n32_connect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport, + bool connected); +#endif +static void n32_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport); + +/* Initialization ***********************************************************/ + +static void n32_portreset(struct n32_usbhost_s *priv); +static void n32_flush_txfifos(uint32_t txfnum); +static void n32_flush_rxfifo(void); +static void n32_vbusdrive(struct n32_usbhost_s *priv, bool state); +static void n32_host_initialize(struct n32_usbhost_s *priv); + +static inline void n32_sw_initialize(struct n32_usbhost_s *priv); +static inline int n32_hw_initialize(struct n32_usbhost_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* In this driver implementation, support is provided for only a single a + * single USB device. All status information can be simply retained in a + * single global instance. + */ + +static struct n32_usbhost_s g_usbhost = +{ + .lock = NXMUTEX_INITIALIZER, + .pscsem = SEM_INITIALIZER(0), +}; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_usbconn = +{ + .wait = n32_wait, + .enumerate = n32_enumerate, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_printreg + * + * Description: + * Print the contents of an N32 register operation + * + ****************************************************************************/ + +#ifdef CONFIG_N32_USBHOST_REGDEBUG +static void n32_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + uinfo("%08" PRIx32 "%s%08" PRIx32 "\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: n32_checkreg + * + * Description: + * Get the contents of an N32 register + * + ****************************************************************************/ + +#ifdef CONFIG_N32_USBHOST_REGDEBUG +static void n32_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register + * last time? Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + n32_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + uinfo("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new regisgter access */ + + n32_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: n32_getreg + * + * Description: + * Get the contents of an N32 register + * + ****************************************************************************/ + +#ifdef CONFIG_N32_USBHOST_REGDEBUG +static uint32_t n32_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + n32_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: n32_putreg + * + * Description: + * Set the contents of an N32 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_N32_USBHOST_REGDEBUG +static void n32_putreg(uint32_t addr, uint32_t val) +{ + /* Check if we need to print this value */ + + n32_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: n32_modifyreg + * + * Description: + * Modify selected bits of an N32 register. + * + ****************************************************************************/ + +static inline void n32_modifyreg(uint32_t addr, uint32_t clrbits, + uint32_t setbits) +{ + n32_putreg(addr, (((n32_getreg(addr)) & ~clrbits) | setbits)); +} + +/**************************************************************************** + * Name: n32_getle16 + * + * Description: + * Get a (possibly unaligned) 16-bit little endian value. + * + ****************************************************************************/ + +static inline uint16_t n32_getle16(const uint8_t *val) +{ + return (uint16_t)val[1] << 8 | (uint16_t)val[0]; +} + +/**************************************************************************** + * Name: n32_chan_alloc + * + * Description: + * Allocate a channel. + * + ****************************************************************************/ + +static int n32_chan_alloc(struct n32_usbhost_s *priv) +{ + int chidx; + + /* Search the table of channels */ + + for (chidx = 0; chidx < N32_NHOST_CHANNELS; chidx++) + { + /* Is this channel available? */ + + if (!priv->chan[chidx].inuse) + { + /* Yes... make it "in use" and return the index */ + + priv->chan[chidx].inuse = true; + return chidx; + } + } + + /* All of the channels are "in-use" */ + + return -EBUSY; +} + +/**************************************************************************** + * Name: n32_chan_free + * + * Description: + * Free a previoiusly allocated channel. + * + ****************************************************************************/ + +static void n32_chan_free(struct n32_usbhost_s *priv, int chidx) +{ + DEBUGASSERT((unsigned)chidx < N32_NHOST_CHANNELS); + + /* Halt the channel */ + + n32_chan_halt(priv, chidx, CHREASON_FREED); + + /* Mark the channel available */ + + priv->chan[chidx].inuse = false; +} + +/**************************************************************************** + * Name: n32_chan_freeall + * + * Description: + * Free all channels. + * + ****************************************************************************/ + +static inline void n32_chan_freeall(struct n32_usbhost_s *priv) +{ + uint8_t chidx; + + /* Free all host channels */ + + for (chidx = 2; chidx < N32_NHOST_CHANNELS; chidx++) + { + n32_chan_free(priv, chidx); + } +} + +/**************************************************************************** + * Name: n32_chan_configure + * + * Description: + * Configure or re-configure a host channel. Host channels are configured + * when endpoint is allocated and EP0 (only) is re-configured with the + * max packet size or device address changes. + * + ****************************************************************************/ + +static void n32_chan_configure(struct n32_usbhost_s *priv, int chidx) +{ + struct n32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + + /* Clear any old pending interrupts for this host channel. */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), 0xffffffff); + + /* Enable channel interrupts required for transfers on this channel. */ + + regval = 0; + + switch (chan->eptype) + { + case N32_USBHS_EPTYPE_CTRL: + case N32_USBHS_EPTYPE_BULK: + { + #ifdef HAVE_USBHOST_TRACE_VERBOSE + uint16_t intrace; + uint16_t outtrace; + + /* Determine the definitive trace ID to use below */ + + if (chan->eptype == N32_USBHS_EPTYPE_CTRL) + { + intrace = N32_USBHS_VTRACE2_CHANCONF_CTRL_IN; + outtrace = N32_USBHS_VTRACE2_CHANCONF_CTRL_OUT; + } + else + { + intrace = N32_USBHS_VTRACE2_CHANCONF_BULK_IN; + outtrace = N32_USBHS_VTRACE2_CHANCONF_BULK_OUT; + } + #endif + + /* Interrupts required for CTRL and BULK endpoints */ + + regval |= (N32_USBHS_HCHINTEN_TXCIEN | + N32_USBHS_HCHINTEN_STALLIEN | + N32_USBHS_HCHINTEN_NAKIEN | + N32_USBHS_HCHINTEN_TXERRIEN | + N32_USBHS_HCHINTEN_DTERRIEN); + + /* Additional setting for IN/OUT endpoints */ + + if (chan->in) + { + usbhost_vtrace2(intrace, chidx, chan->epno); + regval |= N32_USBHS_HCHINTEN_BBERRIEN; + } + else + { + usbhost_vtrace2(outtrace, chidx, chan->epno); + regval |= N32_USBHS_HCHINTEN_NYETIEN; + } + } + break; + + case N32_USBHS_EPTYPE_INTR: + { + /* Interrupts required for INTR endpoints */ + + regval |= (N32_USBHS_HCHINTEN_TXCIEN | + N32_USBHS_HCHINTEN_STALLIEN | + N32_USBHS_HCHINTEN_NAKIEN | + N32_USBHS_HCHINTEN_TXERRIEN | + N32_USBHS_HCHINTEN_FOVRIEN | + N32_USBHS_HCHINTEN_DTERRIEN); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(N32_USBHS_VTRACE2_CHANCONF_INTR_IN, chidx, + chan->epno); + regval |= N32_USBHS_HCHINTEN_BBERRIEN; + } + #ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(N32_USBHS_VTRACE2_CHANCONF_INTR_OUT, chidx, + chan->epno); + } + #endif + } + break; + + case N32_USBHS_EPTYPE_ISOC: + { + /* Interrupts required for ISOC endpoints */ + + regval |= (N32_USBHS_HCHINTEN_TXCIEN | + N32_USBHS_HCHINTEN_ACKIEN | + N32_USBHS_HCHINTEN_FOVRIEN); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(N32_USBHS_VTRACE2_CHANCONF_ISOC_IN, chidx, + chan->epno); + regval |= (N32_USBHS_HCHINTEN_TXERRIEN | + N32_USBHS_HCHINTEN_BBERRIEN); + } + #ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(N32_USBHS_VTRACE2_CHANCONF_ISOC_OUT, chidx, + chan->epno); + } + #endif + } + break; + } + + n32_putreg(N32_USBHS_HCHINTEN(chidx), regval); + + /* Enable the top level host channel interrupt. */ + + n32_modifyreg(N32_USBHS_HACHINTEN, 0, N32_USBHS_HACHINT_CH(chidx)); + + /* Make sure host channel interrupts are enabled. */ + + n32_modifyreg(N32_USBHS_GINTEN, 0, N32_USBHS_GINTEN_HCHIEN); + + /* Program the HCCHAR register */ + + regval = ((uint32_t)chan->maxpacket << N32_USBHS_HCHCTRL_MPS_SHIFT) | + ((uint32_t)chan->epno << N32_USBHS_HCHCTRL_EPNUM_SHIFT) | + ((uint32_t)chan->eptype << N32_USBHS_HCHCTRL_EPTYPE_SHIFT) | + ((uint32_t)chan->funcaddr << N32_USBHS_HCHCTRL_DEVADDR_SHIFT); + + /* Special case settings for low speed devices */ + + if (chan->speed == USB_SPEED_LOW) + { + regval |= N32_USBHS_HCHCTRL_LSPDDEV; + } + + /* Special case settings for IN endpoints */ + + if (chan->in) + { + regval |= N32_USBHS_HCHCTRL_EPDIR; + } + + /* Special case settings for INTR endpoints */ + + if (chan->eptype == N32_USBHS_EPTYPE_INTR) + { + regval |= N32_USBHS_HCHCTRL_ODDFRM; + } + + /* Write the channel configuration */ + + n32_putreg(N32_USBHS_HCHCTRL(chidx), regval); +} + +/**************************************************************************** + * Name: n32_chan_halt + * + * Description: + * Halt the channel associated with 'chidx' by setting the CHannel DISable + * (CHDIS) bit in in the HCCHAR register. + * + ****************************************************************************/ + +static void n32_chan_halt(struct n32_usbhost_s *priv, int chidx, + enum n32_chreason_e chreason) +{ + uint32_t hcchar; + uint32_t intmsk; + uint32_t eptype; + unsigned int avail; + + /* Save the reason for the halt. We need this in the channel halt + * interrupt handling logic to know what to do next. + */ + + usbhost_vtrace2(N32_USBHS_VTRACE2_CHANHALT, chidx, chreason); + + priv->chan[chidx].chreason = (uint8_t)chreason; + + /* "The application can disable any channel by programming the + * N32_USBHS_HCHCTRLx register with the CHDIS and CHENA bits set to 1. + * This enables the USBHS host to flush the posted requests (if any) + * and generates a channel halted interrupt. The application must wait + * for the CHH interrupt in N32_USBHS_HCHINTSTSx before reallocating + * the channel for other transactions. + * The USBHS host does not interrupt the transaction that has already + * been started on the USB." + */ + + hcchar = n32_getreg(N32_USBHS_HCHCTRL(chidx)); + hcchar |= (N32_USBHS_HCHCTRL_CHDIS | N32_USBHS_HCHCTRL_CHEN); + + /* Get the endpoint type from the HCCHAR register */ + + eptype = hcchar & N32_USBHS_HCHCTRL_EPTYPE_MASK; + + /* Check for space in the Tx FIFO to issue the halt. + * + * "Before disabling a channel, the application must ensure that there is + * at least one free space available in the non-periodic request queue + * (when disabling a non-periodic channel) or the periodic request queue + * (when disabling a periodic channel). The application can simply flush + * the posted requests when the Request queue is full (before disabling + * the channel), by programming the N32_USBHS_HCHCTRLx register with the + * CHDIS bit set to 1, and the CHENA bit cleared to 0. + */ + + if (eptype == N32_USBHS_HCHCTRL_EPTYPE_CTRL || + eptype == N32_USBHS_HCHCTRL_EPTYPE_BULK) + { + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = n32_getreg(N32_USBHS_GNPTXFSTS) & + N32_USBHS_GNPTXFSTS_NPTXFSAV_MASK; + } + else + { + /* if (eptype == N32_USBHS_HCHCTRL_EPTYPE_ISOC || + * eptype == N32_USBHS_HCHCTRL_EPTYPE_INTR) + */ + + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = n32_getreg(N32_USBHS_HPTXFQSTS) & + N32_USBHS_HPTXFQSTS_PTXFSAVL_MASK; + } + + /* Check if there is any space available in the Tx FIFO. */ + + if (avail == 0) + { + /* The Tx FIFO is full... disable the channel to flush the requests */ + + hcchar &= ~N32_USBHS_HCHCTRL_CHEN; + } + + /* Unmask the CHannel Halted (CHH) interrupt */ + + intmsk = n32_getreg(N32_USBHS_HCHINTEN(chidx)); + intmsk |= N32_USBHS_HCHINTEN_CHHTDIEN; + n32_putreg(N32_USBHS_HCHINTEN(chidx), intmsk); + + /* Halt the channel by setting CHDIS (and maybe CHENA) in the HCCHAR */ + + n32_putreg(N32_USBHS_HCHCTRL(chidx), hcchar); +} + +/**************************************************************************** + * Name: n32_chan_waitsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling + * the transfer (as soon as we are absolutely committed to the transfer). + * We do this to minimize race conditions. This logic would have to be + * expanded if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Called from a normal thread context BEFORE the transfer has been + * started. + * + ****************************************************************************/ + +static int n32_chan_waitsetup(struct n32_usbhost_s *priv, + struct n32_chan_s *chan) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed + * when either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + chan->waiter = true; +#ifdef CONFIG_USBHOST_ASYNCH + chan->callback = NULL; + chan->arg = NULL; +#endif + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: n32_chan_asynchsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling + * the transfer (as soon as we are absolutely committed to the to avoid + * transfer). We do this to minimize race conditions. This logic would + * have to be expanded if we want to have more than one packet in flight + * at a time! + * + * Assumptions: + * Might be called from the level of an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int n32_chan_asynchsetup(struct n32_usbhost_s *priv, + struct n32_chan_s *chan, + usbhost_asynch_t callback, void *arg) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed + * when either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + chan->waiter = false; + chan->callback = callback; + chan->arg = arg; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: n32_chan_wait + * + * Description: + * Wait for a transfer on a channel to complete. + * + * Assumptions: + * Called from a normal thread context + * + ****************************************************************************/ + +static int n32_chan_wait(struct n32_usbhost_s *priv, + struct n32_chan_s *chan) +{ + irqstate_t flags; + int ret; + + /* Disable interrupts so that the following operations will be atomic. On + * the OTG FS global interrupt needs to be disabled. However, here we + * disable all interrupts to exploit that fact that interrupts will be re- + * enabled while we wait. + */ + + flags = enter_critical_section(); + + /* Loop, testing for an end of transfer condition. The channel 'result' + * was set to EBUSY and 'waiter' was set to true before the transfer; + * 'waiter' will be set to false and 'result' will be set appropriately + * when the transfer is completed. + */ + + do + { + /* Wait for the transfer to complete. NOTE the transfer may already + * completed before we get here or the transfer may complete while we + * wait here. + */ + + nxsem_wait_uninterruptible(&chan->waitsem); + } + while (chan->waiter); + + /* The transfer is complete re-enable interrupts and return the result */ + + ret = -(int)chan->result; + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: n32_chan_wakeup + * + * Description: + * A channel transfer has completed... wakeup any threads waiting for the + * transfer to complete. + * + * Assumptions: + * This function is called from the transfer complete interrupt handler for + * the channel. Interrupts are disabled. + * + ****************************************************************************/ + +static void n32_chan_wakeup(struct n32_usbhost_s *priv, + struct n32_chan_s *chan) +{ + /* Is the transfer complete? */ + + if (chan->result != EBUSY) + { + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + /* Wake'em up! */ + + usbhost_vtrace2(chan->in ? N32_USBHS_VTRACE2_CHANWAKEUP_IN : + N32_USBHS_VTRACE2_CHANWAKEUP_OUT, + chan->epno, chan->result); + + nxsem_post(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + /* Handle continuation of IN/OUT pipes */ + + if (chan->in) + { + n32_in_next(priv, chan); + } + else + { + n32_out_next(priv, chan); + } + } +#endif + } +} + +/**************************************************************************** + * Name: n32_ctrlchan_alloc + * + * Description: + * Allocate and configured channels for a control pipe. + * + ****************************************************************************/ + +static int n32_ctrlchan_alloc(struct n32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, + uint8_t speed, + struct n32_ctrlinfo_s *ctrlep) +{ + struct n32_chan_s *chan; + int inndx; + int outndx; + + outndx = n32_chan_alloc(priv); + if (outndx < 0) + { + return -ENOMEM; + } + + ctrlep->outndx = outndx; + chan = &priv->chan[outndx]; + chan->epno = epno; + chan->in = false; + chan->eptype = N32_USBHS_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->interval = 0; + chan->maxpacket = N32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control OUT channels */ + + n32_chan_configure(priv, outndx); + + /* Allocate and initialize the control IN channel */ + + inndx = n32_chan_alloc(priv); + if (inndx < 0) + { + n32_chan_free(priv, outndx); + return -ENOMEM; + } + + ctrlep->inndx = inndx; + chan = &priv->chan[inndx]; + chan->epno = epno; + chan->in = true; + chan->eptype = N32_USBHS_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->interval = 0; + chan->maxpacket = N32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control IN channels */ + + n32_chan_configure(priv, inndx); + return OK; +} + +/**************************************************************************** + * Name: n32_ctrlep_alloc + * + * Description: + * Allocate a container and channels for control pipe. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_ctrlep_alloc(struct n32_usbhost_s *priv, + const struct usbhost_epdesc_s *epdesc, + usbhost_ep_t *ep) +{ + struct usbhost_hubport_s *hport; + struct n32_ctrlinfo_s *ctrlep; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device + * is connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a container for the control endpoint */ + + ctrlep = (struct n32_ctrlinfo_s *) + kmm_malloc(sizeof(struct n32_ctrlinfo_s)); + if (ctrlep == NULL) + { + uerr("ERROR: Failed to allocate control endpoint container\n"); + return -ENOMEM; + } + + /* Then allocate and configure the IN/OUT channels */ + + ret = n32_ctrlchan_alloc(priv, epdesc->addr & USB_EPNO_MASK, + hport->funcaddr, hport->speed, ctrlep); + if (ret < 0) + { + uerr("ERROR: n32_ctrlchan_alloc failed: %d\n", ret); + kmm_free(ctrlep); + return ret; + } + + /* Return a pointer to the control pipe container as the pipe "handle" */ + + *ep = (usbhost_ep_t)ctrlep; + return OK; +} + +/**************************************************************************** + * Name: n32_xfrep_alloc + * + * Description: + * Allocate and configure one unidirectional endpoint. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_xfrep_alloc(struct n32_usbhost_s *priv, + const struct usbhost_epdesc_s *epdesc, + usbhost_ep_t *ep) +{ + struct usbhost_hubport_s *hport; + struct n32_chan_s *chan; + int chidx; + + /* Sanity check. NOTE that this method should only be called if a device + * is connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a host channel for the endpoint */ + + chidx = n32_chan_alloc(priv); + if (chidx < 0) + { + uerr("ERROR: Failed to allocate a host channel\n"); + return -ENOMEM; + } + + /* Decode the endpoint descriptor to initialize the channel data + * structures. Note: Here we depend on the fact that the endpoint point + * type is encoded in the same way in the endpoint descriptor as it is in + * the OTG HS hardware. + */ + + chan = &priv->chan[chidx]; + chan->epno = epdesc->addr & USB_EPNO_MASK; + chan->in = epdesc->in; + chan->eptype = epdesc->xfrtype; + chan->funcaddr = hport->funcaddr; + chan->speed = hport->speed; + chan->interval = epdesc->interval; + chan->maxpacket = epdesc->mxpacketsize; + chan->indata1 = false; + chan->outdata1 = false; + + /* Then configure the endpoint */ + + n32_chan_configure(priv, chidx); + + /* Return the index to the allocated channel as the endpoint "handle" */ + + *ep = (usbhost_ep_t)chidx; + return OK; +} + +/**************************************************************************** + * Name: n32_transfer_start + * + * Description: + * Start at transfer on the select IN or OUT channel. + * + ****************************************************************************/ + +static void n32_transfer_start(struct n32_usbhost_s *priv, int chidx) +{ + struct n32_chan_s *chan; + uint32_t regval; + unsigned int npackets; + unsigned int maxpacket; + unsigned int avail; + unsigned int wrsize; + unsigned int minsize; + + /* Set up the initial state of the transfer */ + + chan = &priv->chan[chidx]; + + usbhost_vtrace2(N32_USBHS_VTRACE2_STARTTRANSFER, chidx, chan->buflen); + + chan->result = EBUSY; + chan->inflight = 0; + chan->xfrd = 0; + priv->chidx = chidx; + + /* Compute the expected number of packets associated to the transfer. + * If the transfer length is zero (or less than the size of one maximum + * size packet), then one packet is expected. + */ + + /* If the transfer size is greater than one packet, then calculate the + * number of packets that will be received/sent, including any partial + * final packet. + */ + + maxpacket = chan->maxpacket; + + if (chan->buflen > maxpacket) + { + npackets = (chan->buflen + maxpacket - 1) / maxpacket; + + /* Clip if the buffer length if it exceeds the maximum number of + * packets that can be transferred (this should not happen). + */ + + if (npackets > N32_MAX_PKTCOUNT) + { + npackets = N32_MAX_PKTCOUNT; + chan->buflen = N32_MAX_PKTCOUNT * maxpacket; + usbhost_trace2(N32_USBHS_TRACE2_CLIP, chidx, chan->buflen); + } + } + else + { + /* One packet will be sent/received (might be a zero length packet) */ + + npackets = 1; + } + + /* If it is an IN transfer, then adjust the size of the buffer UP to + * a full number of packets. Hmmm... couldn't this cause an overrun + * into unallocated memory? + */ + +#if 0 /* Think about this */ + if (chan->in) + { + /* Force the buffer length to an even multiple of maxpacket */ + + chan->buflen = npackets * maxpacket; + } +#endif + + /* Save the number of packets in the transfer. We will need this in + * order to set the next data toggle correctly when the transfer + * completes. + */ + + chan->npackets = (uint8_t)npackets; + + /* Setup the HCTSIZn register */ + + regval = ((uint32_t)chan->buflen << N32_USBHS_HCHTXSIZ_TXSIZ_SHIFT) | + ((uint32_t)npackets << N32_USBHS_HCHTXSIZ_PKCNT_SHIFT) | + ((uint32_t)chan->pid << N32_USBHS_HCHTXSIZ_PID_SHIFT); + n32_putreg(N32_USBHS_HCHTXSIZ(chidx), regval); + + /* Setup the HCCHAR register: Frame oddness and host channel enable */ + + regval = n32_getreg(N32_USBHS_HCHCTRL(chidx)); + + /* Set/clear the Odd Frame bit. Check for an even frame; if so set Odd + * Frame. This field is applicable for only periodic (isochronous and + * interrupt) channels. + */ + + if ((n32_getreg(N32_USBHS_HFNUM) & 1) == 0) + { + regval |= N32_USBHS_HCHCTRL_ODDFRM; + } + else + { + regval &= ~N32_USBHS_HCHCTRL_ODDFRM; + } + + regval &= ~N32_USBHS_HCHCTRL_CHDIS; + regval |= N32_USBHS_HCHCTRL_CHEN; + n32_putreg(N32_USBHS_HCHCTRL(chidx), regval); + + /* If this is an out transfer, then we need to do more.. we need to copy + * the outgoing data into the correct TxFIFO. + */ + + if (!chan->in && chan->buflen > 0) + { + /* Handle non-periodic (CTRL and BULK) OUT transfers differently than + * periodic (INTR and ISOC) OUT transfers. + */ + + minsize = MIN(chan->buflen, chan->maxpacket); + + switch (chan->eptype) + { + case N32_USBHS_EPTYPE_CTRL: /* Non periodic transfer */ + case N32_USBHS_EPTYPE_BULK: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = n32_getreg(N32_USBHS_GNPTXFSTS); + avail = ((regval & N32_USBHS_GNPTXFSTS_NPTXFSAV_MASK) >> + N32_USBHS_GNPTXFSTS_NPTXFSAV_SHIFT) << 2; + } + break; + + /* Periodic transfer */ + + case N32_USBHS_EPTYPE_INTR: + case N32_USBHS_EPTYPE_ISOC: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = n32_getreg(N32_USBHS_HPTXFQSTS); + avail = ((regval & N32_USBHS_HPTXFQSTS_PTXFSAVL_MASK) >> + N32_USBHS_HPTXFQSTS_PTXFSAVL_SHIFT) << 2; + } + break; + + default: + DEBUGPANIC(); + return; + } + + /* Is there space in the TxFIFO to hold the minimum size packet? */ + + if (minsize <= avail) + { + /* Yes.. Get the size of the biggest thing that we can put + * in the Tx FIFO now + */ + + wrsize = chan->buflen; + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + + wrsize = wrpackets * chan->maxpacket; + } + + /* Write packet into the Tx FIFO. */ + + n32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); + } + + /* Did we put the entire buffer into the Tx FIFO? */ + + if (chan->buflen > avail) + { + /* No, there was insufficient space to hold the entire transfer ... + * Enable the Tx FIFO interrupt to handle the transfer when the Tx + * FIFO becomes empty. + */ + + n32_txfe_enable(priv, chidx); + } + } +} + +/**************************************************************************** + * Name: n32_getframe + * + * Description: + * Get the current frame number. The frame number (FRNUM) field increments + * when a new SOF is transmitted on the USB, and is cleared to 0 when it + * reaches 0x3fff. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static inline uint16_t n32_getframe(void) +{ + return (uint16_t)(n32_getreg(N32_USBHS_HFNUM) & + N32_USBHS_HFNUM_FRNUM_MASK); +} +#endif + +/**************************************************************************** + * Name: n32_ctrl_sendsetup + * + * Description: + * Send an IN/OUT SETUP packet. + * + ****************************************************************************/ + +static int n32_ctrl_sendsetup(struct n32_usbhost_s *priv, + struct n32_ctrlinfo_s *ep0, + const struct usb_ctrlreq_s *req) +{ + struct n32_chan_s *chan; + clock_t start; + clock_t elapsed; + int ret; + + /* Loop while the device reports NAK (and a timeout is not exceeded */ + + chan = &priv->chan[ep0->outndx]; + start = clock_systime_ticks(); + + do + { + /* Send the SETUP packet */ + + chan->pid = N32_USBHS_PID_SETUP; + chan->buffer = (uint8_t *)req; + chan->buflen = USB_SIZEOF_CTRLREQ; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = n32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + n32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete */ + + ret = n32_chan_wait(priv, chan); + + /* Return on success and for all failures other than EAGAIN. EAGAIN + * means that the device NAKed the SETUP command and that we should + * try a few more times. + */ + + if (ret != -EAGAIN) + { + /* Output some debug information if the transfer failed */ + + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_TRNSFRFAILED, ret); + } + + /* Return the result in any event */ + + return ret; + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systime_ticks() - start; + } + while (elapsed < N32_SETUP_DELAY); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: n32_ctrl_senddata + * + * Description: + * Send data in the data phase of an OUT control transfer. Or send status + * in the status phase of an IN control transfer + * + ****************************************************************************/ + +static int n32_ctrl_senddata(struct n32_usbhost_s *priv, + struct n32_ctrlinfo_s *ep0, + uint8_t *buffer, unsigned int buflen) +{ + struct n32_chan_s *chan = &priv->chan[ep0->outndx]; + int ret; + + /* Save buffer information */ + + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set the DATA PID */ + + if (buflen == 0) + { + /* For status OUT stage with buflen == 0, set PID DATA1 */ + + chan->outdata1 = true; + } + + /* Set the Data PID as per the outdata1 boolean */ + + chan->pid = chan->outdata1 ? N32_USBHS_PID_DATA1 : N32_USBHS_PID_DATA0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = n32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + n32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete and return the result */ + + return n32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: n32_ctrl_recvdata + * + * Description: + * Receive data in the data phase of an IN control transfer. Or receive + * status in the status phase of an OUT control transfer + * + ****************************************************************************/ + +static int n32_ctrl_recvdata(struct n32_usbhost_s *priv, + struct n32_ctrlinfo_s *ep0, + uint8_t *buffer, unsigned int buflen) +{ + struct n32_chan_s *chan = &priv->chan[ep0->inndx]; + int ret; + + /* Save buffer information */ + + chan->pid = N32_USBHS_PID_DATA1; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = n32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + n32_transfer_start(priv, ep0->inndx); + + /* Wait for the transfer to complete and return the result */ + + return n32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: n32_in_setup + * + * Description: + * Initiate an IN transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int n32_in_setup(struct n32_usbhost_s *priv, int chidx) +{ + struct n32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case N32_USBHS_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are + * not currently supported + */ + + return -ENOSYS; + } + + case N32_USBHS_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the IN data PID */ + + usbhost_vtrace2(N32_USBHS_VTRACE2_ISOCIN, chidx, chan->buflen); + chan->pid = N32_USBHS_PID_DATA0; + } + break; + + case N32_USBHS_EPTYPE_BULK: /* Bulk */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(N32_USBHS_VTRACE2_BULKIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? N32_USBHS_PID_DATA1 : + N32_USBHS_PID_DATA0; + } + break; + + case N32_USBHS_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(N32_USBHS_VTRACE2_INTRIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? N32_USBHS_PID_DATA1 : + N32_USBHS_PID_DATA0; + } + break; + } + + /* Start the transfer */ + + n32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: n32_in_transfer + * + * Description: + * Transfer 'buflen' bytes into 'buffer' from an IN channel. + * + ****************************************************************************/ + +static ssize_t n32_in_transfer(struct n32_usbhost_s *priv, int chidx, + uint8_t *buffer, size_t buflen) +{ + struct n32_chan_s *chan; + clock_t start; + ssize_t xfrd; + int ret; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs any error other than a simple NAK. NAK would + * simply indicate the end of the transfer (short-transfer). + */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + xfrd = 0; + + start = clock_systime_ticks(); + while (chan->xfrd < chan->buflen) + { + /* Set up for the wait BEFORE starting the transfer */ + + ret = n32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint */ + + ret = n32_in_setup(priv, chidx); + if (ret < 0) + { + uerr("ERROR: n32_in_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = n32_chan_wait(priv, chan); + + /* EAGAIN indicates that the device NAKed the transfer. */ + + if (ret < 0) + { + /* The transfer failed. If we received a NAK, return all data + * buffered so far (if any). + */ + + if (ret == -EAGAIN) + { + /* Was data buffered prior to the NAK? */ + + if (xfrd > 0) + { + /* Yes, return the amount of data received. + * + * REVISIT: This behavior is clearly correct for CDC/ACM + * bulk transfers and HID interrupt transfers. But I am + * not so certain for MSC bulk transfers which, I think, + * could have NAKed packets in the middle of a transfer. + */ + + return xfrd; + } + else + { + useconds_t delay; + + /* Get the elapsed time. Has the timeout elapsed? + * if not then try again. + */ + + clock_t elapsed = clock_systime_ticks() - start; + + if (elapsed >= N32_DATANAK_DELAY) + { + /* Timeout out... break out returning the NAK as + * as a failure. + */ + + return (ssize_t)ret; + } + + /* Wait a bit before retrying after a NAK. */ + + if (chan->eptype == N32_USBHS_EPTYPE_INTR) + { + /* For interrupt (and isochronous) endpoints, the + * polling rate is determined by the bInterval field + * of the endpoint descriptor (in units of frames + * which we treat as milliseconds here). + */ + + if (chan->interval > 0) + { + /* Convert the delay to units of microseconds */ + + delay = (useconds_t)chan->interval * 1000; + } + else + { + /* Out of range! For interrupt endpoints, the valid + * range is 1-255 frames. Assume one frame. + */ + + delay = 1000; + } + } + else + { + /* For Isochronous endpoints, bInterval must be 1. + * Bulk endpoints do not have a polling interval. + * Rather, the should wait until data is received. + * + * REVISIT: For bulk endpoints this 1 msec delay is + * only intended to give the CPU a break from the bulk + * EP tight polling loop. But are there performance + * issues? + */ + + delay = 1000; + } + + /* Wait for the next polling interval. For interrupt and + * isochronous endpoints, this is necessary to assure the + * polling interval. It is used in other cases only to + * prevent the polling from consuming too much CPU + * bandwidth. + * + * Small delays could require more resolution than is + * provided by the system timer. For example, if the + * system timer resolution is 10MS, then + * nxsched_usleep(1000) will actually request a delay 20MS + * (due to both quantization and rounding). + * + * REVISIT: So which is better? To ignore tiny delays and + * hog the system bandwidth? Or to wait for an excessive + * amount and destroy system throughput? + */ + + if (delay > CONFIG_USEC_PER_TICK) + { + nxsched_usleep(delay - CONFIG_USEC_PER_TICK); + } + } + } + else + { + /* Some unexpected, fatal error occurred. */ + + usbhost_trace1(N32_USBHS_TRACE1_TRNSFRFAILED, ret); + + /* Break out and return the error */ + + uerr("ERROR: n32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + } + else + { + /* Successfully received another chunk of data... add that to the + * running total. Then continue reading until we read 'buflen' + * bytes of data or until the devices NAKs (implying a short + * packet). + */ + + xfrd += chan->xfrd; + } + } + + return xfrd; +} + +/**************************************************************************** + * Name: n32_in_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void n32_in_next(struct n32_usbhost_s *priv, + struct n32_chan_s *chan) +{ + usbhost_asynch_t callback; + void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = n32_in_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + uerr("ERROR: n32_in_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uinfo("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: n32_in_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int n32_in_asynch(struct n32_usbhost_s *priv, int chidx, + uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, void *arg) +{ + struct n32_chan_s *chan; + int ret; + + /* Set up for the transfer BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = n32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + uerr("ERROR: n32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = n32_in_setup(priv, chidx); + if (ret < 0) + { + uerr("ERROR: n32_in_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: n32_out_setup + * + * Description: + * Initiate an OUT transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int n32_out_setup(struct n32_usbhost_s *priv, int chidx) +{ + struct n32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case N32_USBHS_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are + * not currently supported + */ + + return -ENOSYS; + } + + case N32_USBHS_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the OUT data PID */ + + usbhost_vtrace2(N32_USBHS_VTRACE2_ISOCOUT, chidx, chan->buflen); + chan->pid = N32_USBHS_PID_DATA0; + } + break; + + case N32_USBHS_EPTYPE_BULK: /* Bulk */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(N32_USBHS_VTRACE2_BULKOUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? N32_USBHS_PID_DATA1 : + N32_USBHS_PID_DATA0; + } + break; + + case N32_USBHS_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(N32_USBHS_VTRACE2_INTROUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? N32_USBHS_PID_DATA1 : + N32_USBHS_PID_DATA0; + + /* Toggle the OUT data PID for the next transfer */ + + chan->outdata1 ^= true; + } + break; + } + + /* Start the transfer */ + + n32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: n32_out_transfer + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' through an OUT channel. + * + ****************************************************************************/ + +static ssize_t n32_out_transfer(struct n32_usbhost_s *priv, + int chidx, uint8_t *buffer, + size_t buflen) +{ + struct n32_chan_s *chan; + clock_t start; + clock_t elapsed; + size_t xfrlen; + ssize_t xfrd; + int ret; + bool zlp; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs (any error other than a simple NAK) + */ + + chan = &priv->chan[chidx]; + start = clock_systime_ticks(); + xfrd = 0; + zlp = (buflen == 0); + + while (buflen > 0 || zlp) + { + /* Transfer one packet at a time. The hardware is capable of queueing + * multiple OUT packets, but I just haven't figured out how to handle + * the case where a single OUT packet in the group is NAKed. + */ + + xfrlen = MIN(chan->maxpacket, buflen); + chan->buffer = buffer; + chan->buflen = xfrlen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = n32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint */ + + ret = n32_out_setup(priv, chidx); + if (ret < 0) + { + uerr("ERROR: n32_out_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = n32_chan_wait(priv, chan); + + /* Handle transfer failures */ + + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_TRNSFRFAILED, ret); + + /* Check for a special case: If (1) the transfer was NAKed and (2) + * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we + * should be able to just flush the Rx and Tx FIFOs and try again. + * We can detect this latter case because then the transfer buffer + * pointer and buffer size will be unaltered. + */ + + elapsed = clock_systime_ticks() - start; + if (ret != -EAGAIN || /* Not a NAK condition OR */ + elapsed >= N32_DATANAK_DELAY || /* Timeout has elapsed OR */ + chan->xfrd > 0) /* Data has been partially transferred */ + { + /* Break out and return the error */ + + uerr("ERROR: n32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Is this flush really necessary? What does the hardware do with + * the data in the FIFO when the NAK occurs? Does it discard it? + */ + + n32_flush_txfifos(N32_USBHS_GRSTCTRL_TXFNUM_HALL); + + /* Get the device a little time to catch up. Then retry the + * transfer using the same buffer pointer and length. + */ + + nxsched_usleep(20 * 1000); + } + else + { + /* Successfully transferred. Update the buffer pointe/length */ + + buffer += xfrlen; + buflen -= xfrlen; + xfrd += chan->xfrd; + zlp = false; + } + } + + return xfrd; +} + +/**************************************************************************** + * Name: n32_out_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void n32_out_next(struct n32_usbhost_s *priv, + struct n32_chan_s *chan) +{ + usbhost_asynch_t callback; + void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = n32_out_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + uerr("ERROR: n32_out_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uinfo("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: n32_out_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int n32_out_asynch(struct n32_usbhost_s *priv, int chidx, + uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, void *arg) +{ + struct n32_chan_s *chan; + int ret; + + /* Set up for the transfer BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = n32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + uerr("ERROR: n32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = n32_out_setup(priv, chidx); + if (ret < 0) + { + uerr("ERROR: n32_out_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: n32_gint_wrpacket + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' to the Tx FIFO associated with + * 'chidx' (non-DMA). + * + ****************************************************************************/ + +static void n32_gint_wrpacket(struct n32_usbhost_s *priv, + uint8_t *buffer, int chidx, int buflen) +{ + uint32_t *src; + uint32_t fifo; + int buflen32; + + n32_pktdump("Sending", buffer, buflen); + + /* Get the number of 32-byte words associated with this byte size */ + + buflen32 = (buflen + 3) >> 2; + + /* Get the address of the Tx FIFO associated with this channel */ + + fifo = N32_USBHS_DFIFO_HCH(chidx); + + /* Transfer all of the data into the Tx FIFO */ + + src = (uint32_t *)buffer; + for (; buflen32 > 0; buflen32--) + { + uint32_t data = *src++; + + n32_putreg(fifo, data); + } + + /* Increment the count of bytes "in-flight" in the Tx FIFO */ + + priv->chan[chidx].inflight += buflen; +} + +/**************************************************************************** + * Name: n32_gint_hcinisr + * + * Description: + * USB OTG FS host IN channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set + * as follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void n32_gint_hcinisr(struct n32_usbhost_s *priv, + int chidx) +{ + struct n32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = n32_getreg(N32_USBHS_HCHINTSTS(chidx)); + regval = n32_getreg(N32_USBHS_HCHINTEN(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + uinfo("HCINTMSK%d: %08" PRIx32 " pending: %08" PRIx32 "\n", + chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted interrupt */ + + if ((pending & N32_USBHS_HCHINTSTS_ACKIF) != 0) + { + /* Clear the pending the ACK response received/transmitted interrupt */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_ACKIF); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_STALLIF) != 0) + { + /* Clear the NAK and STALL Conditions. */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), + N32_USBHS_HCHINTSTS_NAKIF | N32_USBHS_HCHINTSTS_STALLIF); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + n32_chan_halt(priv, chidx, CHREASON_STALL); + + /* When there is a STALL, clear any pending NAK so that it is not + * processed below. + */ + + pending &= ~N32_USBHS_HCHINTSTS_NAKIF; + } + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_DTERRIF) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + n32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the NAK and data toggle error conditions */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), + N32_USBHS_HCHINTSTS_NAKIF | N32_USBHS_HCHINTSTS_DTERRIF); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + if ((pending & N32_USBHS_HCHINTSTS_FOVRIF) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + n32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the FRaMe OverRun (FRMOR) condition */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_FOVRIF); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_TXCFIF) != 0) + { + /* Clear the TransFeR Completed (XFRC) condition */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_TXCFIF); + + /* Then handle the transfer completion event based on the endpoint */ + + if (chan->eptype == N32_USBHS_EPTYPE_CTRL || + chan->eptype == N32_USBHS_EPTYPE_BULK) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + n32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear any pending NAK condition. The 'indata1' data toggle + * should have been appropriately updated by the RxFIFO + * logic as each packet was received. + */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_NAKIF); + } + else if (chan->eptype == N32_USBHS_EPTYPE_INTR) + { + /* Force the next transfer on an ODD frame */ + + regval = n32_getreg(N32_USBHS_HCHCTRL(chidx)); + regval |= N32_USBHS_HCHCTRL_ODDFRM; + n32_putreg(N32_USBHS_HCHCTRL(chidx), regval); + + /* Set the request done state */ + + chan->result = OK; + } + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_CHHTDIF) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = n32_getreg(N32_USBHS_HCHINTEN(chidx)); + regval &= ~N32_USBHS_HCHINTEN_CHHTDIEN; + n32_putreg(N32_USBHS_HCHINTEN(chidx), regval); + + /* Update the request state based on the host state machine state */ + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the request I/O error result */ + + chan->result = EIO; + } + else if (chan->chreason == CHREASON_NAK) + { + /* Set the NAK error result */ + + chan->result = EAGAIN; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame overrun error result */ + + chan->result = EPIPE; + } + + /* Clear the CHannel Halted (CHH) condition */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_CHHTDIF); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_TXERRIF) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + n32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the Transaction ERror (TXERR) condition */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_TXERRIF); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_NAKIF) != 0) + { + /* For a BULK transfer, the hardware is capable of retrying + * automatically on a NAK. However, this is not always + * what we need to do. So we always halt the transfer and + * return control to high level logic in the event of a NAK. + */ + +#if 1 + /* Halt the interrupt channel */ + + if (chan->eptype == N32_USBHS_EPTYPE_INTR || + chan->eptype == N32_USBHS_EPTYPE_BULK) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + n32_chan_halt(priv, chidx, CHREASON_NAK); + } + + /* Re-activate CTRL and BULK channels. + * REVISIT: This can cause a lot of interrupts! + * REVISIT: BULK channel is not re-activated. + */ + + else if (chan->eptype == N32_USBHS_EPTYPE_CTRL) + { + /* Re-activate the channel by clearing CHDIS and assuring that + * CHENA is set + * + * TODO: set channel reason to NACK? + */ + + regval = n32_getreg(N32_USBHS_HCHCTRL(chidx)); + regval |= N32_USBHS_HCHCTRL_CHEN; + regval &= ~N32_USBHS_HCHCTRL_CHDIS; + n32_putreg(N32_USBHS_HCHCTRL(chidx), regval); + } + +#else + /* Halt all transfers on the NAK -- CHH interrupt is expected next */ + + n32_chan_halt(priv, chidx, CHREASON_NAK); +#endif + + /* Clear the NAK condition */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_NAKIF); + } + + /* Check for a transfer complete event */ + + n32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: n32_gint_hcoutisr + * + * Description: + * USB OTG FS host OUT channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set + * as follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void n32_gint_hcoutisr(struct n32_usbhost_s *priv, + int chidx) +{ + struct n32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = n32_getreg(N32_USBHS_HCHINTSTS(chidx)); + regval = n32_getreg(N32_USBHS_HCHINTEN(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + uinfo("HCINTMSK%d: %08" PRIx32 " pending: %08" PRIx32 "\n", + chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted interrupt */ + + if ((pending & N32_USBHS_HCHINTSTS_ACKIF) != 0) + { + /* Clear the pending the ACK response received/transmitted interrupt */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_ACKIF); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_FOVRIF) != 0) + { + /* Halt the channel (probably not necessary for FRMOR) */ + + n32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the pending the FRaMe OverRun (FRMOR) interrupt */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_FOVRIF); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_TXCFIF) != 0) + { + /* Decrement the number of bytes remaining by the number of + * bytes that were "in-flight". + */ + + priv->chan[chidx].buffer += priv->chan[chidx].inflight; + priv->chan[chidx].xfrd += priv->chan[chidx].inflight; + priv->chan[chidx].inflight = 0; + + /* Halt the channel -- the CHH interrupt is expected next */ + + n32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear the pending the TransFeR Completed (XFRC) interrupt */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_TXCFIF); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_STALLIF) != 0) + { + /* Clear the pending STALL response receive (STALL) interrupt */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_STALLIF); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + n32_chan_halt(priv, chidx, CHREASON_STALL); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_NAKIF) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + n32_chan_halt(priv, chidx, CHREASON_NAK); + + /* Clear the pending the NAK response received (NAK) interrupt */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_NAKIF); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_TXERRIF) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + n32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the pending the Transaction ERror (TXERR) interrupt */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_TXERRIF); + } + + /* Check for a NYET interrupt */ + +#if 0 /* NYET is a reserved bit in the HCINT register */ + else if ((pending & N32_USBHS_HCHINTSTS_NYETIF) != 0) + { + /* Halt the channel */ + + n32_chan_halt(priv, chidx, CHREASON_NYET); + + /* Clear the pending the NYET interrupt */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_NYETIF); + } +#endif + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if (pending & N32_USBHS_HCHINTSTS_DTERRIF) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + n32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the pending the Data Toggle ERRor (DTERR) and NAK interrupts */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), + N32_USBHS_HCHINTSTS_DTERRIF | N32_USBHS_HCHINTSTS_NAKIF); + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & N32_USBHS_HCHINTSTS_CHHTDIF) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = n32_getreg(N32_USBHS_HCHINTEN(chidx)); + regval &= ~N32_USBHS_HCHINTEN_CHHTDIEN; + n32_putreg(N32_USBHS_HCHINTEN(chidx), regval); + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + + /* Read the HCCHAR register to get the HCCHAR register to get + * the endpoint type. + */ + + regval = n32_getreg(N32_USBHS_HCHCTRL(chidx)); + + /* Is it a bulk endpoint? Were an odd number of packets + * transferred? + */ + + if ((regval & N32_USBHS_HCHCTRL_EPTYPE_MASK) == + N32_USBHS_HCHCTRL_EPTYPE_BULK && (chan->npackets & 1) != 0) + { + /* Yes to both... toggle the data out PID */ + + chan->outdata1 ^= true; + } + } + else if (chan->chreason == CHREASON_NAK || + chan->chreason == CHREASON_NYET) + { + /* Set the try again later result */ + + chan->result = EAGAIN; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the I/O failure result */ + + chan->result = EIO; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame error result */ + + chan->result = EPIPE; + } + + /* Clear the pending the CHannel Halted (CHH) interrupt */ + + n32_putreg(N32_USBHS_HCHINTSTS(chidx), N32_USBHS_HCHINTSTS_CHHTDIF); + } + + /* Check for a transfer complete event */ + + n32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: n32_gint_connected + * + * Description: + * Handle a connection event. + * + ****************************************************************************/ + +static void n32_gint_connected(struct n32_usbhost_s *priv) +{ + /* We we previously disconnected? */ + + if (!priv->connected) + { + /* Yes.. then now we are connected */ + + usbhost_vtrace1(N32_USBHS_VTRACE1_CONNECTED, 0); + priv->connected = true; + priv->change = true; + DEBUGASSERT(priv->smstate == SMSTATE_DETACHED); + + /* Notify any waiters */ + + priv->smstate = SMSTATE_ATTACHED; + if (priv->pscwait) + { + nxsem_post(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: n32_gint_disconnected + * + * Description: + * Handle a disconnection event. + * + ****************************************************************************/ + +static void n32_gint_disconnected(struct n32_usbhost_s *priv) +{ + /* Were we previously connected? */ + + if (priv->connected) + { + /* Yes.. then we no longer connected */ + + usbhost_vtrace1(N32_USBHS_VTRACE1_DISCONNECTED, 0); + + /* Are we bound to a class driver? */ + + if (priv->rhport.hport.devclass) + { + /* Yes.. Disconnect the class driver */ + + CLASS_DISCONNECTED(priv->rhport.hport.devclass); + priv->rhport.hport.devclass = NULL; + } + + /* Re-Initialize Host for new Enumeration */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = true; + n32_chan_freeall(priv); + + priv->rhport.hport.speed = USB_SPEED_FULL; + priv->rhport.hport.funcaddr = 0; + + /* Notify any waiters that there is a change in the connection state */ + + if (priv->pscwait) + { + nxsem_post(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: n32_gint_sofisr + * + * Description: + * USB OTG FS start-of-frame interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_N32H7_USBHS_SOFINTR +static inline void n32_gint_sofisr(struct n32_usbhost_s *priv) +{ + /* Handle SOF interrupt */ + +#warning "Do what?" + + /* Clear pending SOF interrupt */ + + n32_putreg(N32_USBHS_GINTSTS, N32_USBHS_GINTSTS_SOFIF); +} +#endif + +/**************************************************************************** + * Name: n32_gint_rxflvlisr + * + * Description: + * USB OTG FS RxFIFO non-empty interrupt handler + * + ****************************************************************************/ + +static inline void n32_gint_rxflvlisr(struct n32_usbhost_s *priv) +{ + uint32_t *dest; + uint32_t grxsts; + uint32_t intmsk; + uint32_t hcchar; + uint32_t hctsiz; + uint32_t fifo; + int bcnt; + int bcnt32; + int chidx; + int i; + + /* Disable the RxFIFO non-empty interrupt */ + + intmsk = n32_getreg(N32_USBHS_GINTEN); + intmsk &= ~N32_USBHS_GINTEN_RXFNEIEN; + n32_putreg(N32_USBHS_GINTEN, intmsk); + + /* Read and pop the next status from the Rx FIFO */ + + grxsts = n32_getreg(N32_USBHS_GRXSTSP); + uinfo("GRXSTS: %08" PRIx32 "\n", grxsts); + + /* Isolate the channel number/index in the status word */ + + chidx = (grxsts & N32_USBHS_GRXSTS_CHEPNUM_MASK) >> + N32_USBHS_GRXSTS_CHEPNUM_SHIFT; + + /* Get the host channel characteristics register (HCCHAR) */ + + hcchar = n32_getreg(N32_USBHS_HCHCTRL(chidx)); + + /* Then process the interrupt according to the packet status */ + + switch (grxsts & N32_USBHS_GRXSTS_PKTSTS_MASK) + { + case N32_USBHS_GRXSTS_IN_RCVD: /* IN data packet received */ + { + /* Read the data into the host buffer. */ + + bcnt = (grxsts & N32_USBHS_GRXSTS_BCNT_MASK) >> + N32_USBHS_GRXSTS_BCNT_SHIFT; + if (bcnt > 0 && priv->chan[chidx].buffer != NULL) + { + /* Transfer the packet from the Rx FIFO into the user buffer */ + + dest = (uint32_t *)priv->chan[chidx].buffer; + fifo = N32_USBHS_DFIFO_HCH(0); + bcnt32 = (bcnt + 3) >> 2; + + for (i = 0; i < bcnt32; i++) + { + *dest++ = n32_getreg(fifo); + } + + n32_pktdump("Received", priv->chan[chidx].buffer, bcnt); + + /* Toggle the IN data pid (Used by Bulk and INTR only) */ + + priv->chan[chidx].indata1 ^= true; + + /* Manage multiple packet transfers */ + + priv->chan[chidx].buffer += bcnt; + priv->chan[chidx].xfrd += bcnt; + + /* Check if more packets are expected */ + + hctsiz = n32_getreg(N32_USBHS_HCHTXSIZ(chidx)); + if ((hctsiz & N32_USBHS_HCHTXSIZ_PKCNT_MASK) != 0) + { + /* Re-activate the channel when more packets are expected */ + + hcchar |= N32_USBHS_HCHCTRL_CHEN; + hcchar &= ~N32_USBHS_HCHCTRL_CHDIS; + n32_putreg(N32_USBHS_HCHCTRL(chidx), hcchar); + } + } + } + break; + + case N32_USBHS_GRXSTS_IN_CPLT: /* IN transfer completed */ + case N32_USBHS_GRXSTS_DATA_TOGERR: /* Data toggle error */ + case N32_USBHS_GRXSTS_CHAN_TERMIN: /* Channel halted */ + default: + break; + } + + /* Re-enable the RxFIFO non-empty interrupt */ + + intmsk |= N32_USBHS_GINTEN_RXFNEIEN; + n32_putreg(N32_USBHS_GINTEN, intmsk); +} + +/**************************************************************************** + * Name: n32_gint_nptxfeisr + * + * Description: + * USB OTG FS non-periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void n32_gint_nptxfeisr(struct n32_usbhost_s *priv) +{ + struct n32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously + * placed in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transferred the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the NPTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + n32_modifyreg(N32_USBHS_GINTEN, N32_USBHS_GINTEN_NPTXFEIEN, 0); + return; + } + + /* Read the status from the top of the non-periodic TxFIFO */ + + regval = n32_getreg(N32_USBHS_GNPTXFSTS); + + /* Extract the number of bytes available in the non-periodic Tx FIFO. */ + + avail = ((regval & N32_USBHS_GNPTXFSTS_NPTXFSAV_MASK) >> + N32_USBHS_GNPTXFSTS_NPTXFSAV_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize > 0 && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further NPTXFE interrupts. + */ + + else + { + n32_modifyreg(N32_USBHS_GINTEN, N32_USBHS_GINTEN_NPTXFEIEN, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + uinfo("HNPTXSTS: %08" PRIx32 " chidx: %d avail: %d buflen: %d xfrd: %d " + "wrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + n32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: n32_gint_ptxfeisr + * + * Description: + * USB OTG FS periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void n32_gint_ptxfeisr(struct n32_usbhost_s *priv) +{ + struct n32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously + * placed in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transferred the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the PTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + n32_modifyreg(N32_USBHS_GINTEN, N32_USBHS_GINTEN_PTXFEIEN, 0); + return; + } + + /* Read the status from the top of the periodic TxFIFO */ + + regval = n32_getreg(N32_USBHS_HPTXFQSTS); + + /* Extract the number of bytes available in the periodic Tx FIFO. */ + + avail = ((regval & N32_USBHS_HPTXFQSTS_PTXFSAVL_MASK) >> + N32_USBHS_HPTXFQSTS_PTXFSAVL_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further PTXFE interrupts. + */ + + else + { + n32_modifyreg(N32_USBHS_GINTEN, N32_USBHS_GINTEN_PTXFEIEN, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + uinfo("HPTXSTS: %08" PRIx32 + " chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + n32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: n32_gint_hcisr + * + * Description: + * USB OTG FS host channels interrupt handler + * + ****************************************************************************/ + +static inline void n32_gint_hcisr(struct n32_usbhost_s *priv) +{ + uint32_t haint; + uint32_t hcchar; + int i = 0; + + /* Read the Host all channels interrupt register and test each bit in the + * register. Each bit i, i=0...(N32_NHOST_CHANNELS-1), corresponds to + * a pending interrupt on channel i. + */ + + haint = n32_getreg(N32_USBHS_HACHINT); + for (i = 0; i < N32_NHOST_CHANNELS; i++) + { + /* Is an interrupt pending on this channel? */ + + if ((haint & N32_USBHS_HACHINT_CH(i)) != 0) + { + /* Yes... read the HCCHAR register to get the direction bit */ + + hcchar = n32_getreg(N32_USBHS_HCHCTRL(i)); + + /* Was this an interrupt on an IN or an OUT channel? */ + + if ((hcchar & N32_USBHS_HCHCTRL_EPDIR) != 0) + { + /* Handle the HC IN channel interrupt */ + + n32_gint_hcinisr(priv, i); + } + else + { + /* Handle the HC OUT channel interrupt */ + + n32_gint_hcoutisr(priv, i); + } + } + } +} + +/**************************************************************************** + * Name: n32_gint_hprtisr + * + * Description: + * USB OTG FS host port interrupt handler + * + ****************************************************************************/ + +static inline void n32_gint_hprtisr(struct n32_usbhost_s *priv) +{ + uint32_t hprt; + uint32_t newhprt; + + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_HPRT, 0); + + /* Read the port status and control register (HPRT) */ + + hprt = n32_getreg(N32_USBHS_HPCS); + + /* Setup to clear the interrupt bits in GINTSTS by setting the + * corresponding bits in the HPRT. The HCINT interrupt bit is cleared + * when the appropriate status bits in the HPRT register are cleared. + */ + + newhprt = hprt & ~(N32_USBHS_HPCS_PEN | N32_USBHS_HPCS_PCDET | + N32_USBHS_HPCS_PENC | N32_USBHS_HPCS_POCC); + + /* Check for Port Overcurrent CHaNGe (POCCHNG) */ + + if ((hprt & N32_USBHS_HPCS_POCC) != 0) + { + /* Set up to clear the POCCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_HPRT_POCCHNG, 0); + newhprt |= N32_USBHS_HPCS_POCC; + } + + /* Check for Port Connect DETected (PCDET). The core sets this bit when a + * device connection is detected. + */ + + if ((hprt & N32_USBHS_HPCS_PCDET) != 0) + { + /* Set up to clear the PCDET status in the new HPRT contents. Then + * process the new connection event. + */ + + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_HPRT_PCDET, 0); + newhprt |= N32_USBHS_HPCS_PCDET; + n32_portreset(priv); + n32_gint_connected(priv); + } + + /* Check for Port Enable CHaNGed (PENCHNG) */ + + if ((hprt & N32_USBHS_HPCS_PENC) != 0) + { + /* Set up to clear the PENCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_HPRT_PENCHNG, 0); + newhprt |= N32_USBHS_HPCS_PENC; + + /* Was the port enabled? */ + + if ((hprt & N32_USBHS_HPCS_PEN) != 0) + { + /* Yes.. handle the new connection event */ + + n32_gint_connected(priv); + + /* Is this a low speed or full speed connection? */ + + if ((hprt & N32_USBHS_HPCS_PSPD_MASK) == N32_USBHS_HPCS_PSPD_LS) + { + /* Set the Host Frame Interval Register for the 6KHz speed */ + + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_HPRT_LSDEV, 0); + n32_putreg(N32_USBHS_HFRI, 6000); + } + else + { + /* if ((hprt & N32_USBHS_HPCS_PSPD_MASK) == + * N32_USBHS_HPCS_PSPD_FS) + */ + + /* Set the Host Frame Interval Register for the 48MHz speed */ + + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_HPRT_FSDEV, 0); + n32_putreg(N32_USBHS_HFRI, 48000); + } + } + } + + /* Clear port interrupts by setting bits in the HPRT */ + + n32_putreg(N32_USBHS_HPCS, newhprt); +} + +/**************************************************************************** + * Name: n32_gint_discisr + * + * Description: + * USB OTG FS disconnect detected interrupt handler + * + ****************************************************************************/ + +static inline void n32_gint_discisr(struct n32_usbhost_s *priv) +{ + /* Handle the disconnection event */ + + n32_gint_disconnected(priv); + + /* Clear the dicsonnect interrupt */ + + n32_putreg(N32_USBHS_GINTSTS, N32_USBHS_GINTSTS_DISCIF); +} + +/**************************************************************************** + * Name: n32_gint_ipxfrisr + * + * Description: + * USB OTG FS incomplete periodic interrupt handler + * + ****************************************************************************/ + +static inline void n32_gint_ipxfrisr(struct n32_usbhost_s *priv) +{ + uint32_t regval; + + /* CHENA : Set to enable the channel + * CHDIS : Set to stop transmitting/receiving data on a channel + */ + + regval = n32_getreg(N32_USBHS_HCHCTRL(0)); + regval |= (N32_USBHS_HCHCTRL_CHDIS | N32_USBHS_HCHCTRL_CHEN); + n32_putreg(N32_USBHS_HCHCTRL(0), regval); + + /* Clear the incomplete isochronous OUT interrupt */ + + n32_putreg(N32_USBHS_GINTSTS, N32_USBHS_GINTSTS_PTNCIF_ISOUTNCIF); +} + +/**************************************************************************** + * Name: n32_gint_isr + * + * Description: + * USB OTG global interrupt handler + * + ****************************************************************************/ + +static int n32_gint_isr(int irq, void *context, void *arg) +{ + /* At present, there is only support for a single OTG host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple + * devices. + */ + + struct n32_usbhost_s *priv = &g_usbhost; + uint32_t pending; + + /* If OTG were supported, we would need to check if we are in host or + * device mode when the global interrupt occurs. Here we support only + * host mode + */ + + /* Loop while there are pending interrupts to process. This loop may save + * a little interrupt handling overhead. + */ + + for (; ; ) + { + /* Get the unmasked bits in the GINT status */ + + pending = n32_getreg(N32_USBHS_GINTSTS); + pending &= n32_getreg(N32_USBHS_GINTEN); + + /* Return from the interrupt when there are no further pending + * interrupts. + */ + + if (pending == 0) + { + return OK; + } + + /* Otherwise, process each pending, unmasked GINT interrupts */ + + /* Handle the start of frame interrupt */ + +#ifdef CONFIG_N32H7_USBHS_SOFINTR + if ((pending & N32_USBHS_GINTSTS_SOFIF) != 0) + { + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_SOF, 0); + n32_gint_sofisr(priv); + } +#endif + + /* Handle the RxFIFO non-empty interrupt */ + + if ((pending & N32_USBHS_GINTSTS_RXFNEIF) != 0) + { + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_RXFLVL, 0); + n32_gint_rxflvlisr(priv); + } + + /* Handle the non-periodic TxFIFO empty interrupt */ + + if ((pending & N32_USBHS_GINTSTS_NPTXFEIF) != 0) + { + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_NPTXFE, 0); + n32_gint_nptxfeisr(priv); + } + + /* Handle the periodic TxFIFO empty interrupt */ + + if ((pending & N32_USBHS_GINTSTS_PTXFEIF) != 0) + { + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_PTXFE, 0); + n32_gint_ptxfeisr(priv); + } + + /* Handle the host channels interrupt */ + + if ((pending & N32_USBHS_GINTSTS_HCHIF) != 0) + { + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_HC, 0); + n32_gint_hcisr(priv); + } + + /* Handle the host port interrupt */ + + if ((pending & N32_USBHS_GINTSTS_HPIF) != 0) + { + n32_gint_hprtisr(priv); + } + + /* Handle the disconnect detected interrupt */ + + if ((pending & N32_USBHS_GINTSTS_DISCIF) != 0) + { + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_DISC, 0); + n32_gint_discisr(priv); + } + + /* Handle the incomplete periodic transfer */ + + if ((pending & N32_USBHS_GINTSTS_PTNCIF_ISOUTNCIF) != 0) + { + usbhost_vtrace1(N32_USBHS_VTRACE1_GINT_IPXFR, 0); + n32_gint_ipxfrisr(priv); + } + } + + /* We won't get here */ + + return OK; +} + +/**************************************************************************** + * Name: n32_gint_enable and n32_gint_disable + * + * Description: + * Respectively enable or disable the global OTG FS interrupt. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_gint_enable(void) +{ + uint32_t regval; + + /* Set the GINTMSK bit to unmask the interrupt */ + + regval = n32_getreg(N32_USBHS_GAHBCFG); + regval |= N32_USBHS_GAHBCFG_GINTEN; + n32_putreg(N32_USBHS_GAHBCFG, regval); +} + +static void n32_gint_disable(void) +{ + uint32_t regval; + + /* Clear the GINTMSK bit to mask the interrupt */ + + regval = n32_getreg(N32_USBHS_GAHBCFG); + regval &= ~N32_USBHS_GAHBCFG_GINTEN; + n32_putreg(N32_USBHS_GAHBCFG, regval); +} + +/**************************************************************************** + * Name: n32_hostinit_enable + * + * Description: + * Enable host interrupts. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void n32_hostinit_enable(void) +{ + uint32_t regval; + + /* Disable all interrupts. */ + + n32_putreg(N32_USBHS_GINTEN, 0); + + /* Clear any pending interrupts. */ + + n32_putreg(N32_USBHS_GINTSTS, 0xffffffff); + + /* Enable the host interrupts */ + + /* Common interrupts: + * + * N32_USBHS_GINTEN_WKUPIEN : Resume/remote wakeup detected interrupt + * N32_USBHS_GINTEN_USBSUSPIEN : USB suspend + */ + + regval = (N32_USBHS_GINTEN_WKUPIEN | N32_USBHS_GINTEN_USBSUSPIEN); + + /* If OTG were supported, we would need to enable the following as well: + * + * N32_USBHS_GINTEN_USBHSIEN : OTG interrupt + * N32_USBHS_GINTEN_VBUSVIF : Session request/new session detected + * interrupt + * N32_USBHS_GINTEN_IDSTSCIEN : Connector ID status change + */ + + /* Host-specific interrupts + * + * N32_USBHS_GINTEN_SOFIEN : Start of frame + * N32_USBHS_GINTEN_RXFNEIEN : RxFIFO non-empty + * N32_USBHS_GINTEN_PTNCIEN_ISOUTNCIEN : Incomplete isochronous OUT + * transfer interrupt + * N32_USBHS_GINTEN_HPIEN : Host port interrupt + * N32_USBHS_GINTEN_HCHIEN : Host channels interrupt + * N32_USBHS_GINTEN_DISCIEN : Disconnect detected interrupt + */ + +#ifdef CONFIG_N32H7_USBHS_SOFINTR + regval |= (N32_USBHS_GINTEN_SOFIEN | + N32_USBHS_GINTEN_RXFNEIEN | + N32_USBHS_GINTEN_PTNCIEN_ISOUTNCIEN | + N32_USBHS_GINTEN_HPIEN | + N32_USBHS_GINTEN_HCHIEN | + N32_USBHS_GINTEN_DISCIEN); +#else + regval |= (N32_USBHS_GINTEN_RXFNEIEN | + N32_USBHS_GINTEN_PTNCIEN_ISOUTNCIEN | + N32_USBHS_GINTEN_HPIEN | + N32_USBHS_GINTEN_HCHIEN | + N32_USBHS_GINTEN_DISCIEN); +#endif + n32_putreg(N32_USBHS_GINTEN, regval); +} + +/**************************************************************************** + * Name: n32_txfe_enable + * + * Description: + * Enable Tx FIFO empty interrupts. This is necessary when the entire + * transfer will not fit into Tx FIFO. The transfer will then be completed + * when the Tx FIFO is empty. NOTE: The Tx FIFO interrupt is disabled + * the fifo empty interrupt handler when the transfer is complete. + * + * Input Parameters: + * priv - Driver state structure reference + * chidx - The channel that requires the Tx FIFO empty interrupt + * + * Returned Value: + * None + * + * Assumptions: + * Called from user task context. Interrupts must be disabled to assure + * exclusive access to the GINTMSK register. + * + ****************************************************************************/ + +static void n32_txfe_enable(struct n32_usbhost_s *priv, int chidx) +{ + struct n32_chan_s *chan = &priv->chan[chidx]; + irqstate_t flags; + uint32_t regval; + + /* Disable all interrupts so that we have exclusive access to the GINTMSK + * (it would be sufficient just to disable the GINT interrupt). + */ + + flags = enter_critical_section(); + + /* Should we enable the periodic or non-peridic Tx FIFO empty interrupts */ + + regval = n32_getreg(N32_USBHS_GINTEN); + switch (chan->eptype) + { + default: + case N32_USBHS_EPTYPE_CTRL: /* Non periodic transfer */ + case N32_USBHS_EPTYPE_BULK: + regval |= N32_USBHS_GINTEN_NPTXFEIEN; + break; + + case N32_USBHS_EPTYPE_INTR: /* Periodic transfer */ + case N32_USBHS_EPTYPE_ISOC: + regval |= N32_USBHS_GINTEN_PTXFEIEN; + break; + } + + /* Enable interrupts */ + + n32_putreg(N32_USBHS_GINTEN, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: n32_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected + * the connection related event. + * + * Returned Value: + * Zero (OK) is returned on success when a device is connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_wait(struct usbhost_connection_s *conn, + struct usbhost_hubport_s **hport) +{ + struct n32_usbhost_s *priv = &g_usbhost; + struct usbhost_hubport_s *connport; + irqstate_t flags; + int ret; + + /* Loop until a change in connection state is detected */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Is there a change in the connection state of the single root hub + * port? + */ + + if (priv->change) + { + connport = &priv->rhport.hport; + + /* Yes. Remember the new state */ + + connport->connected = priv->connected; + priv->change = false; + + /* And return the root hub port */ + + *hport = connport; + leave_critical_section(flags); + + uinfo("RHport Connected: %s\n", + connport->connected ? "YES" : "NO"); + return OK; + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (priv->hport) + { + /* Yes.. return the external hub port */ + + connport = (struct usbhost_hubport_s *)priv->hport; + priv->hport = NULL; + + *hport = connport; + leave_critical_section(flags); + + uinfo("Hub port Connected: %s\n", + connport->connected ? "YES" : "NO"); + return OK; + } +#endif + + /* Wait for the next connection event */ + + priv->pscwait = true; + ret = nxsem_wait_uninterruptible(&priv->pscsem); + if (ret < 0) + { + return ret; + } + } +} + +/**************************************************************************** + * Name: n32_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_rh_enumerate(struct n32_usbhost_s *priv, + struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport) +{ + uint32_t regval; + int ret; + + DEBUGASSERT(conn != NULL && hport != NULL && hport->port == 0); + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!priv->connected) + { + /* No, return an error */ + + usbhost_trace1(N32_USBHS_TRACE1_DEVDISCONN, 0); + return -ENODEV; + } + + DEBUGASSERT(priv->smstate == SMSTATE_ATTACHED); + + /* USB 2.0 spec says at least 50ms delay before port reset. We wait + * 100ms. + */ + + nxsched_usleep(100 * 1000); + + /* Reset the host port */ + + n32_portreset(priv); + + /* Get the current device speed */ + + regval = n32_getreg(N32_USBHS_HPCS); + if ((regval & N32_USBHS_HPCS_PSPD_MASK) == N32_USBHS_HPCS_PSPD_LS) + { + priv->rhport.hport.speed = USB_SPEED_LOW; + } + else + { + priv->rhport.hport.speed = USB_SPEED_FULL; + } + + /* Allocate and initialize the root hub port EP0 channels */ + + ret = n32_ctrlchan_alloc(priv, 0, 0, priv->rhport.hport.speed, + &priv->ep0); + if (ret < 0) + { + uerr("ERROR: Failed to allocate a control endpoint: %d\n", ret); + } + + return ret; +} + +static int n32_enumerate(struct usbhost_connection_s *conn, + struct usbhost_hubport_s *hport) +{ + struct n32_usbhost_s *priv = &g_usbhost; + int ret; + + DEBUGASSERT(hport); + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = n32_rh_enumerate(priv, conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + uinfo("Enumerate the device\n"); + priv->smstate = SMSTATE_ENUM; + ret = usbhost_enumerate(hport, &hport->devclass); + + /* The enumeration may fail either because of some HCD interfaces failure + * or because the device class is not supported. In either case, we just + * need to perform the disconnection operation and make ready for a new + * enumeration. + */ + + if (ret < 0) + { + /* Return to the disconnected state */ + + uerr("ERROR: Enumeration failed: %d\n", ret); + n32_gint_disconnected(priv); + } + + return ret; +} + +/**************************************************************************** + * Name: n32_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support an + * external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep0 - The (opaque) EP0 endpoint instance + * funcaddr - The USB address of the function containing the endpoint that + * EP0 controls + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_ep0configure(struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize) +{ + struct n32_usbhost_s *priv = (struct n32_usbhost_s *)drvr; + struct n32_ctrlinfo_s *ep0info = (struct n32_ctrlinfo_s *)ep0; + struct n32_chan_s *chan; + int ret; + + DEBUGASSERT(drvr != NULL && ep0info != NULL && funcaddr < 128 && + maxpacketsize <= 64); + + /* We must have exclusive access to the USB host hardware and structures */ + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return ret; + } + + /* Configure the EP0 OUT channel */ + + chan = &priv->chan[ep0info->outndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + n32_chan_configure(priv, ep0info->outndx); + + /* Configure the EP0 IN channel */ + + chan = &priv->chan[ep0info->inndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + n32_chan_configure(priv, ep0info->inndx); + + nxmutex_unlock(&priv->lock); + return OK; +} + +/**************************************************************************** + * Name: n32_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_epalloc(struct usbhost_driver_s *drvr, + const struct usbhost_epdesc_s *epdesc, + usbhost_ep_t *ep) +{ + struct n32_usbhost_s *priv = (struct n32_usbhost_s *)drvr; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device + * is connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(drvr != 0 && epdesc != NULL && ep != NULL); + + /* We must have exclusive access to the USB host hardware and state + * structures. + */ + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return ret; + } + + /* Handler control pipes differently from other endpoint types. This is + * because the normal, "transfer" endpoints are unidirectional an require + * only a single channel. Control endpoints, however, are bi-directional + * and require two channels, one for the IN and one for the OUT direction. + */ + + if (epdesc->xfrtype == N32_USBHS_EPTYPE_CTRL) + { + ret = n32_ctrlep_alloc(priv, epdesc, ep); + } + else + { + ret = n32_xfrep_alloc(priv, epdesc, ep); + } + + nxmutex_unlock(&priv->lock); + return ret; +} + +/**************************************************************************** + * Name: n32_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep - The endpoint to be freed. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_epfree(struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct n32_usbhost_s *priv = (struct n32_usbhost_s *)drvr; + int ret; + + DEBUGASSERT(priv); + + /* We must have exclusive access to the USB host hardware and structures */ + + ret = nxmutex_lock(&priv->lock); + + /* A single channel is represent by an index in the range of 0 to + * N32_MAX_TX_FIFOS. Otherwise, the ep must be a pointer to an allocated + * control endpoint structure. + */ + + if ((uintptr_t)ep < N32_MAX_TX_FIFOS) + { + /* Halt the channel and mark the channel available */ + + n32_chan_free(priv, (int)ep); + } + else + { + /* Halt both control channel and mark the channels available */ + + struct n32_ctrlinfo_s *ctrlep = + (struct n32_ctrlinfo_s *)ep; + + n32_chan_free(priv, ctrlep->inndx); + n32_chan_free(priv, ctrlep->outndx); + + /* And free the control endpoint container */ + + kmm_free(ctrlep); + } + + nxmutex_unlock(&priv->lock); + return ret; +} + +/**************************************************************************** + * Name: n32_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor + * data can be accessed more efficiently. This method provides a + * mechanism to allocate the request/descriptor memory. If the underlying + * hardware does not support such "special" memory, this functions may + * simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was + * assumed that the driver maintains a pool of small, pre-allocated + * buffers for descriptor traffic. NOTE that size is not an input, but + * an output: The size of the pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * buffer - The address of a memory location provided by the caller in + * which to return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in + * which to return the maximum size of the allocated buffer memory. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_alloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t *maxlen) +{ + uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && maxlen); + + /* There is no special memory requirement for the N32. */ + + alloc = kmm_malloc(CONFIG_N32H7_USBHS_DESCSIZE); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated address and size of the descriptor buffer */ + + *buffer = alloc; + *maxlen = CONFIG_N32H7_USBHS_DESCSIZE; + return OK; +} + +/**************************************************************************** + * Name: n32_free + * + * Description: + * Some hardware supports special memory in which request and descriptor + * data can be accessed more efficiently. This method provides a + * mechanism to free that request/descriptor memory. If the underlying + * hardware does not support such "special" memory, this functions may + * simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_free(struct usbhost_driver_s *drvr, uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: n32_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to + * allocate the request/descriptor memory. If the underlying hardware + * does not support such "special" memory, this functions may simply map + * to kmm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are + * variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * buffer - The address of a memory location provided by the caller in + * which to return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_ioalloc(struct usbhost_driver_s *drvr, + uint8_t **buffer, size_t buflen) +{ + uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && buflen > 0); + + /* There is no special memory requirement */ + + alloc = kmm_malloc(buflen); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated buffer */ + + *buffer = alloc; + return OK; +} + +/**************************************************************************** + * Name: n32_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed + * more efficiently. This method provides a mechanism to free that IO + * buffer memory. If the underlying hardware does not support such + * "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_iofree(struct usbhost_driver_s *drvr, + uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: n32_ctrlin and n32_ctrlout + * + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one + * transfer may be queued; Neither these methods nor the transfer() + * method can be called again until the control transfer functions + * returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in + * memory created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using + * DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same + * allocated memory. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int n32_ctrlin(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + uint8_t *buffer) +{ + struct n32_usbhost_s *priv = (struct n32_usbhost_s *)drvr; + struct n32_ctrlinfo_s *ep0info = (struct n32_ctrlinfo_s *)ep0; + uint16_t buflen; + clock_t start; + clock_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(N32_USBHS_VTRACE2_CTRLIN, req->type, req->req); + uinfo("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = n32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and structures */ + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return ret; + } + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < N32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = n32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Handle the IN data phase (if any) */ + + if (buflen > 0) + { + ret = n32_ctrl_recvdata(priv, ep0info, buffer, buflen); + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_RECVDATA, -ret); + continue; + } + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systime_ticks(); + do + { + /* Handle the status OUT phase */ + + priv->chan[ep0info->outndx].outdata1 ^= true; + ret = n32_ctrl_senddata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactions exit here */ + + nxmutex_unlock(&priv->lock); + return OK; + } + + usbhost_trace1(N32_USBHS_TRACE1_SENDDATA, ret < 0 ? -ret : ret); + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systime_ticks() - start; + } + while (elapsed < N32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts are exhausted */ + + nxmutex_unlock(&priv->lock); + return -ETIMEDOUT; +} + +static int n32_ctrlout(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + const uint8_t *buffer) +{ + struct n32_usbhost_s *priv = (struct n32_usbhost_s *)drvr; + struct n32_ctrlinfo_s *ep0info = (struct n32_ctrlinfo_s *)ep0; + uint16_t buflen; + clock_t start; + clock_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(N32_USBHS_VTRACE2_CTRLOUT, req->type, req->req); + uinfo("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = n32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and structures */ + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return ret; + } + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < N32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = n32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systime_ticks(); + do + { + /* Handle the data OUT phase (if any) */ + + if (buflen > 0) + { + /* Start DATA out transfer (only one DATA packet) */ + + priv->chan[ep0info->outndx].outdata1 = true; + ret = n32_ctrl_senddata(priv, ep0info, (uint8_t *)buffer, + buflen); + if (ret < 0) + { + usbhost_trace1(N32_USBHS_TRACE1_SENDDATA, -ret); + } + } + + /* Handle the status IN phase */ + + if (ret == OK) + { + ret = n32_ctrl_recvdata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactins exit here */ + + nxmutex_unlock(&priv->lock); + return OK; + } + + usbhost_trace1(N32_USBHS_TRACE1_RECVDATA, + ret < 0 ? -ret : ret); + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systime_ticks() - start; + } + while (elapsed < N32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts are exhausted */ + + nxmutex_unlock(&priv->lock); + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: n32_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. + * Only one transfer may be queued; Neither this method nor the ctrlin + * or ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which + * to perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or + * received (IN endpoint). buffer must have been allocated using + * DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Value: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value + * is returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t n32_transfer(struct usbhost_driver_s *drvr, + usbhost_ep_t ep, uint8_t *buffer, + size_t buflen) +{ + struct n32_usbhost_s *priv = (struct n32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + ssize_t nbytes; + int ret; + + uinfo("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < N32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and structures */ + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return (ssize_t)ret; + } + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + nbytes = n32_in_transfer(priv, chidx, buffer, buflen); + } + else + { + nbytes = n32_out_transfer(priv, chidx, buffer, buflen); + } + + nxmutex_unlock(&priv->lock); + return nbytes; +} + +/**************************************************************************** + * Name: n32_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on + * which to perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or + * received (IN endpoint). buffer must have been allocated using + * DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback + * function when the transfer completes. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int n32_asynch(struct usbhost_driver_s *drvr, usbhost_ep_t ep, + uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, void *arg) +{ + struct n32_usbhost_s *priv = (struct n32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + int ret; + + uinfo("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < N32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and structures */ + + ret = nxmutex_lock(&priv->lock); + if (ret < 0) + { + return ret; + } + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + ret = n32_in_asynch(priv, chidx, buffer, buflen, callback, arg); + } + else + { + ret = n32_out_asynch(priv, chidx, buffer, buflen, callback, arg); + } + + nxmutex_unlock(&priv->lock); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/**************************************************************************** + * Name: n32_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on + * which an asynchronous transfer should be transferred. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + ****************************************************************************/ + +static int n32_cancel(struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct n32_usbhost_s *priv = (struct n32_usbhost_s *)drvr; + struct n32_chan_s *chan; + unsigned int chidx = (unsigned int)ep; + irqstate_t flags; + + uinfo("chidx: %u\n", chidx); + + DEBUGASSERT(priv && chidx < N32_MAX_TX_FIFOS); + chan = &priv->chan[chidx]; + + /* We need to disable interrupts to avoid race conditions with the + * asynchronous completion of the transfer being canceled. + */ + + flags = enter_critical_section(); + + /* Halt the channel */ + + n32_chan_halt(priv, chidx, CHREASON_CANCELLED); + chan->result = -ESHUTDOWN; + + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + + /* Wake'em up! */ + + nxsem_post(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + usbhost_asynch_t callback; + void *arg; + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + callback(arg, -ESHUTDOWN); + } +#endif + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: n32_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int n32_connect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport, + bool connected) +{ + struct n32_usbhost_s *priv = (struct n32_usbhost_s *)drvr; + irqstate_t flags; + + DEBUGASSERT(priv != NULL && hport != NULL); + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + uinfo("Hub port %d connected: %s\n", + hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + priv->hport = hport; + if (priv->pscwait) + { + priv->pscwait = false; + nxsem_post(&priv->pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: n32_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been + * disconnected. The USB host driver should discard the handle to the + * class instance (it is stale) and not attempt any further interaction + * with the class driver instance (until a new instance is received from + * the create() method). The driver should not called the class' + * disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * hport - The port from which the device is being disconnected. Might be + * a port on a hub. + * + * Returned Value: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void n32_disconnect(struct usbhost_driver_s *drvr, + struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Name: n32_portreset + * + * Description: + * Reset the USB host port. + * + * NOTE: "Before starting to drive a USB reset, the application waits for + * the OTG interrupt triggered by the debounce done bit (DBCDNE bit in + * N32_USBHS_GPD), which indicates that the bus is stable again after + * the electrical debounce caused by the attachment of a pull-up resistor + * on DP (FS) or DM (LS). + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void n32_portreset(struct n32_usbhost_s *priv) +{ + uint32_t regval; + + regval = n32_getreg(N32_USBHS_HPCS); + regval &= ~(N32_USBHS_HPCS_PEN | + N32_USBHS_HPCS_PCDET | + N32_USBHS_HPCS_PENC | + N32_USBHS_HPCS_POCC); + regval |= N32_USBHS_HPCS_PRST; + n32_putreg(N32_USBHS_HPCS, regval); + + up_mdelay(100); + + regval &= ~N32_USBHS_HPCS_PRST; + n32_putreg(N32_USBHS_HPCS, regval); + + up_mdelay(20); +} + +/**************************************************************************** + * Name: n32_flush_txfifos + * + * Description: + * Flush the selected Tx FIFO. + * + * Input Parameters: + * txfnum -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void n32_flush_txfifos(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = N32_USBHS_GRSTCTRL_TXFFLSH | txfnum; + n32_putreg(N32_USBHS_GRSTCTRL, regval); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < N32_FLUSH_DELAY; timeout++) + { + regval = n32_getreg(N32_USBHS_GRSTCTRL); + if ((regval & N32_USBHS_GRSTCTRL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: n32_flush_rxfifo + * + * Description: + * Flush the Rx FIFO. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void n32_flush_rxfifo(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + n32_putreg(N32_USBHS_GRSTCTRL, N32_USBHS_GRSTCTRL_RXFFLSH); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < N32_FLUSH_DELAY; timeout++) + { + regval = n32_getreg(N32_USBHS_GRSTCTRL); + if ((regval & N32_USBHS_GRSTCTRL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: n32_vbusdrive + * + * Description: + * Drive the Vbus +5V. + * + * Input Parameters: + * priv - USB host driver private data structure. + * state - True: Drive, False: Don't drive + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void n32_vbusdrive(struct n32_usbhost_s *priv, bool state) +{ + uint32_t regval; + + /* Enable/disable the external charge pump */ + + n32_usbhs_vbusdrive(0, state); + + /* Turn on the Host port power. */ + + regval = n32_getreg(N32_USBHS_HPCS); + regval &= ~(N32_USBHS_HPCS_PEN | + N32_USBHS_HPCS_PCDET | + N32_USBHS_HPCS_PENC | + N32_USBHS_HPCS_POCC); + + if (((regval & N32_USBHS_HPCS_PPWR) == 0) && state) + { + regval |= N32_USBHS_HPCS_PPWR; + n32_putreg(N32_USBHS_HPCS, regval); + } + + if (((regval & N32_USBHS_HPCS_PPWR) != 0) && !state) + { + regval &= ~N32_USBHS_HPCS_PPWR; + n32_putreg(N32_USBHS_HPCS, regval); + } + + up_mdelay(200); +} + +/**************************************************************************** + * Name: n32_host_initialize + * + * Description: + * Initialize/re-initialize hardware for host mode operation. At present, + * this function is called only from n32_hw_initialize(). But if OTG + * mode were supported, this function would also be called to switch + * between host and device modes on a connector ID change interrupt. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void n32_host_initialize(struct n32_usbhost_s *priv) +{ + uint32_t regval; + uint32_t offset; + int i; + + /* Restart the PHY Clock */ + + n32_putreg(N32_USBHS_PWRCTRL, 0); + + /* Reset the host port */ + + n32_portreset(priv); + + regval = n32_getreg(N32_USBHS_HPCS); + regval &= ~N32_USBHS_HCFG_SPSEL; + n32_putreg(N32_USBHS_HPCS, regval); + + /* Carve up FIFO memory for the Rx FIFO and the periodic and non-periodic + * Tx FIFOs + */ + + /* Configure Rx FIFO size (GRXFSIZ) */ + + n32_putreg(N32_USBHS_GRXFSIZ, CONFIG_N32H7_USBHS_RXFIFO_SIZE); + offset = CONFIG_N32H7_USBHS_RXFIFO_SIZE; + + /* Setup the host non-periodic Tx FIFO size (HNPTXFSIZ) */ + + regval = (offset | + (CONFIG_N32H7_USBHS_NPTXFIFO_SIZE << + N32_USBHS_GNPTXFSIZ_NPTXFDEP_SHIFT)); + n32_putreg(N32_USBHS_GNPTXFSIZ, regval); + offset += CONFIG_N32H7_USBHS_NPTXFIFO_SIZE; + + /* Set up the host periodic Tx fifo size register (HPTXFSIZ) */ + + regval = (offset | + (CONFIG_N32H7_USBHS_PTXFIFO_SIZE << + N32_USBHS_HPTXFSIZ_HPTXFDEP_SHIFT)); + n32_putreg(N32_USBHS_HPTXFSIZ, regval); + + /* If OTG were supported, we should need to clear HNP enable bit in the + * USB_OTG control register about here. + */ + + /* Flush all FIFOs */ + + n32_flush_txfifos(N32_USBHS_GRSTCTRL_TXFNUM_HALL); + n32_flush_rxfifo(); + + /* Clear all pending HC Interrupts */ + + for (i = 0; i < N32_NHOST_CHANNELS; i++) + { + n32_putreg(N32_USBHS_HCHINTSTS(i), 0xffffffff); + n32_putreg(N32_USBHS_HCHINTEN(i), 0); + } + + /* Driver Vbus +5V (the smoke test). Should be done elsewhere in OTG + * mode. + */ + + n32_vbusdrive(priv, true); + + /* Enable host interrupts */ + + n32_hostinit_enable(); +} + +/**************************************************************************** + * Name: n32_sw_initialize + * + * Description: + * One-time setup of the host driver state structure. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void n32_sw_initialize(struct n32_usbhost_s *priv) +{ + struct usbhost_driver_s *drvr; + struct usbhost_hubport_s *hport; + int i; + + /* Initialize the device operations */ + + drvr = &priv->drvr; + drvr->ep0configure = n32_ep0configure; + drvr->epalloc = n32_epalloc; + drvr->epfree = n32_epfree; + drvr->alloc = n32_alloc; + drvr->free = n32_free; + drvr->ioalloc = n32_ioalloc; + drvr->iofree = n32_iofree; + drvr->ctrlin = n32_ctrlin; + drvr->ctrlout = n32_ctrlout; + drvr->transfer = n32_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + drvr->asynch = n32_asynch; +#endif + drvr->cancel = n32_cancel; +#ifdef CONFIG_USBHOST_HUB + drvr->connect = n32_connect; +#endif + drvr->disconnect = n32_disconnect; + + /* Initialize the public port representation */ + + hport = &priv->rhport.hport; + hport->drvr = drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = (usbhost_ep_t)&priv->ep0; + hport->speed = USB_SPEED_FULL; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&priv->devgen); + priv->rhport.pdevgen = &priv->devgen; + + /* Initialize the driver state data */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = false; + + /* Put all of the channels back in their initial, allocated state */ + + memset(priv->chan, 0, N32_MAX_TX_FIFOS * sizeof(struct n32_chan_s)); + + /* Initialize each channel */ + + for (i = 0; i < N32_MAX_TX_FIFOS; i++) + { + struct n32_chan_s *chan = &priv->chan[i]; + + chan->chidx = i; + nxsem_init(&chan->waitsem, 0, 0); + } +} + +/**************************************************************************** + * Name: n32_hw_initialize + * + * Description: + * One-time setup of the host controller hardware for normal operations. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static inline int n32_hw_initialize(struct n32_usbhost_s *priv) +{ + uint32_t regval; + unsigned long timeout; + + /* Setup PHY PLL */ + + regval = getreg32(N32_USBHS_WRPCFG); + regval &= ~N32_USBHS_WRPCFG_PHYCLKSEL_MASK; + regval |= N32_USBHS_WRPCFG_PHYCLKSEL; + regval |= N32_USBHS_WRPCFG_PLLEN; + regval &= ~N32_USBHS_WRPCFG_IDSIG; + n32_putreg(N32_USBHS_WRPCFG, regval); + + /* Enable Host Pending */ + + regval = n32_getreg(N32_USBHS_WRPCTRL); + regval |= N32_USBHS_WRPCTRL_PINDETEN; + n32_putreg(N32_USBHS_WRPCTRL, regval); + + /* Reset the USBHS core */ + + if (N32_USBHS_BASE == N32_USBCTRL1_BASE) + { + /* Reset the USBHS1 core */ + + regval = n32_getreg(N32_RCC_AHB2RST1); + regval |= RCC_AHB2RST1_USB1PORRST; + n32_putreg(N32_RCC_AHB2RST1, regval); + regval &= ~RCC_AHB2RST1_USB1PORRST; + n32_putreg(N32_RCC_AHB2RST1, regval); + } + else + { + /* Reset the USBHS2 core */ + + regval = n32_getreg(N32_RCC_AHB1RST1); + regval |= RCC_AHB1RST1_USB2PORRST; + n32_putreg(N32_RCC_AHB1RST1, regval); + regval &= ~RCC_AHB1RST1_USB2PORRST; + n32_putreg(N32_RCC_AHB1RST1, regval); + } + + up_mdelay(1); + + regval = n32_getreg(N32_USBHS_GCFG); +#ifdef CONFIG_N32H7_USBHS_FS + /* N32H7 MOD: Set the PHYSEL bit in the GCFG register only when the FS + * serial transceiver is used. The N32H76x has no on-chip HS PHY; with + * the default external ULPI PHY PHYSEL must stay cleared. + */ + + regval |= N32_USBHS_GCFG_PHYSEL; +#endif + regval |= N32_USBHS_GCFG_PHYIF; + n32_putreg(N32_USBHS_GCFG, regval); + + /* Reset after a PHY select and set Host mode. First, wait for AHB master + * IDLE state. + */ + + for (timeout = 0; timeout < N32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = n32_getreg(N32_USBHS_GRSTCTRL); + if ((regval & N32_USBHS_GRSTCTRL_AHBIDLE) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + regval = n32_getreg(N32_USBHS_GRSTCTRL); + regval |= N32_USBHS_GRSTCTRL_CSRST; + n32_putreg(N32_USBHS_GRSTCTRL, regval); + + for (timeout = 0; timeout < N32_READY_DELAY; timeout++) + { + regval = n32_getreg(N32_USBHS_GRSTCTRL); + if ((regval & N32_USBHS_GRSTCTRL_SRSTDNE) != 0) + { + break; + } + } + + regval = n32_getreg(N32_USBHS_GRSTCTRL); + regval &= ~N32_USBHS_GRSTCTRL_CSRST; + n32_putreg(N32_USBHS_GRSTCTRL, regval); + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + + up_mdelay(20); + + /* Initialize OTG features: In order to support OTP, the HNPCAP and SRPCAP + * bits would need to be set in the GUSBCFG register about here. + */ + + /* Force Host Mode */ + + regval = n32_getreg(N32_USBHS_GCFG); + regval &= ~N32_USBHS_GCFG_FDMODE; + regval |= N32_USBHS_GCFG_FHMODE; + n32_putreg(N32_USBHS_GCFG, regval); + up_mdelay(50); + + /* Initialize host mode and return success */ + + n32_host_initialize(priv); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_usbhshost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +struct usbhost_connection_s *n32_usbhshost_initialize(int controller) +{ + /* At present, there is only support for a single OTG FS host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple + * devices. + */ + + struct n32_usbhost_s *priv = &g_usbhost; + + /* Sanity checks */ + + DEBUGASSERT(controller == 0); + + /* Make sure that interrupts from the OTG FS core are disabled */ + + n32_gint_disable(); + + /* Reset the state of the host driver */ + + n32_sw_initialize(priv); + + /* N32H7 MOD: The N32H76x has no PWR_CR3 USB33DEN / USBREGEN bits. + * USB power-domain enable and the USBHS peripheral clock are handled + * by n32_usbhs_enableclock() (PWR IPMEM control + RCC AHB enable); + * the external ULPI PHY needs no internal HS PHY PLL setup. + */ + + n32_usbhs_enableclock(); + n32_usbhs_phy_initialize(); + + /* Alternate function pin configuration. Here we assume that: + * + * 1. GPIO and USBHS peripheral clocking have already been enabled as + * part of the boot sequence (see n32_usbhs_enableclock() above). + * 2. Board-specific logic has already enabled other board specific GPIOs + * for things like soft pull-up, VBUS sensing, power controls, and over- + * current detection. + */ + + /* N32H7 MOD: Configure the USBHS pins. The GPIO_USBHS_* pin macros + * are provided by board.h. With the default external ULPI PHY, the + * ULPI interface pins are configured; with CONFIG_N32H7_USBHS_FS only + * the FS serial transceiver DM/DP pins are needed. + */ + + n32_configgpio(GPIO_USBHS_DM); + n32_configgpio(GPIO_USBHS_DP); + + /* Initialize the USBHS core */ + + n32_hw_initialize(priv); + + /* Attach USB host controller interrupt handler */ + + if (irq_attach(N32_IRQ_USBHS, n32_gint_isr, NULL) != 0) + { + usbhost_trace1(N32_USBHS_TRACE1_IRQATTACH, 0); + return NULL; + } + + /* Enable USBHS global interrupts */ + + n32_gint_enable(); + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(N32_IRQ_USBHS); + return &g_usbconn; +} + +/**************************************************************************** + * Debug Trace String Tables + ****************************************************************************/ + +#ifdef HAVE_USBHOST_TRACE + +#define TR_FMT1 false +#define TR_FMT2 true + +#define TRENTRY(id,fmt1,string) {string} + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct n32_usbhost_trace_s +{ + const char *string; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct n32_usbhost_trace_s g_trace1[TRACE1_NSTRINGS] = +{ +#ifdef HAVE_USBHOST_TRACE + + TRENTRY(N32_USBHS_TRACE1_DEVDISCONN, TR_FMT1, + "USBHS ERROR: Host Port %d. Device disconnected\n"), + TRENTRY(N32_USBHS_TRACE1_IRQATTACH, TR_FMT1, + "USBHS ERROR: Failed to attach IRQ\n"), + TRENTRY(N32_USBHS_TRACE1_TRNSFRFAILED, TR_FMT1, + "USBHS ERROR: Transfer Failed. ret=%d\n"), + TRENTRY(N32_USBHS_TRACE1_SENDSETUP, TR_FMT1, + "USBHS ERROR: ctrl_sendsetup() failed with: %d\n"), + TRENTRY(N32_USBHS_TRACE1_SENDDATA, TR_FMT1, + "USBHS ERROR: ctrl_senddata() failed with: %d\n"), + TRENTRY(N32_USBHS_TRACE1_RECVDATA, TR_FMT1, + "USBHS ERROR: ctrl_recvdata() failed with: %d\n"), + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + TRENTRY(N32_USBHS_VTRACE1_CONNECTED, TR_FMT1, + "USBHS Host Port %d connected.\n"), + TRENTRY(N32_USBHS_VTRACE1_DISCONNECTED, TR_FMT1, + "USBHS Host Port %d disconnected.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT, TR_FMT1, + "USBHS Handling Interrupt. Entry Point.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_SOF, TR_FMT1, + "USBHS Handle the start of frame interrupt.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_RXFLVL, TR_FMT1, + "USBHS Handle the RxFIFO non-empty interrupt.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_NPTXFE, TR_FMT1, + "USBHS Handle the non-periodic TxFIFO empty interrupt.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_PTXFE, TR_FMT1, + "USBHS Handle the periodic TxFIFO empty interrupt.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_HC, TR_FMT1, + "USBHS Handle the host channels interrupt.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_HPRT, TR_FMT1, + "USBHS Handle the host port interrupt.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_HPRT_POCCHNG, TR_FMT1, + "USBHS HPRT: Port Over-Current Change.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_HPRT_PCDET, TR_FMT1, + "USBHS HPRT: Port Connect Detect.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_HPRT_PENCHNG, TR_FMT1, + "USBHS HPRT: Port Enable Changed.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_HPRT_LSDEV, TR_FMT1, + "USBHS HPRT: Low Speed Device Connected.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_HPRT_FSDEV, TR_FMT1, + "USBHS HPRT: Full Speed Device Connected.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_HPRT_LSFSSW, TR_FMT1, + "USBHS HPRT: Host Switch: LS -> FS.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_HPRT_FSLSSW, TR_FMT1, + "USBHS HPRT: Host Switch: FS -> LS.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_DISC, TR_FMT1, + "USBHS Handle the disconnect detected interrupt.\n"), + TRENTRY(N32_USBHS_VTRACE1_GINT_IPXFR, TR_FMT1, + "USBHS Handle the incomplete periodic transfer.\n"), + +# endif +#endif +}; + +static const struct n32_usbhost_trace_s g_trace2[TRACE2_NSTRINGS] = +{ +#ifdef HAVE_USBHOST_TRACE + + TRENTRY(N32_USBHS_TRACE2_CLIP, TR_FMT2, + "USBHS CLIP: chidx: %d buflen: %d\n"), + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + TRENTRY(N32_USBHS_VTRACE2_CHANWAKEUP_IN, TR_FMT2, + "USBHS EP%d(IN) wake up with result: %d\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANWAKEUP_OUT, TR_FMT2, + "USBHS EP%d(OUT) wake up with result: %d\n"), + TRENTRY(N32_USBHS_VTRACE2_CTRLIN, TR_FMT2, + "USBHS CTRL_IN type: %02x req: %02x\n"), + TRENTRY(N32_USBHS_VTRACE2_CTRLOUT, TR_FMT2, + "USBHS CTRL_OUT type: %02x req: %02x\n"), + TRENTRY(N32_USBHS_VTRACE2_INTRIN, TR_FMT2, + "USBHS INTR_IN chidx: %02x len: %02x\n"), + TRENTRY(N32_USBHS_VTRACE2_INTROUT, TR_FMT2, + "USBHS INTR_OUT chidx: %02x len: %02x\n"), + TRENTRY(N32_USBHS_VTRACE2_BULKIN, TR_FMT2, + "USBHS BULK_IN chidx: %02x len: %02x\n"), + TRENTRY(N32_USBHS_VTRACE2_BULKOUT, TR_FMT2, + "USBHS BULK_OUT chidx: %02x len: %02x\n"), + TRENTRY(N32_USBHS_VTRACE2_ISOCIN, TR_FMT2, + "USBHS ISOC_IN chidx: %02x len: %04d\n"), + TRENTRY(N32_USBHS_VTRACE2_ISOCOUT, TR_FMT2, + "USBHS ISOC_OUT chidx: %02x req: %02x\n"), + TRENTRY(N32_USBHS_VTRACE2_STARTTRANSFER, TR_FMT2, + "USBHS Transfer chidx: %d buflen: %d\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANCONF_CTRL_IN, TR_FMT2, + "USBHS Channel configured. chidx: %d: (EP%d,IN ,CTRL)\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANCONF_CTRL_OUT, TR_FMT2, + "USBHS Channel configured. chidx: %d: (EP%d,OUT,CTRL)\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANCONF_INTR_IN, TR_FMT2, + "USBHS Channel configured. chidx: %d: (EP%d,IN ,INTR)\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANCONF_INTR_OUT, TR_FMT2, + "USBHS Channel configured. chidx: %d: (EP%d,OUT,INTR)\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANCONF_BULK_IN, TR_FMT2, + "USBHS Channel configured. chidx: %d: (EP%d,IN ,BULK)\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANCONF_BULK_OUT, TR_FMT2, + "USBHS Channel configured. chidx: %d: (EP%d,OUT,BULK)\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANCONF_ISOC_IN, TR_FMT2, + "USBHS Channel configured. chidx: %d: (EP%d,IN ,ISOC)\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANCONF_ISOC_OUT, TR_FMT2, + "USBHS Channel configured. chidx: %d: (EP%d,OUT,ISOC)\n"), + TRENTRY(N32_USBHS_VTRACE2_CHANHALT, TR_FMT2, + "USBHS Channel halted. chidx: %d, reason: %d\n"), + +# endif +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usbhost_trformat1 and usbhost_trformat2 + * + * Description: + * This interface must be provided by platform specific logic that knows + * the HCDs encoding of USB trace data. + * + * Given an 9-bit index, return a format string suitable for use with, say, + * printf. The returned format is expected to handle two unsigned integer + * values. + * + ****************************************************************************/ + +const char *usbhost_trformat1(uint16_t id) +{ + int ndx = TRACE1_INDEX(id); + + if (ndx < TRACE1_NSTRINGS) + { + return g_trace1[ndx].string; + } + + return NULL; +} + +const char *usbhost_trformat2(uint16_t id) +{ + int ndx = TRACE2_INDEX(id); + + if (ndx < TRACE2_NSTRINGS) + { + return g_trace2[ndx].string; + } + + return NULL; +} + +#endif /* HAVE_USBHOST_TRACE */ + +#endif /* CONFIG_USBHOST && (CONFIG_N32H7_USBHS1_HOST || CONFIG_N32H7_USBHS2_HOST) */ diff --git a/arch/arm/src/n32h7/n32h76x_rcc.c b/arch/arm/src/n32h7/n32h76x_rcc.c new file mode 100644 index 0000000000000..0345d5d03c5a3 --- /dev/null +++ b/arch/arm/src/n32h7/n32h76x_rcc.c @@ -0,0 +1,1349 @@ +/**************************************************************************** + * arch/arm/src/n32h7/n32h76x_rcc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "arm_internal.h" +#include "n32_gpio.h" +#include "n32_rcc.h" +#include "n32_pwr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. 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 */ + +#define HSIRDY_TIMEOUT HSERDY_TIMEOUT + +/* HSE divisor to yield ~1MHz RTC clock */ + +#define HSE_DIVISOR (N32_HSE_FREQUENCY + 500000) / 1000000 + +/* PLL are only enabled if the P,Q or R outputs are enabled. */ + +#undef USE_PLL1 +#ifdef N32_PLL1_VCO_FREQUENCY +# define USE_PLL1 +#endif + +#undef USE_PLL2 +#ifdef N32_PLL2_VCO_FREQUENCY +# define USE_PLL2 +#endif + +#undef USE_PLL3 +#ifdef N32_PLL3_VCO_FREQUENCY +# define USE_PLL3 +#endif + +#if defined(N32_BOARD_USEHSI) && !defined(N32_BOARD_HSIDIV) +#error When HSI is used, you have to define N32_BOARD_HSIDIV in board/include/board.h +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Reset the RCC clock configuration to the default reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ + uint32_t regval; + + /* Config PWR */ + + n32_pwr_setcorepwrsrc(PWR_VCORESRC_LDO); + + /* Set HSIEN bit */ + + regval = getreg32(N32_RCC_SRCCTRL1); + regval |= RCC_SRCCTRL1_HSIEN; + + /* Reset SCLKSW, MSIEN ,HSEBP, HSEEN bits */ + + regval &= ~(RCC_SRCCTRL1_SCLKSW_MASK | RCC_SRCCTRL1_MSIEN | + RCC_SRCCTRL1_HSEBP | RCC_SRCCTRL1_HSEEN); + putreg32(regval, N32_RCC_SRCCTRL1); + + /* Reset M7HYPSEL, AXIHYPSEL */ + + regval = getreg32(N32_RCC_SRCCTRL2); + regval &= ~(RCC_SRCCTRL2_M7HYPSEL_MASK | RCC_SRCCTRL2_AXIHYPSEL_MASK); + putreg32(regval, N32_RCC_SRCCTRL2); + + /* Reset SYSBUSDIV1, SYSBUSDIV2 */ + + putreg32(0x00000000, N32_RCC_SYSBUSDIV1); + putreg32(0x00000000, N32_RCC_SYSBUSDIV2); + + /* Reset PLL1CTRL1, PLL2CTRL1, PLL3CTRL1 */ + + regval = 0x09000000; + regval |= RCC_PLL1CTRL1_PLL1SRC_NONE | RCC_PLL1CTRL1_PLL1RST | + RCC_PLL1CTRL1_PLL1PD | RCC_PLL1CTRL1_PLL1BWAJ(4); + putreg32(regval, N32_RCC_PLL1CTRL1); + putreg32(regval, N32_RCC_PLL2CTRL1); + putreg32(regval, N32_RCC_PLL3CTRL1); + + /* Reset CFG2 register */ + + regval = RCC_CFG2_M4CAHIEN | RCC_CFG2_M4CAHIPCLKEN | + RCC_CFG2_M4CAHDEN | RCC_CFG2_M4CAHDPCLKEN | + RCC_CFG2_M7MMUEN | RCC_CFG2_M4MMUEN | + RCC_CFG2_M7SRAMBKPEN | RCC_CFG2_M4SRAMBKPEN | + RCC_CFG2_M7SRAM1EN | RCC_CFG2_M4SRAM1EN | + RCC_CFG2_M7SRAM2EN | RCC_CFG2_M4SRAM2EN | + RCC_CFG2_M7SRAM3EN | RCC_CFG2_M4SRAM3EN | + RCC_CFG2_M7SRAM4EN | RCC_CFG2_M4SRAM4EN; + putreg32(regval, N32_RCC_CFG2); + + /* Reset CFG3 register */ + + regval = RCC_CFG3_M7STCLKDIV_DIV8 | RCC_CFG3_M4STCLKDIV_DIV8; + putreg32(regval, N32_RCC_CFG3); + + /* Reset CFG4 register */ + + regval = ~(RCC_CFG4_RSVD | RCC_CFG4_DCMURST); + putreg32(regval, N32_RCC_CFG4); + + /* Reset CFG5 register */ + + regval = RCC_CFG5_RTCHSEDIV(2) | RCC_CFG5_M7SRAM5EN | + RCC_CFG5_M4SRAM5EN | RCC_CFG5_DCDCLKEN; + putreg32(regval, N32_RCC_CFG5); + + /* Disable all interrupts and clear pending bits */ + + putreg32(0x00000000, N32_RCC_CLKINT1); + putreg32(0x00000000, N32_RCC_CLKINT2); + putreg32(0x00000000, N32_RCC_CLKINT3); +} + +/**************************************************************************** + * Name: rcc_enableahb1 + * + * Description: + * Enable selected AHB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the RCC_AHB1ENx register to enabled the + * selected AHB1 peripherals. + */ + + regval = getreg32(N32_RCC_AHB1EN1); + +#if defined(CONFIG_N32H7_EMMC) + /* eMMC clock enable */ + + regval |= RCC_AHB1EN1_M7SDMMC2EN; +#endif + +#if defined(CONFIG_N32H7_USB2) + /* USB OTG FS clock enable */ + + regval |= RCC_AHB1EN1_M7USB2EN; +#endif + +#if defined(CONFIG_N32H7_DMA) + /* DMA MUX1 clock enable */ + + regval |= RCC_AHB1EN1_M7DMAMUX1EN; +#endif + +#if defined(CONFIG_N32H7_ADC1) + /* ADC1 clock enable */ + + regval |= RCC_AHB1EN1_M7ADC1PLLEN; + regval |= RCC_AHB1EN1_M7ADC1SYSEN; + regval |= RCC_AHB1EN1_M7ADC1BUSEN; +#endif + putreg32(regval, N32_RCC_AHB1EN1); /* Enable peripherals */ + regval = getreg32(N32_RCC_AHB1EN2); + +#if defined(CONFIG_N32H7_ETH2) + /* ETH2 clock enable */ + + regval |= RCC_AHB1EN2_M7ETH2TXEN; + regval |= RCC_AHB1EN2_M7ETH2RXEN; + regval |= RCC_AHB1EN2_M7ETH2MACEN; +#endif + putreg32(regval, N32_RCC_AHB1EN2); /* Enable peripherals */ + regval = getreg32(N32_RCC_AHB1EN3); + +#if defined(CONFIG_N32H7_ECCMAC) + /* ECCMAC clock enable */ + + regval |= RCC_AHB1EN3_M7ECCMACEN; +#endif + +#if defined(CONFIG_N32H7_DMA) + /* DMA clock enable */ + + regval |= RCC_AHB1EN3_M7DMA1EN; + regval |= RCC_AHB1EN3_M7DMA2EN; + regval |= RCC_AHB1EN3_M7DMA3EN; +#endif + putreg32(regval, N32_RCC_AHB1EN3); /* Enable peripherals */ + regval = getreg32(N32_RCC_AHB1EN4); + +#if defined(CONFIG_N32H7_ADC2) + /* ADC2 clock enable */ + + regval |= RCC_AHB1EN4_M7ADC2PLLEN; + regval |= RCC_AHB1EN4_M7ADC2SYSEN; + regval |= RCC_AHB1EN4_M7ADC2BUSEN; +#endif +#if defined(CONFIG_N32H7_ADC3) + /* ADC3 clock enable */ + + regval |= RCC_AHB1EN4_M7ADC3PLLEN; + regval |= RCC_AHB1EN4_M7ADC3SYSEN; + regval |= RCC_AHB1EN4_M7ADC3BUSEN; +#endif + putreg32(regval, N32_RCC_AHB1EN4); /* 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 RCC_APB1ENx register to enable the + * selected APB1 peripherals. + */ + + regval = getreg32(N32_RCC_APB1EN1); + +#ifdef CONFIG_N32H7_SPI3 + /* SPI3 clock enable */ + + regval |= RCC_APB1EN2_M7SPI3EN; +#endif + +#ifdef CONFIG_N32H7_DAC12 + /* DAC12 clock enable */ + + regval |= RCC_APB1EN2_M7DAC12EN; +#endif + +#ifdef CONFIG_N32H7_WWDG2 + /* WWDG2 clock enable */ + + regval |= RCC_APB1EN2_M7WWDG2EN; +#endif + putreg32(regval, N32_RCC_APB1EN2); /* Enable peripherals */ + regval = getreg32(N32_RCC_APB1EN3); + +#ifdef CONFIG_N32H7_USART1 + /* USART1 clock enable */ + + regval |= RCC_APB1EN3_M7USART1EN; +#endif + +#ifdef CONFIG_N32H7_USART2 + /* USART2 clock enable */ + + regval |= RCC_APB1EN3_M7USART2EN; +#endif + +#ifdef CONFIG_N32H7_USART3 + /* USART3 clock enable */ + + regval |= RCC_APB1EN3_M7USART3EN; +#endif + +#ifdef CONFIG_N32H7_USART4 + /* USART4 clock enable */ + + regval |= RCC_APB1EN3_M7USART4EN; +#endif + +#ifdef CONFIG_N32H7_UART9 + /* UART9 clock enable */ + + regval |= RCC_APB1EN3_M7UART9EN; +#endif + +#ifdef CONFIG_N32H7_UART10 + /* UART10 clock enable */ + + regval |= RCC_APB1EN3_M7UART10EN; +#endif + +#ifdef CONFIG_N32H7_UART11 + /* UART11 clock enable */ + + regval |= RCC_APB1EN3_M7UART11EN; +#endif + +#ifdef CONFIG_N32H7_UART12 + /* UART12 clock enable */ + + regval |= RCC_APB1EN3_M7UART12EN; +#endif + putreg32(regval, N32_RCC_APB1EN3); /* Enable peripherals */ + regval = getreg32(N32_RCC_APB1EN4); + +#ifdef CONFIG_N32H7_I2S3 + /* I2S3 clock enable */ + + regval |= RCC_APB1EN4_M7I2S3EN; +#endif + +#ifdef CONFIG_N32H7_I2S4 + /* I2S4 clock enable */ + + regval |= RCC_APB1EN4_M7I2S4EN; +#endif + +#ifdef CONFIG_N32H7_I2C1 + /* I2C1 clock enable */ + + regval |= RCC_APB1EN4_M7I2C1EN; +#endif + +#ifdef CONFIG_N32H7_I2C2 + /* I2C2 clock enable */ + + regval |= RCC_APB1EN4_M7I2C2EN; +#endif + +#ifdef CONFIG_N32H7_I2C3 + /* I2C3 clock enable */ + + regval |= RCC_APB1EN4_M7I2C3EN; +#endif + putreg32(regval, N32_RCC_APB1EN4); /* Enable peripherals */ + regval = getreg32(N32_RCC_APB1EN5); + +#ifdef CONFIG_N32H7_FDCAN1 + /* FDCAN1 clock enable */ + + regval |= RCC_APB1EN5_M7FDCAN1EN; +#endif + +#ifdef CONFIG_N32H7_FDCAN2 + /* FDCAN2 clock enable */ + + regval |= RCC_APB1EN5_M7FDCAN2EN; +#endif + +#ifdef CONFIG_N32H7_FDCAN5 + /* FDCAN5 clock enable */ + + regval |= RCC_APB1EN5_M7FDCAN5EN; +#endif + +#ifdef CONFIG_N32H7_FDCAN6 + /* FDCAN6 clock enable */ + + regval |= RCC_APB1EN5_M7FDCAN6EN; +#endif + putreg32(regval, N32_RCC_APB1EN5); /* 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 RCC_AHB2EN register to enable the + * selected AHB2 peripherals. + */ + + regval = getreg32(N32_RCC_AHB2EN1); + +#ifdef CONFIG_N32H7_USB1 + /* USB1 clock enable */ + + regval |= RCC_AHB2EN1_M7USB1EN; +#endif + +#ifdef CONFIG_N32H7_ECCM2 + /* ECCM2 clock enable */ + + regval |= RCC_AHB2EN1_M7ECCM2EN; +#endif + +#ifdef CONFIG_N32H7_CORDIC + /* CORDIC clock enable */ + + regval |= RCC_AHB2EN1_M7CORDICEN; +#endif + +#ifdef CONFIG_N32H7_SDP + /* SDP clock enable */ + + regval |= RCC_AHB2EN1_M7SDPUEN; +#endif + +#ifdef CONFIG_N32H7_FMAC + /* FMAC clock enable */ + + regval |= RCC_AHB2EN1_M7FMACEN; +#endif + putreg32(regval, N32_RCC_AHB2EN1); /* Enable peripherals */ + regval = getreg32(N32_RCC_AHB2EN2); + +#ifdef CONFIG_N32H7_DAC56 + /* DAC56 clock enable */ + + regval |= RCC_AHB2EN2_M7DAC56EN; +#endif + +#ifdef CONFIG_N32H7_DAC34 + /* DAC34 clock enable */ + + regval |= RCC_AHB2EN2_M7DAC34EN; +#endif + +#ifdef CONFIG_N32H7_ETH1 + /* ETH1 clock enable */ + + regval |= RCC_AHB2EN2_M7ETH1TEN; + regval |= RCC_AHB2EN2_M7ETH1REN; + regval |= RCC_AHB2EN2_M7ETH1MEN; +#endif + putreg32(regval, N32_RCC_AHB2EN2); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the RCC_APB2ENx register to enable the + * selected APB2 peripherals. + */ + + regval = getreg32(N32_RCC_APB2EN1); + +#ifdef CONFIG_N32H7_SHRTIM1 + /* SHRTIM1 clock enable */ + + regval |= RCC_APB2EN1_M7SHRTIM1EN; +#endif + +#ifdef CONFIG_N32H7_SHRTIM2 + /* SHRTIM2 clock enable */ + + regval |= RCC_APB2EN1_M7SHRTIM2EN; +#endif + putreg32(regval, N32_RCC_APB2EN1); /* Enable peripherals */ + regval = getreg32(N32_RCC_APB2EN2); + +#ifdef CONFIG_N32H7_I2S1 + /* I2S1 clock enable */ + + regval |= RCC_APB2EN2_M7I2S1EN; +#endif + +#ifdef CONFIG_N32H7_I2S2 + /* I2S2 clock enable */ + + regval |= RCC_APB2EN2_M7I2S2EN; +#endif + +#ifdef CONFIG_N32H7_SPI1 + /* SPI1 clock enable */ + + regval |= RCC_APB2EN2_M7SPI1EN; +#endif + +#ifdef CONFIG_N32H7_SPI2 + /* SPI2 clock enable */ + + regval |= RCC_APB2EN2_M7SPI2EN; +#endif + +#ifdef CONFIG_N32H7_DSMU + /* DSMU clock enable */ + + regval |= RCC_APB2EN2_M7DSMUEN; +#endif + +#ifdef CONFIG_N32H7_I2C4 + /* I2C4 clock enable */ + + regval |= RCC_APB2EN2_M7I2C4EN; +#endif + +#ifdef CONFIG_N32H7_I2C5 + /* I2C5 clock enable */ + + regval |= RCC_APB2EN2_M7I2C5EN; +#endif + +#ifdef CONFIG_N32H7_I2C6 + /* I2C6 clock enable */ + + regval |= RCC_APB2EN2_M7I2C6EN; +#endif + putreg32(regval, N32_RCC_APB2EN2); /* Enable peripherals */ + regval = getreg32(N32_RCC_APB2EN3); + +#ifdef CONFIG_N32H7_USART5 + /* USART5 clock enable */ + + regval |= RCC_APB2EN3_M7USART5EN; +#endif + +#ifdef CONFIG_N32H7_USART6 + /* USART6 clock enable */ + + regval |= RCC_APB2EN3_M7USART6EN; +#endif + +#ifdef CONFIG_N32H7_USART7 + /* USART7 clock enable */ + + regval |= RCC_APB2EN3_M7USART7EN; +#endif + +#ifdef CONFIG_N32H7_USART8 + /* USART8 clock enable */ + + regval |= RCC_APB2EN3_M7USART8EN; +#endif + +#ifdef CONFIG_N32H7_UART13 + /* UART13 clock enable */ + + regval |= RCC_APB2EN3_M7UART13EN; +#endif + +#ifdef CONFIG_N32H7_UART14 + /* UART14 clock enable */ + + regval |= RCC_APB2EN3_M7UART14EN; +#endif + +#ifdef CONFIG_N32H7_UART15 + /* UART15 clock enable */ + + regval |= RCC_APB2EN3_M7UART15EN; +#endif + putreg32(regval, N32_RCC_APB2EN3); /* Enable peripherals */ + regval = getreg32(N32_RCC_APB2EN4); + +#ifdef CONFIG_N32H7_FDCAN3 + /* FDCAN3 clock enable */ + + regval |= RCC_APB2EN4_M7FDCAN3EN; +#endif + +#ifdef CONFIG_N32H7_FDCAN4 + /* FDCAN4 clock enable */ + + regval |= RCC_APB2EN4_M7FDCAN4EN; +#endif + +#ifdef CONFIG_N32H7_FDCAN7 + /* FDCAN7 clock enable */ + + regval |= RCC_APB2EN4_M7FDCAN7EN; +#endif + +#ifdef CONFIG_N32H7_FDCAN8 + /* FDCAN8 clock enable */ + + regval |= RCC_APB2EN4_M7FDCAN8EN; +#endif + putreg32(regval, N32_RCC_APB2EN4); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb5 + * + * Description: + * Enable selected AHB5 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb5(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the RCC_AHB5ENx register to enable the + * selected AHB5 peripherals. + */ + + regval = getreg32(N32_RCC_AHB5EN1); + + /* GPIOA clock enable */ + + regval |= RCC_AHB5EN1_M7GPIOAEN; + + /* GPIOB clock enable */ + + regval |= RCC_AHB5EN1_M7GPIOBEN; + + /* GPIOC clock enable */ + + regval |= RCC_AHB5EN1_M7GPIOCEN; + + /* GPIOD clock enable */ + + regval |= RCC_AHB5EN1_M7GPIODEN; + +#if N32H7_NGPIO > 4 + /* GPIOE clock enable */ + + regval |= RCC_AHB5EN1_M7GPIOEEN; +#endif + +#if N32H7_NGPIO > 5 + /* GPIOF clock enable */ + + regval |= RCC_AHB5EN1_M7GPIOFEN; +#endif + +#if N32H7_NGPIO > 6 + /* GPIOG clock enable */ + + regval |= RCC_AHB5EN1_M7GPIOGEN; +#endif + +#if N32H7_NGPIO > 7 + /* GPIOH clock enable */ + + regval |= RCC_AHB5EN1_M7GPIOHEN; +#endif + putreg32(regval, N32_RCC_AHB5EN1); /* Enable peripherals */ + regval = getreg32(N32_RCC_AHB5EN2); + +#if N32H7_NGPIO > 8 + /* GPIOI clock enable */ + + regval |= RCC_AHB5EN2_M7GPIOIEN; +#endif + +#if N32H7_NGPIO > 9 + /* GPIOJ clock enable */ + + regval |= RCC_AHB5EN2_M7GPIOJEN; +#endif + +#if N32H7_NGPIO > 10 + /* GPIOK clock enable */ + + regval |= RCC_AHB5EN2_M7GPIOKEN; +#endif + +#ifdef CONFIG_N32H7_ECCM3 + /* ECCM3 clock enable */ + + regval |= RCC_AHB5EN2_M7ECCM3EN; +#endif + + /* PWR clock enable */ + + regval |= RCC_AHB5EN2_PWREN; + +#ifdef CONFIG_N32H7_CRC + /* CRC clock enable */ + + regval |= RCC_AHB5EN2_M7CRCEN; +#endif + +#ifdef CONFIG_N32H7_SEMA4 + /* SEMA4 clock enable */ + + regval |= RCC_AHB5EN2_M7SEMA4EN; +#endif + + /* AFIO clock enable */ + + regval |= RCC_AHB5EN2_M7AFIOEN; + + putreg32(regval, N32_RCC_AHB5EN2); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb5 + * + * Description: + * Enable selected APB5 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb5(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the RCC_APB5ENx register to enable the + * selected APB5 peripherals. + */ + + regval = getreg32(N32_RCC_APB5EN1); + +#ifdef CONFIG_N32H7_AFEC + /* AFEC clock enable */ + + regval |= RCC_APB5EN1_M7AFECEN; +#endif + +#ifdef CONFIG_N32H7_SPI4 + /* SPI4 clock enable */ + + regval |= RCC_APB5EN1_M7SPI4EN; +#endif + +#ifdef CONFIG_N32H7_SPI5 + /* SPI5 clock enable */ + + regval |= RCC_APB5EN1_M7SPI5EN; +#endif + +#ifdef CONFIG_N32H7_SPI6 + /* SPI6 clock enable */ + + regval |= RCC_APB5EN1_M7SPI6EN; +#endif + +#ifdef CONFIG_N32H7_SPI7 + /* SPI7 clock enable */ + + regval |= RCC_APB5EN1_M7SPI7EN; +#endif + putreg32(regval, N32_RCC_APB5EN1); /* Enable peripherals */ + regval = getreg32(N32_RCC_APB5EN2); + +#ifdef CONFIG_N32H7_I2C7 + /* I2C7 clock enable */ + + regval |= RCC_APB5EN2_M7I2C7EN; +#endif + +#ifdef CONFIG_N32H7_I2C8 + /* I2C8 clock enable */ + + regval |= RCC_APB5EN2_M7I2C8EN; +#endif + +#ifdef CONFIG_N32H7_I2C9 + /* I2C9 clock enable */ + + regval |= RCC_APB5EN2_M7I2C9EN; +#endif + +#ifdef CONFIG_N32H7_I2C10 + /* I2C10 clock enable */ + + regval |= RCC_APB5EN2_M7I2C10EN; +#endif + +#ifdef CONFIG_N32H7_EXTI + /* EXTI clock enable */ + + regval |= RCC_APB5EN2_EXTIEN; +#endif + +#ifdef CONFIG_N32H7_RTC + /* RTC clock enable */ + + regval |= RCC_APB5EN2_M7RTCPCLKEN; +#endif + +#ifdef CONFIG_N32H7_IWDG1 + /* IWDG1 clock enable */ + + regval |= RCC_APB5EN2_IWDG1PCLKEN; +#endif + +#ifdef CONFIG_N32H7_IWDG2 + /* IWDG2 clock enable */ + + regval |= RCC_APB5EN2_IWDG2PCLKEN; +#endif + putreg32(regval, N32_RCC_APB5EN2); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb9 + * + * Description: + * Enable selected APB3 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb9(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the RCC_AHB9EN1 register to enable the + * selected AHB9 peripherals. + */ + + regval = getreg32(N32_RCC_AHB9EN1); + +#ifdef CONFIG_N32H7_ESC + /* ESC clock enable */ + + regval |= RCC_AHB9EN1_M7ESCEN; +#endif + putreg32(regval, N32_RCC_AHB9EN1); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enablerd + * + * Description: + * Enable selected Retention Domain peripherals + * + ****************************************************************************/ + +static inline void rcc_enablerd(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the RCC_RDENx register to enable the + * selected low-power peripherals. + */ + + regval = getreg32(N32_RCC_RDEN1); + +#ifdef CONFIG_N32H7_LPUART1 + /* LPUART1 clock enable */ + + regval |= RCC_RDEN1_M7LPUART1EN; +#endif + +#ifdef CONFIG_N32H7_LPUART2 + /* LPUART2 clock enable */ + + regval |= RCC_RDEN1_M7LPUART2EN; +#endif + putreg32(regval, N32_RCC_RDEN1); /* Enable peripherals */ + regval = getreg32(N32_RCC_RDEN2); + +#ifdef CONFIG_N32H7_COMP + /* COMP clock enable */ + + regval |= RCC_RDEN2_M7COMPEN; +#endif + putreg32(regval, N32_RCC_RDEN2); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableaxi + * + * Description: + * Enable selected AXI peripherals + * + ****************************************************************************/ + +static inline void rcc_enableaxi(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the RCC_AXIENx register to enable the + * selected AXI peripherals. + */ + + regval = getreg32(N32_RCC_AXIEN1); + +#ifdef CONFIG_N32H7_JPEGD + /* JPEGD clock enable */ + + regval |= RCC_AXIEN1_M7JPEGDEN; +#endif + +#ifdef CONFIG_N32H7_JPEGE + /* JPEGE clock enable */ + + regval |= RCC_AXIEN1_M7JPEGEEN; +#endif + +#ifdef CONFIG_N32H7_DMA + /* DMA MUX2 clock enable */ + + regval |= RCC_AXIEN1_M7DMAMUX2EN; +#endif + +#ifdef CONFIG_N32H7_MDMA + /* MDMA clock enable */ + + regval |= RCC_AXIEN1_M7MDMAEN; +#endif + +#ifdef CONFIG_N32H7_SDMMC1 + /* SDMMC1 clock enable */ + + regval |= RCC_AXIEN1_M7SDMMC1EN; +#endif + +#ifdef CONFIG_N32H7_ECCM1 + /* ECCM1 clock enable */ + + regval |= RCC_AXIEN1_M7ECCM1EN; +#endif + +#ifdef CONFIG_N32H7_OTPC + /* OTPC clock enable */ + + regval |= RCC_AXIEN1_M7OTPCEN; +#endif + putreg32(regval, N32_RCC_AXIEN1); /* Enable peripherals */ + regval = getreg32(N32_RCC_AXIEN2); + +#ifdef CONFIG_N32H7_DSI + /* DSI clock enable */ + + regval |= RCC_AXIEN2_M7DSIEN; +#endif + +#ifdef CONFIG_N32H7_LCD + /* LCD clock enable */ + + regval |= RCC_AXIEN2_M7LCDEN; +#endif + +#ifdef CONFIG_N32H7_DVP1 + /* DVP1 clock enable */ + + regval |= RCC_AXIEN2_M7DVP1EN; +#endif + +#ifdef CONFIG_N32H7_DVP2 + /* DVP2 clock enable */ + + regval |= RCC_AXIEN2_M7DVP2EN; +#endif + +#ifdef CONFIG_N32H7_WWDG1 + /* WWDG1 clock enable */ + + regval |= RCC_AXIEN2_M7WWDG1EN; +#endif + putreg32(regval, N32_RCC_AXIEN2); /* Enable peripherals */ + regval = getreg32(N32_RCC_AXIEN3); + +#ifdef CONFIG_N32H7_TASRAM2 + /* TASRAM2 clock enable */ + + regval |= RCC_AXIEN3_M7TASRAM2EN; +#endif + +#ifdef CONFIG_N32H7_TASRAM3 + /* TASRAM3 clock enable */ + + regval |= RCC_AXIEN3_M7TASRAM3EN; +#endif + +#ifdef CONFIG_N32H7_TCM + /* TCM clock enable */ + + regval |= RCC_AXIEN3_M7TCMEN; +#endif + +#ifdef CONFIG_N32H7_TCMAXI + /* TCMAXI clock enable */ + + regval |= RCC_AXIEN3_M7TCMAXIEN; +#endif + +#ifdef CONFIG_N32H7_TCMAPB + /* TCMAPB clock enable */ + + regval |= RCC_AXIEN3_M7TCMAPBEN; +#endif + +#ifdef CONFIG_N32H7_ASRAM1 + /* ASRAM1 clock enable */ + + regval |= RCC_AXIEN3_M7ASRAM1EN; +#endif + +#ifdef CONFIG_N32H7_AXIROM + /* AXIROM clock enable */ + + regval |= RCC_AXIEN3_M7AXIROMEN; +#endif + +#ifdef CONFIG_N32H7_GPU + /* GPU clock enable */ + + regval |= RCC_AXIEN3_M7GPUEN; +#endif + putreg32(regval, N32_RCC_AXIEN3); /* Enable peripherals */ + regval = getreg32(N32_RCC_AXIEN4); + +#ifdef CONFIG_N32H7_XSPI1 + /* XSPI1 clock enable */ + + regval |= RCC_AXIEN4_M7XSPI1EN; +#endif + +#ifdef CONFIG_N32H7_XSPI2 + /* XSPI2 clock enable */ + + regval |= RCC_AXIEN4_M7XSPI2EN; +#endif + +#ifdef CONFIG_N32H7_FEMC + /* FEMC clock enable */ + + regval |= RCC_AXIEN4_M7FEMCEN; +#endif + +#ifdef CONFIG_N32H7_SDRAM + /* SDRAM clock enable */ + + regval |= RCC_AXIEN4_M7SDRAMEN; +#endif + putreg32(regval, N32_RCC_AXIEN4); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enable_rtc + * + * Description: + * Enable RTC + * + ****************************************************************************/ + +static inline void rcc_enable_rtc(void) +{ + uint32_t regval; + + regval = getreg32(N32_RCC_BDCTRL); + +#ifdef CONFIG_N32H7_RTC + /* RTC clock enable */ + + regval |= RCC_BDCTRL_RTCEN; +#endif + putreg32(regval, N32_RCC_BDCTRL); +} + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb1(); + rcc_enableapb1(); + rcc_enableahb2(); + rcc_enableapb2(); + rcc_enableahb5(); + rcc_enableapb5(); + rcc_enableahb9(); + rcc_enablerd(); + rcc_enableaxi(); + rcc_enable_rtc(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_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! + ****************************************************************************/ + +void n32_stdclockconfig(void) +{ + uint32_t regval; + volatile int32_t timeout; + +#ifdef N32_BOARD_USEHSI + /* Enable Internal High-Speed Clock (HSI) */ + + regval = getreg32(N32_RCC_SRCCTRL1); + regval |= RCC_SRCCTRL1_HSIEN; /* Enable HSI */ + putreg32(regval, N32_RCC_SRCCTRL1); + + /* Set HSI predivider to board specific value */ + + regval = getreg32(N32_RCC_SYSBUSDIV1); + regval &= ~RCC_SYSBUSDIV1_HSIDIV_MASK; + regval |= N32_BOARD_HSIDIV; + putreg32(regval, N32_RCC_SYSBUSDIV1); + + /* Wait until the HSI is ready (or until a timeout elapsed) */ + + for (timeout = HSIRDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSIRDF flag is the set in the SRCCTRL1 */ + + if ((getreg32(N32_RCC_SRCCTRL1) & RCC_SRCCTRL1_HSIRDF) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + +#else /* if N32_BOARD_USEHSE */ + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(N32_RCC_SRCCTRL1); + regval |= RCC_SRCCTRL1_HSEEN; /* Enable HSE */ + putreg32(regval, N32_RCC_SRCCTRL1); + + /* 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 SRCCTRL1 */ + + if ((getreg32(N32_RCC_SRCCTRL1) & RCC_SRCCTRL1_HSERDF) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } +#endif + +#ifdef CONFIG_N32H7_MSI + /* Enable MSI */ + + regval = getreg32(N32_RCC_SRCCTRL1); + regval |= RCC_SRCCTRL1_MSIEN; + putreg32(regval, N32_RCC_SRCCTRL1); + + /* Wait until the MSI is ready */ + + while ((getreg32(N32_RCC_SRCCTRL1) & RCC_SRCCTRL1_MSIRDF) == 0); +#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) + { + /* Configure sys_div_clk is sys_clk(PLL1A) = 600M = M7 clock */ + + regval = getreg32(N32_RCC_SYSBUSDIV1); + regval &= ~RCC_SYSBUSDIV1_SYSCLKDIV_MASK; + regval |= RCC_SYSBUSDIV1_SYSCLKDIV_DIV(1); + + /* Configure sys_bus_div_clk is sys_div_clk/2 = 300M = M4 clock + * = AHB1\2\5\9 + */ + + regval &= ~RCC_SYSBUSDIV1_BUSDIV_MASK; + regval |= RCC_SYSBUSDIV1_BUSDIV_DIV(2); + + /* Configure AXI clock is sys_div_clk/2 = 300M = AHB6 */ + + regval &= ~RCC_SYSBUSDIV1_AXIDIV_MASK; + regval |= RCC_SYSBUSDIV1_AXIDIV_DIV(2); + regval &= ~RCC_SYSBUSDIV1_AXIHYPDIV_MASK; + regval |= RCC_SYSBUSDIV1_AXIHYPDIV_DIV(2); + + /* Configure m7_hyp_div_clk is PLLxA = 600M */ + + regval &= ~RCC_SYSBUSDIV1_M7HYPDIV_MASK; + regval |= RCC_SYSBUSDIV1_M7HYPDIV_DIV(1); + + putreg32(regval, N32_RCC_SYSBUSDIV1); + __RCC_DELAY_US(1); + + /* Configure M7 sysTick is sys_div_clk/2 = 300M */ + + regval = getreg32(N32_RCC_CFG3); + regval &= ~RCC_CFG3_M7STCLKDIV_MASK; + regval |= RCC_CFG3_M7STCLKDIV_DIV1; + putreg32(regval, N32_RCC_CFG3); + + regval = getreg32(N32_RCC_SYSBUSDIV2); + + /* Configure APB1 clock is AHB1/2 = 150M */ + + regval &= ~RCC_SYSBUSDIV2_APB1DIV_MASK; + regval |= RCC_SYSBUSDIV2_APB1DIV_DIV(2); + + /* Configure APB2 clock is AHB2/2 = 150M */ + + regval &= ~RCC_SYSBUSDIV2_APB2DIV_MASK; + regval |= RCC_SYSBUSDIV2_APB2DIV_DIV(2); + + /* Configure APB5 clock is AHB5/2 = 150M */ + + regval &= ~RCC_SYSBUSDIV2_APB5DIV_MASK; + regval |= RCC_SYSBUSDIV2_APB5DIV_DIV(2); + + /* Configure APB6 clock is AHB6/2 = 150M */ + + regval &= ~RCC_SYSBUSDIV2_APB6DIV_MASK; + regval |= RCC_SYSBUSDIV2_APB6DIV_DIV(2); + + putreg32(regval, N32_RCC_SYSBUSDIV2); + + /* configure PLL1_VCOx frequency 600M */ + + regval = getreg32(N32_RCC_PLL1CTRL1); + regval &= ~RCC_PLL1CTRL1_PLL1BWAJ_MASK; + regval |= RCC_PLL1CTRL1_PLL1BWAJ(PLL_BWAJ); + putreg32(regval, N32_RCC_PLL1CTRL1); + + regval = getreg32(N32_RCC_PLL1CTRL2); + regval &= ~(RCC_PLL1CTRL2_PLL1CLKF_MASK | RCC_PLL1CTRL2_PLL1CLKR_MASK); + regval |= (RCC_PLL1CTRL2_PLL1CLKF(PLL_PLLF) | + RCC_PLL1CTRL2_PLL1CLKR(PLL_PLLR)); + putreg32(regval, N32_RCC_PLL1CTRL2); + + /* Enable PLL module power */ + + regval = getreg32(N32_RCC_PLL1CTRL1); + regval |= RCC_PLL1CTRL1_PLL1LDOEN; + putreg32(regval, N32_RCC_PLL1CTRL1); + __RCC_DELAY_US(10); + + /* Enable power to analog circuitry in PLL */ + + regval = getreg32(N32_RCC_PLL1CTRL1); + regval &= ~RCC_PLL1CTRL1_PLL1PD; + putreg32(regval, N32_RCC_PLL1CTRL1); + + /* Select Clock Source */ + + regval = getreg32(N32_RCC_PLL1CTRL1); + regval &= ~RCC_PLL1CTRL1_PLL1SRC_MASK; + regval |= PLL_SRC; + putreg32(regval, N32_RCC_PLL1CTRL1); + __RCC_DELAY_US(10); + + /* Clear PLL reset */ + + regval = getreg32(N32_RCC_PLL1CTRL1); + regval &= ~RCC_PLL1CTRL1_PLL1RST; + putreg32(regval, N32_RCC_PLL1CTRL1); + + /* Check if PLL1 is locked */ + + while ((getreg32(N32_RCC_PLL1CTRL1)&RCC_PLL1CTRL1_PLL1PHLK) != + RCC_PLL1CTRL1_PLL1PHLK); + + /* Enable PLL */ + + regval = getreg32(N32_RCC_PLL1CTRL1); + regval |= RCC_PLL1CTRL1_PLL1EN; + putreg32(regval, N32_RCC_PLL1CTRL1); + __RCC_DELAY_US(1); + + /* Configure PLL1A is 600M */ + + regval = getreg32(N32_RCC_PLL1DIV); + regval &= ~RCC_PLL1DIV_PLL1ADIV_MASK; + regval |= RCC_PLL1DIV_PLL1ADIV_DIV(1); + putreg32(regval, N32_RCC_PLL1DIV); + + /* Configure PLL1B is 100M */ + + regval = getreg32(N32_RCC_PLL1DIV); + regval &= ~RCC_PLL1DIV_PLL1BDIV_MASK; + regval |= RCC_PLL1DIV_PLL1BDIV_DIV(6); + putreg32(regval, N32_RCC_PLL1DIV); + + /* Configure sys_clk source is PLL1A */ + + regval = getreg32(N32_RCC_SRCCTRL1); + regval &= ~RCC_SRCCTRL1_SCLKSW_MASK; + regval |= RCC_SRCCTRL1_SCLKSW_PLL1A; + putreg32(regval, N32_RCC_SRCCTRL1); + + /* Check if sys_clk source is PLL1A */ + + while ((getreg32(N32_RCC_SRCCTRL1)&RCC_SRCCTRL1_SCLKSTS_MASK) != + RCC_SRCCTRL1_SCLKSTS_PLL1A); + + /* configure AXI clock source is PLL1A */ + + regval = getreg32(N32_RCC_SRCCTRL2); + regval &= ~RCC_SRCCTRL2_AXIHYPSEL_MASK; + regval |= RCC_SRCCTRL2_AXIHYPSEL_PLL1A; + putreg32(regval, N32_RCC_SRCCTRL2); + + /* configure M7 clock source is PLL1A */ + + regval &= ~RCC_SRCCTRL2_M7HYPSEL_MASK; + regval |= RCC_SRCCTRL2_M7HYPSEL_PLL1A; + putreg32(regval, N32_RCC_SRCCTRL2); + } +} diff --git a/boards/Kconfig b/boards/Kconfig index 640e56c916dbd..ea4bb7ef56ed8 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -1375,6 +1375,15 @@ config ARCH_BOARD_MOXA ---help--- Moxa +config ARCH_BOARD_N32H762IIL7 + bool "Nation Tech N32H762IIL7 DevKit" + depends on ARCH_CHIP_N32H762II + select ARCH_HAVE_LEDS + select ARCH_HAVE_BUTTONS + select ARCH_HAVE_IRQBUTTONS + ---help--- + This is the board configuration for the port of NuttX to the + config ARCH_BOARD_NE64BADGE bool "FEG NE64 /PoE Badge board" depends on ARCH_CHIP_MCS92S12NEC64 @@ -4270,6 +4279,7 @@ config ARCH_BOARD default "phy6222" if ARCH_BOARD_PHY6222 default "sim" if ARCH_BOARD_SIM default "moxa" if ARCH_BOARD_MOXA + default "n32h762iil7" if ARCH_BOARD_N32H762IIL7 default "spresense" if ARCH_BOARD_SPRESENSE default "xx3803" if ARCH_BOARD_XX3803 default "xx3823" if ARCH_BOARD_XX3823 diff --git a/boards/arm/n32h7/n32h762iil7/CMakeLists.txt b/boards/arm/n32h7/n32h762iil7/CMakeLists.txt new file mode 100644 index 0000000000000..39854855c2fcb --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/CMakeLists.txt @@ -0,0 +1,23 @@ +# ############################################################################## +# boards/arm/n32h7/n32h762iil7/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +add_subdirectory(src) diff --git a/boards/arm/n32h7/n32h762iil7/Kconfig b/boards/arm/n32h7/n32h762iil7/Kconfig new file mode 100644 index 0000000000000..56ec045c8ec25 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/Kconfig @@ -0,0 +1,35 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_BOARD_N32H762IIL7 + +config N32_ROMFS + bool "Automount baked-in ROMFS image" + default n + depends on FS_ROMFS + ---help--- + Select N32_ROMFS_IMAGEFILE, N32_ROMFS_DEV_MINOR, N32_ROMFS_MOUNTPOINT + +config N32_ROMFS_DEV_MINOR + int "Minor for the block device backing the data" + depends on N32_ROMFS + default 64 + +config N32_ROMFS_MOUNTPOINT + string "Mountpoint of the custom romfs image" + depends on N32_ROMFS + default "/rom" + +config N32_ROMFS_IMAGEFILE + string "ROMFS image file to include into build" + depends on N32_ROMFS + default "../../../rom.img" + +config N32_BOARDCTL_RESET + bool "Board control reset support" + select BOARDCTL_RESET + default n + +endif # ARCH_BOARD_N32H762IIL7 diff --git a/boards/arm/n32h7/n32h762iil7/configs/nsh/defconfig b/boards/arm/n32h7/n32h762iil7/configs/nsh/defconfig new file mode 100644 index 0000000000000..52efdc07b454b --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/configs/nsh/defconfig @@ -0,0 +1,198 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NDEBUG is not set +# CONFIG_NSH_DISABLE_MW is not set +# CONFIG_STANDARD_SERIAL is not set +# CONFIG_SYSTEM_DD is not set +CONFIG_ALLOW_BSD_COMPONENTS=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="n32h762iil7" +CONFIG_ARCH_BOARD_N32H762IIL7=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP="n32h7" +CONFIG_ARCH_CHIP_N32H762II=y +CONFIG_ARCH_CHIP_N32H7=y +CONFIG_ARCH_CHIP_N32H7_CORTEXM7=y +CONFIG_ARCH_CPUINFO_FREQ_KHZ=600000 +CONFIG_ARCH_IDLE_CUSTOM=y +CONFIG_ARCH_IRQBUTTONS=y +CONFIG_ARCH_IRQPRIO=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_STDARG_H=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_ITCM=y +CONFIG_ARMV7M_STRING_FUNCTION=y +CONFIG_ARM_MPU=y +CONFIG_ARM_MPU_EARLY_RESET=y +CONFIG_BENCHMARK_COREMARK=y +CONFIG_BENCHMARK_MTD=y +CONFIG_BENCHMARK_OSPERF=y +CONFIG_BENCHMARK_RAMSPEED=y +CONFIG_BENCHMARK_SD_BENCH=y +CONFIG_BENCHMARK_SUPERPI=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARDCTL_RESET_CAUSE=y +CONFIG_BOARDCTL_UNIQUEID=y +CONFIG_BOARD_LOOPSPERMSEC=74953 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_COMPOSITE=y +CONFIG_COMPOSITE_IAD=y +CONFIG_COMPOSITE_MSFT_OS_DESCRIPTORS=y +CONFIG_COMPOSITE_PRODUCTID=0x5740 +CONFIG_COMPOSITE_VENDORID=0x19F5 +CONFIG_DEBUG_CUSTOMOPT=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ERROR=y +CONFIG_DEBUG_FS_WARN=y +CONFIG_DEBUG_INPUT=y +CONFIG_DEBUG_INPUT_ERROR=y +CONFIG_DEBUG_INPUT_WARN=y +CONFIG_DEBUG_LEDS=y +CONFIG_DEBUG_LEDS_ERROR=y +CONFIG_DEBUG_LEDS_WARN=y +CONFIG_DEBUG_MEMCARD=y +CONFIG_DEBUG_MEMCARD_ERROR=y +CONFIG_DEBUG_MEMCARD_WARN=y +CONFIG_DEBUG_MM=y +CONFIG_DEBUG_MM_ERROR=y +CONFIG_DEBUG_MM_WARN=y +CONFIG_DEBUG_SCHED=y +CONFIG_DEBUG_SCHED_ERROR=y +CONFIG_DEBUG_SCHED_WARN=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TIMER=y +CONFIG_DEBUG_TIMER_ERROR=y +CONFIG_DEBUG_TIMER_WARN=y +CONFIG_DEFAULT_TASK_STACKSIZE=8192 +CONFIG_EXAMPLES_BUTTONS=y +CONFIG_EXAMPLES_BUTTONS_NAME0="WKUP" +CONFIG_EXAMPLES_BUTTONS_NAME1="KEY1" +CONFIG_EXAMPLES_BUTTONS_NAME2="KEY2" +CONFIG_EXAMPLES_BUTTONS_NAME3="KEY3" +CONFIG_EXAMPLES_BUTTONS_NAMES=y +CONFIG_EXAMPLES_CAPTURE=y +CONFIG_EXAMPLES_CORDIC=y +CONFIG_EXAMPLES_LEDS=y +CONFIG_EXAMPLES_ONESHOT=y +CONFIG_EXAMPLES_ONESHOT_DELAY=500000 +CONFIG_EXAMPLES_PWM=y +CONFIG_EXAMPLES_TERMIOS=y +CONFIG_EXAMPLES_TIMER=y +CONFIG_EXAMPLES_USBSERIAL=y +CONFIG_EXPERIMENTAL=y +CONFIG_FS_FAT=y +CONFIG_FS_LARGEFILE=y +CONFIG_FS_LITTLEFS=y +CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1 +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=4096 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INPUT=y +CONFIG_INPUT_BUTTONS=y +CONFIG_INPUT_BUTTONS_LOWER=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_MMCSD_MULTIBLOCK_LIMIT=8 +CONFIG_MMCSD_SDIO=y +CONFIG_MM_REGIONS=3 +CONFIG_N32H7_ATIM1=y +CONFIG_N32H7_ATIM1_CHANNEL1=y +CONFIG_N32H7_ATIM1_CHANNEL2=y +CONFIG_N32H7_ATIM1_CHANNEL3=y +CONFIG_N32H7_ATIM1_CHANNEL4=y +CONFIG_N32H7_ATIM1_PWM=y +CONFIG_N32H7_ATIM4=y +CONFIG_N32H7_BTIM1=y +CONFIG_N32H7_BTIM2=y +CONFIG_N32H7_BTIM3=y +CONFIG_N32H7_BTIM4=y +CONFIG_N32H7_CAPTURE=y +CONFIG_N32H7_CORDIC=y +CONFIG_N32H7_DMA1=y +CONFIG_N32H7_DMA2=y +CONFIG_N32H7_DMA3=y +CONFIG_N32H7_DMA=y +CONFIG_N32H7_GTIMA1=y +CONFIG_N32H7_GTIMA2=y +CONFIG_N32H7_GTIMA2_CAP=y +CONFIG_N32H7_GTIMB1=y +CONFIG_N32H7_GTIMB1_CHANNEL1=y +CONFIG_N32H7_GTIMB1_CHANNEL2=y +CONFIG_N32H7_GTIMB1_CHANNEL3=y +CONFIG_N32H7_GTIMB1_CHANNEL4=y +CONFIG_N32H7_GTIMB1_PWM=y +CONFIG_N32H7_ONESHOT=y +CONFIG_N32H7_ONESHOT_MAXCHANNELS=8 +CONFIG_N32H7_PROGMEM=y +CONFIG_N32H7_PWM=y +CONFIG_N32H7_PWM_MULTICHAN=y +CONFIG_N32H7_PWR=y +CONFIG_N32H7_SDMMC1=y +CONFIG_N32H7_SDMMC_ADMA=y +CONFIG_N32H7_SERIAL=y +CONFIG_N32H7_TIMER=y +CONFIG_N32H7_TIMER_ADVANCED=y +CONFIG_N32H7_TIMER_BASIC=y +CONFIG_N32H7_TIMER_GTIMA=y +CONFIG_N32H7_TIMER_GTIMB=y +CONFIG_N32H7_USART1=y +CONFIG_N32H7_USART3=y +CONFIG_N32H7_USBHS1_DEV=y +CONFIG_N32H7_USBHS2_HOST=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PWM_NCHANNELS=4 +CONFIG_RAM_SIZE=131072 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_CPULOAD_SYSCLK=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_IRQMONITOR=y +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=21 +CONFIG_START_MONTH=2 +CONFIG_START_YEAR=2006 +CONFIG_SYSTEM_CLE_CMD_HISTORY=y +CONFIG_SYSTEM_COLOR_CLE=y +CONFIG_SYSTEM_COMPOSITE=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_NSH_STACKSIZE=4096 +CONFIG_SYSTEM_UNIQUEID=y +CONFIG_TESTING_OSTEST=y +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGTSTP=y +CONFIG_USART1_BAUD=921600 +CONFIG_USART1_RXBUFSIZE=128 +CONFIG_USART1_RXDMA=y +CONFIG_USART1_SERIAL_CONSOLE=y +CONFIG_USART1_TXBUFSIZE=128 +CONFIG_USART1_TXDMA=y +CONFIG_USART3_RXBUFSIZE=128 +CONFIG_USART3_RXDMA=y +CONFIG_USART3_TXBUFSIZE=128 +CONFIG_USART3_TXDMA=y +CONFIG_USBDEV_COMPOSITE=y +CONFIG_USBHOST_MSC=y +CONFIG_USBHOST_MSC_NOTIFIER=y +CONFIG_USERLED=y +CONFIG_USERLED_LOWER=y +CONFIG_USERLED_LOWER_READSTATE=y diff --git a/boards/arm/n32h7/n32h762iil7/include/board.h b/boards/arm/n32h7/n32h762iil7/include/board.h new file mode 100644 index 0000000000000..fbc019c04d2bc --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/include/board.h @@ -0,0 +1,328 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/include/board.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + + #ifndef __BOARDS_ARM_N32H7_N32H762IIL7_INCLUDE_BOARD_H + #define __BOARDS_ARM_N32H7_N32H762IIL7_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + + #include + + #ifndef __ASSEMBLY__ + # include + #endif + +/* Do not include N32H7 header files here */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Clocking *****************************************************************/ + +/* The N32H762IIL7 board provides the following clock sources: + * + * X1: 25 MHz crystal oscillator + * X2: 32.768 KHz crystal oscillator + * + * So we have these clock source available within the N32H7 + * + * HSI: 64 MHz RC factory-trimmed + * MSI: 16 MHz RC factory-trimmed + * LSI: 32 KHz RC + * HSE: 25 MHz crystal oscillator + * LSE: 32.768 KHz crystal oscillator + */ + + #define N32_BOARD_XTAL 25000000ul + + #define N32_HSI_FREQUENCY 64000000ul + #define N32_MSI_FREQUENCY 16000000ul + #define N32_LSI_FREQUENCY 32000ul + #define N32_HSE_FREQUENCY N32_BOARD_XTAL + #define N32_LSE_FREQUENCY 32768ul + +/* Main PLL Configuration. + * + * PLL source is HSE = 25,000,000 + * + * PLL_VCOx = N32_HSE_FREQUENCY*(PLLF/16384)/(PLLR+1) + * PLL_BWAJx = PLLF/32768 - 1 + * Subject to: + * + * 1 <= PLLF <= 67,108,863 + * 0 <= PLLR <= 63 + * 438 MHz <= PLL_VCO <= 800MHz + * + * Use SysClkMode0: M7 from PLL1A, AXI from PLL1A, M4 from PLL1A. + * + * Configure the M7 clock is 600MHz, + * M4, AXI, AHB(1,2,5,6,9) clock is 300MHz, APB(1,2,5,6) clock is 150MHz. + * + * 0010_11 00_0100_1000_0000_0000_0000_0000 + * Target PLL_VCOx: 600 MHz PLL1CTRL1.BWAJ[11:0] = 0x08F + * PLLF[25:0]: 4718592 PLL1CTRL2 = 0x2C480000 + * PLLR[5:0]: 11 + * PLL_BWAJx: 143 + * Actual PLL_VCOx: 600000000 Hz + * + * *************!!!WARNING!!!*************** + * * * + * *!!!OVERCLOCK CAN DAMAGE YOU HARDWARE!!!* + * * * + * *************!!!WARNING!!!*************** + * + * 0010_11 00_0110_0000_0000_0000_0000_0000 + * Target PLL_VCOx: 800 MHz PLL1CTRL1.BWAJ[11:0] = 0x0C7 + * PLLF[25:0]: 6291456 PLL1CTRL2 = 0x2C600000 + * PLLR[5:0]: 11 + * PLL_BWAJx: 191 + * Actual PLL_VCOx: 800000000 Hz + */ + +#define TCM_SIZE_VALUE N32H7_TCM_CFG(896, 128, 0) +#define CLK_TCK 1000 + +#define N32_BOARD_USEHSE +/* #define N32_BOARD_USEHSI */ + +#ifdef N32_BOARD_USEHSI +# define N32_BOARD_HSIDIV RCC_SYSBUSDIV1_HSIDIV_DIV(1) +# define PLL_PLLF 153600U +# define PLL_PLLR 0U +# define PLL_BWAJ 3U +# define PLL_SRC RCC_PLL1CTRL1_PLL1SRC_HSI +#elif defined(N32_BOARD_USEHSE) +# define N32_BOARD_HSEDIV RCC_SYSBUSDIV1_HSEDIV_DIV(1) +# define PLL_PLLF 4718592U +# define PLL_PLLR 11U +# define PLL_BWAJ 143U +# define PLL_SRC RCC_PLL1CTRL1_PLL1SRC_HSE +#else +# error "PLL configuration not supported" +#endif + +#define N32_BOARD_SYSCLKMODE 0 +/* #define N32_BOARD_SYSCLKMODE 1 + * #define N32_BOARD_SYSCLKMODE 2 + */ + +#define N32_PLL1_VCO_FREQUENCY 600000000ul +#define N32_PLL1A_FREQUENCY N32_PLL1_VCO_FREQUENCY/1 +#define N32_PLL1B_FREQUENCY N32_PLL1_VCO_FREQUENCY/6 +#if N32_BOARD_SYSCLKMODE != 0 +# define N32_PLL2_VCO_FREQUENCY 600000000ul +# define N32_PLL2A_FREQUENCY N32_PLL2_VCO_FREQUENCY/1 +#endif + +#if N32_BOARD_SYSCLKMODE == 2 +# define N32_M7CPU_FREQUENCY (N32_PLL2A_FREQUENCY/1) +# define N32_M4CPU_FREQUENCY (N32_PLL1A_FREQUENCY/2) +# define N32_AXI_FREQUENCY (N32_PLL1A_FREQUENCY/2) +# define N32_AHB_FREQUENCY (N32_PLL1A_FREQUENCY/2) +# define N32_APB_FREQUENCY (N32_AHB_FREQUENCY/2) +#elif N32_BOARD_SYSCLKMODE == 1 +# define N32_M7CPU_FREQUENCY (N32_PLL2A_FREQUENCY/1) +# define N32_M4CPU_FREQUENCY (N32_PLL1A_FREQUENCY/2) +# define N32_AXI_FREQUENCY (N32_PLL2A_FREQUENCY/2) +# define N32_AHB_FREQUENCY (N32_PLL1A_FREQUENCY/2) +# define N32_APB_FREQUENCY (N32_AHB_FREQUENCY/2) +#else +# define N32_M7CPU_FREQUENCY (N32_PLL1A_FREQUENCY/1) +# define N32_M4CPU_FREQUENCY (N32_PLL1A_FREQUENCY/2) +# define N32_AXI_FREQUENCY (N32_PLL1A_FREQUENCY/2) +# define N32_AHB_FREQUENCY (N32_PLL1A_FREQUENCY/2) +# define N32_APB_FREQUENCY (N32_AHB_FREQUENCY/2) +#endif + +/* LED definitions **********************************************************/ + +/* The Nucleo-144 board has numerous LEDs but only three, LD1 a Green LED, + * LD2 a Blue LED and LD3 a Red LED, that can be controlled by software. + * The following definitions assume the default Solder Bridges are installed. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in + * any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED1 0 /* PA1 */ +#define BOARD_LED2 1 /* PA2 */ +#define BOARD_LED3 2 /* PA3 */ +#define BOARD_NLEDS 3 + +#define BOARD_LED_GREEN BOARD_LED1 +#define BOARD_LED_BLUE BOARD_LED2 +#define BOARD_LED_RED BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +#ifdef CONFIG_ARCH_LEDS +# define CONFIG_N32H7_GPIOA +#endif + +/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in + * include/board.h and src/stm32_leds.c. + * The LEDs are used to encode OS-related events as follows: + * + * + * SYMBOL Meaning LED state + * Red Green Blue + * ---------------------- -------------------------- ------ ------ --- + */ + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Thus if the Green LED is statically on, NuttX has successfully booted and + * is, apparently, running normally. If the Red LED is flashing at + * approximately 2Hz, then a fatal error has been detected and the system + * has halted. + */ + +/* Button definitions *******************************************************/ + +/* The NUCLEO board supports four button: Pushbutton B1, labeled "User", is + * connected to GPIO PC0. + * A high value will be sensed when the button is depressed. + */ + +#define BUTTON_WKUP 0 +#define BUTTON_KEY1 1 +#define BUTTON_KEY2 2 +#define BUTTON_KEY3 3 +#define NUM_BUTTONS 4 +#define BUTTON_WKUP_BIT (1 << BUTTON_WKUP) +#define BUTTON_KEY1_BIT (1 << BUTTON_KEY1) +#define BUTTON_KEY2_BIT (1 << BUTTON_KEY2) +#define BUTTON_KEY3_BIT (1 << BUTTON_KEY3) + +/* Alternate function pin selections ****************************************/ + +/* SDMMC GPIO pin definitions */ +#define GPIO_SDMMC1_CMD (GPIO_SDMMC1_CMD_0 | GPIO_DRIVE_12mA) /* PD2 */ +#define GPIO_SDMMC1_D0 (GPIO_SDMMC1_D0_1 | GPIO_DRIVE_12mA) /* PC8 */ +#define GPIO_SDMMC1_D1 (GPIO_SDMMC1_D1_0 | GPIO_DRIVE_12mA) /* PC9 */ +#define GPIO_SDMMC1_D2 (GPIO_SDMMC1_D2_0 | GPIO_DRIVE_12mA) /* PC10 */ +#define GPIO_SDMMC1_D3 (GPIO_SDMMC1_D3_0 | GPIO_DRIVE_12mA) /* PC11 */ +#define GPIO_SDMMC1_CK (GPIO_SDMMC1_CK_0 | GPIO_DRIVE_12mA) /* PC12 */ + +#define GPIO_SDIO_NCD (GPIO_INPUT | GPIO_PULLUP | GPIO_SLEW_RATE_SLOW | GPIO_PORTC |GPIO_PIN13) /* PC13 */ + +/* USBHS GPIO pin definitions */ +#define GPIO_USBHS1_DM (GPIO_USBHS1_DM_0) /* PA11 */ +#define GPIO_USBHS1_DP (GPIO_USBHS1_DP_0) /* PA12 */ + +#define GPIO_USBHS1_PWRON (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SLEW_RATE_SLOW | GPIO_PORTC |GPIO_PIN6) /* PC6 */ + +#define GPIO_USBHS2_DM (GPIO_USBHS2_DM_0) /* PB14 */ +#define GPIO_USBHS2_DP (GPIO_USBHS2_DP_0) /* PB15 */ + +#define GPIO_USBHS2_PWRON (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SLEW_RATE_SLOW | GPIO_PORTD |GPIO_PIN12) /* PD12 */ + +/* USBHS configuration */ +#define N32_USBHS_WRPCFG_PHYCLKSEL N32_USBHS_WRPCFG_PHYCLKSEL_25 + +/* ep0-8 x 2 for IN and OUT but driver internals use byte to map + one + * bit for direction + */ +#define N32_USBHS_NENDPOINTS (9) + +/* There is 4Kb of FIFO memory in the USBHS core */ +#define N32_USBHS_FIFO_SIZE 4096 + +/* USART1 (Serial Shield) */ +#define GPIO_USART1_RX (GPIO_USART1_RX_2) /* PA10 */ +#define GPIO_USART1_TX (GPIO_USART1_TX_2) /* PA9 */ + +/* USART3 (Serial Shield) */ +#define GPIO_USART3_RX (GPIO_USART3_RX_0) /* PB10 */ +#define GPIO_USART3_TX (GPIO_USART3_TX_0) /* PB11 */ + +/* DMA mappings */ +#define DMAMAP_USART1_TX (DMAMAP_DMA1_USART1_TX) +#define DMAMAP_USART1_RX (DMAMAP_DMA1_USART1_RX) +#define DMAMAP_USART3_TX (DMAMAP_DMA1_USART3_TX) +#define DMAMAP_USART3_RX (DMAMAP_DMA1_USART3_RX) + +/* ATIM1 (CH Output) */ +#define PWM_ATIM1_NCHANNELS 4 +#define GPIO_ATIM1_CH1OUT (GPIO_ATIM1_CH1OUT_1) /* PE9 */ +#define GPIO_ATIM1_CH2OUT (GPIO_ATIM1_CH2OUT_1) /* PE11 */ +#define GPIO_ATIM1_CH3OUT (GPIO_ATIM1_CH3OUT_1) /* PE13 */ +#define GPIO_ATIM1_CH4OUT (GPIO_ATIM1_CH4OUT_1) /* PE14 */ + +/* GTIMB1 (CH Output) */ +#define PWM_GTIMB1_NCHANNELS 4 +#define GPIO_GTIMB1_CH1OUT (GPIO_GTIMB1_CH1POUT_0) /* PE5 */ +#define GPIO_GTIMB1_CH2OUT (GPIO_GTIMB1_CH2OUT_0) /* PE6 */ +#define GPIO_GTIMB1_CH3OUT (GPIO_GTIMB1_CH3OUT_0) /* PE0 */ +#define GPIO_GTIMB1_CH4OUT (GPIO_GTIMB1_CH4OUT_0) /* PE1 */ + +/* GTIMA2 (CH Input) */ +#define GPIO_GTIMA2_CH1IN (GPIO_GTIMA2_CH1IN_0) /* PA6 */ +#define GPIO_GTIMA2_CH2IN (GPIO_GTIMA2_CH1IN_0) /* PA6 */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_ARM_N32H7_N32H762IIL7_INCLUDE_BOARD_H */ diff --git a/boards/arm/n32h7/n32h762iil7/scripts/Make.defs b/boards/arm/n32h7/n32h762iil7/scripts/Make.defs new file mode 100644 index 0000000000000..47ea46078473c --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/scripts/Make.defs @@ -0,0 +1,38 @@ +############################################################################ +# boards/arm/n32h7/n32h762iil7/scripts/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/arch/arm/src/armv7-m/Toolchain.defs + +LDSCRIPT = flash.ld + +ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS := $(CFLAGS) -D__ASSEMBLY__ + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 diff --git a/boards/arm/n32h7/n32h762iil7/scripts/flash.ld b/boards/arm/n32h7/n32h762iil7/scripts/flash.ld new file mode 100644 index 0000000000000..2a2e840b2a985 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/scripts/flash.ld @@ -0,0 +1,134 @@ +/* Specify the memory areas */ +MEMORY +{ +ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 896K +DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +AXI_RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 128K +AHB_RAM (xrw) : ORIGIN = 0x30000000, LENGTH = 352K +FLASH (rx ) : ORIGIN = 0x15000000, LENGTH = 896K /* 896K for code, 1024K for mtd */ +} + +/* Entry Point */ +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* Define output sections */ +SECTIONS +{ + _sivectors = LOADADDR(.vectors); + + .vectors : + { + _svectors = ABSOLUTE(.); + *(.vectors) + _evectors = ABSOLUTE(.); + } > ITCMRAM AT > FLASH + + .startup : + { + *(.rodata.g_idle_topstack) + *(.text.start) + *(.text.__start) + *(.text.n32_tcmenable) + *(.text.n32_tcm_init) + } > FLASH + + _sitext = LOADADDR(.text); + + .text : + { + _stext = ABSOLUTE(.); + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > ITCMRAM AT > FLASH + + .init_section : + { + _sinit = ABSOLUTE(.); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o) .ctors)) + _einit = ABSOLUTE(.); + } > ITCMRAM AT > FLASH + + .ARM.extab : + { + __extab_start = ABSOLUTE(.); + *(.ARM.extab*) + __extab_end = ABSOLUTE(.); + } > ITCMRAM AT > FLASH + + .ARM.exidx : + { + __exidx_start = ABSOLUTE(.); + *(.ARM.exidx*) + __exidx_end = ABSOLUTE(.); + } > ITCMRAM AT > FLASH + + .data : + { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > DTCMRAM AT > FLASH + + _eronly = LOADADDR(.data); + + .bss (NOLOAD) : + { + _sbss_rel = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss_rel = ABSOLUTE(.); + } > DTCMRAM + + /* Emit the the D3 power domain section for locating BDMA data + * + * Static data with locate_data(".axi_ram") will be located + * at start of AXI_RAM; the rest of AXI_RAM will be added to the heap. + */ + .ahb_ram_reserve (NOLOAD) : + { + *(.ahb_ram) + . = ALIGN(4); + _ahbram_heap_start = ABSOLUTE(.); + } > AHB_RAM + + .axi_ram_reserve (NOLOAD) : + { + _sbss = ABSOLUTE(.); + *(.axi_ram) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + _axiram_heap_start = ABSOLUTE(.); + } > AXI_RAM + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/arm/n32h7/n32h762iil7/src/CMakeLists.txt b/boards/arm/n32h7/n32h762iil7/src/CMakeLists.txt new file mode 100644 index 0000000000000..3908333960f78 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/CMakeLists.txt @@ -0,0 +1,72 @@ +# ############################################################################## +# boards/arm/n32h7/n32h762iil7/src/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## +set(SRCS n32_boot.c n32_bringup.c) + +if(CONFIG_BOARDCTL) + list(APPEND SRCS n32_appinitialize.c) +endif() + +if(CONFIG_ARCH_LEDS) + list(APPEND SRCS n32_autoleds.c) +else() + list(APPEND SRCS n32_userleds.c) +endif() + +if(CONFIG_ARCH_BUTTONS) + list(APPEND SRCS n32_buttons.c) +endif() + +if(CONFIG_BOARDCTL_RESET) + list(APPEND SRCS n32_reset.c) +endif() + +if(CONFIG_BOARDCTL_UNIQUEID) + list(APPEND SRCS n32_uid.c) +endif() + +if(CONFIG_PWM) + list(APPEND SRCS n32_pwm.c) +endif() + +if(CONFIG_N32H7_PROGMEM) + list(APPEND SRCS n32_progmem.c) +endif() + +if(CONFIG_N32H7_SDMMC) + list(APPEND SRCS n32_sdmmc.c) +endif() + +if(CONFIG_N32H7_USBHS) + list(APPEND SRCS n32_usb.c) +endif() + +if(CONFIG_USBDEV_COMPOSITE) + list(APPEND SRCS n32_composite.c) +endif() + +if(CONFIG_MATH_CORDIC) + list(APPEND SRCS n32_cordic.c) +endif() + +target_sources(board PRIVATE ${SRCS}) + +set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/flash.ld") diff --git a/boards/arm/n32h7/n32h762iil7/src/Make.defs b/boards/arm/n32h7/n32h762iil7/src/Make.defs new file mode 100644 index 0000000000000..df47567ff8e53 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/Make.defs @@ -0,0 +1,75 @@ +############################################################################ +# boards/arm/n32h7/n32h762iil7/src/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/Make.defs + +CSRCS = n32_boot.c n32_bringup.c + +ifeq ($(CONFIG_BOARDCTL),y) +CSRCS += n32_appinitialize.c +endif + +ifeq ($(CONFIG_ARCH_LEDS),y) +CSRCS += n32_autoleds.c +else +CSRCS += n32_userleds.c +endif + +ifeq ($(CONFIG_ARCH_BUTTONS),y) +CSRCS += n32_buttons.c +endif + +ifeq ($(CONFIG_BOARDCTL_RESET),y) +CSRCS += n32_reset.c +endif + +ifeq ($(CONFIG_BOARDCTL_UNIQUEID),y) +CSRCS += n32_uid.c +endif + +ifeq ($(CONFIG_PWM),y) +CSRCS += n32_pwm.c +endif + +ifeq ($(CONFIG_N32H7_PROGMEM),y) +CSRCS += n32_progmem.c +endif + +ifeq ($(CONFIG_N32H7_SDMMC),y) +CSRCS += n32_sdmmc.c +endif + +ifeq ($(CONFIG_N32H7_USBHS),y) +CSRCS += n32_usb.c +endif + +ifeq ($(CONFIG_USBDEV_COMPOSITE),y) +CSRCS += n32_composite.c +endif + +ifeq ($(CONFIG_MATH_CORDIC),y) +CSRCS += n32_cordic.c +endif + +DEPPATH += --dep-path board +VPATH += :board +CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board diff --git a/boards/arm/n32h7/n32h762iil7/src/Makefile b/boards/arm/n32h7/n32h762iil7/src/Makefile new file mode 100644 index 0000000000000..c64a6c8bd43c4 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/Makefile @@ -0,0 +1,25 @@ +############################################################################ +# boards/arm/n32h7/n32h762iil7/src/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +include Make.defs +include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_appinitialize.c b/boards/arm/n32h7/n32h762iil7/src/n32_appinitialize.c new file mode 100644 index 0000000000000..049c8641f3afa --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_appinitialize.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_appinitialize.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "n32h762iil7.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initialization logic and the + * matching application logic. The value could be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +int board_app_initialize(uintptr_t arg) +{ +#ifdef CONFIG_BOARD_LATE_INITIALIZE + /* Board initialization already performed by board_late_initialize() */ + + return OK; +#else + /* Perform board-specific initialization */ + + return n32_bringup(); +#endif +} diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_autoleds.c b/boards/arm/n32h7/n32h762iil7/src/n32_autoleds.c new file mode 100644 index 0000000000000..e25d37b66f2a3 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_autoleds.c @@ -0,0 +1,172 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_autoleds.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "n32_gpio.h" +#include "n32h762iil7.h" + +#ifdef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Indexed by BOARD_LED_ */ + +static const uint32_t g_ledmap[BOARD_NLEDS] = +{ + GPIO_LED_BLUE, + GPIO_LED_GREEN, + GPIO_LED_RED, +}; + +static bool g_initialized; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void phy_set_led(int led, bool state) +{ + /* Active High */ + + n32_gpiowrite(g_ledmap[led], state); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_autoled_initialize + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + int i; + + /* Configure the LD1 GPIO for output. Initial state is OFF */ + + for (i = 0; i < nitems(g_ledmap); i++) + { + n32_configgpio(GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SLEW_RATE_SLOW | + g_ledmap[i]); + } +} + +/**************************************************************************** + * Name: board_autoled_on + ****************************************************************************/ + +void board_autoled_on(int led) +{ + switch (led) + { + default: + break; + + case LED_HEAPALLOCATE: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_IRQSENABLED: + phy_set_led(BOARD_LED_BLUE, false); + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_STACKCREATED: + phy_set_led(BOARD_LED_GREEN, true); + phy_set_led(BOARD_LED_BLUE, true); + g_initialized = true; + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, true); + break; + + case LED_IDLE : /* IDLE */ + phy_set_led(BOARD_LED_RED, true); + break; + } +} + +/**************************************************************************** + * Name: board_autoled_off + ****************************************************************************/ + +void board_autoled_off(int led) +{ + switch (led) + { + default: + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, false); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, false); + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, false); + break; + + case LED_IDLE : /* IDLE */ + phy_set_led(BOARD_LED_RED, false); + break; + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_boot.c b/boards/arm/n32h7/n32h762iil7/src/n32_boot.c new file mode 100644 index 0000000000000..f5c2017b15936 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_boot.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_boot.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "arm_internal.h" +#include "n32h762iil7.h" + +#include "n32_dma.h" +#include "n32_systemreset.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_boardinitialize + * + * Description: + * All N32 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 n32_boardinitialize(void) +{ +#ifdef CONFIG_ARCH_LEDS + board_autoled_initialize(); +#endif +#ifdef CONFIG_N32H7_DMA + modifyreg32(N32_DMA1_CFG, 0, DMA_CFG_EN); + modifyreg32(N32_DMA2_CFG, 0, DMA_CFG_EN); + modifyreg32(N32_DMA3_CFG, 0, DMA_CFG_EN); +#endif +#if (defined(CONFIG_N32H7_USBHS1_HOST) || defined(CONFIG_N32H7_USBHS2_HOST)) && defined(CONFIG_USBHOST) + n32_usbinitialize(); +#endif +} + +/**************************************************************************** + * Name: board_late_initialize + * + * Description: + * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional + * initialization call will be performed in the boot-up sequence to a + * function called board_late_initialize(). board_late_initialize() + * will be called immediately after up_initialize() is called and just + * before the initial application is started. This additional + * initialization phase may be used, for example, to initialize board- + * specific device drivers. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ +#ifdef CONFIG_BOARDCTL_RESET_CAUSE + n32_get_reset_cause(); +#endif + n32_bringup(); +} +#endif diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_bringup.c b/boards/arm/n32h7/n32h762iil7/src/n32_bringup.c new file mode 100644 index 0000000000000..2c432024fdeb2 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_bringup.c @@ -0,0 +1,386 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_bringup.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include +#include + +#include "n32h762iil7.h" + +#ifdef CONFIG_USERLED +# include +#endif + +#ifdef CONFIG_INPUT_BUTTONS +# include +#endif + +#if CONFIG_ONESHOT +#include +#endif + +#ifdef CONFIG_CAPTURE +#include +#endif + +#ifdef CONFIG_USBMONITOR +# include +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Forward declarations */ + +#ifdef CONFIG_TIMER +extern int n32_timer_initialize(const char *devpath, int timer); +#endif + +#ifdef CONFIG_CAPTURE +extern struct cap_lowerhalf_s *n32_cap_initialize(int timer); +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_bringup + * + * Description: + * Perform architecture-specific initialization + * + * CONFIG_BOARD_LATE_INITIALIZE=y : + * Called from board_late_initialize(). + * + * CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_BOARDCTL=y && + * CONFIG_NSH_ARCHINIT: + * Called from the NSH library + * + ****************************************************************************/ + +int n32_bringup(void) +{ + int ret = OK; + + UNUSED(ret); + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, N32_PROCFS_MOUNTPOINT, "procfs", 0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to mount the PROC filesystem: %d\n", ret); + } +#endif /* CONFIG_FS_PROCFS */ + +#if !defined(CONFIG_ARCH_LEDS) && defined(CONFIG_USERLED_LOWER) + /* Register the LED driver */ + + ret = userled_lower_initialize(LED_DRIVER_PATH); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret); + } +#endif /* !CONFIG_ARCH_LEDS && CONFIG_USERLED_LOWER */ + +#ifdef CONFIG_INPUT_BUTTONS_LOWER + /* Register the BUTTON driver */ + + ret = btn_lower_initialize(BTN_DRIVER_PATH); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret); + } +#endif /* CONFIG_INPUT_BUTTONS */ + +#ifdef CONFIG_MATH_CORDIC + /* Initialize CORDIC and register the CORDIC driver. */ + + ret = n32_cordic_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: n32_cordic_setup failed: %d\n", ret); + } +#endif + +#ifdef HAVE_USBHOST + /* Initialize USB host operation. n32_usbhost_initialize() + * starts a thread will monitor for USB connection and + * disconnection events. + */ + + ret = n32_usbhost_initialize(); + if (ret != OK) + { + syslog(LOG_ERR, + "ERROR: Failed to initialize USB host: %d\n", + ret); + } +#endif + +#ifdef HAVE_USBMONITOR + /* Start the USB Monitor */ + + ret = usbmonitor_start(); + if (ret != OK) + { + syslog(LOG_ERR, + "ERROR: Failed to start USB monitor: %d\n", + ret); + } +#endif + +#if defined(CONFIG_CDCACM) && !defined(CONFIG_CDCACM_CONSOLE) && \ + !defined(CONFIG_CDCACM_COMPOSITE) + /* Initialize CDCACM */ + + syslog(LOG_INFO, "Initialize CDCACM device\n"); + + ret = cdcacm_initialize(0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: cdcacm_initialize failed: %d\n", ret); + } +#endif /* CONFIG_CDCACM & !CONFIG_CDCACM_CONSOLE */ + + /* ======================================================================== + * Timer driver initialization + * ======================================================================== + * Register timer devices for each enabled timer. + * Timer number mapping (see n32_tim_lowerhalf.c): + * 1..4 = ATIM1-4 + * 3..11 = GTIMA1-7 (3=GTIMA1, 4=GTIMA2, ..., 11=GTIMA7) + * 12..14= GTIMB1-3 + * 15..18= BTIM1-4 + * ======================================================================== + */ + +#ifdef CONFIG_TIMER + + mkdir("/dev/timer", 0666); + +#ifdef CONFIG_N32H7_BTIM1 + /* Register BTIM1 as /dev/timer0 (timer number 15) */ + + ret = n32_timer_initialize("/dev/timer/0", 15); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/timer0: %d\n", ret); + } +#endif + +#ifdef CONFIG_N32H7_BTIM2 + ret = n32_timer_initialize("/dev/timer/1", 16); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/timer/1: %d\n", ret); + } +#endif + +#ifdef CONFIG_N32H7_BTIM3 + ret = n32_timer_initialize("/dev/timer/2", 17); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/timer/2: %d\n", ret); + } +#endif + +#ifdef CONFIG_N32H7_BTIM4 + ret = n32_timer_initialize("/dev/timer/3", 18); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/timer/3: %d\n", ret); + } +#endif + +#ifdef CONFIG_N32H7_GTIMA1 + ret = n32_timer_initialize("/dev/timer/4", 3); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/timer/4: %d\n", ret); + } +#endif + +#endif /* CONFIG_TIMER */ + + /* ======================================================================== + * Oneshot driver initialization + * ======================================================================== + * Register oneshot devices as /dev/oneshotX using NuttX oneshot_register() + * + * oneshot_initialize() returns a struct oneshot_lowerhalf_s * + * oneshot_register() registers it as a device node. + * ======================================================================== + */ + +#ifdef CONFIG_N32H7_ONESHOT + + mkdir("/dev/oneshot", 0666); + +# ifdef CONFIG_N32H7_GTIMA1 + struct oneshot_lowerhalf_s *oneshot; + int chan; + + /* Use GTIMA1 (timer 3) with channel 1, 20us resolution */ + + chan = (3 << 4) | 1; /* timer=3, channel=1 */ + oneshot = oneshot_initialize(chan, 20); + if (oneshot == NULL) + { + syslog(LOG_ERR, "ERROR: Failed to initialize oneshot (GTIMA1)\n"); + } + else + { + ret = oneshot_register("/dev/oneshot/0", oneshot); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/oneshot/1/0: %d\n", + ret); + } + } + + /* Use GTIMA1 (timer 3) with channel 2, 20us resolution */ + + chan = (3 << 4) | 2; /* timer=3, channel=2 */ + oneshot = oneshot_initialize(chan, 20); + if (oneshot == NULL) + { + syslog(LOG_ERR, "ERROR: Failed to initialize oneshot (GTIMA1)\n"); + } + else + { + ret = oneshot_register("/dev/oneshot/1", oneshot); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/oneshot/1: %d\n", + ret); + } + } + + /* Use GTIMA1 (timer 3) with channel 3, 20us resolution */ + + chan = (3 << 4) | 3; /* timer=3, channel=3 */ + oneshot = oneshot_initialize(chan, 20); + if (oneshot == NULL) + { + syslog(LOG_ERR, "ERROR: Failed to initialize oneshot (GTIMA1)\n"); + } + else + { + ret = oneshot_register("/dev/oneshot/2", oneshot); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/oneshot/2: %d\n", + ret); + } + } + + /* Use GTIMA1 (timer 3) with channel 4, 20us resolution */ + + chan = (3 << 4) | 4; /* timer=3, channel=4 */ + oneshot = oneshot_initialize(chan, 20); + if (oneshot == NULL) + { + syslog(LOG_ERR, "ERROR: Failed to initialize oneshot (GTIMA1)\n"); + } + else + { + ret = oneshot_register("/dev/oneshot/3", oneshot); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/oneshot/3: %d\n", + ret); + } + } +# endif /* CONFIG_N32H7_GTIMA1 */ + +#endif /* CONFIG_N32H7_ONESHOT */ + +#ifdef CONFIG_MMCSD + /* Initialize the MMC/SD driver */ + + ret = n32_sdmmc_initialize(CONFIG_NSH_MMCSDMINOR); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to initialize SD slot %d: %d\n", + CONFIG_NSH_MMCSDMINOR, ret); + } +#endif + +#ifdef CONFIG_PWM + /* Initialize PWM and register the PWM device. */ + + ret = n32_pwm_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: n32_pwm_setup() failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_CAPTURE +# ifdef CONFIG_N32H7_GTIMA2_CAP + struct cap_lowerhalf_s *cap = n32_cap_initialize(4); + + if (cap == NULL) + { + syslog(LOG_ERR, "ERROR: Failed to initialize capture (GTIMA2)\n"); + } + else + { + ret = cap_register("/dev/capture0", cap); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register /dev/capture0: %d\n", + ret); + } + } +# endif /* CONFIG_N32H7_GTIMA2_CAP */ +#endif /* CONFIG_CAPTURE */ + +#ifdef CONFIG_MTD +#ifdef HAVE_PROGMEM_CHARDEV + ret = n32_progmem_init(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to initialize MTD progmem: %d\n", + ret); + } +#endif /* HAVE_PROGMEM_CHARDEV */ +#endif /* CONFIG_MTD */ + + return OK; +} diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_buttons.c b/boards/arm/n32h7/n32h762iil7/src/n32_buttons.c new file mode 100644 index 0000000000000..f7864b6f1a2ce --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_buttons.c @@ -0,0 +1,150 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_buttons.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "n32_gpio.h" +#include "n32h762iil7.h" +#include + +#ifdef CONFIG_ARCH_BUTTONS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +static const uint32_t g_btncfg[NUM_BUTTONS] = +{ + GPIO_BTN_WKUP, + GPIO_BTN_KEY1, + GPIO_BTN_KEY2, + GPIO_BTN_KEY3, +}; + +static const bool g_btnactive[NUM_BUTTONS] = +{ + true, + false, + false, + false, +}; + +/**************************************************************************** + * Name: board_button_initialize + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + ****************************************************************************/ + +uint32_t board_button_initialize(void) +{ + int i; + + /* Configure button GPIOs for input */ + + for (i = 0; i < nitems(g_btncfg); i++) + { + n32_configgpio(g_btncfg[i]); + } + + return NUM_BUTTONS; +} + +/**************************************************************************** + * Name: board_buttons + ****************************************************************************/ + +uint32_t board_buttons(void) +{ + uint32_t ret = 0; + int i; + + for (i = 0; i < nitems(g_btncfg); i++) + { + ret |= ((n32_gpioread(g_btncfg[i]) == g_btnactive[i] ? 1 : 0) ? + (1 << i) : 0); + } + + return ret; +} + +/**************************************************************************** + * Button support. + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + * After board_button_initialize() has been called, board_buttons() may be + * called to collect the state of all buttons. board_buttons() returns a + * 32-bit bit set with each bit associated with a button. See the + * BUTTON_*_BIT definitions in board.h for the meaning of each bit. + * + * board_button_irq() may be called to register an interrupt handler that + * will be called when a button is depressed or released. The ID value is + * a button enumeration value that uniquely identifies a button resource. + * See the BUTTON_* definitions in board.h for the meaning of enumeration + * value. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQBUTTONS +int board_button_irq(int id, xcpt_t irqhandler, void *arg) +{ + int ret = -EINVAL; + + if (id >= 0 && id < nitems(g_btncfg)) + { + if (irqhandler != NULL) + { + ret = n32_gpiosetevent(g_btncfg[id], true, true, true, + irqhandler, arg); + } + else + { + ret = n32_gpiosetevent(g_btncfg[id], false, false, false, + irqhandler, arg); + } + } + + return ret; +} +#endif +#endif /* CONFIG_ARCH_BUTTONS */ diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_composite.c b/boards/arm/n32h7/n32h762iil7/src/n32_composite.c new file mode 100644 index 0000000000000..5dc09eb400d32 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_composite.c @@ -0,0 +1,349 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_composite.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define COMPOSITE0_DEV (3) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_USBMSC_COMPOSITE +static void *g_mschandle; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_mscclassobject + * + * Description: + * If the mass storage class driver is part of composite device, then + * its instantiation and configuration is a multi-step, board-specific, + * process (See comments for usbmsc_configure below). In this case, + * board-specific logic must provide board_mscclassobject(). + * + * board_mscclassobject() is called from the composite driver. It must + * encapsulate the instantiation and configuration of the mass storage + * class and the return the mass storage device's class driver instance + * to the composite driver. + * + * Input Parameters: + * classdev - The location to return the mass storage class' device + * instance. + * + * Returned Value: + * 0 on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_USBMSC_COMPOSITE +static int board_mscclassobject(int minor, + struct usbdev_devinfo_s *devinfo, + struct usbdevclass_driver_s **classdev) +{ + int ret; + + DEBUGASSERT(g_mschandle == NULL); + + /* Configure the mass storage device */ + + uinfo("Configuring with NLUNS=1\n"); + ret = usbmsc_configure(1, &g_mschandle); + if (ret < 0) + { + uerr("ERROR: usbmsc_configure failed: %d\n", -ret); + return ret; + } + + uinfo("MSC handle=%p\n", g_mschandle); + + /* Bind the LUN(s) */ + + uinfo("Bind LUN=0 to /dev/mmcsd0\n"); + ret = usbmsc_bindlun(g_mschandle, "/dev/mmcsd0", 0, 0, 0, false); + if (ret < 0) + { + uerr("ERROR: usbmsc_bindlun failed for LUN 1 at /dev/mmcsd0: %d\n", + ret); + usbmsc_uninitialize(g_mschandle); + g_mschandle = NULL; + return ret; + } + + /* Get the mass storage device's class object */ + + ret = usbmsc_classobject(g_mschandle, devinfo, classdev); + if (ret < 0) + { + uerr("ERROR: usbmsc_classobject failed: %d\n", -ret); + usbmsc_uninitialize(g_mschandle); + g_mschandle = NULL; + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: board_mscuninitialize + * + * Description: + * Un-initialize the USB storage class driver. + * This is just an application specific wrapper for usbmsc_unitialize() + * that is called form the composite device logic. + * + * Input Parameters: + * classdev - The class driver instance previously given to the composite + * driver by board_mscclassobject(). + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_USBMSC_COMPOSITE +static void board_mscuninitialize(struct usbdevclass_driver_s *classdev) +{ + if (g_mschandle) + { + usbmsc_uninitialize(g_mschandle); + } + + g_mschandle = NULL; +} +#endif + +/**************************************************************************** + * Name: board_composite_connect + * + * Description: + * Connect the USB composite device on the specified USB device port for + * configuration 0. + * + * Input Parameters: + * port - The USB device port. + * + * Returned Value: + * A non-NULL handle value is returned on success. NULL is returned on + * any failure. + * + ****************************************************************************/ + +static void *board_composite0_connect(int port) +{ + struct composite_devdesc_s dev[COMPOSITE0_DEV]; + int ifnobase = 0; + int strbase = COMPOSITE_NSTRIDS; + int dev_idx = 0; + int epin = 1; + int epout = 1; + +#ifdef CONFIG_RNDIS_COMPOSITE + /* Configure the RNDIS USB device */ + + /* Ask the rndis driver to fill in the constants we didn't + * know here. + */ + + usbdev_rndis_get_composite_devdesc(&dev[dev_idx]); + + /* Interfaces */ + + dev[dev_idx].devinfo.ifnobase = ifnobase; + dev[dev_idx].minor = 0; + + /* Strings */ + + dev[dev_idx].devinfo.strbase = strbase; + + /* Endpoints */ + + dev[dev_idx].devinfo.epno[RNDIS_EP_INTIN_IDX] = epin++; + dev[dev_idx].devinfo.epno[RNDIS_EP_BULKIN_IDX] = epin++; + dev[dev_idx].devinfo.epno[RNDIS_EP_BULKOUT_IDX] = epout++; + + /* Count up the base numbers */ + + ifnobase += dev[dev_idx].devinfo.ninterfaces; + strbase += dev[dev_idx].devinfo.nstrings; + + dev_idx += 1; +#endif + +#ifdef CONFIG_CDCACM_COMPOSITE + /* Configure the CDC/ACM device */ + + /* Ask the cdcacm driver to fill in the constants we didn't + * know here. + */ + + cdcacm_get_composite_devdesc(&dev[dev_idx]); + + /* Overwrite and correct some values... */ + + /* The callback functions for the CDC/ACM class */ + + dev[dev_idx].classobject = cdcacm_classobject; + dev[dev_idx].uninitialize = cdcacm_uninitialize; + + /* Interfaces */ + + dev[dev_idx].devinfo.ifnobase = ifnobase; /* Offset to Interface-IDs */ + dev[dev_idx].minor = 0; /* The minor interface number */ + + /* Strings */ + + dev[dev_idx].devinfo.strbase = strbase; /* Offset to String Numbers */ + + /* Endpoints */ + + dev[dev_idx].devinfo.epno[CDCACM_EP_INTIN_IDX] = epin++; + dev[dev_idx].devinfo.epno[CDCACM_EP_BULKIN_IDX] = epin++; + dev[dev_idx].devinfo.epno[CDCACM_EP_BULKOUT_IDX] = epout++; + + /* Count up the base numbers */ + + ifnobase += dev[dev_idx].devinfo.ninterfaces; + strbase += dev[dev_idx].devinfo.nstrings; + + dev_idx += 1; +#endif + +#ifdef CONFIG_USBMSC_COMPOSITE + /* Configure the mass storage device device */ + + /* Ask the usbmsc driver to fill in the constants we didn't + * know here. + */ + + usbmsc_get_composite_devdesc(&dev[dev_idx]); + + /* Overwrite and correct some values... */ + + /* The callback functions for the USBMSC class */ + + dev[dev_idx].classobject = board_mscclassobject; + dev[dev_idx].uninitialize = board_mscuninitialize; + + /* Interfaces */ + + dev[dev_idx].devinfo.ifnobase = ifnobase; /* Offset to Interface-IDs */ + dev[dev_idx].minor = 0; /* The minor interface number */ + + /* Strings */ + + dev[dev_idx].devinfo.strbase = strbase; /* Offset to String Numbers */ + + /* Endpoints */ + + dev[dev_idx].devinfo.epno[USBMSC_EP_BULKIN_IDX] = epin++; + dev[dev_idx].devinfo.epno[USBMSC_EP_BULKOUT_IDX] = epout++; + + /* Count up the base numbers */ + + ifnobase += dev[dev_idx].devinfo.ninterfaces; + strbase += dev[dev_idx].devinfo.nstrings; + + dev_idx += 1; +#endif + + /* Sanity checks */ + + DEBUGASSERT(epin < N32_USBHS_NENDPOINTS); + DEBUGASSERT(epout < N32_USBHS_NENDPOINTS); + + return composite_initialize(composite_getdevdescs(), dev, dev_idx); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_composite_initialize + * + * Description: + * Perform architecture specific initialization of a composite USB device. + * + ****************************************************************************/ + +int board_composite_initialize(int port) +{ + return OK; +} + +/**************************************************************************** + * Name: board_composite_connect + * + * Description: + * Connect the USB composite device on the specified USB device port using + * the specified configuration. The interpretation of the configid is + * board specific. + * + * Input Parameters: + * port - The USB device port. + * configid - The USB composite configuration + * + * Returned Value: + * A non-NULL handle value is returned on success. NULL is returned on + * any failure. + * + ****************************************************************************/ + +void *board_composite_connect(int port, int configid) +{ + if (configid == 0) + { + return board_composite0_connect(port); + } + else + { + return NULL; + } +} diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_cordic.c b/boards/arm/n32h7/n32h762iil7/src/n32_cordic.c new file mode 100644 index 0000000000000..91a923ef4a23d --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_cordic.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_cordic.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "n32_cordic.h" + +#include "n32h762iil7.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_cordic_setup + * + * Description: + * Initialize CORDIC and register the CORDIC device. + * + ****************************************************************************/ + +int n32_cordic_setup(void) +{ + struct cordic_lowerhalf_s *cordic = NULL; + static bool initialized = false; + int ret = OK; + + /* Have we already initialized? */ + + if (!initialized) + { + /* Call n32_cordicinitialize() to get an instance of the CORDIC + * interface + */ + + cordic = n32_cordicinitialize(); + if (!cordic) + { + tmrerr("Failed to get the N32 CORDIC lower half\n"); + ret = -ENODEV; + goto errout; + } + + /* Register the CORDIC driver at "/dev/cordic0" */ + + ret = cordic_register("/dev/cordic0", cordic); + if (ret < 0) + { + tmrerr("cordic_register failed: %d\n", ret); + goto errout; + } + + /* Now we are initialized */ + + initialized = true; + } + +errout: + return ret; +} diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_progmem.c b/boards/arm/n32h7/n32h762iil7/src/n32_progmem.c new file mode 100644 index 0000000000000..930c180e229e5 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_progmem.c @@ -0,0 +1,109 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_progmem.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "n32_flash.h" +#include "n32h762iil7.h" +#include + +#ifdef HAVE_PROGMEM_CHARDEV + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct mtd_dev_s *g_progmem_mtd; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_progmem_init + * + * Initialize Progmem partition. Read partition information, and use + * these data for creating MTD. + * + * Input Parameters: + * None + * + * Returned Value: + * 0 if success or a negative value if fail. + * + ****************************************************************************/ + +int n32_progmem_init(void) +{ + int ret = 0; + + g_progmem_mtd = progmem_initialize(); + if (g_progmem_mtd == NULL) + { + ferr("ERROR: Failed to get progmem flash MTD\n"); + ret = -EIO; + } + else + { + ret = register_mtddriver("/dev/mtd0", g_progmem_mtd, 0775, NULL); + if (ret < 0) + { + ferr("ERROR: Failed to register progmem flash MTD driver\n"); + } + } + +#ifdef CONFIG_FS_LITTLEFS + /* Mount the LittleFS file system */ + + ret = nx_mount("/dev/mtd0", "/flash", "littlefs", 0, "autoformat"); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to mount LittleFS at /flash: %d\n", ret); + return ret; + } +#endif /* CONFIG_FS_LITTLEFS */ + + return ret; +} + +#endif /* HAVE_PROGMEM_CHARDEV */ diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_pwm.c b/boards/arm/n32h7/n32h762iil7/src/n32_pwm.c new file mode 100644 index 0000000000000..3e48306b6e593 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_pwm.c @@ -0,0 +1,131 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_pwm.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "chip.h" +#include "arm_internal.h" +#include "n32_pwm.h" +#include "n32h762iil7.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#define HAVE_PWM 1 + +#ifndef CONFIG_PWM +# undef HAVE_PWM +#endif + +#ifndef CONFIG_N32H7_ATIM1 +# undef HAVE_PWM +#endif + +#ifndef CONFIG_N32H7_ATIM1_PWM +# undef HAVE_PWM +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ****************************************************************************/ + +int n32_pwm_setup(void) +{ +#ifdef HAVE_PWM + static bool initialized = false; + struct pwm_lowerhalf_s *pwm; + int ret; + + /* Have we already initialized? */ + + if (!initialized) + { + mkdir("/dev/pwm", 0666); + + /* Get an instance of the PWM interface */ + + pwm = n32_pwminitialize(N32H762IIL7_PWM0TIMER); + if (!pwm) + { + tmrerr("ERROR: Failed to get the N32H7 PWM lower half\n"); + return -ENODEV; + } + + /* Register the PWM driver at "/dev/pwm/0" */ + + ret = pwm_register("/dev/pwm/0", pwm); + if (ret < 0) + { + tmrerr("ERROR: pwm_register failed: %d\n", ret); + return ret; + } + + /* Get an instance of the PWM interface */ + + pwm = n32_pwminitialize(N32H762IIL7_PWM1TIMER); + if (!pwm) + { + tmrerr("ERROR: Failed to get the N32H7 PWM lower half\n"); + return -ENODEV; + } + + /* Register the PWM driver at "/dev/pwm/1" */ + + ret = pwm_register("/dev/pwm/1", pwm); + if (ret < 0) + { + tmrerr("ERROR: pwm_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +#else + return -ENODEV; +#endif +} diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_reset.c b/boards/arm/n32h7/n32h762iil7/src/n32_reset.c new file mode 100644 index 0000000000000..970ca69ab43ba --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_reset.c @@ -0,0 +1,136 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_reset.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "n32_systemreset.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_reset_cause + * + * Description: + * Get the cause of last board reset. This should call architecture + * specific logic to handle the register read. + * + * Input Parameters: + * cause - Pointer to boardioc_reset_cause_s structure to which the + * reason (and potentially subreason) is saved. + * + * Returned Value: + * This functions should always return successfully with 0. We save + * BOARDIOC_RESETCAUSE_UNKOWN in cause structure if we are + * not able to get last reset cause from HW (which is unlikely). + * + ****************************************************************************/ + +#ifdef CONFIG_BOARDCTL_RESET_CAUSE +int board_reset_cause(struct boardioc_reset_cause_s *cause) +{ + int rst_cause; + + /* Get the reset cause from hardware */ + + rst_cause = n32_get_reset_cause(); + + switch (rst_cause) + { + case N32H7_RESET_PWRUP: + + /* Power up */ + + cause->cause = BOARDIOC_RESETCAUSE_SYS_CHIPPOR; + break; + case N32H7_RESET_BOR: + + /* Brown-out reset (BOR) error */ + + cause->cause = BOARDIOC_RESETCAUSE_SYS_BOR; + break; + case N32H7_RESET_WDOG: + + /* Watchdog error */ + + cause->cause = BOARDIOC_RESETCAUSE_CPU_MWDT; + break; + case N32H7_RESET_SWRST: + + /* SW reset */ + + cause->cause = BOARDIOC_RESETCAUSE_CPU_SOFT; + break; + case N32H7_RESET_NRST: + + /* Reset from user by pressing reset button */ + + cause->cause = BOARDIOC_RESETCAUSE_PIN; + break; + default: + + /* Unknown cause returned from HW */ + + cause->cause = BOARDIOC_RESETCAUSE_UNKOWN; + break; + } + + return 0; +} +#endif /* CONFIG_BOARDCTL_RESET_CAUSE */ + +/**************************************************************************** + * Name: board_reset + * + * Description: + * Reset board. Support for this function is required by board-level + * logic if CONFIG_BOARDCTL_RESET is selected. + * + * Input Parameters: + * status - Status information provided with the reset event. This + * meaning of this status information is board-specific. If not + * used by a board, the value zero may be provided in calls to + * board_reset(). + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ +#ifdef CONFIG_BOARDCTL_RESET + +int board_reset(int status) +{ + up_systemreset(); + return 0; +} + +#endif /* CONFIG_BOARDCTL_RESET */ diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_sdmmc.c b/boards/arm/n32h7/n32h762iil7/src/n32_sdmmc.c new file mode 100644 index 0000000000000..b378d0d1ed138 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_sdmmc.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_sdmmc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "n32_gpio.h" +#include "n32_sdmmc.h" +#include "n32h762iil7.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Card detections requires card support and a card detection GPIO */ + +#define HAVE_NCD 1 +#if !defined(HAVE_SDIO) || !defined(GPIO_SDIO_NCD) +# undef HAVE_NCD +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct sdio_dev_s *g_sdio_dev; +#ifdef HAVE_NCD +static bool g_sd_inserted; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_ncd_interrupt + * + * Description: + * Card detect interrupt handler. + * + ****************************************************************************/ + +#ifdef HAVE_NCD +static int n32_ncd_interrupt(int irq, void *context, void *param) +{ + bool present; + + present = !n32_gpioread(GPIO_SDIO_NCD); + if (present != g_sd_inserted) + { + sdio_mediachange(g_sdio_dev, present); + g_sd_inserted = present; + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_sdmmc_initialize + * + * Description: + * Initialize SDMMC-based MMC/SD card support + * + ****************************************************************************/ + +int n32_sdmmc_initialize(int minor) +{ + int ret; + +#ifdef HAVE_NCD + /* Configure the card detect GPIO */ + + n32_configgpio(GPIO_SDIO_NCD); + + /* Register an interrupt handler for the card detect pin */ + + n32_gpiosetevent(GPIO_SDIO_NCD, true, true, true, + n32_ncd_interrupt, NULL); +#endif + + /* Mount the SDIO-based MMC/SD block driver */ + + /* First, get an instance of the SDIO interface */ + + finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO); + + g_sdio_dev = sdio_initialize(SDIO_SLOTNO); + if (!g_sdio_dev) + { + ferr("ERROR: Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", minor); + + ret = mmcsd_slotinitialize(minor, g_sdio_dev); + if (ret != OK) + { + ferr("ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + finfo("Successfully bound SDIO to the MMC/SD driver\n"); + +#ifdef HAVE_NCD + /* Use SD card detect pin to check if a card is g_sd_inserted */ + + g_sd_inserted = !n32_gpioread(GPIO_SDIO_NCD); + finfo("Card detect : %d\n", g_sd_inserted); + + sdio_mediachange(g_sdio_dev, g_sd_inserted); +#else + /* Assume that the SD card is inserted. What choice do we have? */ + + sdio_mediachange(g_sdio_dev, true); +#endif + + return OK; +} diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_uid.c b/boards/arm/n32h7/n32h762iil7/src/n32_uid.c new file mode 100644 index 0000000000000..f53b65e0e9859 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_uid.c @@ -0,0 +1,69 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_uid.c + * + * SPDX-License-Identifier: BSD-3-Clause + * SPDX-FileCopyrightText: 2015 Marawan Ragab. All rights reserved. + * SPDX-FileContributor: Marawan Ragab + * SPDX-FileContributor: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include "n32_uid.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#if defined(CONFIG_BOARDCTL_UNIQUEID) +int board_uniqueid(uint8_t *uniqueid) +{ + if (uniqueid == NULL) + { + return -EINVAL; + } + + n32_get_uniqueid(uniqueid); + return OK; +} +#endif diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_usb.c b/boards/arm/n32h7/n32h762iil7/src/n32_usb.c new file mode 100644 index 0000000000000..5d77c55070222 --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_usb.c @@ -0,0 +1,305 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_usb.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "arm_internal.h" +#include "chip.h" +#include "n32_gpio.h" +#include "n32h762iil7.h" + +#ifdef CONFIG_N32H7_USBHS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_USBDEV) || defined(CONFIG_USBHOST) +# define HAVE_USB 1 +#else +# warning "CONFIG_N32H7_USBHS is enabled but neither CONFIG_USBDEV nor CONFIG_USBHOST" +# undef HAVE_USB +#endif + +#ifndef CONFIG_N32H762IIL7_USBHOST_PRIO +# define CONFIG_N32H762IIL7_USBHOST_PRIO 100 +#endif + +#ifndef CONFIG_N32H762IIL7_USBHOST_STACKSIZE +# define CONFIG_N32H762IIL7_USBHOST_STACKSIZE 2048 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +static struct usbhost_connection_s *g_usbconn; +extern struct usbhost_connection_s *n32_usbhshost_initialize(int controller); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usbhost_waiter + * + * Description: + * Wait for USB devices to be connected. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +static int usbhost_waiter(int argc, char *argv[]) +{ + struct usbhost_hubport_s *hport; + + uinfo("Running\n"); + for (; ; ) + { + /* Wait for the device to change state */ + + DEBUGVERIFY(CONN_WAIT(g_usbconn, &hport)); + uinfo("%s\n", hport->connected ? "connected" : "disconnected"); + + /* Did we just become connected? */ + + if (hport->connected) + { + /* Yes.. enumerate the newly connected device */ + + CONN_ENUMERATE(g_usbconn, hport); + } + } + + /* Keep the compiler from complaining */ + + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_usbinitialize + * + * Description: + * Called from n32_usbinitialize very early in initialization to setup + * USB-related GPIO pins for the n32h762iil7 board. + * + ****************************************************************************/ + +void n32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up. + * No GPIO configuration is required + */ + + /* Configure the OTG FS Power On GPIOs + */ + +#ifdef CONFIG_N32H7_USBHS +# ifdef CONFIG_USBHOST +# if defined(CONFIG_N32H7_USBHS1_HOST) +# define GPIO_USBHS_PWRON GPIO_USBHS1_PWRON + n32_configgpio(GPIO_USBHS1_PWRON); +# endif +# if defined(CONFIG_N32H7_USBHS2_HOST) +# define GPIO_USBHS_PWRON GPIO_USBHS2_PWRON + n32_configgpio(GPIO_USBHS2_PWRON); +# endif +# endif +#endif +} + +/**************************************************************************** + * Name: n32_usbhost_initialize + * + * Description: + * Called at application startup time to initialize the USB host + * functionality. + * This function will start a thread that will monitor for device + * connection/disconnection events. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +int n32_usbhost_initialize(void) +{ + int ret; + + /* First, register all of the class drivers needed to support the drivers + * that we care about: + */ + + uinfo("Register class drivers\n"); + +#ifdef CONFIG_USBHOST_HUB + /* Initialize USB hub class support */ + + ret = usbhost_hub_initialize(); + if (ret < 0) + { + uerr("ERROR: usbhost_hub_initialize failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_MSC + /* Register the USB mass storage class class */ + + ret = usbhost_msc_initialize(); + if (ret != OK) + { + uerr("ERROR: Failed to register the mass storage class: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_CDCACM + /* Register the CDC/ACM serial class */ + + ret = usbhost_cdcacm_initialize(); + if (ret != OK) + { + uerr("ERROR: Failed to register the CDC/ACM serial class: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_HIDKBD + /* Initialize the HID keyboard class */ + + ret = usbhost_kbdinit(); + if (ret != OK) + { + uerr("ERROR: Failed to register the HID keyboard class\n"); + } +#endif + +#ifdef CONFIG_USBHOST_HIDMOUSE + /* Initialize the HID mouse class */ + + ret = usbhost_mouse_init(); + if (ret != OK) + { + uerr("ERROR: Failed to register the HID mouse class\n"); + } +#endif + + /* Then get an instance of the USB host interface */ + + uinfo("Initialize USB host\n"); + g_usbconn = n32_usbhshost_initialize(0); + if (g_usbconn) + { + /* Start a thread to handle device connection. */ + + uinfo("Start usbhost_waiter\n"); + + ret = kthread_create("usbhost", CONFIG_N32H762IIL7_USBHOST_PRIO, + CONFIG_N32H762IIL7_USBHOST_STACKSIZE, + usbhost_waiter, NULL); + return ret < 0 ? -ENOEXEC : OK; + } + + return -ENODEV; +} +#endif + +/**************************************************************************** + * Name: n32_usbhs_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be + * provided be each platform that implements the N32H7 USBHS host + * interface + * + * "On-chip 5 V VBUS generation is not supported. For this reason, a + * charge pump or, if 5 V are available on the application board, a + * basic power switch, must be added externally to drive the 5 V VBUS + * line. The external charge pump can be driven by any GPIO output. + * When the application decides to power on VBUS using the chosen GPIO, + * it must also set the port power bit in the host port control and status + * register (PPWR bit in OTG_FS_HPRT). + * + * "The application uses this field to control power to this port, and + * the core clears this bit on an overcurrent condition." + * + * Input Parameters: + * iface - For future growth to handle multiple USB host interface. + * Should be zero. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +void n32_usbhs_vbusdrive(int iface, bool enable) +{ + DEBUGASSERT(iface == 0); + + /* Set the Power Switch by driving the active high enable pin */ + + n32_gpiowrite(GPIO_USBHS_PWRON, enable); +} +#endif + +/**************************************************************************** + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV + * driver is used. This function is called whenever the USB enters or + * leaves suspend mode. This is an opportunity for the board logic to + * shutdown clocks, power, etc. while the USB is suspended. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV +void n32_usbsuspend(struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} +#endif + +#endif /* CONFIG_STM32_OTGFS */ diff --git a/boards/arm/n32h7/n32h762iil7/src/n32_userleds.c b/boards/arm/n32h7/n32h762iil7/src/n32_userleds.c new file mode 100644 index 0000000000000..a96576a84203a --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32_userleds.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32_userleds.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include +#include + +#include "n32_gpio.h" +#include "n32h762iil7.h" + +#ifndef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array maps an LED number to GPIO pin configuration and is indexed by + * BOARD_LED_ + */ + +static const uint32_t g_ledcfg[BOARD_NLEDS] = +{ + GPIO_LED_BLUE, + GPIO_LED_GREEN, + GPIO_LED_RED, +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_userled_initialize + * + * Description: + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then the + * board_userled_initialize() is available to initialize the LED from user + * application logic. + * + ****************************************************************************/ + +uint32_t board_userled_initialize(void) +{ + int i; + + /* Configure LED1-3 GPIOs for output */ + + for (i = 0; i < nitems(g_ledcfg); i++) + { + n32_configgpio(GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SLEW_RATE_SLOW | + g_ledcfg[i]); + } + + return BOARD_NLEDS; +} + +/**************************************************************************** + * Name: board_userled + * + * Description: + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then the board_userled() is + * available to control the LED from user application logic. + * + ****************************************************************************/ + +void board_userled(int led, bool ledon) +{ + if ((unsigned)led < nitems(g_ledcfg)) + { + n32_gpiowrite(g_ledcfg[led], ledon); + } +} + +/**************************************************************************** + * Name: board_userled_all + * + * Description: + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then the board_userled_all() + * is available to control the LED from user application logic. NOTE: since + * there is only a single LED on-board, this is function is not very useful. + * + ****************************************************************************/ + +void board_userled_all(uint32_t ledset) +{ + int i; + + /* Configure LED1-3 GPIOs for output */ + + for (i = 0; i < nitems(g_ledcfg); i++) + { + n32_gpiowrite(g_ledcfg[i], (ledset & (1 << i)) != 0); + } +} + +/**************************************************************************** + * Name: board_userled_getall + * + * Description: + * This interface may be used by application specific logic to read the + * state of all board LEDs. Definitions for the led set member + * identification is provided in the board-specific board.h header file + * that may be included like: + * + * #included + * + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then this interfaces may be + * available to check the LEDs directly from user board logic or indirectly + * user applications (via the common LED character driver). + * + ****************************************************************************/ + +#if defined(CONFIG_USERLED_LOWER_READSTATE) +void board_userled_getall(uint32_t *ledset) +{ + int i; + + *ledset = 0; + for (i = 0; i < nitems(g_ledcfg); i++) + { + *ledset |= (n32_gpioread(g_ledcfg[i]) << i); + } +} +#endif + +#endif /* !CONFIG_ARCH_LEDS */ diff --git a/boards/arm/n32h7/n32h762iil7/src/n32h762iil7.h b/boards/arm/n32h7/n32h762iil7/src/n32h762iil7.h new file mode 100644 index 0000000000000..67341a93d1c3e --- /dev/null +++ b/boards/arm/n32h7/n32h762iil7/src/n32h762iil7.h @@ -0,0 +1,306 @@ +/**************************************************************************** + * boards/arm/n32h7/n32h762iil7/src/n32h762iil7.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_N32H7_N32H762IIL7_SRC_N32H762IIL7_H +#define __BOARDS_ARM_N32H7_N32H762IIL7_SRC_N32H762IIL7_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#define HAVE_PROC 1 +#define HAVE_SDIO 1 +#define HAVE_USBDEV 1 +#define HAVE_USBHOST 1 +#define HAVE_USBMONITOR 1 +#define HAVE_MTDCONFIG 1 +#define HAVE_PROGMEM_CHARDEV 1 + +/* Can't support USB host or device features if USB OTG FS is not enabled */ + +#ifndef CONFIG_N32H7_USBHS +# undef HAVE_USBDEV +# undef HAVE_USBHOST +#endif + +/* Can't support USB device if USB device is not enabled */ + +#ifndef CONFIG_USBDEV +# undef HAVE_USBDEV +#endif + +/* Can't support USB host is USB host is not enabled */ + +#ifndef CONFIG_USBHOST +# undef HAVE_USBHOST +#endif + +/* Check if we should enable the USB monitor before starting NSH */ + +#ifndef CONFIG_USBMONITOR +# undef HAVE_USBMONITOR +#endif + +#ifndef HAVE_USBDEV +# undef CONFIG_USBDEV_TRACE +#endif + +#ifndef HAVE_USBHOST +# undef CONFIG_USBHOST_TRACE +#endif + +#if !defined(CONFIG_USBDEV_TRACE) && !defined(CONFIG_USBHOST_TRACE) +# undef HAVE_USBMONITOR +#endif + +#if !defined(CONFIG_N32H7_PROGMEM) || !defined(CONFIG_MTD_PROGMEM) +# undef HAVE_PROGMEM_CHARDEV +#endif + +/* This is the on-chip progmem memory driver minor number */ + +#define PROGMEM_MTD_MINOR 0 + +/* Can't support MMC/SD features if mountpoints are disabled or if SDIO + * support is not enabled. + */ + +#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_N32H7_SDMMC) +# undef HAVE_SDIO +#endif + +#define SDIO_SLOTNO 0 /* Only one slot */ + +#ifdef HAVE_SDIO +# if !defined(CONFIG_NSH_MMCSDSLOTNO) +# define CONFIG_NSH_MMCSDSLOTNO SDIO_SLOTNO +# elif CONFIG_NSH_MMCSDSLOTNO != 0 +# warning "Only one MMC/SD slot, slot 0" +# undef CONFIG_NSH_MMCSDSLOTNO +# define CONFIG_NSH_MMCSDSLOTNO SDIO_SLOTNO +# endif +#endif + +/* procfs File System */ + +#ifdef CONFIG_FS_PROCFS +# ifdef CONFIG_NSH_PROC_MOUNTPOINT +# define N32_PROCFS_MOUNTPOINT CONFIG_NSH_PROC_MOUNTPOINT +# else +# define N32_PROCFS_MOUNTPOINT "/proc" +# endif +#endif + +/* Check if we can support the RTC driver */ + +#define HAVE_RTC_DRIVER 0 +#if !defined(CONFIG_RTC) || !defined(CONFIG_RTC_DRIVER) +# undef HAVE_RTC_DRIVER +#endif + +/* LED + * + * The N32H762IIL7 board has numerous LEDs but only three, LD1 a Green LED, + * LD2 a Blue LED and LD3 a Red LED, that can be controlled by software. The + * following definitions assume the default Solder Bridges are installed. + */ + +#define GPIO_LD1 (GPIO_PORTA | GPIO_PIN1) +#define GPIO_LD2 (GPIO_PORTA | GPIO_PIN2) +#define GPIO_LD3 (GPIO_PORTA | GPIO_PIN3) + +#define GPIO_LED_RED GPIO_LD1 +#define GPIO_LED_GREEN GPIO_LD2 +#define GPIO_LED_BLUE GPIO_LD3 + +#define LED_DRIVER_PATH "/dev/userleds" + +/* BUTTONS + * + * The Blue pushbutton B1, labeled "User", is connected to GPIO PC13. + * A high value will be sensed when the button is depressed. + * Note: + * 1) That the EXTI is included in the definition to enable an interrupt + * on this IO. + * 2) The following definitions assume the default Solder Bridges are + * installed. + */ + +#define GPIO_BTN_WKUP (GPIO_PORTA | GPIO_PIN0 | GPIO_INPUT | GPIO_FLOAT) +#define GPIO_BTN_KEY1 (GPIO_PORTC | GPIO_PIN0 | GPIO_INPUT | GPIO_PULLUP) +#define GPIO_BTN_KEY2 (GPIO_PORTC | GPIO_PIN1 | GPIO_INPUT | GPIO_PULLUP) +#define GPIO_BTN_KEY3 (GPIO_PORTC | GPIO_PIN4 | GPIO_INPUT | GPIO_PULLUP) + +#define BTN_DRIVER_PATH "/dev/buttons" + +/* PWM */ + +#define N32H762IIL7_PWM0TIMER 1 +#define N32H762IIL7_PWM1TIMER 12 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: n32_bringup + * + * Description: + * Perform architecture-specific initialization + * + * CONFIG_BOARD_LATE_INITIALIZE=y : + * Called from board_late_initialize(). + * + * CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_BOARDCTL=y && + * CONFIG_NSH_ARCHINIT: + * Called from the NSH library + * + ****************************************************************************/ + +int n32_bringup(void); + +/**************************************************************************** + * Name: n32_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the + * Nucleo-H743ZI board. + * + ****************************************************************************/ + +#ifdef CONFIG_N32H7_SPI +void n32_spidev_initialize(void); +#endif + +/**************************************************************************** + * Name: n32_adc_setup + * + * Description: + * Initialize ADC and register the ADC driver. + * + ****************************************************************************/ + +#ifdef CONFIG_ADC +int n32_adc_setup(void); +#endif + +/**************************************************************************** + * Name: n32_gpio_initialize + * + * Description: + * Initialize GPIO-Driver. + * + ****************************************************************************/ + +#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF) +int n32_gpio_initialize(void); +#endif + +/**************************************************************************** + * Name: n32_usbinitialize + * + * Description: + * Called from n32_usbinitialize very early in initialization to setup + * USB-related GPIO pins for the N32H762IIL7 board. + * + ****************************************************************************/ + +#ifdef CONFIG_N32H7_USBHS +void weak_function n32_usbinitialize(void); +#endif + +/**************************************************************************** + * Name: n32_usbhost_initialize + * + * Description: + * Called at application startup time to initialize the USB host + * functionality. This function will start a thread that will monitor for + * device connection/disconnection events. + * + ****************************************************************************/ + +#if (defined(CONFIG_N32H7_USBHS1_HOST) || defined(CONFIG_N32H7_USBHS2_HOST)) && defined(CONFIG_USBHOST) +int n32_usbhost_initialize(void); +#endif + +/**************************************************************************** + * Name: n32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ****************************************************************************/ + +#ifdef CONFIG_PWM +int n32_pwm_setup(void); +#endif + +/**************************************************************************** + * Name: n32_mtd_initialize + * + * Description: + * Initialize MTD drivers. + * + ****************************************************************************/ +#ifdef CONFIG_MTD + +#ifdef HAVE_PROGMEM_CHARDEV +int n32_progmem_init(void); +#endif /* HAVE_PROGMEM_CHARDEV */ +#endif + +/**************************************************************************** + * Name: n32_cordic_setup + * + * Description: + * Initialize CORDIC peripheral for the board. + * + ****************************************************************************/ + +#ifdef CONFIG_MATH_CORDIC +int n32_cordic_setup(void); +#endif + +/**************************************************************************** + * Name: n32_sdmmc_initialize + * + * Description: + * Initialize SDMMC-based MMC/SD card support + * + ****************************************************************************/ + +#ifdef CONFIG_MMCSD_SDIO +int n32_sdmmc_initialize(int minor); +#endif + +#endif /* __BOARDS_ARM_N32H7_N32H762IIL7_SRC_N32H762IIL7_H */ diff --git a/tools/generate_cmake_presets.py b/tools/generate_cmake_presets.py new file mode 100644 index 0000000000000..17cbfcc4f3917 --- /dev/null +++ b/tools/generate_cmake_presets.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +""" +generate_cmake_presets.py - Generate CMake User Presets for all NuttX boards/configs. +Run from NuttX root directory, or as a Git hook. +""" + +import json +import os +import subprocess +import sys + +# --- Locate NuttX root (parent of the tools/ directory) --- +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +NUTTX_ROOT = os.path.dirname(SCRIPT_DIR) # since script is under tools/ + +os.chdir(NUTTX_ROOT) + +GENERATED_PRESETS_FILE = "CMakeUserPresets.json" +USER_PRESETS_FILE = "" + +print(f"[generate_cmake_presets] NuttX root: {NUTTX_ROOT}") + +# --- Run ./tools/configure.sh -L to get all board configs --- +try: + output = subprocess.check_output( + ["./tools/configure.sh", "-L"], text=True, stderr=subprocess.DEVNULL + ) +except FileNotFoundError: + print("Error: ./tools/configure.sh not found. Are you in the NuttX root directory?") + sys.exit(1) +except subprocess.CalledProcessError as e: + print(f"Error running configure.sh: {e}") + sys.exit(1) + +configs = [] +for line in output.strip().splitlines(): + line = line.strip() + if line and ":" in line and not line.startswith("Board Configurations:"): + configs.append(line) + +if not configs: + print("Warning: No board configurations found.") + # Keep empty list + +presets = [] +for config in configs: + board, conf = config.split(":", 1) + preset_name = f"{board}_{conf}".replace("-", "_").replace(".", "_") + presets.append( + { + "name": preset_name, + "inherits": "default", + "cacheVariables": {"BOARD_CONFIG": config}, + } + ) + +with open(GENERATED_PRESETS_FILE, "w") as f: + json.dump({"version": 3, "configurePresets": presets}, f, indent=2) + +print(f"Generated {len(presets)} board presets in '{GENERATED_PRESETS_FILE}'")