diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0fc2fab9f90..b16dae7b3d3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -240,6 +240,19 @@ config ARCH_CHIP_STM32F7 ---help--- STMicro STM32 architectures (ARM Cortex-M7). +config ARCH_CHIP_STM32L4 + bool "STMicro STM32 L4" + select ARCH_HAVE_CMNVECTOR + select ARMV7M_CMNVECTOR + select ARCH_CORTEXM4 + select ARCH_HAVE_MPU + select ARM_HAVE_MPU_UNIFIED + select ARCH_HAVE_I2CRESET + select ARCH_HAVE_HEAPCHECK + select ARMV7M_HAVE_STACKCHECK + ---help--- + STMicro STM32 architectures (ARM Cortex-M4). + config ARCH_CHIP_STR71X bool "STMicro STR71x" select ARCH_ARM7TDMI @@ -407,6 +420,7 @@ config ARCH_CHIP default "samv7" if ARCH_CHIP_SAMV7 default "stm32" if ARCH_CHIP_STM32 default "stm32f7" if ARCH_CHIP_STM32F7 + default "stm32l4" if ARCH_CHIP_STM32L4 default "str71x" if ARCH_CHIP_STR71X default "tms570" if ARCH_CHIP_TMS570 default "moxart" if ARCH_CHIP_MOXART @@ -628,6 +642,9 @@ endif if ARCH_CHIP_STM32F7 source arch/arm/src/stm32f7/Kconfig endif +if ARCH_CHIP_STM32L4 +source arch/arm/src/stm32l4/Kconfig +endif if ARCH_CHIP_STR71X source arch/arm/src/str71x/Kconfig endif diff --git a/arch/arm/include/stm32l4/chip.h b/arch/arm/include/stm32l4/chip.h new file mode 100644 index 00000000000..7fa5bd94607 --- /dev/null +++ b/arch/arm/include/stm32l4/chip.h @@ -0,0 +1,154 @@ +/************************************************************************************ + * arch/arm/include/stm32l4/chip.h + * + * Copyright (C) 2015 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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_INCLUDE_STM32L4_CHIP_H +#define __ARCH_ARM_INCLUDE_STM32L4_CHIP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* STM32F476, STM32F486. Differences between family members: 486 has AES. + * + * ----------- ---------------- ----- ------ ------ ---- ---- ----- + * PART PACKAGE GPIOs LCD Tamper FSMC CapS AdcCh + * ----------- ---------------- ----- ------ ------ ---- ---- ----- + * STM32L4x6Jx WLCSP72L 57 8x28 2 No 12 16 + * STM32L476Mx WLCSP81L 65 ? ? ? ? ? + * STM32L4x6Qx UFBGA132L 109 8x40 3 Yes 24 16 + * STM32L4x6Rx LQFP64 51 8x28 2 No 12 16 + * STM32L4x6Vx LQFP100 82 8x40 3 Yes 21 16 + * STM32L4x6Zx LQFP144 114 8x40 3 Yes 24 24 + * ----------- ---------------- ----- ------ ------ ---- ---- ----- + * + * Parts STM32L4x6xC have 256Kb of FLASH + * Parts STM32L4x6xE have 512Kb of FLASH + * Parts STM32L4x6xG have 1024Kb of FLASH + * + * The correct FLASH size must be set with a CONFIG_STM32L4_FLASH_*KB + * selection. + */ + +# define STM32L4_SRAM1_SIZE (96*1024) /* 96Kb SRAM1 on AHB bus Matrix */ +# define STM32L4_SRAM2_SIZE (32*1024) /* 32Kb SRAM2 on AHB bus Matrix */ + +# define STM32L4_NFSMC 1 /* Have FSMC memory controller */ +# define STM32L4_NATIM 2 /* Two advanced timers TIM1 and 8 */ +# define STM32L4_NGTIM32 2 /* 32-bit general timers TIM2 and 5 with DMA */ +# define STM32L4_NGTIM16 2 /* 16-bit general timers TIM3 and 4 with DMA */ +# define STM32L4_NGTIMNDMA 3 /* 16-bit general timers TIM15-17 without DMA */ +# define STM32L4_NBTIM 2 /* Two basic timers, TIM6-7 */ +# define STM32L4_NLPTIM 2 /* Two low-power timers, LPTIM1-2 */ +# define STM32L4_NRNG 1 /* Random number generator (RNG) */ +# define STM32L4_NUART 4 /* UART 4-5 */ +# define STM32L4_NUSART 3 /* USART 1-3 */ +# define STM32L4_NLPUART 1 /* LPUART 1 */ +# define STM32L4_NSPI 3 /* SPI1-3 */ +# define STM32L4_NI2C 3 /* I2C1-3 */ +# define STM32L4_NUSBOTGFS 1 /* USB OTG FS */ +# define STM32L4_NCAN 1 /* CAN1 */ +# define STM32L4_NSAI 2 /* SAI1-2 */ +# define STM32L4_NSDMMC 1 /* SDMMC interface */ +# define STM32L4_NDMA 2 /* DMA1-2 */ +# define STM32L4_NGPIO 8 /* 11 GPIO ports, GPIOA-H */ +# define STM32L4_NADC 3 /* 12-bit ADC1-3, 24 channels *except V series) */ +# define STM32L4_NDAC 2 /* 12-bit DAC1-2 */ +# define STM32L4_NCRC 1 /* CRC */ +# define STM32L4_NCOMP 2 /* Comparators */ +# define STM32L4_NOPAMP 2 /* Operational Amplifiers */ + +/* NVIC priority levels *************************************************************/ +/* 16 Programmable interrupt levels */ + +#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits set in minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x10 /* Four bits of interrupt priority used */ + +/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled + * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most + * interrupts will not have execution priority. SVCall must have execution + * priority in all cases. + * + * In the normal cases, interrupts are not nest-able and all interrupts run + * at an execution priority between NVIC_SYSH_PRIORITY_MIN and + * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall). + * + * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special + * high priority interrupts are supported. These are not "nested" in the + * normal sense of the word. These high priority interrupts can interrupt + * normal processing but execute outside of OS (although they can "get back + * into the game" via a PendSV interrupt). + * + * In the normal course of things, interrupts must occasionally be disabled + * using the irqsave() inline function to prevent contention in use of + * resources that may be shared between interrupt level and non-interrupt + * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, + * do we disable all interrupts (except SVCall), or do we only disable the + * "normal" interrupts. Since the high priority interrupts cannot interact + * with the OS, you may want to permit the high priority interrupts even if + * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be + * used to select either behavior: + * + * ----------------------------+--------------+---------------------------- + * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES + * ----------------------------+--------------+--------------+------------- + * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO + * ----------------------------+--------------+--------------+------------- + * | | | SVCall + * | SVCall | SVCall | HIGH + * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL + * | | MAXNORMAL | + * ----------------------------+--------------+--------------+------------- + */ + +#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#else +# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32L4_CHIP_H */ diff --git a/arch/arm/include/stm32l4/irq.h b/arch/arm/include/stm32l4/irq.h new file mode 100644 index 00000000000..ebfb2266789 --- /dev/null +++ b/arch/arm/include/stm32l4/irq.h @@ -0,0 +1,113 @@ +/************************************************************************************ + * arch/arm/include/stm32l4/irq.h + * + * Copyright (C) 2015 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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. + * + ************************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32L4_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32L4_IRQ_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to + * bits in the NVIC. This does, however, waste several words of memory in the IRQ + * to handle mapping tables. + */ + +/* Processor Exceptions (vectors 0-15) */ + +#define STM32L4_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */ + /* Vector 0: Reset stack pointer value */ + /* Vector 1: Reset (not handler as an IRQ) */ +#define STM32L4_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define STM32L4_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ +#define STM32L4_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ +#define STM32L4_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ +#define STM32L4_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ + /* Vectors 7-10: Reserved */ +#define STM32L4_IRQ_SVCALL (11) /* Vector 11: SVC call */ +#define STM32L4_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + /* Vector 13: Reserved */ +#define STM32L4_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define STM32L4_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are chip-specific */ + +#define STM32L4_IRQ_FIRST (16) /* Vector number of the first external interrupt */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include +#else +# error "Unsupported STM32 L4 chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32L4_IRQ_H */ + diff --git a/arch/arm/include/stm32l4/stm32l4x6xx_irq.h b/arch/arm/include/stm32l4/stm32l4x6xx_irq.h new file mode 100644 index 00000000000..c992ed942fa --- /dev/null +++ b/arch/arm/include/stm32l4/stm32l4x6xx_irq.h @@ -0,0 +1,183 @@ +/**************************************************************************************************** + * arch/arm/include/stm32l4/stm32l4x6xx_irq.h + * + * Copyright (C) 2015 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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. + * + ****************************************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly through arch/irq.h */ + +#ifndef __ARCH_ARM_INCLUDE_STM32L4_STM32L4X6XX_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32L4_STM32L4X6XX_IRQ_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* 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/stm32f7/irq.h which includes this file + * + * External interrupts (vectors >= 16) + */ + +#define STM32L4_IRQ_WWDG (STM32L4_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */ +#define STM32L4_IRQ_PVD (STM32L4_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */ +#define STM32L4_IRQ_TAMPER (STM32L4_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32L4_IRQ_TIMESTAMP (STM32L4_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */ +#define STM32L4_IRQ_RTC_WKUP (STM32L4_IRQ_FIRST+3) /* 3: RTC global interrupt */ +#define STM32L4_IRQ_FLASH (STM32L4_IRQ_FIRST+4) /* 4: Flash global interrupt */ +#define STM32L4_IRQ_RCC (STM32L4_IRQ_FIRST+5) /* 5: RCC global interrupt */ +#define STM32L4_IRQ_EXTI0 (STM32L4_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */ +#define STM32L4_IRQ_EXTI1 (STM32L4_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */ +#define STM32L4_IRQ_EXTI2 (STM32L4_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt */ +#define STM32L4_IRQ_EXTI3 (STM32L4_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */ +#define STM32L4_IRQ_EXTI4 (STM32L4_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */ +#define STM32L4_IRQ_DMA1CH1 (STM32L4_IRQ_FIRST+11) /* 12: DMA1 Channel 1 global interrupt */ +#define STM32L4_IRQ_DMA1CH2 (STM32L4_IRQ_FIRST+12) /* 13: DMA1 Channel 2 global interrupt */ +#define STM32L4_IRQ_DMA1CH3 (STM32L4_IRQ_FIRST+13) /* 14: DMA1 Channel 3 global interrupt */ +#define STM32L4_IRQ_DMA1CH4 (STM32L4_IRQ_FIRST+14) /* 15: DMA1 Channel 4 global interrupt */ +#define STM32L4_IRQ_DMA1CH5 (STM32L4_IRQ_FIRST+15) /* 16: DMA1 Channel 5 global interrupt */ +#define STM32L4_IRQ_DMA1CH6 (STM32L4_IRQ_FIRST+16) /* 17: DMA1 Channel 6 global interrupt */ +#define STM32L4_IRQ_DMA1CH7 (STM32L4_IRQ_FIRST+17) /* 17: DMA1 Channel 7 global interrupt */ +#define STM32L4_IRQ_ADC12 (STM32L4_IRQ_FIRST+18) /* 18: ADC1 and ADC2 global interrupt */ +#define STM32L4_IRQ_CAN1TX (STM32L4_IRQ_FIRST+19) /* 19: CAN1 TX interrupts */ +#define STM32L4_IRQ_CAN1RX0 (STM32L4_IRQ_FIRST+20) /* 20: CAN1 RX0 interrupts */ +#define STM32L4_IRQ_CAN1RX1 (STM32L4_IRQ_FIRST+21) /* 21: CAN1 RX1 interrupt */ +#define STM32L4_IRQ_CAN1SCE (STM32L4_IRQ_FIRST+22) /* 22: CAN1 SCE interrupt */ +#define STM32L4_IRQ_EXTI95 (STM32L4_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */ +#define STM32L4_IRQ_TIM1BRK (STM32L4_IRQ_FIRST+24) /* 24: TIM1 Break interrupt */ +#define STM32L4_IRQ_TIM15 (STM32L4_IRQ_FIRST+24) /* 24: TIM15 global interrupt */ +#define STM32L4_IRQ_TIM1UP (STM32L4_IRQ_FIRST+25) /* 25: TIM1 Update interrupt */ +#define STM32L4_IRQ_TIM16 (STM32L4_IRQ_FIRST+25) /* 25: TIM16 global interrupt */ +#define STM32L4_IRQ_TIM1TRGCOM (STM32L4_IRQ_FIRST+26) /* 26: TIM1 Trigger and Commutation interrupts */ +#define STM32L4_IRQ_TIM17 (STM32L4_IRQ_FIRST+26) /* 26: TIM17 global interrupt */ +#define STM32L4_IRQ_TIM1CC (STM32L4_IRQ_FIRST+27) /* 27: TIM1 Capture Compare interrupt */ +#define STM32L4_IRQ_TIM2 (STM32L4_IRQ_FIRST+28) /* 28: TIM2 global interrupt */ +#define STM32L4_IRQ_TIM3 (STM32L4_IRQ_FIRST+29) /* 29: TIM3 global interrupt */ +#define STM32L4_IRQ_TIM4 (STM32L4_IRQ_FIRST+30) /* 30: TIM4 global interrupt */ +#define STM32L4_IRQ_I2C1EV (STM32L4_IRQ_FIRST+31) /* 31: I2C1 event interrupt */ +#define STM32L4_IRQ_I2C1ER (STM32L4_IRQ_FIRST+32) /* 32: I2C1 error interrupt */ +#define STM32L4_IRQ_I2C2EV (STM32L4_IRQ_FIRST+33) /* 33: I2C2 event interrupt */ +#define STM32L4_IRQ_I2C2ER (STM32L4_IRQ_FIRST+34) /* 34: I2C2 error interrupt */ +#define STM32L4_IRQ_SPI1 (STM32L4_IRQ_FIRST+35) /* 35: SPI1 global interrupt */ +#define STM32L4_IRQ_SPI2 (STM32L4_IRQ_FIRST+36) /* 36: SPI2 global interrupt */ +#define STM32L4_IRQ_USART1 (STM32L4_IRQ_FIRST+37) /* 37: USART1 global interrupt */ +#define STM32L4_IRQ_USART2 (STM32L4_IRQ_FIRST+38) /* 38: USART2 global interrupt */ +#define STM32L4_IRQ_USART3 (STM32L4_IRQ_FIRST+39) /* 39: USART3 global interrupt */ +#define STM32L4_IRQ_EXTI1510 (STM32L4_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */ +#define STM32L4_IRQ_RTCALRM (STM32L4_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */ +#define STM32L4_IRQ_DFSDM3 (STM32L4_IRQ_FIRST+42) /* 42: Digital Filter / Sigma Delta Modulator interrupt */ +#define STM32L4_IRQ_TIM8BRK (STM32L4_IRQ_FIRST+43) /* 43: TIM8 Break interrupt */ +#define STM32L4_IRQ_TIM8UP (STM32L4_IRQ_FIRST+44) /* 44: TIM8 Update interrupt */ +#define STM32L4_IRQ_TIM8TRGCOM (STM32L4_IRQ_FIRST+45) /* 45: TIM8 Trigger and Commutation interrupts */ +#define STM32L4_IRQ_TIM8CC (STM32L4_IRQ_FIRST+46) /* 46: TIM8 Capture Compare interrupt */ +#define STM32L4_IRQ_ADC3 (STM32L4_IRQ_FIRST+47) /* 47: ADC3 global interrupt */ +#define STM32L4_IRQ_FSMC (STM32L4_IRQ_FIRST+48) /* 48: FSMC global interrupt */ +#define STM32L4_IRQ_SDMMC1 (STM32L4_IRQ_FIRST+49) /* 49: SDMMC1 global interrupt */ +#define STM32L4_IRQ_TIM5 (STM32L4_IRQ_FIRST+50) /* 50: TIM5 global interrupt */ +#define STM32L4_IRQ_SPI3 (STM32L4_IRQ_FIRST+51) /* 51: SPI3 global interrupt */ +#define STM32L4_IRQ_UART4 (STM32L4_IRQ_FIRST+52) /* 52: UART4 global interrupt */ +#define STM32L4_IRQ_UART5 (STM32L4_IRQ_FIRST+53) /* 53: UART5 global interrupt */ +#define STM32L4_IRQ_TIM6 (STM32L4_IRQ_FIRST+54) /* 54: TIM6 global interrupt */ +#define STM32L4_IRQ_DAC (STM32L4_IRQ_FIRST+54) /* 54: DAC1 and DAC2 underrun error interrupts */ +#define STM32L4_IRQ_TIM7 (STM32L4_IRQ_FIRST+55) /* 55: TIM7 global interrupt */ +#define STM32L4_IRQ_DMA2CH1 (STM32L4_IRQ_FIRST+56) /* 56: DMA2 Channel 1 global interrupt */ +#define STM32L4_IRQ_DMA2CH2 (STM32L4_IRQ_FIRST+57) /* 57: DMA2 Channel 2 global interrupt */ +#define STM32L4_IRQ_DMA2CH3 (STM32L4_IRQ_FIRST+58) /* 58: DMA2 Channel 3 global interrupt */ +#define STM32L4_IRQ_DMA2CH4 (STM32L4_IRQ_FIRST+59) /* 59: DMA2 Channel 4 global interrupt */ +#define STM32L4_IRQ_DMA2CH5 (STM32L4_IRQ_FIRST+60) /* 60: DMA2 Channel 5 global interrupt */ +#define STM32L4_IRQ_DFSDM0 (STM32L4_IRQ_FIRST+61) /* 61: DFSDM0 global interrupt */ +#define STM32L4_IRQ_DFSDM1 (STM32L4_IRQ_FIRST+62) /* 62: DFSDM1 global interrupt*/ +#define STM32L4_IRQ_DFSDM2 (STM32L4_IRQ_FIRST+63) /* 63: DFSDM2 global interrupt */ +#define STM32L4_IRQ_COMP (STM32L4_IRQ_FIRST+64) /* 64: COMP1/COMP2 interrupts */ +#define STM32L4_IRQ_LPTIM1 (STM32L4_IRQ_FIRST+65) /* 65: LPTIM1 global interrupt */ +#define STM32L4_IRQ_LPTIM2 (STM32L4_IRQ_FIRST+66) /* 66: LPTIM2 global interrupt */ +#define STM32L4_IRQ_OTGFS (STM32L4_IRQ_FIRST+67) /* 67: USB On The Go FS global interrupt */ +#define STM32L4_IRQ_DMA2CH6 (STM32L4_IRQ_FIRST+68) /* 68: DMA2 Channel 6 global interrupt */ +#define STM32L4_IRQ_DMA2CH7 (STM32L4_IRQ_FIRST+69) /* 69: DMA2 Channel 7 global interrupt */ +#define STM32L4_IRQ_LPUART1 (STM32L4_IRQ_FIRST+70) /* 70: Low power UART 1 global interrupt */ +#define STM32L4_IRQ_QUADSPI (STM32L4_IRQ_FIRST+71) /* 71: QUADSPI global interrupt */ +#define STM32L4_IRQ_I2C3EV (STM32L4_IRQ_FIRST+72) /* 72: I2C3 event interrupt */ +#define STM32L4_IRQ_I2C3ER (STM32L4_IRQ_FIRST+73) /* 73: I2C3 error interrupt */ +#define STM32L4_IRQ_SAI1 (STM32L4_IRQ_FIRST+74) /* 74: SAI1 global interrupt */ +#define STM32L4_IRQ_SAI2 (STM32L4_IRQ_FIRST+75) /* 75: SAI2 global interrupt */ +#define STM32L4_IRQ_SWPMI1 (STM32L4_IRQ_FIRST+76) /* 76: SWPMI1 global interrupt */ +#define STM32L4_IRQ_TSC (STM32L4_IRQ_FIRST+77) /* 77: TSC global interrupt */ +#define STM32L4_IRQ_LCD (STM32L4_IRQ_FIRST+78) /* 78: LCD global interrupt */ +#define STM32L4_IRQ_AES (STM32L4_IRQ_FIRST+79) /* 79: AES crypto global interrupt */ +#define STM32L4_IRQ_RNG (STM32L4_IRQ_FIRST+80) /* 80: Rng global interrupt */ +#define STM32L4_IRQ_FPU (STM32L4_IRQ_FIRST+81) /* 81: FPU global interrupt */ + +#define NR_INTERRUPTS 82 +#define NR_VECTORS (STM32L4_IRQ_FIRST+NR_INTERRUPTS) + +/* EXTI interrupts (Do not use IRQ numbers) */ + +#define NR_IRQS NR_VECTORS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32L4_STM32L4X6XX_IRQ_H */ diff --git a/arch/arm/src/stm32l4/Kconfig b/arch/arm/src/stm32l4/Kconfig new file mode 100644 index 00000000000..8c6f3211df9 --- /dev/null +++ b/arch/arm/src/stm32l4/Kconfig @@ -0,0 +1,618 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_STM32L4 + +comment "STM32L4 Configuration Options" + +choice + prompt "STM32 L4 Chip Selection" + default ARCH_CHIP_STM32L476RG + depends on ARCH_CHIP_STM32L4 + +config ARCH_CHIP_STM32L476RG + bool "STM32L476RG" + select STM32L4_STM32L476XX + select STM32L4_FLASH_1024KB + ---help--- + STM32 L4 Cortex M4, 1024Kb FLASH, 96+32 Kb SRAM + +config ARCH_CHIP_STM32L476RE + bool "STM32L476RE" + select STM32L4_STM32L476XX + select STM32L4_FLASH_512KB + ---help--- + STM32 L4 Cortex M4, 512 FLASH, 96+32 Kb SRAM + +config ARCH_CHIP_STM32L486 + bool "STM32L486xx" + select STM32L4_STM32L486XX + select STM32L4_HAVE_AES + ---help--- + STM32 L4 Cortex M4, AES, 1024Kb FLASH, 96+32 Kb SRAM + +endchoice # STM32 L4 Chip Selection + +# Chip families + +config STM32L4_STM32L476XX + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU # REVISIT + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + +config STM32L4_STM32L486XX + bool + default n + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU # REVISIT + select ARMV7M_HAVE_ITCM + select ARMV7M_HAVE_DTCM + select STM32L4_FLASH_1024KB + +choice + prompt "Embedded FLASH size" + default STM32L4_FLASH_1024KB + +config STM32L4_FLASH_256KB + bool "256 KB" + +config STM32L4_FLASH_512KB + bool "512 KB" + +config STM32L4_FLASH_1024KB + bool "1024 KB" + +endchoice # Embedded FLASH size + +menu "STM32L4 Peripheral Support" + +# These "hidden" settings determine is a peripheral option is available for the +# selection MCU + +config STM32L4_HAVE_LTDC + bool + default n + +# These "hidden" settings are the OR of individual peripheral selections +# indicating that the general capabilitiy is required. + +config STM32L4_ADC + bool + default n + +config STM32L4_CAN + bool + default n + +config STM32L4_DAC + bool + default n + +config STM32L4_DMA + bool + default n + +config STM32L4_I2C + bool + default n + +config STM32L4_SAI + bool + default n + +config STM32L4_SPI + bool + default n + +config STM32L4_USART + bool + default n + +config STM32L4_LPTIM + bool + default n + +# These are the peripheral selections proper + +comment "AHB1 Peripherals" + +config STM32L4_DMA1 + bool "DMA1" + default n + select STM32L4_DMA + select ARCH_DMA + +config STM32L4_DMA2 + bool "DMA2" + default n + select STM32L4_DMA + select ARCH_DMA + + +config STM32L4_CRC + bool "CRC" + default n + +config STM32L4_TSC + bool "TSC" + default n + +comment "AHB2 Peripherals" + +config STM32L4_OTGFS + bool "OTG FS" + default n + select USBHOST_HAVE_ASYNCH if USBHOST + +config STM32L4_ADC1 + bool "ADC1" + default n + select STM32L4_ADC + +config STM32L4_ADC2 + bool "ADC2" + default n + select STM32L4_ADC + +config STM32L4_ADC3 + bool "ADC3" + default n + select STM32L4_ADC + +config STM32L4_AES + bool "AES" + default n + +config STM32L4_RNG + bool "RNG" + default n + select ARCH_HAVE_RNG + +comment "AHB3 Peripherals" + +config STM32L4_FMC + bool "FMC" + default n + +config STM32L4_QUADSPI + bool "QuadSPI" + default n + +comment "APB1 Peripherals" + +config STM32_PWR + bool "PWR" + default n + +config STM32L4_TIM2 + bool "TIM2" + default n + +config STM32L4_TIM3 + bool "TIM3" + default n + +config STM32L4_TIM4 + bool "TIM4" + default n + +config STM32L4_TIM5 + bool "TIM5" + default n + +config STM32L4_TIM6 + bool "TIM6" + default n + +config STM32L4_TIM7 + bool "TIM7" + default n + +config STM32L4_LCD + bool "LCD" + default n + +config STM32L4_SPI2 + bool "SPI2" + default n + select SPI + select STM32L4_SPI + +config STM32L4_SPI3 + bool "SPI3" + default n + select SPI + select STM32L4_SPI + +config STM32L4_USART1 + bool "USART1" + default n + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32L4_USART + +config STM32L4_USART2 + bool "USART2" + default n + select ARCH_HAVE_USART2 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32L4_USART + +config STM32L4_USART3 + bool "USART3" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_USART3 + select STM32L4_USART + +config STM32L4_UART4 + bool "UART4" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART4 + select STM32L4_USART + +config STM32L4_UART5 + bool "UART5" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_UART5 + select STM32L4_USART + +config STM32L4_I2C1 + bool "I2C1" + default n + select STM32L4_I2C + +config STM32L4_I2C2 + bool "I2C2" + default n + select STM32L4_I2C + +config STM32L4_I2C3 + bool "I2C3" + default n + select STM32L4_I2C + +config STM32L4_CAN1 + bool "CAN1" + default n + select CAN + select STM32L4_CAN + +config STM32L4_DAC1 + bool "DAC1" + default n + select STM32L4_DAC + +config STM32L4_DAC2 + bool "DAC2" + default n + select STM32L4_DAC + +config STM32L4_OPAMP + bool "OPAMP" + default n + +config STM32L4_LPTIM1 + bool "LPTIM1" + default n + select STM32L4_LPTIM + +config STM32L4_LPUART1 + bool "LPUART1" + default n + select ARCH_HAVE_SERIAL_TERMIOS + select ARCH_HAVE_LPUART1 + +config STM32L4_SWPMI + bool "SWPMI" + default n + +config STM32L4_LPTIM2 + bool "LPTIM2" + default n + select STM32L4_LPTIM + +comment "APB2 Peripherals" + +config STM32L4_SYSCFG + bool "SYSCFG" + default y + +config STM32L4_FIREWALL + bool "FIREWALL" + default y + depends on STM32L4_SYSCFG + +config STM32L4_SDMMC1 + bool "SDMMC1" + default n + select ARCH_HAVE_SDIO + +config STM32L4_TIM1 + bool "TIM1" + default n + +config STM32L4_SPI1 + bool "SPI1" + default n + select SPI + select STM32L4_SPI + +config STM32L4_TIM8 + bool "TIM8" + default n + +config STM32L4_USART1 + bool "USART1" + default n + select ARCH_HAVE_USART1 + select ARCH_HAVE_SERIAL_TERMIOS + select STM32L4_USART + +config STM32L4_TIM15 + bool "TIM15" + default n + +config STM32L4_TIM16 + bool "TIM16" + default n + +config STM32L4_TIM17 + bool "TIM17" + default n + +config STM32L4_SAI1 + bool "SAI1" + default n + select STM32L4_SAI + +config STM32L4_SAI2 + bool "SAI2" + default n + select STM32L4_SAI + +config STM32L4_DFSDM + bool "DFSDM" + default n + +comment "Other Peripherals" + +config STM32L4_BKPSRAM + bool "Enable BKP RAM Domain" + default n + +config STM32L4_IWDG + bool "IWDG" + default n + select WATCHDOG + +config STM32L4_WWDG + bool "WWDG" + default n + select WATCHDOG + +endmenu + +config STM32L4_FLASH_PREFETCH + bool "Enable FLASH Pre-fetch" + default y + ---help--- + Enable FLASH prefetch + +config STM32L4_DISABLE_IDLE_SLEEP_DURING_DEBUG + bool "Disable IDLE Sleep (WFI) in debug mode" + default n + ---help--- + In debug configuration, disables the WFI instruction in the IDLE loop + to prevent the JTAG from disconnecting. With some JTAG debuggers, such + as the ST-LINK2 with OpenOCD, if the ARM is put to sleep via the WFI + instruction, the debugger will disconnect, terminating the debug session. + +config STM32L4_CUSTOM_CLOCKCONFIG + bool "Custom clock configuration" + default n + ---help--- + Enables special, board-specific STM32 clock configuration. + +config STM32L4_SAI1PLL + bool "SAI1PLL" + default n + ---help--- + The STM32L476 has a separate PLL for the SAI1 block. + Set this true and provide configuration parameters in + board.h to use this PLL. + +config STM32L4_SAI2PLL + bool "SAI2PLL" + default n + ---help--- + The STM32L476 has a separate PLL for the SAI2 block. + Set this true and provide configuration parameters in + board.h to use this PLL. + +config STM32L4_USART + bool + +menu "U[S]ART Configuration" + depends on STM32L4_USART + +config USART1_RS485 + bool "RS-485 on USART1" + default n + depends on STM32L4_USART1 + ---help--- + Enable RS-485 interface on USART1. Your board config will have to + provide GPIO_USART1_RS485_DIR pin definition. Currently it cannot be + used with USART1_RXDMA. + +config USART1_RS485_DIR_POLARITY + int "USART1 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART1_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART1. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART1_RXDMA + bool "USART1 Rx DMA" + default n + depends on STM32L4_USART1 && ( STM32L4_DMA1 || STM32L4_DMA2 ) + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config USART2_RS485 + bool "RS-485 on USART2" + default n + depends on STM32L4_USART2 + ---help--- + Enable RS-485 interface on USART2. Your board config will have to + provide GPIO_USART2_RS485_DIR pin definition. Currently it cannot be + used with USART2_RXDMA. + +config USART2_RS485_DIR_POLARITY + int "USART2 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART2_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART2. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART2_RXDMA + bool "USART2 Rx DMA" + default n + depends on STM32L4_USART2 && STM32L4_DMA1 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config USART3_RS485 + bool "RS-485 on USART3" + default n + depends on STM32L4_USART3 + ---help--- + Enable RS-485 interface on USART3. Your board config will have to + provide GPIO_USART3_RS485_DIR pin definition. Currently it cannot be + used with USART3_RXDMA. + +config USART3_RS485_DIR_POLARITY + int "USART3 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on USART3_RS485 + ---help--- + Polarity of DIR pin for RS-485 on USART3. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config USART3_RXDMA + bool "USART3 Rx DMA" + default n + depends on STM32L4_USART3 && STM32L4_DMA1 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config UART4_RS485 + bool "RS-485 on UART4" + default n + depends on STM32L4_UART4 + ---help--- + Enable RS-485 interface on UART4. Your board config will have to + provide GPIO_UART4_RS485_DIR pin definition. Currently it cannot be + used with UART4_RXDMA. + +config UART4_RS485_DIR_POLARITY + int "UART4 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART4_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART4. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART4_RXDMA + bool "UART4 Rx DMA" + default n + depends on STM32L4_UART4 && STM32L4_DMA2 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config UART5_RS485 + bool "RS-485 on UART5" + default n + depends on STM32L4_UART5 + ---help--- + Enable RS-485 interface on UART5. Your board config will have to + provide GPIO_UART5_RS485_DIR pin definition. Currently it cannot be + used with UART5_RXDMA. + +config UART5_RS485_DIR_POLARITY + int "UART5 RS-485 DIR pin polarity" + default 1 + range 0 1 + depends on UART5_RS485 + ---help--- + Polarity of DIR pin for RS-485 on UART5. Set to state on DIR pin which + enables TX (0 - low / nTXEN, 1 - high / TXEN). + +config UART5_RXDMA + bool "UART5 Rx DMA" + default n + depends on STM32L4_UART5 && STM32L4_DMA2 + ---help--- + In high data rate usage, Rx DMA may eliminate Rx overrun errors + +config SERIAL_DISABLE_REORDERING + bool "Disable reordering of ttySx devices." + depends on STM32L4_USART1 || STM32L4_USART2 || STM32L4_USART3 || STM32L4_UART4 || STM32L4_UART5 + default n + ---help--- + NuttX per default reorders the serial ports (/dev/ttySx) so that the + console is always on /dev/ttyS0. If more than one UART is in use this + can, however, have the side-effect that all port mappings + (hardware USART1 -> /dev/ttyS0) change if the console is moved to another + UART. This is in particular relevant if a project uses the USB console + in some configs and a serial console in other configs, but does not + want the side effect of having all serial port names change when just + the console is moved from serial to USB. + +config STM32L4_FLOWCONTROL_BROKEN + bool "Use Software UART RTS flow control" + depends on STM32L4_USART + default n + ---help--- + Enable UART RTS flow control using Software. Because STM + Current STM32 have broken HW based RTS behavior (they assert + nRTS after every byte received) Enable this setting workaround + this issue by useing software based management of RTS + +endmenu + +menu "SPI Configuration" + depends on STM32L4_SPI + +config STM32L4_SPI_INTERRUPTS + bool "Interrupt driver SPI" + default n + ---help--- + Select to enable interrupt driven SPI support. Non-interrupt-driven, + poll-waiting is recommended if the interrupt rate would be to high in + the interrupt driven case. + +config STM32L4_SPI_DMA + bool "SPI DMA" + default n + ---help--- + Use DMA to improve SPI transfer performance. Cannot be used with STM32L4_SPI_INTERRUPT. + +endmenu + +#todo i2c config + +endif # ARCH_CHIP_STM32L4 diff --git a/arch/arm/src/stm32l4/Make.defs b/arch/arm/src/stm32l4/Make.defs new file mode 100644 index 00000000000..d8d72950e15 --- /dev/null +++ b/arch/arm/src/stm32l4/Make.defs @@ -0,0 +1,152 @@ +############################################################################ +# arch/arm/src/stm32l4/Make.defs +# +# Copyright (C) 2015 Sebastien Lorquet. All rights reserved. +# Author: Sebastien Lorquet +# +# 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. +# +############################################################################ + +# The start-up, "head", file. Only common vectors are support so there +# isn't one. + +HEAD_ASRC = + +# Common ARM and Cortex-M4 files (copied from stm32/Make.defs) + +CMN_UASRCS = +CMN_UCSRCS = + +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S +CMN_ASRCS += vfork.S + +CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c +CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c +CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c +CMN_CSRCS += up_systemreset.c up_unblocktask.c up_usestack.c up_doirq.c +CMN_CSRCS += up_hardfault.c up_svcall.c up_vfork.c + +# Configuration-dependent common files + +ifeq ($(CONFIG_ARMV7M_STACKCHECK),y) +CMN_CSRCS += up_stackcheck.c +endif + +ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) +ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_ASRCS += up_lazyexception.S +else +CMN_ASRCS += up_exception.S +endif +CMN_CSRCS += up_vectors.c +endif + +ifeq ($(CONFIG_ARCH_FPU),y) +CMN_ASRCS += up_fpu.S +ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y) +CMN_CSRCS += up_copyarmstate.c +else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) +CMN_CSRCS += up_copyarmstate.c +endif +endif + +ifeq ($(CONFIG_ARCH_RAMVECTORS),y) +CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c +endif + +ifeq ($(CONFIG_ARCH_MEMCPY),y) +CMN_ASRCS += up_memcpy.S +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c +ifneq ($(CONFIG_DISABLE_SIGNALS),y) +CMN_CSRCS += up_signal_dispatch.c +CMN_UASRCS += up_signal_handler.S +endif +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +ifeq ($(CONFIG_ELF),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c +else ifeq ($(CONFIG_MODULE),y) +CMN_CSRCS += up_elf.c up_coherent_dcache.c +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += up_checkstack.c +endif + +# Required STM32L4 files + +CHIP_ASRCS = +CHIP_CSRCS = stm32l4_allocateheap.c stm32l4_exti_gpio.c stm32l4_gpio.c +CHIP_CSRCS += stm32l4_idle.c stm32l4_irq.c stm32l4_lowputc.c stm32l4_rcc.c +CHIP_CSRCS += stm32l4_serial.c stm32l4_start.c stm32l4_waste.c +CHIP_CSRCS += stm32l4_spi.c + +ifneq ($(CONFIG_SCHED_TICKLESS),y) +CHIP_CSRCS += stm32l4_timerisr.c +endif + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CHIP_CSRCS += stm32l4_userspace.c stm32l4_mpuinit.c +endif + +ifeq ($(CONFIG_ARMV7M_DTCM),y) +CHIP_CSRCS += stm32l4_dtcm.c +ifeq ($(CONFIG_STM32L4_DTCM_PROCFS),y) +CHIP_CSRCS += stm32l4_procfs_dtcm.c +endif +endif + +ifeq ($(CONFIG_STM32L4_DMA),y) +CHIP_CSRCS += stm32l4_dma.c +endif + +ifeq ($(CONFIG_STM32_PWR),y) +CHIP_CSRCS += stm32l4_exti_pwr.c +endif + +ifeq ($(CONFIG_RTC),y) +ifeq ($(CONFIG_RTC_ALARM),y) +CHIP_CSRCS += stm32l4_exti_alarm.c +endif +endif + +ifeq ($(CONFIG_DEBUG),y) +CHIP_CSRCS += stm32l4_dumpgpio.c +endif + diff --git a/arch/arm/src/stm32l4/README.txt b/arch/arm/src/stm32l4/README.txt new file mode 100644 index 00000000000..c0bb2bb14dc --- /dev/null +++ b/arch/arm/src/stm32l4/README.txt @@ -0,0 +1,60 @@ +This is a port of NuttX to the STM32L4 Family +Used development board is the Nucleo L476RG + +The status is HIGHLY EXPERIMENTAL. + +OSTEST application works, but drivers are not complete. + +Most code is copied and adapted from the STM32 Port. + +TODO list +--------- + +Peripherals with equivalent implementation in STM32 port + +IRQs : OK +GPIO : OK +EXTI : OK, to be tested. +HSI : OK +HSE : To be tested +PLL : Works @ 80 MHz +MSI : TODO +LSE : TODO, including calibration +RCC : All registers defined, peripherals enabled, basic clock working +SYSCTL : All registers defined +USART : Working in normal mode (no DMA, to be tested, code is written) +DMA : Ported from STM32, code written, to be tested +SRAM2 : Should work with enough MM regions +FIREWALL : Code written, to be tested, requires support from ldscript +SPI : Code written, to be tested, including DMA +I2C : Registers defined +RTC : TODO +QSPI : TODO (port from stm32f7) +CAN : TODO +OTGFS : TODO +Timers : TODO +PM : TODO, PWR registers defined +FSMC : TODO +AES : TODO +RNG : TODO +CRC : TODO (configurable polynomial) +WWDG : TODO +IWDG : TODO +MMCSD : TODO +ADC : TODO +DAC : TODO + +New peripherals with implementation to be written from scratch +These are Low Priority TODO items, unless someone requests or contributes it. + +TSC : TODO (Touch Screen Controller) +SWP : TODO (Single wire protocol master, to connect with NFC enabled SIM cards) +LPUART : TODO (Low power UART working with LSE at low baud rates) +LPTIMER : TODO (Low power TIMER) +OPAMP : TODO (Analog operational amplifier) +COMP : TODO (Analog comparators) +DFSDM : TODO (Digital Filter and Sigma-Delta Modulator) +LCD : TODO (Segment LCD controller) +SAIPLL : TODO (PLL For Digital Audio interfaces) +SAI : TODO (Digital Audio interfaces, I2S, SPDIF, etc) + diff --git a/arch/arm/src/stm32l4/chip.h b/arch/arm/src/stm32l4/chip.h new file mode 100644 index 00000000000..b4caa13eaca --- /dev/null +++ b/arch/arm/src/stm32l4/chip.h @@ -0,0 +1,83 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip.h + * + * Copyright (C) 2015 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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_STM32L4_CHIP_H +#define __ARCH_ARM_SRC_STM32L4_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 "chip/stm32l4_pinmap.h" +#include "chip/stm32l4_memorymap.h" + +/* 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/stm32f7/chip.h + * header file. + */ + +#define ARMV7M_PERIPHERAL_INTERRUPTS NR_INTERRUPTS + +/* Cache line sizes (in bytes)for the STM32L4 */ + +#define ARMV7M_DCACHE_LINESIZE 0 /* no cache */ +#define ARMV7M_ICACHE_LINESIZE 0 /* no cache */ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4_exti.h b/arch/arm/src/stm32l4/chip/stm32l4_exti.h new file mode 100644 index 00000000000..1fb1628a7a9 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_exti.h @@ -0,0 +1,179 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_exti.h + * + * Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_CHIP_STM32L4_EXTI_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_EXTI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define STM32L4_NEXTI1 31 +#define STM32L4_EXTI1_MASK 0xffffffff +#define STM32L4_NEXTI2 8 +#define STM32L4_EXTI2_MASK 0x000000ff + +#define STM32L4_EXTI1_BIT(n) (1 << (n)) +#define STM32L4_EXTI2_BIT(n) (1 << (n)) + +/* Register Offsets *****************************************************************/ + +#define STM32L4_EXTI1_OFFSET 0x0000 /* Offset to EXTI1 registers */ +#define STM32L4_EXTI2_OFFSET 0x0020 /* Offset to EXTI2 registers */ + +#define STM32L4_EXTI_IMR_OFFSET 0x0000 /* Interrupt mask register */ +#define STM32L4_EXTI_EMR_OFFSET 0x0004 /* Event mask register */ +#define STM32L4_EXTI_RTSR_OFFSET 0x0008 /* Rising Trigger selection register */ +#define STM32L4_EXTI_FTSR_OFFSET 0x000c /* Falling Trigger selection register */ +#define STM32L4_EXTI_SWIER_OFFSET 0x0010 /* Software interrupt event register */ +#define STM32L4_EXTI_PR_OFFSET 0x0014 /* Pending register */ + +/* Register Addresses ***************************************************************/ + +#define STM32L4_EXTI1_BASE (STM32L4_EXTI_BASE+STM32L4_EXTI1_OFFSET) +#define STM32L4_EXTI2_BASE (STM32L4_EXTI_BASE+STM32L4_EXTI2_OFFSET) + +#define STM32L4_EXTI1_IMR (STM32L4_EXTI1_BASE+STM32L4_EXTI_IMR_OFFSET) +#define STM32L4_EXTI1_EMR (STM32L4_EXTI1_BASE+STM32L4_EXTI_EMR_OFFSET) +#define STM32L4_EXTI1_RTSR (STM32L4_EXTI1_BASE+STM32L4_EXTI_RTSR_OFFSET) +#define STM32L4_EXTI1_FTSR (STM32L4_EXTI1_BASE+STM32L4_EXTI_FTSR_OFFSET) +#define STM32L4_EXTI1_SWIER (STM32L4_EXTI1_BASE+STM32L4_EXTI_SWIER_OFFSET) +#define STM32L4_EXTI1_PR (STM32L4_EXTI1_BASE+STM32L4_EXTI_PR_OFFSET) + +#define STM32L4_EXTI2_IMR (STM32L4_EXTI2_BASE+STM32L4_EXTI_IMR_OFFSET) +#define STM32L4_EXTI2_EMR (STM32L4_EXTI2_BASE+STM32L4_EXTI_EMR_OFFSET) +#define STM32L4_EXTI2_RTSR (STM32L4_EXTI2_BASE+STM32L4_EXTI_RTSR_OFFSET) +#define STM32L4_EXTI2_FTSR (STM32L4_EXTI2_BASE+STM32L4_EXTI_FTSR_OFFSET) +#define STM32L4_EXTI2_SWIER (STM32L4_EXTI2_BASE+STM32L4_EXTI_SWIER_OFFSET) +#define STM32L4_EXTI2_PR (STM32L4_EXTI2_BASE+STM32L4_EXTI_PR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* EXTI lines > 15 are associated with internal devices: */ + +#define EXTI1_PVD_LINE (1 << 16) /* EXTI line 16 is connected to the PVD output */ +#define EXTI1_OTGFS_WAKEUP (1 << 17) /* EXTI line 17 is connected to the USB OTG FS Wakeup event */ +#define EXTI1_RTC_ALARM (1 << 18) /* EXTI line 18 is connected to the RTC Alarm event */ +#define EXTI1_RTC_TAMPER (1 << 19) /* EXTI line 19 is connected to the RTC Tamper and TimeStamp events */ +#define EXTI1_RTC_WAKEUP (1 << 20) /* EXTI line 20 is connected to the RTC Wakeup event */ +#define EXTI1_COMP1 (1 << 21) /* EXTI line 21 is connected to the COMP1 (comparator) output */ +#define EXTI1_COMP2 (1 << 22) /* EXTI line 22 is connected to the COMP2 (comparator) output */ +#define EXTI1_I2C1 (1 << 23) /* EXTI line 23 is connected to the I2C1 wakeup */ +#define EXTI1_I2C2 (1 << 24) /* EXTI line 24 is connected to the I2C2 wakeup */ +#define EXTI1_I2C3 (1 << 25) /* EXTI line 25 is connected to the I2C3 wakeup */ +#define EXTI1_USART1 (1 << 26) /* EXTI line 26 is connected to the USART1 wakeup */ +#define EXTI1_USART2 (1 << 27) /* EXTI line 27 is connected to the USART2 wakeup */ +#define EXTI1_USART3 (1 << 28) /* EXTI line 28 is connected to the USART3 wakeup */ +#define EXTI1_UART4 (1 << 29) /* EXTI line 29 is connected to the UART4 wakeup */ +#define EXTI1_UART5 (1 << 30) /* EXTI line 30 is connected to the UART5 wakeup */ +#define EXTI1_LPUART1 (1 << 31) /* EXTI line 31 is connected to the LPUART1 wakeup */ +#define EXTI2_LPTIM1 (1 << 0) /* EXTI line 32 is connected to LPTIM1 */ +#define EXTI2_LPTIM2 (1 << 1) /* EXTI line 33 is connected to LPTIM2 */ +#define EXTI2_SWPMI1 (1 << 2) /* EXTI line 34 is connected to the SWPMI1 wakeup */ +#define EXTI2_PVM1 (1 << 3) /* EXTI line 35 is connected to the PVM1 wakeup */ +#define EXTI2_PVM2 (1 << 4) /* EXTI line 36 is connected to the PVM2 wakeup */ +#define EXTI2_PVM3 (1 << 5) /* EXTI line 37 is connected to the PVM3 wakeup */ +#define EXTI2_PVM4 (1 << 6) /* EXTI line 38 is connected to the PVM4 wakeup */ +#define EXTI2_LCD (1 << 7) /* EXTI line 39 is connected to the LCD wakeup */ + +/* Interrupt mask register */ + +#define EXTI_IMR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Interrupt request from line x is not masked */ +#define EXTI_IMR1_SHIFT (0) /* Bits 0-X: Interrupt Mask for all lines */ +#define EXTI_IMR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_IMR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Interrupt request from line x is not masked */ +#define EXTI_IMR2_SHIFT (0) /* Bits 0-X: Interrupt Mask for all lines */ +#define EXTI_IMR2_MASK STM32L4_EXTI2_MASK + +/* Event mask register */ + +#define EXTI_EMR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Event request from line x is not mask */ +#define EXTI_EMR1_SHIFT (0) /* Bits Bits 0-X: Event Mask for all lines */ +#define EXTI_EMR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_EMR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Event request from line x is not mask */ +#define EXTI_EMR2_SHIFT (0) /* Bits Bits 0-X: Event Mask for all lines */ +#define EXTI_EMR2_MASK STM32L4_EXTI2_MASK + +/* Rising Trigger selection register */ + +#define EXTI_RTSR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Rising trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_RTSR1_SHIFT (0) /* Bits 0-X: Rising trigger event configuration bit for all lines */ +#define EXTI_RTSR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_RTSR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Rising trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_RTSR2_SHIFT (0) /* Bits 0-X: Rising trigger event configuration bit for all lines */ +#define EXTI_RTSR2_MASK STM32L4_EXTI2_MASK + +/* Falling Trigger selection register */ + +#define EXTI_FTSR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Falling trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_FTSR1_SHIFT (0) /* Bits 0-X: Falling trigger event configuration bitfor all lines */ +#define EXTI_FTSR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_FTSR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Falling trigger enabled (for Event and Interrupt) for input line */ +#define EXTI_FTSR2_SHIFT (0) /* Bits 0-X: Falling trigger event configuration bitfor all lines */ +#define EXTI_FTSR2_MASK STM32L4_EXTI2_MASK + +/* Software interrupt event register */ + +#define EXTI_SWIER1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Sets the corresponding pending bit in EXTI_PR */ +#define EXTI_SWIER1_SHIFT (0) /* Bits 0-X: Software Interrupt for all lines */ +#define EXTI_SWIER1_MASK STM32L4_EXTI1_MASK + +#define EXTI_SWIER2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Sets the corresponding pending bit in EXTI_PR */ +#define EXTI_SWIER2_SHIFT (0) /* Bits 0-X: Software Interrupt for all lines */ +#define EXTI_SWIER2_MASK STM32L4_EXTI2_MASK + +/* Pending register */ + +#define EXTI_IMR1_BIT(n) STM32L4_EXTI1_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_IMR1_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_IMR1_MASK STM32L4_EXTI1_MASK + +#define EXTI_IMR2_BIT(n) STM32L4_EXTI2_BIT(n) /* 1=Selected trigger request occurred */ +#define EXTI_IMR2_SHIFT (0) /* Bits 0-X: Pending bit for all lines */ +#define EXTI_IMR2_MASK STM32L4_EXTI2_MASK + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_EXTI_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_i2c.h b/arch/arm/src/stm32l4/chip/stm32l4_i2c.h new file mode 100644 index 00000000000..02927801fd3 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_i2c.h @@ -0,0 +1,249 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_i2c.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_CHIP_STM32L4_I2C_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_I2C_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_I2C_CR1_OFFSET 0x0000 /* Control register 1 (32-bit) */ +#define STM32L4_I2C_CR2_OFFSET 0x0004 /* Control register 2 (32-bit) */ +#define STM32L4_I2C_OAR1_OFFSET 0x0008 /* Own address register 1 (16-bit) */ +#define STM32L4_I2C_OAR2_OFFSET 0x000c /* Own address register 2 (16-bit) */ +#define STM32L4_I2C_TIMINGR_OFFSET 0x0010 /* Timing register */ +#define STM32L4_I2C_TIMEOUTR_OFFSET 0x0014 /* Timeout register */ +#define STM32L4_I2C_ISR_OFFSET 0x0018 /* Interrupt and Status register */ +#define STM32L4_I2C_ICR_OFFSET 0x001c /* Interrupt clear register */ +#define STM32L4_I2C_PECR_OFFSET 0x0020 /* Packet error checking register */ +#define STM32L4_I2C_RXDR_OFFSET 0x0024 /* Receive data register */ +#define STM32L4_I2C_TXDR_OFFSET 0x0028 /* Transmit data register */ + +/* Register Addresses ***************************************************************/ + +#if STM32L4_NI2C > 0 +# define STM32L4_I2C1_CR1 (STM32L4_I2C1_BASE+STM32L4_I2C_CR1_OFFSET) +# define STM32L4_I2C1_CR2 (STM32L4_I2C1_BASE+STM32L4_I2C_CR2_OFFSET) +# define STM32L4_I2C1_OAR1 (STM32L4_I2C1_BASE+STM32L4_I2C_OAR1_OFFSET) +# define STM32L4_I2C1_OAR2 (STM32L4_I2C1_BASE+STM32L4_I2C_OAR2_OFFSET) +# define STM32L4_I2C1_TIMINGR (STM32L4_I2C1_BASE+STM32L4_I2C_TIMINGR_OFFSET) +# define STM32L4_I2C1_TIMEOUTR (STM32L4_I2C1_BASE+STM32L4_I2C_TIMEOUTR_OFFSET) +# define STM32L4_I2C1_ISR (STM32L4_I2C1_BASE+STM32L4_I2C_ISR_OFFSET) +# define STM32L4_I2C1_ICR (STM32L4_I2C1_BASE+STM32L4_I2C_ICR_OFFSET) +# define STM32L4_I2C1_PECR (STM32L4_I2C1_BASE+STM32L4_I2C_PECR_OFFSET) +# define STM32L4_I2C1_RXDR (STM32L4_I2C1_BASE+STM32L4_I2C_RXDR_OFFSET) +# define STM32L4_I2C1_TXDR (STM32L4_I2C1_BASE+STM32L4_I2C_TXDR_OFFSET) +#endif + +#if STM32L4_NI2C > 1 +# define STM32L4_I2C2_CR1 (STM32L4_I2C2_BASE+STM32L4_I2C_CR1_OFFSET) +# define STM32L4_I2C2_CR2 (STM32L4_I2C2_BASE+STM32L4_I2C_CR2_OFFSET) +# define STM32L4_I2C2_OAR1 (STM32L4_I2C2_BASE+STM32L4_I2C_OAR1_OFFSET) +# define STM32L4_I2C2_OAR2 (STM32L4_I2C2_BASE+STM32L4_I2C_OAR2_OFFSET) +# define STM32L4_I2C2_TIMINGR (STM32L4_I2C2_BASE+STM32L4_I2C_TIMINGR_OFFSET) +# define STM32L4_I2C2_TIMEOUTR (STM32L4_I2C2_BASE+STM32L4_I2C_TIMEOUTR_OFFSET) +# define STM32L4_I2C2_ISR (STM32L4_I2C2_BASE+STM32L4_I2C_ISR_OFFSET) +# define STM32L4_I2C2_ICR (STM32L4_I2C2_BASE+STM32L4_I2C_ICR_OFFSET) +# define STM32L4_I2C2_PECR (STM32L4_I2C2_BASE+STM32L4_I2C_PECR_OFFSET) +# define STM32L4_I2C2_RXDR (STM32L4_I2C2_BASE+STM32L4_I2C_RXDR_OFFSET) +# define STM32L4_I2C2_TXDR (STM32L4_I2C2_BASE+STM32L4_I2C_TXDR_OFFSET) +#endif + +#if STM32L4_NI2C > 2 +# define STM32L4_I2C3_CR1 (STM32L4_I2C3_BASE+STM32L4_I2C_CR1_OFFSET) +# define STM32L4_I2C3_CR2 (STM32L4_I2C3_BASE+STM32L4_I2C_CR2_OFFSET) +# define STM32L4_I2C3_OAR1 (STM32L4_I2C3_BASE+STM32L4_I2C_OAR1_OFFSET) +# define STM32L4_I2C3_OAR2 (STM32L4_I2C3_BASE+STM32L4_I2C_OAR2_OFFSET) +# define STM32L4_I2C3_TIMINGR (STM32L4_I2C3_BASE+STM32L4_I2C_TIMINGR_OFFSET) +# define STM32L4_I2C3_TIMEOUTR (STM32L4_I2C3_BASE+STM32L4_I2C_TIMEOUTR_OFFSET) +# define STM32L4_I2C3_ISR (STM32L4_I2C3_BASE+STM32L4_I2C_ISR_OFFSET) +# define STM32L4_I2C3_ICR (STM32L4_I2C3_BASE+STM32L4_I2C_ICR_OFFSET) +# define STM32L4_I2C3_PECR (STM32L4_I2C3_BASE+STM32L4_I2C_PECR_OFFSET) +# define STM32L4_I2C3_RXDR (STM32L4_I2C3_BASE+STM32L4_I2C_RXDR_OFFSET) +# define STM32L4_I2C3_TXDR (STM32L4_I2C3_BASE+STM32L4_I2C_TXDR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Control register 1 */ + +#define I2C_CR1_PE (1 << 0) /* Bit 0: Peripheral Enable */ +#define I2C_CR1_TXIE (1 << 1) /* Bit 1: TX Interrupt enable */ +#define I2C_CR1_RXIE (1 << 2) /* Bit 2: RX Interrupt enable */ +#define I2C_CR1_ADDRIE (1 << 3) /* Bit 3: Address match interrupt enable (slave) */ +#define I2C_CR1_NACKIE (1 << 4) /* Bit 4: Not acknowledge received interrupt enable */ +#define I2C_CR1_STOPIE (1 << 5) /* Bit 5: STOP detection interrupt enable */ +#define I2C_CR1_TCIE (1 << 6) /* Bit 6: Transfer Complete interrupt enable */ +#define I2C_CR1_ERRIE (1 << 7) /* Bit 7: Error interrupts enable */ +#define I2C_CR1_DNF_SHIFT (8) /* Bits 8-11: Digital noise filter */ +#define I2C_CR1_DNF_MASK (15 << I2C_CR1_DNF_SHIFT) +# define I2C_CR1_DNF_DISABLE (0 << I2C_CR1_DNF_SHIFT) +# define I2C_CR1_DNF(n) ((n) << I2C_CR1_DNF_SHIFT) /* Up to n * Ti2cclk, n=1..15 */ +#define I2C_CR1_ANFOFF (1 << 12) /* Bit 12: Analog noise filter OFF */ +#define I2C_CR1_TXDMAEN (1 << 14) /* Bit 14: DMA transmission requests enable */ +#define I2C_CR1_RXDMAEN (1 << 15) /* Bit 15: DMA reception requests enable */ +#define I2C_CR1_SBC (1 << 16) /* Bit 16: Slave byte control */ +#define I2C_CR1_NOSTRETCH (1 << 17) /* Bit 17: Clock stretching disable */ +#define I2C_CR1_WUPEN (1 << 18) /* Bit 18: Wakeup from STOP enable */ +#define I2C_CR1_GCEN (1 << 19) /* Bit 19: General call enable */ +#define I2C_CR1_SMBHEN (1 << 20) /* Bit 20: SMBus Host address enable */ +#define I2C_CR1_SMBDEN (1 << 21) /* Bit 21: SMBus Device Default address enable */ +#define I2C_CR1_ALERTEN (1 << 22) /* Bit 22: SMBus alert enable */ +#define I2C_CR1_PECEN (1 << 23) /* Bit 23: PEC enable */ + +/* Control register 2 */ + +#define I2C_CR2_SADD10_SHIFT (0) /* Bits 0-9: Slave 10-bit address (master) */ +#define I2C_CR2_SADD10_MASK (0x3ff << I2C_CR2_SADD10_SHIFT) +#define I2C_CR2_SADD7_SHIFT (1) /* Bits 1-7: Slave 7-bit address (master) */ +#define I2C_CR2_SADD7_MASK (0x7f << I2C_CR2_SADD7_SHIFT) +#define I2C_CR2_RD_WRN (1 << 10) /* Bit 10: Transfer direction (master) */ +#define I2C_CR2_ADD10 (1 << 11) /* Bit 11: 10-bit addressing mode (master) */ +#define I2C_CR2_HEAD10R (1 << 12) /* Bit 12: 10-bit address header only read direction (master) */ +#define I2C_CR2_START (1 << 13) /* Bit 13: Start generation */ +#define I2C_CR2_STOP (1 << 14) /* Bit 14: Stop generation (master) */ +#define I2C_CR2_NACK (1 << 15) /* Bit 15: NACK generation (slave) */ +#define I2C_CR2_NBYTES_SHIFT (16) /* Bits 16-23: Number of bytes */ +#define I2C_CR2_NBYTES_MASK (0xff << I2C_CR2_NBYTES_SHIFT) +#define I2C_CR2_RELOAD (1 << 24) /* Bit 24: NBYTES reload mode */ +#define I2C_CR2_AUTOEND (1 << 25) /* Bit 25: Automatic end mode (master) */ +#define I2C_CR2_PECBYTE (1 << 26) /* Bit 26: Packet error checking byte */ + +/* Own address register 1 */ + +#define I2C_OAR1_OA1_10_SHIFT (0) /* Bits 0-9: 10-bit interface address */ +#define I2C_OAR1_OA1_10_MASK (0x3ff << I2C_OAR1_OA1_10_SHIFT) +#define I2C_OAR1_OA1_7_SHIFT (1) /* Bits 1-7: 7-bit interface address */ +#define I2C_OAR1_OA1_7_MASK (0x7f << I2C_OAR1_OA1_7_SHIFT) +#define I2C_OAR1_OA1MODE (1 << 10) /* Bit 10: Own Address 1 10-bit mode */ +#define I2C_OAR1_OA1EN (1 << 15) /* Bit 15: Own Address 1 enable */ + +/* Own address register 2 */ + +#define I2C_OAR2_OA2_SHIFT (1) /* Bits 1-7: 7-bit interface address */ +#define I2C_OAR2_OA2_MASK (0x7f << I2C_OAR2_OA2_SHIFT) +#define I2C_OAR2_OA2MSK_SHIFT (8) /* Bits 8-10: Own Address 2 masks */ +#define I2C_OAR2_OA2MSK_MASK (7 << I2C_OAR2_OA2MSK_SHIFT) +# define I2C_OAR2_OA2MSK_NONE (0 << I2C_OAR2_OA2MSK_SHIFT) /* No mask */ +# define I2C_OAR2_OA2MSK_2_7 (1 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:2] are compared */ +# define I2C_OAR2_OA2MSK_3_7 (2 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:3] are compared */ +# define I2C_OAR2_OA2MSK_4_7 (3 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:4] are compared */ +# define I2C_OAR2_OA2MSK_5_7 (4 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:5] are compared */ +# define I2C_OAR2_OA2MSK_6_7 (5 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7:6] are compared */ +# define I2C_OAR2_OA2MSK_7 (6 << I2C_OAR2_OA2MSK_SHIFT) /* Only OA2[7] is compared */ +# define I2C_OAR2_OA2MSK_ALL (7 << I2C_OAR2_OA2MSK_SHIFT) /* All 7-bit addresses acknowledged */ +#define I2C_OAR2_OA2EN (1 << 15) /* Bit 15: Own Address 2 enable */ + +/* Timing register */ + +#define I2C_TIMINGR_SCLL_SHIFT (0) /* Bits 0-7: SCL low period (master) */ +#define I2C_TIMINGR_SCLL_MASK (0xff << I2C_TIMINGR_SCLL_SHIFT) +# define I2C_TIMINGR_SCLL(n) (((n)-1) << I2C_TIMINGR_SCLL_SHIFT) /* tSCLL = n x tPRESC */ + +#define I2C_TIMINGR_SCLH_SHIFT (8) /* Bits 8-15: SCL high period (master) */ +#define I2C_TIMINGR_SCLH_MASK (0xff << I2C_TIMINGR_SCLH_SHIFT) +# define I2C_TIMINGR_SCLH(n) (((n)-1) << I2C_TIMINGR_SCLH_SHIFT) /* tSCLH = n x tPRESC */ + +#define I2C_TIMINGR_SDADEL_SHIFT (16) /* Bits 16-19: Data hold time */ +#define I2C_TIMINGR_SDADEL_MASK (15 << I2C_TIMINGR_SDADEL_SHIFT) +# define I2C_TIMINGR_SDADEL(n) ((n) << I2C_TIMINGR_SDADEL_SHIFT) /* tSDADEL= n x tPRESC */ + +#define I2C_TIMINGR_SCLDEL_SHIFT (20) /* Bits 20-23: Data setup time */ +#define I2C_TIMINGR_SCLDEL_MASK (15 << I2C_TIMINGR_SCLDEL_SHIFT) +# define I2C_TIMINGR_SCLDEL(n) (((n)-1) << I2C_TIMINGR_SCLDEL_SHIFT) /* tSCLDEL = n x tPRESC */ + +#define I2C_TIMINGR_PRESC_SHIFT (28) /* Bits 28-31: Timing prescaler */ +#define I2C_TIMINGR_PRESC_MASK (15 << I2C_TIMINGR_PRESC_SHIFT) +# define I2C_TIMINGR_PRESC(n) (((n)-1) << I2C_TIMINGR_PRESC_SHIFT) /* tPRESC = n x tI2CCLK */ + +/* Timeout register */ + +#define I2C_TIMEOUTR_A_SHIFT (0) /* Bits 0-11: Bus Timeout A */ +#define I2C_TIMEOUTR_A_MASK (0x0fff << I2C_TIMEOUTR_A_SHIFT) +# define I2C_TIMEOUTR_A(n) ((n) << I2C_TIMEOUTR_A_SHIFT) +#define I2C_TIMEOUTR_TIDLE (1 << 12) /* Bit 12: Idle clock timeout detection */ +#define I2C_TIMEOUTR_TIMOUTEN (1 << 15) /* Bit 15: Clock timeout enable */ +#define I2C_TIMEOUTR_B_SHIFT (16) /* Bits 16-27: Bus Timeout B */ +#define I2C_TIMEOUTR_B_MASK (0x0fff << I2C_TIMEOUTR_B_SHIFT) +# define I2C_TIMEOUTR_B(n) ((n) << I2C_TIMEOUTR_B_SHIFT) +#define I2C_TIMEOUTR_TEXTEN (1 << 31) /* Bits 31: Extended clock timeout enable */ + +/* Interrupt and Status register and interrupt clear register */ +/* Common interrupt bits */ + +#define I2C_INT_ADDR (1 << 3) /* Bit 3: Address matched (slave) */ +#define I2C_INT_NACK (1 << 4) /* Bit 4: Not Acknowledge received flag */ +#define I2C_INT_STOP (1 << 5) /* Bit 5: Stop detection flag */ +#define I2C_INT_BERR (1 << 8) /* Bit 8: Bus error */ +#define I2C_INT_ARLO (1 << 9) /* Bit 9: Arbitration lost */ +#define I2C_INT_OVR (1 << 10) /* Bit 10: Overrun/Underrun (slave) */ +#define I2C_INT_PECERR (1 << 11) /* Bit 11: PEC Error in reception */ +#define I2C_INT_TIMEOUT (1 << 12) /* Bit 12: Timeout or tLOW detection flag */ +#define I2C_INT_ALERT (1 << 13) /* Bit 13: SMBus alert */ + +/* Fields unique to the Interrupt and Status register */ + +#define I2C_ISR_TXE (1 << 0) /* Bit 0: Transmit data register empty (transmitters) */ +#define I2C_ISR_TXIS (1 << 1) /* Bit 1: Transmit interrupt status (transmitters) */ +#define I2C_ISR_RXNE (1 << 2) /* Bit 2: Receive data register not empty (receivers) */ +#define I2C_ISR_TC (1 << 6) /* Bit 6: Transfer Complete (master) */ +#define I2C_ISR_TCR (1 << 7) /* Bit 7: Transfer Complete Reload */ +#define I2C_ISR_BUSY (1 << 15) /* Bit 15: Bus busy */ +#define I2C_ISR_DIR (1 << 16) /* Bit 16: Transfer direction (slave) */ +#define I2C_ISR_ADDCODE_SHIFT (17) /* Bits 17-23: Address match code (slave) */ +#define I2C_ISR_ADDCODE_MASK (0x7f << I2C_ISR_ADDCODE_SHIFT) + +#define I2C_ISR_ERRORMASK (I2C_INT_BERR | I2C_INT_ARLO | I2C_INT_OVR | I2C_INT_PECERR | I2C_INT_TIMEOUT) + +#define I2C_ICR_CLEARMASK (I2C_INT_ADDR | I2C_INT_NACK | I2C_INT_STOP | I2C_INT_BERR | I2C_INT_ARLO \ + | I2C_INT_OVR | I2C_INT_PECERR | I2C_INT_TIMEOUT | I2C_INT_ALERT) + +/* Packet error checking register */ + +#define I2C_PECR_MASK (0xff) + +/* Receive data register */ + +#define I2C_RXDR_MASK (0xff) + +/* Transmit data register */ + +#define I2C_TXDR_MASK (0xff) + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32F30XXX_I2C_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h b/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h new file mode 100644 index 00000000000..f766cae723f --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h @@ -0,0 +1,196 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_memorymap.h + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_STM32L4_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_MEMORYMAP_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* STM32F40XXX Address Blocks *******************************************************/ + +#define STM32L4_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32L4_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block (96k) */ +#define STM32L4_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ +#define STM32L4_FSMC_BASE12 0x60000000 /* 0x60000000-0x7fffffff: 512Mb FSMC bank1&2 block */ +# define STM32L4_FSMC_BANK1 0x60000000 /* 0x60000000-0x6fffffff: 256Mb NOR/SRAM */ +# define STM32L4_FSMC_BANK2 0x70000000 /* 0x70000000-0x7fffffff: 256Mb NAND FLASH */ +#define STM32L4_FSMC_BASE34 0x80000000 /* 0x80000000-0x8fffffff: 512Mb FSMC bank3 / QSPI block */ +# define STM32L4_FSMC_BANK3 0x80000000 /* 0x80000000-0x8fffffff: 256Mb NAND FLASH */ +# define STM32L4_QSPI_BANK 0x90000000 /* 0x90000000-0x9fffffff: 256Mb QUADSPI*/ +#define STM32L4_FSMC_BASE 0xa0000000 /* 0xa0000000-0xbfffffff: FSMC register block */ +#define STM32L4_QSPI_BASE 0xa0001000 /* 0xa0000000-0xbfffffff: QSPI register block */ + /* 0xc0000000-0xdfffffff: 512Mb (not used) */ +#define STM32L4_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M4 block */ + +#define STM32L4_REGION_MASK 0xf0000000 +#define STM32L4_IS_SRAM(a) ((((uint32_t)(a)) & STM32L4_REGION_MASK) == STM32L4_SRAM_BASE) +#define STM32L4_IS_EXTSRAM(a) ((((uint32_t)(a)) & STM32L4_REGION_MASK) == STM32L4_FSMC_BANK1) + +/* Code Base Addresses **************************************************************/ + +#define STM32L4_BOOT_BASE 0x00000000 /* 0x00000000-0x000fffff: Aliased boot memory */ + /* 0x00100000-0x07ffffff: Reserved */ +#define STM32L4_FLASH_BASE 0x08000000 /* 0x08000000-0x080fffff: FLASH memory */ + /* 0x08100000-0x0fffffff: Reserved */ +#define STM32L4_SRAM2_BASE 0x10000000 /* 0x10000000-0x1000ffff: 32Kb SRAM2 */ + /* 0x10010000-0x1ffeffff: Reserved */ +#define STM32L4_SYSMEM_BASE 0x1fff0000 /* 0x1fff0000-0x1fff7a0f: System memory */ + /* 0x1fff7a10-0x1fff7fff: Reserved */ +#define STM32L4_OPTION_BASE 0x1fffc000 /* 0x1fffc000-0x1fffc007: Option bytes */ + /* 0x1fffc008-0x1fffffff: Reserved */ + +/* System Memory Addresses **********************************************************/ + +#define STM32L4_SYSMEM_UID 0x1fff7590 /* The 96-bit unique device identifier */ +#define STM32L4_SYSMEM_FSIZE 0x1fff75E0 /* This bitfield indicates the size of + * the device Flash memory expressed in + * Kbytes. Example: 0x0400 corresponds + * to 1024 Kbytes. + */ +#define STM32L4_SYSMEM_PACKAGE 0x1fff7500 /* This bitfield indicates the package + * type. + * 0: LQFP64 + * 2: LQFP100 + * 3: BGA132 + * 4: LQFP144, WLCSP81 or WLCSP72 + */ + +/* SRAM Base Addresses **************************************************************/ + + /* 0x20000000-0x2000ffff: 64k aliased by bit-banding */ + /* 0x2001c000-0x2001ffff: 16Kb aliased by bit-banding */ +#define STM32L4_SRAMBB_BASE 0x22000000 /* 0x22000000- : SRAM bit-band region */ + +/* Peripheral Base Addresses ********************************************************/ + +#define STM32L4_APB1_BASE 0x40000000 /* 0x40000000-0x400097ff: APB1 */ + /* 0x40009800-0x4000ffff: Reserved */ +#define STM32L4_APB2_BASE 0x40010000 /* 0x40010000-0x400163ff: APB2 */ + /* 0x40016400-0x4001ffff: Reserved */ +#define STM32L4_AHB1_BASE 0x40020000 /* 0x40020000-0x400243ff: APB1 */ + /* 0x40024400-0x47ffffff: Reserved */ +#define STM32L4_AHB2_BASE 0x48000000 /* 0x48000000-0x50060bff: AHB2 */ + /* 0x50060c00-0x5fffffff: Reserved */ + +/* FSMC/QSPI Base Addresses **************************************************************/ + +#define STM32L4_AHB3_BASE 0x60000000 /* 0x60000000-0xa0000fff: AHB3 */ + +/* in datasheet order */ + +/* APB1 Base Addresses **************************************************************/ + +#define STM32L4_LPTIM2_BASE 0x40009400 +#define STM32L4_SWPMI1_BASE 0x40008800 +#define STM32L4_LPUART1_BASE 0x40008000 +#define STM32L4_LPTIM1_BASE 0x40007c00 +#define STM32L4_OPAMP_BASE 0x40007800 +#define STM32L4_DAC_BASE 0x40007400 +#define STM32L4_PWR_BASE 0x40007000 +#define STM32L4_CAN1_BASE 0x40006400 +#define STM32L4_I2C3_BASE 0x40005c00 +#define STM32L4_I2C2_BASE 0x40005800 +#define STM32L4_I2C1_BASE 0x40005400 +#define STM32L4_UART5_BASE 0x40005000 +#define STM32L4_UART4_BASE 0x40004c00 +#define STM32L4_USART3_BASE 0x40004800 +#define STM32L4_USART2_BASE 0x40004400 +#define STM32L4_SPI3_BASE 0x40003c00 +#define STM32L4_SPI2_BASE 0x40003800 +#define STM32L4_IWDG_BASE 0x40003000 +#define STM32L4_WWDG_BASE 0x40002c00 +#define STM32L4_RTC_BASE 0x40002800 +#define STM32L4_LCD_BASE 0x40002400 +#define STM32L4_TIM7_BASE 0x40001400 +#define STM32L4_TIM6_BASE 0x40001000 +#define STM32L4_TIM5_BASE 0x40000c00 +#define STM32L4_TIM4_BASE 0x40000800 +#define STM32L4_TIM3_BASE 0x40000400 +#define STM32L4_TIM2_BASE 0x40000000 + +/* APB2 Base Addresses **************************************************************/ + +#define STM32L4_DFSDM_BASE 0x40016000 +#define STM32L4_SAI2_BASE 0x40015800 +#define STM32L4_SAI1_BASE 0x40015400 +#define STM32L4_TIM17_BASE 0x40014800 +#define STM32L4_TIM16_BASE 0x40014400 +#define STM32L4_TIM15_BASE 0x40014000 +#define STM32L4_USART1_BASE 0x40013800 +#define STM32L4_TIM8_BASE 0x40013400 +#define STM32L4_SPI1_BASE 0x40013000 +#define STM32L4_TIM1_BASE 0x40012c00 +#define STM32L4_SDMMC1_BASE 0x40012800 +#define STM32L4_FIREWALL_BASE 0x40011c00 +#define STM32L4_EXTI_BASE 0x40010400 +#define STM32L4_COMP_BASE 0x40010200 +#define STM32L4_VREFBUF_BASE 0x40010030 +#define STM32L4_SYSCFG_BASE 0x40010000 + +/* AHB1 Base Addresses **************************************************************/ + +#define STM32L4_TSC_BASE 0x40024000 +#define STM32L4_CRC_BASE 0x40023000 +#define STM32L4_FLASHIF_BASE 0x40022000 +#define STM32L4_RCC_BASE 0x40021000 +#define STM32L4_DMA2_BASE 0x40020400 +#define STM32L4_DMA1_BASE 0x40020000 + +/* AHB2 Base Addresses **************************************************************/ + +#define STM32L4_AES_BASE 0x50060800 +#define STM32L4_ADC_BASE 0x50060000 +#define STM32L4_OTG_FS_BASE 0x50040000 +#define STM32L4_GPIOH_BASE 0x50001c00 +#define STM32L4_GPIOG_BASE 0x48001800 +#define STM32L4_GPIOF_BASE 0x48001400 +#define STM32L4_GPIOE_BASE 0x48001000 +#define STM32L4_GPIOD_BASE 0x48000c00 +#define STM32L4_GPIOC_BASE 0x48000800 +#define STM32L4_GPIOB_BASE 0x48000400 +#define STM32L4_GPIOA_BASE 0x48000000 + +/* Cortex-M4 Base Addresses *********************************************************/ +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M3 registers in this + * address range + */ + +#define STM32L4_SCS_BASE 0xe000e000 +#define STM32L4_DEBUGMCU_BASE 0xe0042000 + +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_MEMORYMAP_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h b/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h new file mode 100644 index 00000000000..16bbdec7ab1 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h @@ -0,0 +1,53 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32_pinmap.h + * + * Copyright (C) 2015 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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_STM32L4_CHIP_STM32_PINMAP_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_pinmap.h" +#else +# error "Unsupported STM32 L4 pin map" +#endif + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32_PINMAP_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_pwr.h b/arch/arm/src/stm32l4/chip/stm32l4_pwr.h new file mode 100644 index 00000000000..2e771551f8e --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_pwr.h @@ -0,0 +1,195 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_pwr.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_CHIP_STM32L4_PWR_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_PWR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_PWR_CR1_OFFSET 0x0000 /* Power control register 1 */ +#define STM32L4_PWR_CR2_OFFSET 0x0004 /* Power control register 2 */ +#define STM32L4_PWR_CR3_OFFSET 0x0008 /* Power control register 3 */ +#define STM32L4_PWR_CR4_OFFSET 0x000C /* Power control register 4 */ +#define STM32L4_PWR_SR1_OFFSET 0x0010 /* Power status register 1 */ +#define STM32L4_PWR_SR2_OFFSET 0x0014 /* Power status register 2 */ +#define STM32L4_PWR_SCR_OFFSET 0x0018 /* Power status clear register */ +#define STM32L4_PWR_PUCRA_OFFSET 0x0020 /* Power Port A pull-up control register */ +#define STM32L4_PWR_PDCRA_OFFSET 0x0024 /* Power Port A pull-down control register */ +#define STM32L4_PWR_PUCRB_OFFSET 0x0028 /* Power Port B pull-up control register */ +#define STM32L4_PWR_PDCRB_OFFSET 0x002C /* Power Port B pull-down control register */ +#define STM32L4_PWR_PUCRC_OFFSET 0x0030 /* Power Port C pull-up control register */ +#define STM32L4_PWR_PDCRC_OFFSET 0x0034 /* Power Port C pull-down control register */ +#define STM32L4_PWR_PUCRD_OFFSET 0x0038 /* Power Port D pull-up control register */ +#define STM32L4_PWR_PDCRD_OFFSET 0x003C /* Power Port D pull-down control register */ +#define STM32L4_PWR_PUCRE_OFFSET 0x0040 /* Power Port E pull-up control register */ +#define STM32L4_PWR_PDCRE_OFFSET 0x0044 /* Power Port E pull-down control register */ +#define STM32L4_PWR_PUCRF_OFFSET 0x0048 /* Power Port F pull-up control register */ +#define STM32L4_PWR_PDCRF_OFFSET 0x004C /* Power Port F pull-down control register */ +#define STM32L4_PWR_PUCRG_OFFSET 0x0050 /* Power Port G pull-up control register */ +#define STM32L4_PWR_PDCRG_OFFSET 0x0054 /* Power Port G pull-down control register */ +#define STM32L4_PWR_PUCRH_OFFSET 0x0058 /* Power Port H pull-up control register */ +#define STM32L4_PWR_PDCRH_OFFSET 0x005C /* Power Port H pull-down control register */ + +/* Register Addresses ***************************************************************/ + +#define STM32L4_PWR_CR1 (STM32L4_PWR_BASE+STM32L4_PWR_CR1_OFFSET) +#define STM32L4_PWR_CR2 (STM32L4_PWR_BASE+STM32L4_PWR_CR2_OFFSET) +#define STM32L4_PWR_CR3 (STM32L4_PWR_BASE+STM32L4_PWR_CR3_OFFSET) +#define STM32L4_PWR_CR4 (STM32L4_PWR_BASE+STM32L4_PWR_CR4_OFFSET) +#define STM32L4_PWR_SR1 (STM32L4_PWR_BASE+STM32L4_PWR_SR1_OFFSET) +#define STM32L4_PWR_SR2 (STM32L4_PWR_BASE+STM32L4_PWR_SR2_OFFSET) +#define STM32L4_PWR_SCR (STM32L4_PWR_BASE+STM32L4_PWR_SCR_OFFSET) +#define STM32L4_PWR_PUCRA (STM32L4_PWR_BASE+STM32L4_PWR_PUCRA_OFFSET) +#define STM32L4_PWR_PDCRA (STM32L4_PWR_BASE+STM32L4_PWR_PDCRA_OFFSET) +#define STM32L4_PWR_PUCRB (STM32L4_PWR_BASE+STM32L4_PWR_PUCRB_OFFSET) +#define STM32L4_PWR_PDCRB (STM32L4_PWR_BASE+STM32L4_PWR_PDCRB_OFFSET) +#define STM32L4_PWR_PUCRC (STM32L4_PWR_BASE+STM32L4_PWR_PUCRC_OFFSET) +#define STM32L4_PWR_PDCRC (STM32L4_PWR_BASE+STM32L4_PWR_PDCRC_OFFSET) +#define STM32L4_PWR_PUCRD (STM32L4_PWR_BASE+STM32L4_PWR_PUCRD_OFFSET) +#define STM32L4_PWR_PDCRD (STM32L4_PWR_BASE+STM32L4_PWR_PDCRD_OFFSET) +#define STM32L4_PWR_PUCRE (STM32L4_PWR_BASE+STM32L4_PWR_PUCRE_OFFSET) +#define STM32L4_PWR_PDCRE (STM32L4_PWR_BASE+STM32L4_PWR_PDCRE_OFFSET) +#define STM32L4_PWR_PUCRF (STM32L4_PWR_BASE+STM32L4_PWR_PUCRF_OFFSET) +#define STM32L4_PWR_PDCRF (STM32L4_PWR_BASE+STM32L4_PWR_PDCRF_OFFSET) +#define STM32L4_PWR_PUCRG (STM32L4_PWR_BASE+STM32L4_PWR_PUCRG_OFFSET) +#define STM32L4_PWR_PDCRG (STM32L4_PWR_BASE+STM32L4_PWR_PDCRG_OFFSET) +#define STM32L4_PWR_PUCRH (STM32L4_PWR_BASE+STM32L4_PWR_PUCRH_OFFSET) +#define STM32L4_PWR_PDCRH (STM32L4_PWR_BASE+STM32L4_PWR_PDCRH_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Power control register 1 */ + +#define PWR_CR1_LPMS_SHIFT 0 +#define PWR_CR1_LPMS_MASK (7 << PWR_CR1_LPMS_SHIFT) /* Bits 0-2: Low-power mode selection */ +# define PWR_CR1_LPMS_STOP0 (0 << PWR_CR1_LPMS_SHIFT) /* 000: Stop 0 mode */ +# define PWR_CR1_LPMS_STOP1 (1 << PWR_CR1_LPMS_SHIFT) /* 001: Stpp 1 mode */ +# define PWR_CR1_LPMS_STOP2 (2 << PWR_CR1_LPMS_SHIFT) /* 010: Stop 2 mode*/ +# define PWR_CR1_LPMS_STANDBY (3 << PWR_CR1_LPMS_SHIFT) /* 011: Standby mode */ +# define PWR_CR1_LPMS_SHUTDOWN (4 << PWR_CR1_LPMS_SHIFT) /* 1xx: Shutdown node */ +#define PWR_CR1_DBP (1 << 8) /* Bit 8: Disable Backup domain write protection */ +#define PWR_CR1_VOS_SHIFT 9 +#define PWR_CR1_VOS_MASK (3 << PWR_CR1_VOS_SHIFT) /* Bits 9-10: Voltage scaling range selection */ +#define PWR_CR1_VOS_RANGE1 (1 << PWR_CR1_VOS_SHIFT) /* 01: Range 1 */ +#define PWR_CR1_VOS_RANGE2 (2 << PWR_CR1_VOS_SHIFT) /* 10: Range 2 */ +#define PWR_CR1_LPR (1 << 14) /* Bit 14: Low-power run */ + +/* Power control register 2 */ + +#define PWR_CR2_PVDE (1 << 0) /* Bit 0: Power voltage detector enable */ +#define PWR_CR2_PLS_SHIFT 1 +#define PWR_CR2_PLS_MASK (7 << PWR_CR2_PLS_SHIFT) /* Bits 1-3: Power voltage detector level selection */ +# define PWR_CR2_PLS_2000mv (0 << PWR_CR2_PLS_SHIFT) /* 000: VPVD0 around 2.0V */ +# define PWR_CR2_PLS_2200mv (1 << PWR_CR2_PLS_SHIFT) /* 001: VPVD1 around 2.2V */ +# define PWR_CR2_PLS_2400mv (2 << PWR_CR2_PLS_SHIFT) /* 010: VPVD2 around 2.4V */ +# define PWR_CR2_PLS_2500mv (3 << PWR_CR2_PLS_SHIFT) /* 011: VPVD3 around 2.5V */ +# define PWR_CR2_PLS_2600mv (4 << PWR_CR2_PLS_SHIFT) /* 100: VPVD4 around 2.6V */ +# define PWR_CR2_PLS_2800mv (5 << PWR_CR2_PLS_SHIFT) /* 101: VPVD5 around 2.8V */ +# define PWR_CR2_PLS_2900mv (6 << PWR_CR2_PLS_SHIFT) /* 110: VPVD6 around 2.9V */ +# define PWR_CR2_PLS_EXT (7 << PWR_CR2_PLS_SHIFT) /* 111: External input analog voltage PVD_IN */ +#define PWR_CR2_PVME1 (1 << 4) /* Bit 4: Peripheral voltage monitoring 1 enable (VDDUSB vs 1.2V) */ +#define PWR_CR2_PVME2 (1 << 5) /* Bit 5: Peripheral voltage monitoring 2 enable (VDDIO2 vs 0.9V) */ +#define PWR_CR2_PVME3 (1 << 6) /* Bit 6: Peripheral voltage monitoring 3 enable (VDDA vs 1.62V) */ +#define PWR_CR2_PVME4 (1 << 7) /* Bit 7: Peripheral voltage monitoring 4 enable (VDDA vs 2.2V) */ +#define PWR_CR2_IOSV (1 << 9) /* Bit 9: VDDIO2 Independent I/Os supply valid */ +#define PWR_CR2_USV (1 << 10) /* Bit 10: VDDUSB USB supply valid */ + +/* Power control register 3 */ + +#define PWR_CR3_EWUP1 (1 << 0) /* Bit 0: Enable Wakeup pin WKUP1 */ +#define PWR_CR3_EWUP2 (1 << 1) /* Bit 1: Enable Wakeup pin WKUP2 */ +#define PWR_CR3_EWUP3 (1 << 2) /* Bit 2: Enable Wakeup pin WKUP3 */ +#define PWR_CR3_EWUP4 (1 << 3) /* Bit 3: Enable Wakeup pin WKUP4 */ +#define PWR_CR3_EWUP5 (1 << 4) /* Bit 4: Enable Wakeup pin WKUP5 */ +#define PWR_CR3_RRS (1 << 8) /* Bit 8: SRAM2 retention in Standby mode */ +#define PWR_CR3_APC (1 << 10) /* Bit 10: Apply pull-up and pull-down configuration */ +#define PWR_CR3_EIWUL (1 << 15) /* Bit 15: Enable internal wakeup line */ + +/* Power control register 4 */ + +#define PWR_CR4_WP1 (1 << 0) /* Bit 0: Wakeup pin WKUP1 polarity */ +#define PWR_CR4_WP2 (1 << 1) /* Bit 1: Wakeup pin WKUP2 polarity */ +#define PWR_CR4_WP3 (1 << 2) /* Bit 2: Wakeup pin WKUP3 polarity */ +#define PWR_CR4_WP4 (1 << 3) /* Bit 3: Wakeup pin WKUP4 polarity */ +#define PWR_CR4_WP5 (1 << 4) /* Bit 4: Wakeup pin WKUP5 polarity */ +#define PWR_CR4_VBE (1 << 8) /* Bit 8: Vbat battery charging enable */ +#define PWR_CR4_VBRS (1 << 9) /* Bit 9: Vbat barrery charging resistor selection */ +# define PWR_CR4_VBRS_5k 0 /* 0: 5k resistor */ +# define PWR_CR4_VBRS_1k5 PWR_CR4_VBRS /* 1: 1k5 resistor */ + +/* Power status register 1 */ + +#define PWR_SR1_WUF1 (1 << 0) /* Bit 0: Wakeup flag 1 */ +#define PWR_SR1_WUF2 (1 << 1) /* Bit 1: Wakeup flag 2 */ +#define PWR_SR1_WUF3 (1 << 2) /* Bit 2: Wakeup flag 3 */ +#define PWR_SR1_WUF4 (1 << 3) /* Bit 3: Wakeup flag 4 */ +#define PWR_SR1_WUF5 (1 << 4) /* Bit 4: Wakeup flag 5 */ +#define PWR_SR1_SBF (1 << 8) /* Bit 8: Standby flag */ +#define PWR_SR1_WUFI (1 << 15) /* Bit 15: Wakeup internal flag */ + +/* Power status register 2 */ + +#define PWR_SR2_REGLPS (1 << 0) /* Bit 0: Low power regulator started */ +#define PWR_SR2_REGLPF (1 << 1) /* Bit 1: Low power regulator flag */ +#define PWR_SR2_VOSF (1 << 10) /* Bit 10: Voltage scaling flag */ +#define PWR_SR2_PVDO (1 << 11) /* Bit 11: Power voltage detector output */ +#define PWR_SR2_PVMO1 (1 << 12) /* Bit 12: Peripheral voltage monitoring output 1 (VDDUSB vs 1.2V) */ +#define PWR_SR2_PVMO2 (1 << 13) /* Bit 13: Peripheral voltage monitoring output 2 (VDDIO2 vs 0.9V) */ +#define PWR_SR2_PVMO3 (1 << 14) /* Bit 14: Peripheral voltage monitoring output 3 (VDDA vs 1.62V) */ +#define PWR_SR2_PVMO4 (1 << 15) /* Bit 15: Peripheral voltage monitoring output 4 (VDDA vs 2.2V) */ + +/* Power status clear register */ + +#define PWR_SCR_CWUF1 (1 << 0) /* Bit 0: Clear wakeup flag 1 */ +#define PWR_SCR_CWUF2 (1 << 1) /* Bit 1: Clear wakeup flag 2 */ +#define PWR_SCR_CWUF3 (1 << 2) /* Bit 2: Clear wakeup flag 3 */ +#define PWR_SCR_CWUF4 (1 << 3) /* Bit 3: Clear wakeup flag 4 */ +#define PWR_SCR_CWUF5 (1 << 4) /* Bit 4: Clear wakeup flag 5 */ +#define PWR_SCR_CSBF (1 << 8) /* Bit 8: Clear standby flag */ + +/* Port X pull-up/down registers have one bit per port line, with a few exceptions */ + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_PWR_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4_spi.h b/arch/arm/src/stm32l4/chip/stm32l4_spi.h new file mode 100644 index 00000000000..c9a1a03ef28 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_spi.h @@ -0,0 +1,181 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_spi.h + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_CHIP_STM32L4_SPI_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Maximum allowed speed as per specifications for all SPIs */ + +#if defined(CONFIG_STM32L4_STM32F40XX) +# define STM32L4_SPI_CLK_MAX 37500000UL +#else +# define STM32L4_SPI_CLK_MAX 18000000UL +#endif + +/* Register Offsets *****************************************************************/ + +#define STM32L4_SPI_CR1_OFFSET 0x0000 /* SPI Control Register 1 (16-bit) */ +#define STM32L4_SPI_CR2_OFFSET 0x0004 /* SPI control register 2 (16-bit) */ +#define STM32L4_SPI_SR_OFFSET 0x0008 /* SPI status register (16-bit) */ +#define STM32L4_SPI_DR_OFFSET 0x000c /* SPI data register (16-bit) */ +#define STM32L4_SPI_CRCPR_OFFSET 0x0010 /* SPI CRC polynomial register (16-bit) */ +#define STM32L4_SPI_RXCRCR_OFFSET 0x0014 /* SPI Rx CRC register (16-bit) */ +#define STM32L4_SPI_TXCRCR_OFFSET 0x0018 /* SPI Tx CRC register (16-bit) */ + +/* Register Addresses ***************************************************************/ + +#if STM32L4_NSPI > 0 +# define STM32L4_SPI1_CR1 (STM32L4_SPI1_BASE+STM32L4_SPI_CR1_OFFSET) +# define STM32L4_SPI1_CR2 (STM32L4_SPI1_BASE+STM32L4_SPI_CR2_OFFSET) +# define STM32L4_SPI1_SR (STM32L4_SPI1_BASE+STM32L4_SPI_SR_OFFSET) +# define STM32L4_SPI1_DR (STM32L4_SPI1_BASE+STM32L4_SPI_DR_OFFSET) +# define STM32L4_SPI1_CRCPR (STM32L4_SPI1_BASE+STM32L4_SPI_CRCPR_OFFSET) +# define STM32L4_SPI1_RXCRCR (STM32L4_SPI1_BASE+STM32L4_SPI_RXCRCR_OFFSET) +# define STM32L4_SPI1_TXCRCR (STM32L4_SPI1_BASE+STM32L4_SPI_TXCRCR_OFFSET) +#endif + +#if STM32L4_NSPI > 1 +# define STM32L4_SPI2_CR1 (STM32L4_SPI2_BASE+STM32L4_SPI_CR1_OFFSET) +# define STM32L4_SPI2_CR2 (STM32L4_SPI2_BASE+STM32L4_SPI_CR2_OFFSET) +# define STM32L4_SPI2_SR (STM32L4_SPI2_BASE+STM32L4_SPI_SR_OFFSET) +# define STM32L4_SPI2_DR (STM32L4_SPI2_BASE+STM32L4_SPI_DR_OFFSET) +# define STM32L4_SPI2_CRCPR (STM32L4_SPI2_BASE+STM32L4_SPI_CRCPR_OFFSET) +# define STM32L4_SPI2_RXCRCR (STM32L4_SPI2_BASE+STM32L4_SPI_RXCRCR_OFFSET) +# define STM32L4_SPI2_TXCRCR (STM32L4_SPI2_BASE+STM32L4_SPI_TXCRCR_OFFSET) +#endif + +#if STM32L4_NSPI > 2 +# define STM32L4_SPI3_CR1 (STM32L4_SPI3_BASE+STM32L4_SPI_CR1_OFFSET) +# define STM32L4_SPI3_CR2 (STM32L4_SPI3_BASE+STM32L4_SPI_CR2_OFFSET) +# define STM32L4_SPI3_SR (STM32L4_SPI3_BASE+STM32L4_SPI_SR_OFFSET) +# define STM32L4_SPI3_DR (STM32L4_SPI3_BASE+STM32L4_SPI_DR_OFFSET) +# define STM32L4_SPI3_CRCPR (STM32L4_SPI3_BASE+STM32L4_SPI_CRCPR_OFFSET) +# define STM32L4_SPI3_RXCRCR (STM32L4_SPI3_BASE+STM32L4_SPI_RXCRCR_OFFSET) +# define STM32L4_SPI3_TXCRCR (STM32L4_SPI3_BASE+STM32L4_SPI_TXCRCR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* SPI Control Register 1 */ + +#define SPI_CR1_CPHA (1 << 0) /* Bit 0: Clock Phase */ +#define SPI_CR1_CPOL (1 << 1) /* Bit 1: Clock Polarity */ +#define SPI_CR1_MSTR (1 << 2) /* Bit 2: Master Selection */ +#define SPI_CR1_BR_SHIFT (3) /* Bits 5:3 Baud Rate Control */ +#define SPI_CR1_BR_MASK (7 << SPI_CR1_BR_SHIFT) +# define SPI_CR1_FPCLCKd2 (0 << SPI_CR1_BR_SHIFT) /* 000: fPCLK/2 */ +# define SPI_CR1_FPCLCKd4 (1 << SPI_CR1_BR_SHIFT) /* 001: fPCLK/4 */ +# define SPI_CR1_FPCLCKd8 (2 << SPI_CR1_BR_SHIFT) /* 010: fPCLK/8 */ +# define SPI_CR1_FPCLCKd16 (3 << SPI_CR1_BR_SHIFT) /* 011: fPCLK/16 */ +# define SPI_CR1_FPCLCKd32 (4 << SPI_CR1_BR_SHIFT) /* 100: fPCLK/32 */ +# define SPI_CR1_FPCLCKd64 (5 << SPI_CR1_BR_SHIFT) /* 101: fPCLK/64 */ +# define SPI_CR1_FPCLCKd128 (6 << SPI_CR1_BR_SHIFT) /* 110: fPCLK/128 */ +# define SPI_CR1_FPCLCKd256 (7 << SPI_CR1_BR_SHIFT) /* 111: fPCLK/256 */ +#define SPI_CR1_SPE (1 << 6) /* Bit 6: SPI Enable */ +#define SPI_CR1_LSBFIRST (1 << 7) /* Bit 7: Frame Format */ +#define SPI_CR1_SSI (1 << 8) /* Bit 8: Internal slave select */ +#define SPI_CR1_SSM (1 << 9) /* Bit 9: Software slave management */ +#define SPI_CR1_RXONLY (1 << 10) /* Bit 10: Receive only */ +#define SPI_CR1_CRCL (1 << 11) /* Bit 11: CRC length */ +#define SPI_CR1_CRCNEXT (1 << 12) /* Bit 12: Transmit CRC next */ +#define SPI_CR1_CRCEN (1 << 13) /* Bit 13: Hardware CRC calculation enable */ +#define SPI_CR1_BIDIOE (1 << 14) /* Bit 14: Output enable in bidirectional mode */ +#define SPI_CR1_BIDIMODE (1 << 15) /* Bit 15: Bidirectional data mode enable */ + +/* SPI Control Register 2 */ + +#define SPI_CR2_RXDMAEN (1 << 0) /* Bit 0: Rx Buffer DMA Enable */ +#define SPI_CR2_TXDMAEN (1 << 1) /* Bit 1: Tx Buffer DMA Enable */ +#define SPI_CR2_SSOE (1 << 2) /* Bit 2: SS Output Enable */ +#define SPI_CR2_NSSP (1 << 3) /* Bit 3: NSS pulse management */ +#define SPI_CR2_FRF (1 << 4) /* Bit 4: Frame format */ +#define SPI_CR2_ERRIE (1 << 5) /* Bit 5: Error interrupt enable */ +#define SPI_CR2_RXNEIE (1 << 6) /* Bit 6: RX buffer not empty interrupt enable */ +#define SPI_CR2_TXEIE (1 << 7) /* Bit 7: Tx buffer empty interrupt enable */ +#define SPI_CR2_DS_SHIFT (8) /* Bits 8-11: Data size */ +#define SPI_CR2_DS_MASK (15 << SPI_CR2_DS_SHIFT) +# define SPI_CR2_DS_VAL(bits) ( ((bits)-1) << SPI_CR2_DS_SHIFT) +# define SPI_CR2_DS_4BIT SPI_CR2_DS_VAL( 4) +# define SPI_CR2_DS_5BIT SPI_CR2_DS_VAL( 5) +# define SPI_CR2_DS_6BIT SPI_CR2_DS_VAL( 6) +# define SPI_CR2_DS_7BIT SPI_CR2_DS_VAL( 7) +# define SPI_CR2_DS_8BIT SPI_CR2_DS_VAL( 8) +# define SPI_CR2_DS_9BIT SPI_CR2_DS_VAL( 9) +# define SPI_CR2_DS_10BIT SPI_CR2_DS_VAL(10) +# define SPI_CR2_DS_11BIT SPI_CR2_DS_VAL(11) +# define SPI_CR2_DS_12BIT SPI_CR2_DS_VAL(12) +# define SPI_CR2_DS_13BIT SPI_CR2_DS_VAL(13) +# define SPI_CR2_DS_14BIT SPI_CR2_DS_VAL(14) +# define SPI_CR2_DS_15BIT SPI_CR2_DS_VAL(15) +# define SPI_CR2_DS_16BIT SPI_CR2_DS_VAL(16) +#define SPI_CR2_FRXTH (1 << 12) /* Bit 12: FIFO reception threshold */ +#define SPI_CR2_LDMARX (1 << 13) /* Bit 13: Last DMA transfer for receptione */ +#define SPI_CR2_LDMATX (1 << 14) /* Bit 14: Last DMA transfer for transmission */ + +/* SPI status register */ + +#define SPI_SR_RXNE (1 << 0) /* Bit 0: Receive buffer not empty */ +#define SPI_SR_TXE (1 << 1) /* Bit 1: Transmit buffer empty */ +#define SPI_SR_CRCERR (1 << 4) /* Bit 4: CRC error flag */ +#define SPI_SR_MODF (1 << 5) /* Bit 5: Mode fault */ +#define SPI_SR_OVR (1 << 6) /* Bit 6: Overrun flag */ +#define SPI_SR_BSY (1 << 7) /* Bit 7: Busy flag */ +#define SPI_SR_FRE (1 << 8) /* Bit 8: Frame format error */ +#define SPI_SR_FRLVL_SHIFT (9) /* Bits 9-10: FIFO reception level */ +#define SPI_SR_FRLVL_MASK (3 << SPI_SR_FRLVL_SHIFT) +# define SPI_SR_FRLVL_EMPTY (0 << SPI_SR_FRLVL_SHIFT) /* FIFO empty */ +# define SPI_SR_FRLVL_QUARTER (1 << SPI_SR_FRLVL_SHIFT) /* 1/4 FIFO */ +# define SPI_SR_FRLVL_HALF (2 << SPI_SR_FRLVL_SHIFT) /* 1/2 FIFO */ +# define SPI_SR_FRLVL_FULL (3 << SPI_SR_FRLVL_SHIFT) /* FIFO full */ +#define SPI_SR_FTLVL_SHIFT (11) /* Bits 11-12: FIFO transmission level */ +#define SPI_SR_FTLVL_MASK (3 << SPI_SR_FTLVL_SHIFT) +# define SPI_SR_FTLVL_EMPTY (0 << SPI_SR_FTLVL_SHIFT) /* FIFO empty */ +# define SPI_SR_FTLVL_QUARTER (1 << SPI_SR_FTLVL_SHIFT) /* 1/4 FIFO */ +# define SPI_SR_FTLVL_HALF (2 << SPI_SR_FTLVL_SHIFT) /* 1/2 FIFO */ +# define SPI_SR_FTLVL_FULL (3 << SPI_SR_FTLVL_SHIFT) /* FIFO full */ + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SPI_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h b/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h new file mode 100644 index 00000000000..2e34974769c --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h @@ -0,0 +1,184 @@ +/**************************************************************************************************** + * arch/arm/src/stm32l4/chip/stm32l4_syscfg.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_CHIP_STM32L4_SYSCFG_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SYSCFG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32L4_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */ +#define STM32L4_SYSCFG_CFGR1_OFFSET 0x0004 /* SYSCFG configuration register 1 */ +#define STM32L4_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32L4_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */ +#define STM32L4_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */ +#define STM32L4_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */ +#define STM32L4_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */ +#define STM32L4_SYSCFG_SCSR_OFFSET 0x0018 /* SYSCFG SRAM2 control and status register */ +#define STM32L4_SYSCFG_CFGR2_OFFSET 0x001c /* SYSCFG configuration register 2 */ +#define STM32L4_SYSCFG_SWPR_OFFSET 0x0020 /* SYSCFG SRAM2 write protection register */ +#define STM32L4_SYSCFG_SKR_OFFSET 0x0024 /* SYSCFG SRAM2 key register */ + +/* Register Addresses *******************************************************************************/ + +#define STM32L4_SYSCFG_MEMRMP (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_MEMRMP_OFFSET) +#define STM32L4_SYSCFG_CFGR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR1_OFFSET) +#define STM32L4_SYSCFG_EXTICR(p) (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR_OFFSET(p)) +#define STM32L4_SYSCFG_EXTICR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR1_OFFSET) +#define STM32L4_SYSCFG_EXTICR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR2_OFFSET) +#define STM32L4_SYSCFG_EXTICR3 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR3_OFFSET) +#define STM32L4_SYSCFG_EXTICR4 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR4_OFFSET) +#define STM32L4_SYSCFG_SCSR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SCSR_OFFSET) +#define STM32L4_SYSCFG_CFGR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR2_OFFSET) +#define STM32L4_SYSCFG_SWPR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SWPR_OFFSET) +#define STM32L4_SYSCFG_SKR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SKR_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* SYSCFG memory remap register */ + +#define SYSCFG_MEMRMP_SHIFT (0) /* Bits 2:0 MEM_MODE: Memory mapping selection */ +#define SYSCFG_MEMRMP_MASK (7 << SYSCFG_MEMRMP_SHIFT) +# define SYSCFG_MEMRMP_FLASH (0 << SYSCFG_MEMRMP_SHIFT) /* 000: Main Flash memory mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_SYSTEM (1 << SYSCFG_MEMRMP_SHIFT) /* 001: System Flash memory mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_FMC (2 << SYSCFG_MEMRMP_SHIFT) /* 010: FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_SRAM (3 << SYSCFG_MEMRMP_SHIFT) /* 011: SRAM1 (112kB) mapped at 0x0000 0000 */ +# define SYSCFG_MEMRMP_QSPI (6 << SYSCFG_MEMRMP_SHIFT) /* 110: QUADSPI mapped at 0x0000 0000 */ +#define SYSCFG_FBMODE (1 << 8) /* Bit 8: Flash Bank mode selection */ + +/* SYSCFG configuration register 1 */ + +#define SYSCFG_CFGR1_FWDIS (1 << 0) /* Bit 0: Firewall disable */ +#define SYSCFG_CFGR1_BOOSTEN (1 << 8) /* Bit 8: I/O analog switch voltage booster enable (use when vdd is low) */ +#define SYSCFG_CFGR1_I2C_PB6_FMP (1 << 16) /* Bit 16: Fast-mode Plus (Fm+) driving capability activation on PB6 */ +#define SYSCFG_CFGR1_I2C_PB7_FMP (1 << 17) /* Bit 17: Fast-mode Plus (Fm+) driving capability activation on PB7 */ +#define SYSCFG_CFGR1_I2C_PB8_FMP (1 << 18) /* Bit 18: Fast-mode Plus (Fm+) driving capability activation on PB8 */ +#define SYSCFG_CFGR1_I2C_PB9_FMP (1 << 19) /* Bit 19: Fast-mode Plus (Fm+) driving capability activation on PB9 */ +#define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 Fast-mode Plus (Fm+) driving capability activation */ +#define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C1 Fast-mode Plus (Fm+) driving capability activation */ +#define SYSCFG_CFGR1_I2C3_FMP (1 << 22) /* Bit 22: I2C1 Fast-mode Plus (Fm+) driving capability activation */ +#define SYSCFG_CFGR1_FPU_IE0 (1 << 26) /* Bit 26: FPU Invalid operation interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE1 (1 << 27) /* Bit 27: FPU Divide-by-zero interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE2 (1 << 28) /* Bit 28: FPU Underflow interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE3 (1 << 29) /* Bit 29: FPU Overflow interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE4 (1 << 30) /* Bit 30: FPU Input denormal interrupt enable */ +#define SYSCFG_CFGR1_FPU_IE5 (1 << 31) /* Bit 31: FPU Inexact interrupt enable */ + +/* SYSCFG external interrupt configuration register 1-4 */ + +#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */ +#define SYSCFG_EXTICR_PORTF (5) /* 0101: PF[C] pin */ +#define SYSCFG_EXTICR_PORTG (6) /* 0110: PG[x] pin */ + +#define SYSCFG_EXTICR_PORT_MASK (7) +#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2) +#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g))) + +#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-2: EXTI 0 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT) +#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-6: EXTI 1 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT) +#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-10: EXTI 2 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT) +#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-14: EXTI 3 coinfiguration */ +#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT) + +#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-2: EXTI 4 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT) +#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-6: EXTI 5 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT) +#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-10: EXTI 6 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT) +#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-14: EXTI 7 coinfiguration */ +#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT) + +#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-2: EXTI 8 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT) +#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-6: EXTI 9 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT) +#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-10: EXTI 10 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT) +#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-14: EXTI 11 coinfiguration */ +#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT) + +#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-2: EXTI 12 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT) +#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-6: EXTI 13 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT) +#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-10: EXTI 14 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT) +#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-14: EXTI 15 coinfiguration */ +#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT) + +/* SYSCFG SRAM2 control and status register */ + +#define SYSCFG_SCSR_SRAM2ER (1 << 0) /* Bit 0: SRAM2 Erase */ +#define SYSCFG_SCSR_SRAM2BSY (1 << 1) /* Bit 1: SRAM2 busy in erase operation */ + +/* SYSCFG configuration register 2 */ + +#define SYSCFG_CFGR2_CLL (1 << 0) /* Bit 0: Cortex-M4 LOCKUP (Hardfault) output enable (TIMx break enable, see refman) */ +#define SYSCFG_CFGR2_SPL (1 << 1) /* Bit 1: SRAM2 parity lock enable (same) */ +#define SYSCFG_CFGR2_PVDL (1 << 2) /* Bit 2: PVD lock enable (same) */ +#define SYSCFG_CFGR2_ECCL (1 << 3) /* Bit 3: ECC lock enable (same) */ +#define SYSCFG_CFGR2_SPF (1 << 8) /* Bit 8: SRAM2 parity error flag */ + +/* SYSCFG SRAM2 write protection register */ +/* There is one bit per SRAM2 page */ + +/* SYSCFG SRAM2 key register */ + +#define SYSCFG_SKR_SHIFT 0 +#define SYSCFG_SKR_MASK (0xFF << SYSCFG_SKR_SHIFT) + +#endif /* CONFIG_STM32L4_STM32L476XX || CONFIG_STM32L4_STM32L486XX */ +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SYSCFG_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h new file mode 100644 index 00000000000..95558c3b381 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h @@ -0,0 +1,435 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_CHIP_STM32L4X6XX_DMA_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_DMA_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* These definitions apply to both the STM32 F1 and F3 families */ +/* 12 Channels Total: 7 DMA1 Channels(1-7) and 5 DMA2 channels (1-5) */ + +#define DMA1 0 +#define DMA2 1 +#define DMA3 2 +#define DMA4 3 +#define DMA5 4 +#define DMA6 5 +#define DMA7 6 + +/* Register Offsets *****************************************************************/ + +#define STM32L4_DMA_ISR_OFFSET 0x0000 /* DMA interrupt status register */ +#define STM32L4_DMA_IFCR_OFFSET 0x0004 /* DMA interrupt flag clear register */ + +#define STM32L4_DMACHAN_OFFSET(n) (0x0014*(n)) +#define STM32L4_DMACHAN1_OFFSET 0x0000 +#define STM32L4_DMACHAN2_OFFSET 0x0014 +#define STM32L4_DMACHAN3_OFFSET 0x0028 +#define STM32L4_DMACHAN4_OFFSET 0x003c +#define STM32L4_DMACHAN5_OFFSET 0x0050 +#define STM32L4_DMACHAN6_OFFSET 0x0064 +#define STM32L4_DMACHAN7_OFFSET 0x0078 + +#define STM32L4_DMACHAN_CCR_OFFSET 0x0008 /* DMA channel configuration register */ +#define STM32L4_DMACHAN_CNDTR_OFFSET 0x000c /* DMA channel number of data register */ +#define STM32L4_DMACHAN_CPAR_OFFSET 0x0010 /* DMA channel peripheral address register */ +#define STM32L4_DMACHAN_CMAR_OFFSET 0x0014 /* DMA channel memory address register */ + +#define STM32L4_DMA_CCR_OFFSET(n) (STM32L4_DMACHAN_CCR_OFFSET+STM32L4_DMACHAN_OFFSET(n)) +#define STM32L4_DMA_CNDTR_OFFSET(n) (STM32L4_DMACHAN_CNDTR_OFFSET+STM32L4_DMACHAN_OFFSET(n)) +#define STM32L4_DMA_CPAR_OFFSET(n) (STM32L4_DMACHAN_CPAR_OFFSET+STM32L4_DMACHAN_OFFSET(n)) +#define STM32L4_DMA_CMAR_OFFSET(n) (STM32L4_DMACHAN_CMAR_OFFSET+STM32L4_DMACHAN_OFFSET(n)) + +#define STM32L4_DMA_CCR1_OFFSET 0x0008 /* DMA channel 1 configuration register */ +#define STM32L4_DMA_CCR2_OFFSET 0x001c /* DMA channel 2 configuration register */ +#define STM32L4_DMA_CCR3_OFFSET 0x0030 /* DMA channel 3 configuration register */ +#define STM32L4_DMA_CCR4_OFFSET 0x0044 /* DMA channel 4 configuration register */ +#define STM32L4_DMA_CCR5_OFFSET 0x0058 /* DMA channel 5 configuration register */ +#define STM32L4_DMA_CCR6_OFFSET 0x006c /* DMA channel 6 configuration register */ +#define STM32L4_DMA_CCR7_OFFSET 0x0080 /* DMA channel 7 configuration register */ + +#define STM32L4_DMA_CNDTR1_OFFSET 0x000c /* DMA channel 1 number of data register */ +#define STM32L4_DMA_CNDTR2_OFFSET 0x0020 /* DMA channel 2 number of data register */ +#define STM32L4_DMA_CNDTR3_OFFSET 0x0034 /* DMA channel 3 number of data register */ +#define STM32L4_DMA_CNDTR4_OFFSET 0x0048 /* DMA channel 4 number of data register */ +#define STM32L4_DMA_CNDTR5_OFFSET 0x005c /* DMA channel 5 number of data register */ +#define STM32L4_DMA_CNDTR6_OFFSET 0x0070 /* DMA channel 6 number of data register */ +#define STM32L4_DMA_CNDTR7_OFFSET 0x0084 /* DMA channel 7 number of data register */ + +#define STM32L4_DMA_CPAR1_OFFSET 0x0010 /* DMA channel 1 peripheral address register */ +#define STM32L4_DMA_CPAR2_OFFSET 0x0024 /* DMA channel 2 peripheral address register */ +#define STM32L4_DMA_CPAR3_OFFSET 0x0038 /* DMA channel 3 peripheral address register */ +#define STM32L4_DMA_CPAR4_OFFSET 0x004c /* DMA channel 4 peripheral address register */ +#define STM32L4_DMA_CPAR5_OFFSET 0x0060 /* DMA channel 5 peripheral address register */ +#define STM32L4_DMA_CPAR6_OFFSET 0x0074 /* DMA channel 6 peripheral address register */ +#define STM32L4_DMA_CPAR7_OFFSET 0x0088 /* DMA channel 7 peripheral address register */ + +#define STM32L4_DMA_CMAR1_OFFSET 0x0014 /* DMA channel 1 memory address register */ +#define STM32L4_DMA_CMAR2_OFFSET 0x0028 /* DMA channel 2 memory address register */ +#define STM32L4_DMA_CMAR3_OFFSET 0x003c /* DMA channel 3 memory address register */ +#define STM32L4_DMA_CMAR4_OFFSET 0x0050 /* DMA channel 4 memory address register */ +#define STM32L4_DMA_CMAR5_OFFSET 0x0064 /* DMA channel 5 memory address register */ +#define STM32L4_DMA_CMAR6_OFFSET 0x0078 /* DMA channel 6 memory address register */ +#define STM32L4_DMA_CMAR7_OFFSET 0x008c /* DMA channel 7 memory address register */ + +#define STM32L4_DMA_CSELR_OFFSET 0x00a8 /* DMA channel selection register */ + +/* Register Addresses ***************************************************************/ + +#define STM32L4_DMA1_ISRC (STM32L4_DMA1_BASE+STM32L4_DMA_ISR_OFFSET) +#define STM32L4_DMA1_IFCR (STM32L4_DMA1_BASE+STM32L4_DMA_IFCR_OFFSET) + +#define STM32L4_DMA1_CCR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CCR_OFFSET(n)) +#define STM32L4_DMA1_CCR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR1_OFFSET) +#define STM32L4_DMA1_CCR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR2_OFFSET) +#define STM32L4_DMA1_CCR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR3_OFFSET) +#define STM32L4_DMA1_CCR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR4_OFFSET) +#define STM32L4_DMA1_CCR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR5_OFFSET) +#define STM32L4_DMA1_CCR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR6_OFFSET) +#define STM32L4_DMA1_CCR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR7_OFFSET) + +#define STM32L4_DMA1_CNDTR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR_OFFSET(n)) +#define STM32L4_DMA1_CNDTR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR1_OFFSET) +#define STM32L4_DMA1_CNDTR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR2_OFFSET) +#define STM32L4_DMA1_CNDTR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR3_OFFSET) +#define STM32L4_DMA1_CNDTR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR4_OFFSET) +#define STM32L4_DMA1_CNDTR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR5_OFFSET) +#define STM32L4_DMA1_CNDTR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR6_OFFSET) +#define STM32L4_DMA1_CNDTR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR7_OFFSET) + +#define STM32L4_DMA1_CPAR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR_OFFSET(n)) +#define STM32L4_DMA1_CPAR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR1_OFFSET) +#define STM32L4_DMA1_CPAR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR2_OFFSET) +#define STM32L4_DMA1_CPAR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR3_OFFSET) +#define STM32L4_DMA1_CPAR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR4_OFFSET) +#define STM32L4_DMA1_CPAR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR5_OFFSET) +#define STM32L4_DMA1_CPAR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR6_OFFSET) +#define STM32L4_DMA1_CPAR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR7_OFFSET) + +#define STM32L4_DMA1_CMAR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR_OFFSET(n)) +#define STM32L4_DMA1_CMAR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR1_OFFSET) +#define STM32L4_DMA1_CMAR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR2_OFFSET) +#define STM32L4_DMA1_CMAR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR3_OFFSET) +#define STM32L4_DMA1_CMAR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR4_OFFSET) +#define STM32L4_DMA1_CMAR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR5_OFFSET) +#define STM32L4_DMA1_CMAR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR6_OFFSET) +#define STM32L4_DMA1_CMAR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR7_OFFSET) + +#define STM32L4_DMA2_ISRC (STM32L4_DMA2_BASE+STM32L4_DMA_ISR_OFFSET) +#define STM32L4_DMA2_IFCR (STM32L4_DMA2_BASE+STM32L4_DMA_IFCR_OFFSET) + +#define STM32L4_DMA2_CCR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CCR_OFFSET(n)) +#define STM32L4_DMA2_CCR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR1_OFFSET) +#define STM32L4_DMA2_CCR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR2_OFFSET) +#define STM32L4_DMA2_CCR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR3_OFFSET) +#define STM32L4_DMA2_CCR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR4_OFFSET) +#define STM32L4_DMA2_CCR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR5_OFFSET) + +#define STM32L4_DMA2_CNDTR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR_OFFSET(n)) +#define STM32L4_DMA2_CNDTR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR1_OFFSET) +#define STM32L4_DMA2_CNDTR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR2_OFFSET) +#define STM32L4_DMA2_CNDTR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR3_OFFSET) +#define STM32L4_DMA2_CNDTR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR4_OFFSET) +#define STM32L4_DMA2_CNDTR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR5_OFFSET) + +#define STM32L4_DMA2_CPAR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR_OFFSET(n)) +#define STM32L4_DMA2_CPAR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR1_OFFSET) +#define STM32L4_DMA2_CPAR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR2_OFFSET) +#define STM32L4_DMA2_CPAR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR3_OFFSET) +#define STM32L4_DMA2_CPAR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR4_OFFSET) +#define STM32L4_DMA2_CPAR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR5_OFFSET) + +#define STM32L4_DMA2_CMAR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR_OFFSET(n)) +#define STM32L4_DMA2_CMAR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR1_OFFSET) +#define STM32L4_DMA2_CMAR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR2_OFFSET) +#define STM32L4_DMA2_CMAR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR3_OFFSET) +#define STM32L4_DMA2_CMAR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR4_OFFSET) +#define STM32L4_DMA2_CMAR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR5_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +#define DMA_CHAN_SHIFT(n) ((n) << 2) +#define DMA_CHAN_MASK 0x0f +#define DMA_CHAN_GIF_BIT (1 << 0) /* Bit 0: Channel Global interrupt flag */ +#define DMA_CHAN_TCIF_BIT (1 << 1) /* Bit 1: Channel Transfer Complete flag */ +#define DMA_CHAN_HTIF_BIT (1 << 2) /* Bit 2: Channel Half Transfer flag */ +#define DMA_CHAN_TEIF_BIT (1 << 3) /* Bit 3: Channel Transfer Error flag */ + +/* DMA interrupt status register */ + +#define DMA_ISR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n) +#define DMA_ISR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt status */ +#define DMA_ISR_CHAN1_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN1_SHIFT) +#define DMA_ISR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt status */ +#define DMA_ISR_CHAN2_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN2_SHIFT) +#define DMA_ISR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt status */ +#define DMA_ISR_CHAN3_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN3_SHIFT) +#define DMA_ISR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt status */ +#define DMA_ISR_CHAN4_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN4_SHIFT) +#define DMA_ISR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt status */ +#define DMA_ISR_CHAN5_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN5_SHIFT) +#define DMA_ISR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt status */ +#define DMA_ISR_CHAN6_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN6_SHIFT) +#define DMA_ISR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt status */ +#define DMA_ISR_CHAN7_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN7_SHIFT) + +#define DMA_ISR_GIF(n) (DMA_CHAN_GIF_BIT << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_TCIF(n) (DMA_CHAN_TCIF_BIT << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_HTIF(n) (DMA_CHAN_HTIF_BIT << DMA_ISR_CHAN_SHIFT(n)) +#define DMA_ISR_TEIF(n) (DMA_CHAN_TEIF_BIT << DMA_ISR_CHAN_SHIFT(n)) + +/* DMA interrupt flag clear register */ + +#define DMA_IFCR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n) +#define DMA_IFCR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt flag clear */ +#define DMA_IFCR_CHAN1_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN1_SHIFT) +#define DMA_IFCR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt flag clear */ +#define DMA_IFCR_CHAN2_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN2_SHIFT) +#define DMA_IFCR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt flag clear */ +#define DMA_IFCR_CHAN3_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN3_SHIFT) +#define DMA_IFCR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt flag clear */ +#define DMA_IFCR_CHAN4_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN4_SHIFT) +#define DMA_IFCR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt flag clear */ +#define DMA_IFCR_CHAN5_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN5_SHIFT) +#define DMA_IFCR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt flag clear */ +#define DMA_IFCR_CHAN6_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN6_SHIFT) +#define DMA_IFCR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt flag clear */ +#define DMA_IFCR_CHAN7_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN7_SHIFT) +#define DMA_IFCR_ALLCHANNELS (0x0fffffff) + +#define DMA_IFCR_CGIF(n) (DMA_CHAN_GIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CTCIF(n) (DMA_CHAN_TCIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CHTIF(n) (DMA_CHAN_HTIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) +#define DMA_IFCR_CTEIF(n) (DMA_CHAN_TEIF_BIT << DMA_IFCR_CHAN_SHIFT(n)) + +/* DMA channel configuration register */ + +#define DMA_CCR_EN (1 << 0) /* Bit 0: Channel enable */ +#define DMA_CCR_TCIE (1 << 1) /* Bit 1: Transfer complete interrupt enable */ +#define DMA_CCR_HTIE (1 << 2) /* Bit 2: Half Transfer interrupt enable */ +#define DMA_CCR_TEIE (1 << 3) /* Bit 3: Transfer error interrupt enable */ +#define DMA_CCR_DIR (1 << 4) /* Bit 4: Data transfer direction */ +#define DMA_CCR_CIRC (1 << 5) /* Bit 5: Circular mode */ +#define DMA_CCR_PINC (1 << 6) /* Bit 6: Peripheral increment mode */ +#define DMA_CCR_MINC (1 << 7) /* Bit 7: Memory increment mode */ +#define DMA_CCR_PSIZE_SHIFT (8) /* Bits 8-9: Peripheral size */ +#define DMA_CCR_PSIZE_MASK (3 << DMA_CCR_PSIZE_SHIFT) +# define DMA_CCR_PSIZE_8BITS (0 << DMA_CCR_PSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_CCR_PSIZE_16BITS (1 << DMA_CCR_PSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_CCR_PSIZE_32BITS (2 << DMA_CCR_PSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_CCR_MSIZE_SHIFT (10) /* Bits 10-11: Memory size */ +#define DMA_CCR_MSIZE_MASK (3 << DMA_CCR_MSIZE_SHIFT) +# define DMA_CCR_MSIZE_8BITS (0 << DMA_CCR_MSIZE_SHIFT) /* 00: 8-bits */ +# define DMA_CCR_MSIZE_16BITS (1 << DMA_CCR_MSIZE_SHIFT) /* 01: 16-bits */ +# define DMA_CCR_MSIZE_32BITS (2 << DMA_CCR_MSIZE_SHIFT) /* 10: 32-bits */ +#define DMA_CCR_PL_SHIFT (12) /* Bits 12-13: Channel Priority level */ +#define DMA_CCR_PL_MASK (3 << DMA_CCR_PL_SHIFT) +# define DMA_CCR_PRILO (0 << DMA_CCR_PL_SHIFT) /* 00: Low */ +# define DMA_CCR_PRIMED (1 << DMA_CCR_PL_SHIFT) /* 01: Medium */ +# define DMA_CCR_PRIHI (2 << DMA_CCR_PL_SHIFT) /* 10: High */ +# define DMA_CCR_PRIVERYHI (3 << DMA_CCR_PL_SHIFT) /* 11: Very high */ +#define DMA_CCR_MEM2MEM (1 << 14) /* Bit 14: Memory to memory mode */ + +#define DMA_CCR_ALLINTS (DMA_CCR_TEIE|DMA_CCR_HTIE|DMA_CCR_TCIE) + +/* DMA channel number of data register */ + +#define DMA_CNDTR_NDT_SHIFT (0) /* Bits 15-0: Number of data to Transfer */ +#define DMA_CNDTR_NDT_MASK (0xffff << DMA_CNDTR_NDT_SHIFT) + +/* DMA Channel mapping. Each DMA channel has a mapping to one of several + * possible sources/sinks of data. The requests from peripherals assigned to a + * channel are multiplexed together before entering the DMA block. This means + * that only one request on a given channel can be enabled at once. + * + * Alternative DMA channel 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. + */ + +#define STM32L4_DMA1_CHAN1 (0) +#define STM32L4_DMA1_CHAN2 (1) +#define STM32L4_DMA1_CHAN3 (2) +#define STM32L4_DMA1_CHAN4 (3) +#define STM32L4_DMA1_CHAN5 (4) +#define STM32L4_DMA1_CHAN6 (5) +#define STM32L4_DMA1_CHAN7 (6) + +#define STM32L4_DMA2_CHAN1 (7) +#define STM32L4_DMA2_CHAN2 (8) +#define STM32L4_DMA2_CHAN3 (9) +#define STM32L4_DMA2_CHAN4 (10) +#define STM32L4_DMA2_CHAN5 (11) +#define STM32L4_DMA2_CHAN6 (12) +#define STM32L4_DMA2_CHAN7 (13) + +#define DMACHAN_SETTING(chan, sel) ( ( ( (sel) & 0xff) << 8) | ( (chan) & 0xff) ) +#define DMACHAN_SETTING_CHANNEL_MASK 0x00FF +#define DMACHAN_SETTING_CHANNEL_SHIFT (0) +#define DMACHAN_SETTING_FUNCTION_MASK 0xFF00 +#define DMACHAN_SETTING_FUNCTION_SHIFT (8) + +#define DMACHAN_ADC1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 0) +#define DMACHAN_TIM2_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 4) +#define DMACHAN_TIM17_CH1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 5) +#define DMACHAN_TIM17_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 5) +#define DMACHAN_TIM4_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 6) + +#define DMACHAN_ADC2_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 0) +#define DMACHAN_SPI1_RX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 1) +#define DMACHAN_USART3_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 2) +#define DMACHAN_I2C3_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 3) +#define DMACHAN_TIM2_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 4) +#define DMACHAN_TIM3_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 5) +#define DMACHAN_TIM1_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 7) + +#define DMACHAN_ADC3_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 0) +#define DMACHAN_SPI1_TX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 0) +#define DMACHAN_USART3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 1) +#define DMACHAN_I2C3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 2) +#define DMACHAN_TIM16_CH1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 4) +#define DMACHAN_TIM16_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 4) +#define DMACHAN_TIM3_CH4 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 5) +#define DMACHAN_TIM3_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 5) +#define DMACHAN_TIM6_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 6) +#define DMACHAN_DAC1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 6) +#define DMACHAN_TIM1_CH2 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 7) + +#define DMACHAN_DFSDM0 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 0) +#define DMACHAN_SPI2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 1) +#define DMACHAN_USART1_TX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 2) +#define DMACHAN_I2C2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 3) +#define DMACHAN_TIM7_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 5) +#define DMACHAN_DAC1_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 5) +#define DMACHAN_TIM4_CH2 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 6) +#define DMACHAN_TIM1_CH4 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 7) +#define DMACHAN_TIM1_TRIG DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 7) +#define DMACHAN_TIM1_COM DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 7) + +#define DMACHAN_DFSDM1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 0) +#define DMACHAN_SPI2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 1) +#define DMACHAN_USART1_RX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 2) +#define DMACHAN_I2C2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 3) +#define DMACHAN_TIM2_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 4) +#define DMACHAN_QUADSPI_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 5) +#define DMACHAN_TIM4_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 6) +#define DMACHAN_TIM15_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7) +#define DMACHAN_TIM15_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7) +#define DMACHAN_TIM15_TRIG DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7) +#define DMACHAN_TIM15_COM DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7) + +#define DMACHAN_DFSDM2 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 0) +#define DMACHAN_SAI2_A_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 1) +#define DMACHAN_USART2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 2) +#define DMACHAN_I2C1_TX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 3) +#define DMACHAN_TIM16_CH1_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 4) +#define DMACHAN_TIM16_UP_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 4) +#define DMACHAN_TIM3_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 5) +#define DMACHAN_TIM3_TRIG DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 5) +#define DMACHAN_TIM1_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 7) + +#define DMACHAN_DFSDM3 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 0) +#define DMACHAN_SAI2_B_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 1) +#define DMACHAN_USART2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 2) +#define DMACHAN_I2C1_RX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 3) +#define DMACHAN_TIM2_CH2 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 4) +#define DMACHAN_TIM2_CH4 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 4) +#define DMACHAN_TIM17_CH1_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 5) +#define DMACHAN_TIM17_UP_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 5) +#define DMACHAN_TIM4_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 6) +#define DMACHAN_TIM1_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 7) + +#define DMACHAN_SAI1_A_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 1) +#define DMACHAN_UART5_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 2) +#define DMACHAN_SPI3_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 3) +#define DMACHAN_SWPMI_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 4) +#define DMACHAN_TIM5_CH4 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 5) +#define DMACHAN_TIM5_TRIG DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 5) +#define DMACHAN_TIM5_COM DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 5) +#define DMACHAN_AES_IN_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 6) +#define DMACHAN_TIM8_CH3 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 7) +#define DMACHAN_TIM8_UP DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 7) + +#define DMACHAN_SAI1_B_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 1) +#define DMACHAN_UART5_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 2) +#define DMACHAN_SPI3_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 3) +#define DMACHAN_SWPMI_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 4) +#define DMACHAN_TIM5_CH3 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 5) +#define DMACHAN_TIM5_UP DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 5) +#define DMACHAN_AES_OUT_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 6) +#define DMACHAN_TIM8_CH4 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 7) +#define DMACHAN_TIM8_TRIG DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 7) +#define DMACHAN_TIM8_COM DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 7) + +#define DMACHAN_ADC1_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 0) +#define DMACHAN_SAI2_A_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 1) +#define DMACHAN_UART4_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 2) +#define DMACHAN_SPI1_RX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 4) +#define DMACHAN_AES_OUT_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 6) + +#define DMACHAN_ADC2_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 0) +#define DMACHAN_SAI2_B_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 1) +#define DMACHAN_TIM6_UP_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 3) +#define DMACHAN_DAC1 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 3) +#define DMACHAN_SPI1_TX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 4) +#define DMACHAN_TIM5_CH2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 5) +#define DMACHAN_SDMMC_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 7) + +#define DMACHAN_ADC3_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 0) +#define DMACHAN_UART4_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 2) +#define DMACHAN_TIM7_UP_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 3) +#define DMACHAN_DAC2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 3) +#define DMACHAN_TIM5_CH1 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 5) +#define DMACHAN_AES_IN_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 6) +#define DMACHAN_SDMMC_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 7) + +#define DMACHAN_SAI1_A_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 1) +#define DMACHAN_USART1_TX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 2) +#define DMACHAN_LPUART_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 4) +#define DMACHAN_I2C1_RX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 5) +#define DMACHAN_TIM8_CH1 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 7) + +#define DMACHAN_SAI1_B_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 1) +#define DMACHAN_USART1_RX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 2) +#define DMACHAN_QUADSPI_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 3) +#define DMACHAN_LPUART_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 4) +#define DMACHAN_I2C1_TX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 5) +#define DMACHAN_TIM8_CH2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 7) + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_DMA_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h new file mode 100644 index 00000000000..e0471567fec --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h @@ -0,0 +1,104 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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_STM32L4_CHIP_STM32L4X6XX_FIREWALL_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_FIREWALL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_FIREWALL_CSSA_OFFSET 0x0000 +#define STM32L4_FIREWALL_CSL_OFFSET 0x0004 +#define STM32L4_FIREWALL_NVDSSA_OFFSET 0x0008 +#define STM32L4_FIREWALL_NVDSL_OFFSET 0x000C +#define STM32L4_FIREWALL_VDSSA_OFFSET 0x0010 +#define STM32L4_FIREWALL_VDSL_OFFSET 0x0014 +#define STM32L4_FIREWALL_CR_OFFSET 0x0020 + +/* Register Addresses ***************************************************************/ + +#define STM32L4_FIREWALL_CSSA (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_CSSA_OFFSET) +#define STM32L4_FIREWALL_CSL (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_CSL_OFFSET) +#define STM32L4_FIREWALL_NVDSSA (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_NVDSSA_OFFSET) +#define STM32L4_FIREWALL_NVDSL (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_NVDSL_OFFSET) +#define STM32L4_FIREWALL_VDSSA (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_VDSSA_OFFSET) +#define STM32L4_FIREWALL_VDSL (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_VDSL_OFFSET) +#define STM32L4_FIREWALL_CR (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_CR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* Code Segment Start Address */ +#define FIREWALL_CSSADD_SHIFT 8 +#define FIREWALL_CSSADD_MASK (0xFFFF << FIREWALL_CSSADD_SHIFT) + +/* Code Segment Length */ +#define FIREWALL_CSSLENG_SHIFT 8 +#define FIREWALL_CSSLENG_MASK (0x3FFF << FIREWALL_CSSLENG_SHIFT) + +/* Non-volatile Data Segment Start Address */ +#define FIREWALL_NVDSADD_SHIFT 8 +#define FIREWALL_NVDSADD_MASK (0xFFFF << FIREWALL_NVDSADD_SHIFT) + +/* Non-volatile Data Segment Length */ +#define FIREWALL_NVDSLENG_SHIFT 8 +#define FIREWALL_NVDSLENG_MASK (0x3FFF << FIREWALL_NVDSLENG_SHIFT) + +/* Volatile Data Segment Start Address */ +#define FIREWALL_VDSADD_SHIFT 6 +#define FIREWALL_VDSADD_MASK (0x07FF << FIREWALL_VDSADD_SHIFT) + +/* Volatile Data Segment Length */ +#define FIREWALL_VDSLENG_SHIFT 6 +#define FIREWALL_VDSLENG_MASK (0x07FF << FIREWALL_VDSLENG_SHIFT) + +/* Configuration Register */ +#define FIREWALL_CR_FPA (1 << 0) /* Bit 0: Firewall prearm */ +#define FIREWALL_CR_VDS (1 << 1) /* Bit 1: Volatile data shared */ +#define FIREWALL_CR_VDE (1 << 2) /* Bit 2: Volatile data execution */ + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_FIREWALL_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h new file mode 100644 index 00000000000..74f2882fad5 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h @@ -0,0 +1,357 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h + * + * Copyright (C) 2016, Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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_STM32L4_CHIP_STM32L4X6XX_GPIO_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_GPIO_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define STM32L4_NGPIO_PORTS (8) + +/* Register Offsets *****************************************************************/ + +#define STM32L4_GPIO_MODER_OFFSET 0x0000 /* GPIO port mode register */ +#define STM32L4_GPIO_OTYPER_OFFSET 0x0004 /* GPIO port output type register */ +#define STM32L4_GPIO_OSPEED_OFFSET 0x0008 /* GPIO port output speed register */ +#define STM32L4_GPIO_PUPDR_OFFSET 0x000c /* GPIO port pull-up/pull-down register */ +#define STM32L4_GPIO_IDR_OFFSET 0x0010 /* GPIO port input data register */ +#define STM32L4_GPIO_ODR_OFFSET 0x0014 /* GPIO port output data register */ +#define STM32L4_GPIO_BSRR_OFFSET 0x0018 /* GPIO port bit set/reset register */ +#define STM32L4_GPIO_LCKR_OFFSET 0x001c /* GPIO port configuration lock register */ +#define STM32L4_GPIO_AFRL_OFFSET 0x0020 /* GPIO alternate function low register */ +#define STM32L4_GPIO_AFRH_OFFSET 0x0024 /* GPIO alternate function high register */ + +/* Register Addresses ***************************************************************/ + +#if STM32L4_NGPIO_PORTS > 0 +# define STM32L4_GPIOA_MODER (STM32L4_GPIOA_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOA_OTYPER (STM32L4_GPIOA_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOA_OSPEED (STM32L4_GPIOA_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOA_PUPDR (STM32L4_GPIOA_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOA_IDR (STM32L4_GPIOA_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOA_ODR (STM32L4_GPIOA_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOA_BSRR (STM32L4_GPIOA_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOA_LCKR (STM32L4_GPIOA_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOA_AFRL (STM32L4_GPIOA_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOA_AFRH (STM32L4_GPIOA_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NGPIO_PORTS > 1 +# define STM32L4_GPIOB_MODER (STM32L4_GPIOB_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOB_OTYPER (STM32L4_GPIOB_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOB_OSPEED (STM32L4_GPIOB_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOB_PUPDR (STM32L4_GPIOB_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOB_IDR (STM32L4_GPIOB_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOB_ODR (STM32L4_GPIOB_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOB_BSRR (STM32L4_GPIOB_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOB_LCKR (STM32L4_GPIOB_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOB_AFRL (STM32L4_GPIOB_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOB_AFRH (STM32L4_GPIOB_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NGPIO_PORTS > 2 +# define STM32L4_GPIOC_MODER (STM32L4_GPIOC_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOC_OTYPER (STM32L4_GPIOC_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOC_OSPEED (STM32L4_GPIOC_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOC_PUPDR (STM32L4_GPIOC_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOC_IDR (STM32L4_GPIOC_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOC_ODR (STM32L4_GPIOC_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOC_BSRR (STM32L4_GPIOC_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOC_LCKR (STM32L4_GPIOC_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOC_AFRL (STM32L4_GPIOC_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOC_AFRH (STM32L4_GPIOC_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NGPIO_PORTS > 3 +# define STM32L4_GPIOD_MODER (STM32L4_GPIOD_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOD_OTYPER (STM32L4_GPIOD_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOD_OSPEED (STM32L4_GPIOD_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOD_PUPDR (STM32L4_GPIOD_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOD_IDR (STM32L4_GPIOD_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOD_ODR (STM32L4_GPIOD_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOD_BSRR (STM32L4_GPIOD_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOD_LCKR (STM32L4_GPIOD_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOD_AFRL (STM32L4_GPIOD_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOD_AFRH (STM32L4_GPIOD_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NGPIO_PORTS > 4 +# define STM32L4_GPIOE_MODER (STM32L4_GPIOE_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOE_OTYPER (STM32L4_GPIOE_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOE_OSPEED (STM32L4_GPIOE_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOE_PUPDR (STM32L4_GPIOE_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOE_IDR (STM32L4_GPIOE_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOE_ODR (STM32L4_GPIOE_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOE_BSRR (STM32L4_GPIOE_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOE_LCKR (STM32L4_GPIOE_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOE_AFRL (STM32L4_GPIOE_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOE_AFRH (STM32L4_GPIOE_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NGPIO_PORTS > 5 +# define STM32L4_GPIOF_MODER (STM32L4_GPIOF_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOF_OTYPER (STM32L4_GPIOF_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOF_OSPEED (STM32L4_GPIOF_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOF_PUPDR (STM32L4_GPIOF_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOF_IDR (STM32L4_GPIOF_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOF_ODR (STM32L4_GPIOF_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOF_BSRR (STM32L4_GPIOF_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOF_LCKR (STM32L4_GPIOF_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOF_AFRL (STM32L4_GPIOF_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOF_AFRH (STM32L4_GPIOF_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NGPIO_PORTS > 6 +# define STM32L4_GPIOG_MODER (STM32L4_GPIOG_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOG_OTYPER (STM32L4_GPIOG_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOG_OSPEED (STM32L4_GPIOG_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOG_PUPDR (STM32L4_GPIOG_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOG_IDR (STM32L4_GPIOG_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOG_ODR (STM32L4_GPIOG_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOG_BSRR (STM32L4_GPIOG_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOG_LCKR (STM32L4_GPIOG_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOG_AFRL (STM32L4_GPIOG_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOG_AFRH (STM32L4_GPIOG_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +#if STM32L4_NGPIO_PORTS > 7 +# define STM32L4_GPIOH_MODER (STM32L4_GPIOH_BASE+STM32L4_GPIO_MODER_OFFSET) +# define STM32L4_GPIOH_OTYPER (STM32L4_GPIOH_BASE+STM32L4_GPIO_OTYPER_OFFSET) +# define STM32L4_GPIOH_OSPEED (STM32L4_GPIOH_BASE+STM32L4_GPIO_OSPEED_OFFSET) +# define STM32L4_GPIOH_PUPDR (STM32L4_GPIOH_BASE+STM32L4_GPIO_PUPDR_OFFSET) +# define STM32L4_GPIOH_IDR (STM32L4_GPIOH_BASE+STM32L4_GPIO_IDR_OFFSET) +# define STM32L4_GPIOH_ODR (STM32L4_GPIOH_BASE+STM32L4_GPIO_ODR_OFFSET) +# define STM32L4_GPIOH_BSRR (STM32L4_GPIOH_BASE+STM32L4_GPIO_BSRR_OFFSET) +# define STM32L4_GPIOH_LCKR (STM32L4_GPIOH_BASE+STM32L4_GPIO_LCKR_OFFSET) +# define STM32L4_GPIOH_AFRL (STM32L4_GPIOH_BASE+STM32L4_GPIO_AFRL_OFFSET) +# define STM32L4_GPIOH_AFRH (STM32L4_GPIOH_BASE+STM32L4_GPIO_AFRH_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* GPIO port mode register */ + +#define GPIO_MODER_INPUT (0) /* Input */ +#define GPIO_MODER_OUTPUT (1) /* General purpose output mode */ +#define GPIO_MODER_ALT (2) /* Alternate mode */ +#define GPIO_MODER_ANALOG (3) /* Analog mode */ + +#define GPIO_MODER_SHIFT(n) ((n) << 1) +#define GPIO_MODER_MASK(n) (3 << GPIO_MODER_SHIFT(n)) + +#define GPIO_MODER0_SHIFT (0) +#define GPIO_MODER0_MASK (3 << GPIO_MODER0_SHIFT) +#define GPIO_MODER1_SHIFT (2) +#define GPIO_MODER1_MASK (3 << GPIO_MODER1_SHIFT) +#define GPIO_MODER2_SHIFT (4) +#define GPIO_MODER2_MASK (3 << GPIO_MODER2_SHIFT) +#define GPIO_MODER3_SHIFT (6) +#define GPIO_MODER3_MASK (3 << GPIO_MODER3_SHIFT) +#define GPIO_MODER4_SHIFT (8) +#define GPIO_MODER4_MASK (3 << GPIO_MODER4_SHIFT) +#define GPIO_MODER5_SHIFT (10) +#define GPIO_MODER5_MASK (3 << GPIO_MODER5_SHIFT) +#define GPIO_MODER6_SHIFT (12) +#define GPIO_MODER6_MASK (3 << GPIO_MODER6_SHIFT) +#define GPIO_MODER7_SHIFT (14) +#define GPIO_MODER7_MASK (3 << GPIO_MODER7_SHIFT) +#define GPIO_MODER8_SHIFT (16) +#define GPIO_MODER8_MASK (3 << GPIO_MODER8_SHIFT) +#define GPIO_MODER9_SHIFT (18) +#define GPIO_MODER9_MASK (3 << GPIO_MODER9_SHIFT) +#define GPIO_MODER10_SHIFT (20) +#define GPIO_MODER10_MASK (3 << GPIO_MODER10_SHIFT) +#define GPIO_MODER11_SHIFT (22) +#define GPIO_MODER11_MASK (3 << GPIO_MODER11_SHIFT) +#define GPIO_MODER12_SHIFT (24) +#define GPIO_MODER12_MASK (3 << GPIO_MODER12_SHIFT) +#define GPIO_MODER13_SHIFT (26) +#define GPIO_MODER13_MASK (3 << GPIO_MODER13_SHIFT) +#define GPIO_MODER14_SHIFT (28) +#define GPIO_MODER14_MASK (3 << GPIO_MODER14_SHIFT) +#define GPIO_MODER15_SHIFT (30) +#define GPIO_MODER15_MASK (3 << GPIO_MODER15_SHIFT) + +/* GPIO port output type register */ + +#define GPIO_OTYPER_OD(n) (1 << (n)) /* 1=Output open-drain */ +#define GPIO_OTYPER_PP(n) (0) /* 0=Ouput push-pull */ + +/* GPIO port output speed register */ + +#define GPIO_OSPEED_2MHz (0) /* 2 MHz Low speed */ +#define GPIO_OSPEED_25MHz (1) /* 25 MHz Medium speed */ +#define GPIO_OSPEED_50MHz (2) /* 50 MHz High speed */ +#define GPIO_OSPEED_100MHz (3) /* 100 MHz Very High speed on 30 pF (80 MHz Output max speed on 15 pF) */ + +#define GPIO_OSPEED_SHIFT(n) ((n) << 1) +#define GPIO_OSPEED_MASK(n) (3 << GPIO_OSPEED_SHIFT(n)) + +#define GPIO_OSPEED0_SHIFT (0) +#define GPIO_OSPEED0_MASK (3 << GPIO_OSPEED0_SHIFT) +#define GPIO_OSPEED1_SHIFT (2) +#define GPIO_OSPEED1_MASK (3 << GPIO_OSPEED1_SHIFT) +#define GPIO_OSPEED2_SHIFT (4) +#define GPIO_OSPEED2_MASK (3 << GPIO_OSPEED2_SHIFT) +#define GPIO_OSPEED3_SHIFT (6) +#define GPIO_OSPEED3_MASK (3 << GPIO_OSPEED3_SHIFT) +#define GPIO_OSPEED4_SHIFT (8) +#define GPIO_OSPEED4_MASK (3 << GPIO_OSPEED4_SHIFT) +#define GPIO_OSPEED5_SHIFT (10) +#define GPIO_OSPEED5_MASK (3 << GPIO_OSPEED5_SHIFT) +#define GPIO_OSPEED6_SHIFT (12) +#define GPIO_OSPEED6_MASK (3 << GPIO_OSPEED6_SHIFT) +#define GPIO_OSPEED7_SHIFT (14) +#define GPIO_OSPEED7_MASK (3 << GPIO_OSPEED7_SHIFT) +#define GPIO_OSPEED8_SHIFT (16) +#define GPIO_OSPEED8_MASK (3 << GPIO_OSPEED8_SHIFT) +#define GPIO_OSPEED9_SHIFT (18) +#define GPIO_OSPEED9_MASK (3 << GPIO_OSPEED9_SHIFT) +#define GPIO_OSPEED10_SHIFT (20) +#define GPIO_OSPEED10_MASK (3 << GPIO_OSPEED10_SHIFT) +#define GPIO_OSPEED11_SHIFT (22) +#define GPIO_OSPEED11_MASK (3 << GPIO_OSPEED11_SHIFT) +#define GPIO_OSPEED12_SHIFT (24) +#define GPIO_OSPEED12_MASK (3 << GPIO_OSPEED12_SHIFT) +#define GPIO_OSPEED13_SHIFT (26) +#define GPIO_OSPEED13_MASK (3 << GPIO_OSPEED13_SHIFT) +#define GPIO_OSPEED14_SHIFT (28) +#define GPIO_OSPEED14_MASK (3 << GPIO_OSPEED14_SHIFT) +#define GPIO_OSPEED15_SHIFT (30) +#define GPIO_OSPEED15_MASK (3 << GPIO_OSPEED15_SHIFT) + +/* GPIO port pull-up/pull-down register */ + +#define GPIO_PUPDR_NONE (0) /* No pull-up, pull-down */ +#define GPIO_PUPDR_PULLUP (1) /* Pull-up */ +#define GPIO_PUPDR_PULLDOWN (2) /* Pull-down */ + +#define GPIO_PUPDR_SHIFT(n) ((n) << 1) +#define GPIO_PUPDR_MASK(n) (3 << GPIO_PUPDR_SHIFT(n)) + +#define GPIO_PUPDR0_SHIFT (0) +#define GPIO_PUPDR0_MASK (3 << GPIO_PUPDR0_SHIFT) +#define GPIO_PUPDR1_SHIFT (2) +#define GPIO_PUPDR1_MASK (3 << GPIO_PUPDR1_SHIFT) +#define GPIO_PUPDR2_SHIFT (4) +#define GPIO_PUPDR2_MASK (3 << GPIO_PUPDR2_SHIFT) +#define GPIO_PUPDR3_SHIFT (6) +#define GPIO_PUPDR3_MASK (3 << GPIO_PUPDR3_SHIFT) +#define GPIO_PUPDR4_SHIFT (8) +#define GPIO_PUPDR4_MASK (3 << GPIO_PUPDR4_SHIFT) +#define GPIO_PUPDR5_SHIFT (10) +#define GPIO_PUPDR5_MASK (3 << GPIO_PUPDR5_SHIFT) +#define GPIO_PUPDR6_SHIFT (12) +#define GPIO_PUPDR6_MASK (3 << GPIO_PUPDR6_SHIFT) +#define GPIO_PUPDR7_SHIFT (14) +#define GPIO_PUPDR7_MASK (3 << GPIO_PUPDR7_SHIFT) +#define GPIO_PUPDR8_SHIFT (16) +#define GPIO_PUPDR8_MASK (3 << GPIO_PUPDR8_SHIFT) +#define GPIO_PUPDR9_SHIFT (18) +#define GPIO_PUPDR9_MASK (3 << GPIO_PUPDR9_SHIFT) +#define GPIO_PUPDR10_SHIFT (20) +#define GPIO_PUPDR10_MASK (3 << GPIO_PUPDR10_SHIFT) +#define GPIO_PUPDR11_SHIFT (22) +#define GPIO_PUPDR11_MASK (3 << GPIO_PUPDR11_SHIFT) +#define GPIO_PUPDR12_SHIFT (24) +#define GPIO_PUPDR12_MASK (3 << GPIO_PUPDR12_SHIFT) +#define GPIO_PUPDR13_SHIFT (26) +#define GPIO_PUPDR13_MASK (3 << GPIO_PUPDR13_SHIFT) +#define GPIO_PUPDR14_SHIFT (28) +#define GPIO_PUPDR14_MASK (3 << GPIO_PUPDR14_SHIFT) +#define GPIO_PUPDR15_SHIFT (30) +#define GPIO_PUPDR15_MASK (3 << GPIO_PUPDR15_SHIFT) + +/* GPIO port input data register */ + +#define GPIO_IDR(n) (1 << (n)) + +/* GPIO port output data register */ + +#define GPIO_ODR(n) (1 << (n)) + +/* GPIO port bit set/reset register */ + +#define GPIO_BSRR_SET(n) (1 << (n)) +#define GPIO_BSRR_RESET(n) (1 << ((n)+16)) + +/* GPIO port configuration lock register */ + +#define GPIO_LCKR(n) (1 << (n)) +#define GPIO_LCKK (1 << 16) /* Lock key */ + +/* GPIO alternate function low/high register */ + +#define GPIO_AFR_SHIFT(n) ((n) << 2) +#define GPIO_AFR_MASK(n) (15 << GPIO_AFR_SHIFT(n)) + +#define GPIO_AFRL0_SHIFT (0) +#define GPIO_AFRL0_MASK (15 << GPIO_AFRL0_SHIFT) +#define GPIO_AFRL1_SHIFT (4) +#define GPIO_AFRL1_MASK (15 << GPIO_AFRL1_SHIFT) +#define GPIO_AFRL2_SHIFT (8) +#define GPIO_AFRL2_MASK (15 << GPIO_AFRL2_SHIFT) +#define GPIO_AFRL3_SHIFT (12) +#define GPIO_AFRL3_MASK (15 << GPIO_AFRL3_SHIFT) +#define GPIO_AFRL4_SHIFT (16) +#define GPIO_AFRL4_MASK (15 << GPIO_AFRL4_SHIFT) +#define GPIO_AFRL5_SHIFT (20) +#define GPIO_AFRL5_MASK (15 << GPIO_AFRL5_SHIFT) +#define GPIO_AFRL6_SHIFT (24) +#define GPIO_AFRL6_MASK (15 << GPIO_AFRL6_SHIFT) +#define GPIO_AFRL7_SHIFT (28) +#define GPIO_AFRL7_MASK (15 << GPIO_AFRL7_SHIFT) + +#define GPIO_AFRH8_SHIFT (0) +#define GPIO_AFRH8_MASK (15 << GPIO_AFRH8_SHIFT) +#define GPIO_AFRH9_SHIFT (4) +#define GPIO_AFRH9_MASK (15 << GPIO_AFRH9_SHIFT) +#define GPIO_AFRH10_SHIFT (8) +#define GPIO_AFRH10_MASK (15 << GPIO_AFRH10_SHIFT) +#define GPIO_AFRH11_SHIFT (12) +#define GPIO_AFRH11_MASK (15 << GPIO_AFRH11_SHIFT) +#define GPIO_AFRH12_SHIFT (16) +#define GPIO_AFRH12_MASK (15 << GPIO_AFRH12_SHIFT) +#define GPIO_AFRH13_SHIFT (20) +#define GPIO_AFRH13_MASK (15 << GPIO_AFRH13_SHIFT) +#define GPIO_AFRH14_SHIFT (24) +#define GPIO_AFRH14_MASK (15 << GPIO_AFRH14_SHIFT) +#define GPIO_AFRH15_SHIFT (28) +#define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_GPIO_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h new file mode 100644 index 00000000000..d711f730bff --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h @@ -0,0 +1,783 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h + * + * Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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_STM32L4_CHIP_STM32L4X6XX_PINMAP_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32l4_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Alternate Pin Functions. All members of the STM32L4xxx 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 vis PA11 on some board, then the following definitions should + * appear inthe board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configre PA11 as the CAN1 RX pin. + */ + +/* WARNING!!! 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. + */ + +/* ADC */ + +#define GPIO_ADC1_IN1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC1_IN2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC1_IN3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC1_IN4 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC1_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC1_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC1_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC1_IN8 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC1_IN9 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC1_IN10 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC1_IN11 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC1_IN12 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC1_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC1_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ADC1_IN15 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC1_IN16 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) + +#define GPIO_ADC2_IN1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC2_IN2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC2_IN3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC2_IN4 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC2_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0) +#define GPIO_ADC2_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC2_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC2_IN8 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC2_IN9 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC2_IN10 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC2_IN11 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC2_IN12 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC2_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC2_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) +#define GPIO_ADC2_IN15 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC2_IN16 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) + +#define GPIO_ADC3_IN1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC3_IN2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC3_IN3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC3_IN4 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC3_IN6 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN3) +#define GPIO_ADC3_IN7 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN4) +#define GPIO_ADC3_IN8 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN5) +#define GPIO_ADC3_IN9 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN6) +#define GPIO_ADC3_IN10 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN7) +#define GPIO_ADC3_IN11 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN8) +#define GPIO_ADC3_IN12 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN9) +#define GPIO_ADC3_IN13 (GPIO_ANALOG|GPIO_PORTF|GPIO_PIN10) + +/* CAN */ + +#define GPIO_CAN1_RX_1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN11) +#define GPIO_CAN1_RX_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN8) +#define GPIO_CAN1_RX_3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN0) +#define GPIO_CAN1_TX_1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN12) +#define GPIO_CAN1_TX_2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_CAN1_TX_3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN1) + +/* Clocks outputs */ + +#define GPIO_MCO (GPIO_ALT|GPIO_AF0 |GPIO_PORTA|GPIO_PIN8) + +/* Comparators */ + +#define GPIO_COMP1_INM_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_COMP1_INM_2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_COMP1_INP_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN2) +#define GPIO_COMP1_INP_2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) +#define GPIO_COMP1_OUT_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN0) +#define GPIO_COMP1_OUT_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN10) + +#define GPIO_COMP2_INM_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN3) +#define GPIO_COMP2_INM_2 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN7) +#define GPIO_COMP2_INP_1 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN4) +#define GPIO_COMP2_INP_2 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN6) +#define GPIO_COMP2_OUT_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN5) +#define GPIO_COMP2_OUT_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN11) + +/* DAC */ + +#define GPIO_DAC1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC2_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) + +/* Digital Filter for Sigma-Delta Modulators (DFSDM) */ + +#define GPIO_DFSDM_DATIN0_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_DFSDM_DATIN0_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN3) +#define GPIO_DFSDM_DATIN1_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_DFSDM_DATIN1_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN6) +#define GPIO_DFSDM_DATIN2_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_DFSDM_DATIN2_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN7) +#define GPIO_DFSDM_DATIN3_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN7) +#define GPIO_DFSDM_DATIN3_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN4) +#define GPIO_DFSDM_DATIN4_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN0) +#define GPIO_DFSDM_DATIN4_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN10) +#define GPIO_DFSDM_DATIN5_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_DFSDM_DATIN5_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN12) +#define GPIO_DFSDM_DATIN6_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN8) +#define GPIO_DFSDM_DATIN6_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTF|GPIO_PIN13) +#define GPIO_DFSDM_DATIN7_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_DFSDM_DATIN7_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN0) + +#define GPIO_DFSDM_CKIN0_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN2) +#define GPIO_DFSDM_CKIN0_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN4) +#define GPIO_DFSDM_CKIN1_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_DFSDM_CKIN1_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN7) +#define GPIO_DFSDM_CKIN2_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN15) +#define GPIO_DFSDM_CKIN2_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN8) +#define GPIO_DFSDM_CKIN3_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN6) +#define GPIO_DFSDM_CKIN3_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN5) +#define GPIO_DFSDM_CKIN4_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN1) +#define GPIO_DFSDM_CKIN4_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN11) +#define GPIO_DFSDM_CKIN5_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_DFSDM_CKIN5_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN13) +#define GPIO_DFSDM_CKIN6_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_DFSDM_CKIN6_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTF|GPIO_PIN14) +#define GPIO_DFSDM_CKIN7_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_DFSDM_CKIN7_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN1) + +#define GPIO_DFSDM_CKOUT_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN2) +#define GPIO_DFSDM_CKOUT_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN9) + + +/* Flexible Static Memory Controller (FSMC) */ + +#define GPIO_FMC_NL (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN7) +#define GPIO_FMC_NBL0 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN0) +#define GPIO_FMC_NBL1 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN1) +#define GPIO_FMC_CLK (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN3) +#define GPIO_FMC_NOE (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN4) +#define GPIO_FMC_NWE (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN5) +#define GPIO_FMC_NWAIT (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN6) +#define GPIO_FMC_NE1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN7) +#define GPIO_FMC_NE2 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN9) +#define GPIO_FMC_NE3 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN10) +#define GPIO_FMC_NE4 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN12) +#define GPIO_FMC_INT3 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN7) +#define GPIO_FMC_NCE3 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN9) + +#define GPIO_FMC_A0 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN0) +#define GPIO_FMC_A1 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN1) +#define GPIO_FMC_A2 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN2) +#define GPIO_FMC_A3 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN3) +#define GPIO_FMC_A4 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN4) +#define GPIO_FMC_A5 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN5) +#define GPIO_FMC_A6 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN12) +#define GPIO_FMC_A7 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN13) +#define GPIO_FMC_A8 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN14) +#define GPIO_FMC_A9 (GPIO_ALT|GPIO_AF12|GPIO_PORTF|GPIO_PIN15) +#define GPIO_FMC_A10 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN0) +#define GPIO_FMC_A11 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN1) +#define GPIO_FMC_A12 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN2) +#define GPIO_FMC_A13 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN3) +#define GPIO_FMC_A14 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN4) +#define GPIO_FMC_A15 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN5) +#define GPIO_FMC_A16 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN11) +#define GPIO_FMC_A17 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN12) +#define GPIO_FMC_A18 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN13) +#define GPIO_FMC_A19 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN3) +#define GPIO_FMC_A20 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN4) +#define GPIO_FMC_A21 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN5) +#define GPIO_FMC_A22 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN6) +#define GPIO_FMC_A23 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN2) +#define GPIO_FMC_A24 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN13) +#define GPIO_FMC_A25 (GPIO_ALT|GPIO_AF12|GPIO_PORTG|GPIO_PIN14) + +#define GPIO_FMC_D0 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN14) +#define GPIO_FMC_D1 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN15) +#define GPIO_FMC_D2 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN0) +#define GPIO_FMC_D3 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN1) +#define GPIO_FMC_D4 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN7) +#define GPIO_FMC_D5 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN8) +#define GPIO_FMC_D6 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN9) +#define GPIO_FMC_D7 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN10) +#define GPIO_FMC_D8 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN11) +#define GPIO_FMC_D9 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN12) +#define GPIO_FMC_D10 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN13) +#define GPIO_FMC_D11 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN14) +#define GPIO_FMC_D12 (GPIO_ALT|GPIO_AF12|GPIO_PORTE|GPIO_PIN15) +#define GPIO_FMC_D13 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN8) +#define GPIO_FMC_D14 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN9) +#define GPIO_FMC_D15 (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN10) + +/* I2C */ + +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN13) +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN14) +#define GPIO_I2C1_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_I2C1_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN15) + +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN2) + +#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN8) +#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN0) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN7) +#define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN2) +#define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN6) + +/* JTAG */ + +#define GPIO_JTCK_SWCLK (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14) +#define GPIO_JTDI (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN15) +#define GPIO_JTDO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) +#define GPIO_JTMS_SWDIO (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13) +#define GPIO_JTRST (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN4) + +/* LCD Segment Controller */ + +#define GPIO_LCD_VLCD (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN3) + +#define GPIO_LCD_SEG0 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN1) +#define GPIO_LCD_SEG1 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN2) +#define GPIO_LCD_SEG2 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN3) +#define GPIO_LCD_SEG3 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN6) +#define GPIO_LCD_SEG4 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN7) +#define GPIO_LCD_SEG5 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN0) +#define GPIO_LCD_SEG6 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LCD_SEG7 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN3) +#define GPIO_LCD_SEG8 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN4) +#define GPIO_LCD_SEG9 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN5) +#define GPIO_LCD_SEG10 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN10) +#define GPIO_LCD_SEG11 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN11) +#define GPIO_LCD_SEG12 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN12) +#define GPIO_LCD_SEG13 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN13) +#define GPIO_LCD_SEG14 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN14) +#define GPIO_LCD_SEG15 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN15) +#define GPIO_LCD_SEG16 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN8) +#define GPIO_LCD_SEG17 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN15) +#define GPIO_LCD_SEG18 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN0) +#define GPIO_LCD_SEG19 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN1) +#define GPIO_LCD_SEG20 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN2) +#define GPIO_LCD_SEG21 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN7) +#define GPIO_LCD_SEG22 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN4) +#define GPIO_LCD_SEG23 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN5) +#define GPIO_LCD_SEG24 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN6) +#define GPIO_LCD_SEG25 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN7) +#define GPIO_LCD_SEG26 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN8) +#define GPIO_LCD_SEG27 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN9) +#define GPIO_LCD_SEG28_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LCD_SEG28_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN8) +#define GPIO_LCD_SEG29_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN11) +#define GPIO_LCD_SEG29_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN9) +#define GPIO_LCD_SEG30_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN12) +#define GPIO_LCD_SEG30_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN10) +#define GPIO_LCD_SEG31_1 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN2) +#define GPIO_LCD_SEG31_2 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN11) +#define GPIO_LCD_SEG32 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN12) +#define GPIO_LCD_SEG33 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN13) +#define GPIO_LCD_SEG34 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN14) +#define GPIO_LCD_SEG35 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN15) +#define GPIO_LCD_SEG36 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN0) +#define GPIO_LCD_SEG37 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN1) +#define GPIO_LCD_SEG38 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN2) +#define GPIO_LCD_SEG39 (GPIO_ALT|GPIO_AF11|GPIO_PORTE|GPIO_PIN3) +#define GPIO_LCD_SEG40 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LCD_SEG41 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN11) +#define GPIO_LCD_SEG42 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN12) +#define GPIO_LCD_SEG43 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN2) + +#define GPIO_LCD_COM0 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN8) +#define GPIO_LCD_COM1 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN9) +#define GPIO_LCD_COM2 (GPIO_ALT|GPIO_AF11|GPIO_PORTA|GPIO_PIN10) +#define GPIO_LCD_COM3 (GPIO_ALT|GPIO_AF11|GPIO_PORTB|GPIO_PIN9) +#define GPIO_LCD_COM4 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LCD_COM5 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN11) +#define GPIO_LCD_COM6 (GPIO_ALT|GPIO_AF11|GPIO_PORTC|GPIO_PIN12) +#define GPIO_LCD_COM7 (GPIO_ALT|GPIO_AF11|GPIO_PORTD|GPIO_PIN2) + +/* OTG FS */ + +#define GPIO_OTG_FS_SOF (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN8) +#define GPIO_OTG_FS_ID (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN10) +#define GPIO_OTG_FS_DM (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN11) +#define GPIO_OTG_FS_DP (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN12) +#define GPIO_OTG_FS_NOE_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN13) +#define GPIO_OTG_FS_NOE_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTC|GPIO_PIN9) + +/* QUADSPI */ + +#define GPIO_QUADSPI_NCS_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN11) +#define GPIO_QUADSPI_NCS_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN11) +#define GPIO_QUADSPI_CLK_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN10) +#define GPIO_QUADSPI_CLK_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN10) +#define GPIO_QUADSPI_BK1_IO0_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN1) +#define GPIO_QUADSPI_BK1_IO0_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN12) +#define GPIO_QUADSPI_BK1_IO1_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN0) +#define GPIO_QUADSPI_BK1_IO1_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN13) +#define GPIO_QUADSPI_BK1_IO2_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN7) +#define GPIO_QUADSPI_BK1_IO2_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN14) +#define GPIO_QUADSPI_BK1_IO3_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN6) +#define GPIO_QUADSPI_BK1_IO3_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN15) + +/* RTC */ + +#define GPIO_RTC_OUT (GPIO_ALT|GPIO_AF0 |GPIO_PORTB|GPIO_PIN2) +#define GPIO_RTC_REFIN (GPIO_ALT|GPIO_AF0 |GPIO_PORTB|GPIO_PIN15) + +/* SAI */ + +#define GPIO_SAI1_EXTCLK (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN0) + +#define GPIO_SAI1_FS_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SAI1_FS_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN4) +#define GPIO_SAI1_SCK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SAI1_SCK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN5) +#define GPIO_SAI1_SD_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN3) +#define GPIO_SAI1_SD_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN6) +#define GPIO_SAI1_SD_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN6) +#define GPIO_SAI1_MCLK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SAI1_MCLK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN2) + +#define GPIO_SAI1_FS_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN4) +#define GPIO_SAI1_FS_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN6) +#define GPIO_SAI1_FS_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN9) +#define GPIO_SAI1_FS_B_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN9) +#define GPIO_SAI1_SCK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN3) +#define GPIO_SAI1_SCK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN8) +#define GPIO_SAI1_SCK_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN8) +#define GPIO_SAI1_SD_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN5) +#define GPIO_SAI1_SD_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN3) +#define GPIO_SAI1_SD_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN7) +#define GPIO_SAI1_SD_B_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN6) +#define GPIO_SAI1_MCLK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN4) +#define GPIO_SAI1_MCLK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN10) +#define GPIO_SAI1_MCLK_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTF|GPIO_PIN7) + +#define GPIO_SAI2_EXTCLK_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN2) +#define GPIO_SAI2_EXTCLK_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN9) + +#define GPIO_SAI2_FS_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SAI2_FS_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN12) +#define GPIO_SAI2_FS_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN10) +#define GPIO_SAI2_SCK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SAI2_SCK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN10) +#define GPIO_SAI2_SCK_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN9) +#define GPIO_SAI2_SD_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SAI2_SD_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN11) +#define GPIO_SAI2_SD_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN12) +#define GPIO_SAI2_MCLK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SAI2_MCLK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SAI2_MCLK_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN9) +#define GPIO_SAI2_MCLK_A_4 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN11) + +#define GPIO_SAI2_FS_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN15) +#define GPIO_SAI2_FS_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN3) +#define GPIO_SAI2_SCK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SAI2_SCK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN2) +#define GPIO_SAI2_SD_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SAI2_SD_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN5) +#define GPIO_SAI2_MCLK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN7) +#define GPIO_SAI2_MCLK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SAI2_MCLK_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTG|GPIO_PIN4) + +/* SDIO */ + +#define GPIO_SDMMC1_CK (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN12) +#define GPIO_SDMMC1_CMD (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN2) +#define GPIO_SDMMC1_D0 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN8) +#define GPIO_SDMMC1_D1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN9) +#define GPIO_SDMMC1_D2 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN10) +#define GPIO_SDMMC1_D3 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN11) +#define GPIO_SDMMC1_D4 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN8) +#define GPIO_SDMMC1_D5 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN9) +#define GPIO_SDMMC1_D6 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN6) +#define GPIO_SDMMC1_D7 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN7) + +/* Single Wire Protocol Interface */ + +#define GPIO_SWPMI1_IO (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN12) +#define GPIO_SWPMI1_TX (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN13) +#define GPIO_SWPMI1_RX (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SWPMI1_SUSPEND (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN15) + +/* SPI */ + +#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI1_NSS_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN12) +#define GPIO_SPI1_NSS_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTG|GPIO_PIN5) +#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN5) +#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI1_SCK_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN13) +#define GPIO_SPI1_SCK_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTG|GPIO_PIN2) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN7) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI1_MOSI_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN15) +#define GPIO_SPI1_MOSI_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTG|GPIO_PIN4) +#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI1_MISO_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN14) +#define GPIO_SPI1_MISO_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTG|GPIO_PIN3) + +#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN0) +#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN1) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN15) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTC|GPIO_PIN3) +#define GPIO_SPI2_MOSI_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN4) +#define GPIO_SPI2_MISO_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_SPI2_MISO_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTC|GPIO_PIN2) +#define GPIO_SPI2_MISO_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN3) + +#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTA|GPIO_PIN4) +#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTA|GPIO_PIN15) +#define GPIO_SPI3_NSS_3 (GPIO_ALT|GPIO_AF6 |GPIO_PORTG|GPIO_PIN12) +#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN3) +#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN10) +#define GPIO_SPI3_SCK_3 (GPIO_ALT|GPIO_AF6 |GPIO_PORTG|GPIO_PIN9) +#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN12) +#define GPIO_SPI3_MOSI_3 (GPIO_ALT|GPIO_AF6 |GPIO_PORTG|GPIO_PIN11) +#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN11) +#define GPIO_SPI3_MISO_3 (GPIO_ALT|GPIO_AF6 |GPIO_PORTG|GPIO_PIN10) + +/* Timers */ + +#define GPIO_TIM1_CH1_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN8) +#define GPIO_TIM1_CH1_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN9) +#define GPIO_TIM1_CH2_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM1_CH2_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN11) +#define GPIO_TIM1_CH3_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM1_CH3_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN13) +#define GPIO_TIM1_CH4_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_CH4_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN8) +#define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN10) +#define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN12) +#define GPIO_TIM1_BKIN_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM1_BKIN_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM1_BKIN_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_BKIN_COMP1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTE|GPIO_PIN15) +#define GPIO_TIM1_BKIN_COMP2_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM1_BKIN_COMP2_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_TIM1_BKIN2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_BKIN2_COMP1 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN11) +#define GPIO_TIM1_BKIN2_COMP2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM1_ETR_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN12) +#define GPIO_TIM1_ETR_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN7) + +#define GPIO_TIM2_CH1_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_CH1_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_CH1_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN15) +#define GPIO_TIM2_CH2_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM2_CH2_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN3) +#define GPIO_TIM2_CH3_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM2_CH3_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_TIM2_CH4_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM2_CH4_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_TIM2_BKIN (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN14) +#define GPIO_TIM2_ETR_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM2_ETR_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM2_ETR_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN15) + +#define GPIO_TIM3_CH1_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM3_CH1_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_TIM3_CH1_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM3_CH1_4 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN3) +#define GPIO_TIM3_CH2_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM3_CH2_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_TIM3_CH2_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM3_CH2_4 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN4) +#define GPIO_TIM3_CH3_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM3_CH3_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM3_CH3_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN5) +#define GPIO_TIM3_CH4_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM3_CH4_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM3_CH4_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN6) +#define GPIO_TIM3_ETR_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN2) +#define GPIO_TIM3_ETR_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN2) + +#define GPIO_TIM4_CH1_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM4_CH1_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN12) +#define GPIO_TIM4_CH2_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM4_CH2_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN13) +#define GPIO_TIM4_CH3_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM4_CH3_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN14) +#define GPIO_TIM4_CH4_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM4_CH4_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN15) +#define GPIO_TIM4_ETR (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN0) + +#define GPIO_TIM5_CH1_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN0) +#define GPIO_TIM5_CH1_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTF|GPIO_PIN6) +#define GPIO_TIM5_CH2_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM5_CH2_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTF|GPIO_PIN7) +#define GPIO_TIM5_CH3_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM5_CH3_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTF|GPIO_PIN8) +#define GPIO_TIM5_CH4_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM5_CH4_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM5_ETR (GPIO_ALT|GPIO_AF1 |GPIO_PORTF|GPIO_PIN6) + +#define GPIO_TIM8_CH1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTC|GPIO_PIN6) +#define GPIO_TIM8_CH2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTC|GPIO_PIN7) +#define GPIO_TIM8_CH3 (GPIO_ALT|GPIO_AF3 |GPIO_PORTC|GPIO_PIN8) +#define GPIO_TIM8_CH4 (GPIO_ALT|GPIO_AF3 |GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_CH1N_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTA|GPIO_PIN5) +#define GPIO_TIM8_CH1N_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM8_CH2N_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN0) +#define GPIO_TIM8_CH2N_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM8_CH3N_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_TIM8_CH3N_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM8_BKIN_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_BKIN_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM8_BKIN_COMP1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM8_BKIN_COMP2 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM8_BKIN2_1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM8_BKIN2_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_BKIN2_COMP1 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN9) +#define GPIO_TIM8_BKIN2_COMP2 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM8_ETR (GPIO_ALT|GPIO_AF3 |GPIO_PORTA|GPIO_PIN0) + +#define GPIO_TIM15_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN2) +#define GPIO_TIM15_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN14) +#define GPIO_TIM15_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTF|GPIO_PIN9) +#define GPIO_TIM15_CH1_4 (GPIO_ALT|GPIO_AF14|GPIO_PORTG|GPIO_PIN10) +#define GPIO_TIM15_CH2_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN3) +#define GPIO_TIM15_CH2_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN15) +#define GPIO_TIM15_CH2_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTF|GPIO_PIN10) +#define GPIO_TIM15_CH2_4 (GPIO_ALT|GPIO_AF14|GPIO_PORTG|GPIO_PIN11) +#define GPIO_TIM15_CH1N_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN1) +#define GPIO_TIM15_CH1N_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN13) +#define GPIO_TIM15_CH1N_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTG|GPIO_PIN9) +#define GPIO_TIM15_BKIN_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN9) +#define GPIO_TIM15_BKIN_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN12) + +#define GPIO_TIM16_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN6) +#define GPIO_TIM16_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN8) +#define GPIO_TIM16_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTE|GPIO_PIN0) +#define GPIO_TIM16_CH1N (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN6) +#define GPIO_TIM16_BKIN (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN5) + +#define GPIO_TIM17_CH1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN7) +#define GPIO_TIM17_CH1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN9) +#define GPIO_TIM17_CH1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTE|GPIO_PIN1) +#define GPIO_TIM17_CH1N (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN7) +#define GPIO_TIM17_BKIN_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN10) +#define GPIO_TIM17_BKIN_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN4) + +#define GPIO_LPTIM1_IN1_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_LPTIM1_IN1_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN0) +#define GPIO_LPTIM1_IN1_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTG|GPIO_PIN10) +#define GPIO_LPTIM1_IN2_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_LPTIM1_IN2_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN2) +#define GPIO_LPTIM1_IN2_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTG|GPIO_PIN11) +#define GPIO_LPTIM1_OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN2) +#define GPIO_LPTIM1_OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN1) +#define GPIO_LPTIM1_OUT_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTG|GPIO_PIN15) +#define GPIO_LPTIM1_ETR_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_LPTIM1_ETR_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN3) +#define GPIO_LPTIM1_ETR_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTG|GPIO_PIN12) + +#define GPIO_LPTIM2_IN1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LPTIM2_IN1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN0) +#define GPIO_LPTIM2_IN1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN12) +#define GPIO_LPTIM2_OUT_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN4) +#define GPIO_LPTIM2_OUT_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN8) +#define GPIO_LPTIM2_OUT_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN13) +#define GPIO_LPTIM2_ETR_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN5) +#define GPIO_LPTIM2_ETR_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN3) +#define GPIO_LPTIM2_ETR_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN11) + +/* Touch Screen Controller */ + +#define GPIO_TSC_SYNC (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN2) + +#define GPIO_TSC_G1_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_TSC_G1_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_TSC_G1_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_TSC_G1_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN15) + +#define GPIO_TSC_G2_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_TSC_G2_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_TSC_G2_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_TSC_G2_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN7) + +#define GPIO_TSC_G3_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN15) +#define GPIO_TSC_G3_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN10) +#define GPIO_TSC_G3_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN11) +#define GPIO_TSC_G3_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN12) + +#define GPIO_TSC_G4_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN6) +#define GPIO_TSC_G4_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN7) +#define GPIO_TSC_G4_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN8) +#define GPIO_TSC_G4_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN9) + +#define GPIO_TSC_G5_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN10) +#define GPIO_TSC_G5_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN11) +#define GPIO_TSC_G5_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN12) +#define GPIO_TSC_G5_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN13) + +#define GPIO_TSC_G6_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN10) +#define GPIO_TSC_G6_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN11) +#define GPIO_TSC_G6_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN12) +#define GPIO_TSC_G6_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN13) + +#define GPIO_TSC_G7_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN2) +#define GPIO_TSC_G7_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN3) +#define GPIO_TSC_G7_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN4) +#define GPIO_TSC_G7_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN5) + +#define GPIO_TSC_G8_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTF|GPIO_PIN14) +#define GPIO_TSC_G8_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTF|GPIO_PIN15) +#define GPIO_TSC_G8_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTG|GPIO_PIN0) +#define GPIO_TSC_G8_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTG|GPIO_PIN1) + +/* IR interface (with timers 16 and 17) */ + +#define GPIO_IR_OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN13) +#define GPIO_IR_OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN9) + +/* Trace */ + +#define GPIO_TRACECK (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN2) +#define GPIO_TRACED0 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN3) +#define GPIO_TRACED1 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN4) +#define GPIO_TRACED2 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN5) +#define GPIO_TRACED3 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN6) + +/* UARTs/USARTs */ + +#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN6) +#define GPIO_USART1_TX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN9) +#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_USART1_RX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN10) +#define GPIO_USART1_CK_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN8) +#define GPIO_USART1_CK_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_USART1_CK_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN13) +#define GPIO_USART1_CTS_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN11) +#define GPIO_USART1_CTS_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN4) +#define GPIO_USART1_CTS_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN11) +#define GPIO_USART1_RTS_DE_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN12) +#define GPIO_USART1_RTS_DE_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN3) +#define GPIO_USART1_RTS_DE_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTG|GPIO_PIN12) + +#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN2) +#define GPIO_USART2_TX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN5) +#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_RX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN6) +#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN4) +#define GPIO_USART2_CK_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN7) +#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN3) +#define GPIO_USART2_RTS_DE_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN1) +#define GPIO_USART2_RTS_DE_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN4) + +#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN4) +#define GPIO_USART3_TX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN10) +#define GPIO_USART3_TX_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN8) +#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN5) +#define GPIO_USART3_RX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN11) +#define GPIO_USART3_RX_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN9) +#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN0) +#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_USART3_CK_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN12) +#define GPIO_USART3_CK_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN10) +#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN6) +#define GPIO_USART3_CTS_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_USART3_CTS_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN11) +#define GPIO_USART3_RTS_DE_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN1) +#define GPIO_USART3_RTS_DE_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN14) +#define GPIO_USART3_RTS_DE_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN2) +#define GPIO_USART3_RTS_DE_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN12) + +#define GPIO_UART4_TX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN0) +#define GPIO_UART4_TX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN10) +#define GPIO_UART4_RX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN1) +#define GPIO_UART4_RX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN11) +#define GPIO_UART4_CTS (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN7) +#define GPIO_UART4_RTS_DE (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN15) + +#define GPIO_UART5_TX (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN12) +#define GPIO_UART5_RX (GPIO_ALT|GPIO_AF8 |GPIO_PORTD|GPIO_PIN2) +#define GPIO_UART5_CTS (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN5) +#define GPIO_UART5_RTS_DE (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN4) + +#define GPIO_LPUART1_TX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN11) +#define GPIO_LPUART1_TX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN1) +#define GPIO_LPUART1_TX_3 (GPIO_ALT|GPIO_AF8 |GPIO_PORTG|GPIO_PIN7) +#define GPIO_LPUART1_RX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN10) +#define GPIO_LPUART1_RX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN0) +#define GPIO_LPUART1_RX_3 (GPIO_ALT|GPIO_AF8 |GPIO_PORTG|GPIO_PIN8) +#define GPIO_LPUART1_CTS_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_LPUART1_CTS_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTG|GPIO_PIN5) +#define GPIO_LPUART1_RTS_DE_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN12) +#define GPIO_LPUART1_RTS_DE_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTG|GPIO_PIN6) + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_PINMAP_H */ + diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h new file mode 100644 index 00000000000..d8e12470c35 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h @@ -0,0 +1,763 @@ +/**************************************************************************************************** + * arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h + * + * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Gregory Nutt + * Author: Sebastien Lorquet + * + * 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_STM32L4_CHIP_STM32F42XXX_RCC_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32F42XXX_RCC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32L4_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32L4_RCC_ICSCR_OFFSET 0x0004 /* Internal clock sources calibration register */ +#define STM32L4_RCC_CFGR_OFFSET 0x0008 /* Clock configuration register */ +#define STM32L4_RCC_PLLCFG_OFFSET 0x000c /* PLL configuration register */ +#define STM32L4_RCC_PLLSAI1CFG_OFFSET 0x0010 /* PLLSAI1 configuration register */ +#define STM32L4_RCC_PLLSAI2CFG_OFFSET 0x0014 /* PLLSAI2 configuration register */ +#define STM32L4_RCC_CIER_OFFSET 0x0018 /* Clock interrupt enable register */ +#define STM32L4_RCC_CIFR_OFFSET 0x001c /* Clock interrupt flag register */ +#define STM32L4_RCC_CICR_OFFSET 0x0020 /* Clock interrupt clear register */ +#define STM32L4_RCC_AHB1RSTR_OFFSET 0x0028 /* AHB1 peripheral reset register */ +#define STM32L4_RCC_AHB2RSTR_OFFSET 0x002c /* AHB2 peripheral reset register */ +#define STM32L4_RCC_AHB3RSTR_OFFSET 0x0030 /* AHB3 peripheral reset register */ +#define STM32L4_RCC_APB1RSTR1_OFFSET 0x0038 /* APB1 Peripheral reset register 1 */ +#define STM32L4_RCC_APB1RSTR2_OFFSET 0x003c /* APB1 Peripheral reset register 2 */ +#define STM32L4_RCC_APB2RSTR_OFFSET 0x0040 /* APB2 Peripheral reset register */ +#define STM32L4_RCC_AHB1ENR_OFFSET 0x0048 /* AHB1 Peripheral Clock enable register */ +#define STM32L4_RCC_AHB2ENR_OFFSET 0x004c /* AHB2 Peripheral Clock enable register */ +#define STM32L4_RCC_AHB3ENR_OFFSET 0x0050 /* AHB3 Peripheral Clock enable register */ +#define STM32L4_RCC_APB1ENR1_OFFSET 0x0058 /* APB1 Peripheral Clock enable register 1 */ +#define STM32L4_RCC_APB1ENR2_OFFSET 0x005c /* APB1 Peripheral Clock enable register 2 */ +#define STM32L4_RCC_APB2ENR_OFFSET 0x0060 /* APB2 Peripheral Clock enable register */ +#define STM32L4_RCC_AHB1SMENR_OFFSET 0x0068 /* RCC AHB1 low power mode peripheral clock enable register */ +#define STM32L4_RCC_AHB2SMENR_OFFSET 0x006c /* RCC AHB2 low power mode peripheral clock enable register */ +#define STM32L4_RCC_AHB3SMENR_OFFSET 0x0070 /* RCC AHB3 low power mode peripheral clock enable register */ +#define STM32L4_RCC_APB1SMENR1_OFFSET 0x0078 /* RCC APB1 low power mode peripheral clock enable register 1 */ +#define STM32L4_RCC_APB1SMENR2_OFFSET 0x007c /* RCC APB1 low power mode peripheral clock enable register 2 */ +#define STM32L4_RCC_APB2SMENR_OFFSET 0x0080 /* RCC APB2 low power mode peripheral clock enable register */ +#define STM32L4_RCC_CCIPR_OFFSET 0x0088 /* Peripherals independ clock configuration register */ +#define STM32L4_RCC_BDCR_OFFSET 0x0090 /* Backup domain control register */ +#define STM32L4_RCC_CSR_OFFSET 0x0094 /* Control/status register */ + +/* Register Addresses *******************************************************************************/ + +#define STM32L4_RCC_CR (STM32L4_RCC_BASE+STM32L4_RCC_CR_OFFSET) +#define STM32L4_RCC_ICSCR (STM32L4_RCC_BASE+STM32L4_RCC_ICSCR_OFFSET) +#define STM32L4_RCC_CFGR (STM32L4_RCC_BASE+STM32L4_RCC_CFGR_OFFSET) +#define STM32L4_RCC_PLLCFG (STM32L4_RCC_BASE+STM32L4_RCC_PLLCFG_OFFSET) +#define STM32L4_RCC_PLLSAI1CFG (STM32L4_RCC_BASE+STM32L4_RCC_PLLSAI1CFGR_OFFSET) +#define STM32L4_RCC_PLLSAI2CFG (STM32L4_RCC_BASE+STM32L4_RCC_PLLSAI2CFGR_OFFSET) +#define STM32L4_RCC_CIER (STM32L4_RCC_BASE+STM32L4_RCC_CIER_OFFSET) +#define STM32L4_RCC_CIFR (STM32L4_RCC_BASE+STM32L4_RCC_CIFR_OFFSET) +#define STM32L4_RCC_CICR (STM32L4_RCC_BASE+STM32L4_RCC_CICR_OFFSET) +#define STM32L4_RCC_AHB1RSTR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1RSTR_OFFSET) +#define STM32L4_RCC_AHB2RSTR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2RSTR_OFFSET) +#define STM32L4_RCC_AHB3RSTR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3RSTR_OFFSET) +#define STM32L4_RCC_APB1RSTR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1RSTR1_OFFSET) +#define STM32L4_RCC_APB1RSTR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1RSTR2_OFFSET) +#define STM32L4_RCC_APB2RSTR (STM32L4_RCC_BASE+STM32L4_RCC_APB2RSTR_OFFSET) +#define STM32L4_RCC_AHB1ENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1ENR_OFFSET) +#define STM32L4_RCC_AHB2ENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2ENR_OFFSET) +#define STM32L4_RCC_AHB3ENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3ENR_OFFSET) +#define STM32L4_RCC_APB1ENR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1ENR1_OFFSET) +#define STM32L4_RCC_APB1ENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1ENR2_OFFSET) +#define STM32L4_RCC_APB2ENR (STM32L4_RCC_BASE+STM32L4_RCC_APB2ENR_OFFSET) +#define STM32L4_RCC_AHB1SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1SMENR_OFFSET) +#define STM32L4_RCC_AHB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2SMENR) +#define STM32L4_RCC_AHB3SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3SMENR_OFFSET) +#define STM32L4_RCC_APB1SMENR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR1_OFFSET) +#define STM32L4_RCC_APB1SMENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR2_OFFSET) +#define STM32L4_RCC_APB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_APB2SMENR_OFFSET) +#define STM32L4_RCC_CCIPR (STM32L4_RCC_BASE+STM32L4_RCC_CCIPR_OFFSET) +#define STM32L4_RCC_BDCR (STM32L4_RCC_BASE+STM32L4_RCC_BDCR_OFFSET) +#define STM32L4_RCC_CSR (STM32L4_RCC_BASE+STM32L4_RCC_CSR_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ + +/* Clock control register */ + +#define RCC_CR_MSION (1 << 0) /* Bit 0: Internal Medium Speed clock enable */ +#define RCC_CR_MSIRDY (1 << 1) /* Bit 1: Internal Medium Speed clock ready flag */ +#define RCC_CR_MSIPLLEN (1 << 2) /* Bit 2: MSI clock PLL enable */ +#define RCC_CR_MSIRGSEL (1 << 3) /* Bit 2: MSI clock range selection */ +#define RCC_CR_MSIRANGE_SHIFT (4) /* Bits 7-4: MSI clock range */ +#define RCC_CR_MSIRANGE_MASK (0x0f << RCC_CR_MSIRANGE_SHIFT) +# define RCC_CR_MSIRANGE_100K (0 << RCC_CR_MSIRANGE_SHIFT) /* 0000: around 100 kHz */ +# define RCC_CR_MSIRANGE_200K (1 << RCC_CR_MSIRANGE_SHIFT) /* 0001: around 200 kHz */ +# define RCC_CR_MSIRANGE_400K (2 << RCC_CR_MSIRANGE_SHIFT) /* 0010: around 400 kHz */ +# define RCC_CR_MSIRANGE_800K (3 << RCC_CR_MSIRANGE_SHIFT) /* 0011: around 800 kHz */ +# define RCC_CR_MSIRANGE_1M (4 << RCC_CR_MSIRANGE_SHIFT) /* 0100: around 1 MHz */ +# define RCC_CR_MSIRANGE_2M (5 << RCC_CR_MSIRANGE_SHIFT) /* 0101: around 2 MHz */ +# define RCC_CR_MSIRANGE_4M (6 << RCC_CR_MSIRANGE_SHIFT) /* 0110: around 4 MHz */ +# define RCC_CR_MSIRANGE_8M (7 << RCC_CR_MSIRANGE_SHIFT) /* 0111: around 8 MHz */ +# define RCC_CR_MSIRANGE_16M (8 << RCC_CR_MSIRANGE_SHIFT) /* 1000: around 16 MHz */ +# define RCC_CR_MSIRANGE_24M (9 << RCC_CR_MSIRANGE_SHIFT) /* 1001: around 24 MHz */ +# define RCC_CR_MSIRANGE_32M (10 << RCC_CR_MSIRANGE_SHIFT) /* 1010: around 32 MHz */ +# define RCC_CR_MSIRANGE_48M (11 << RCC_CR_MSIRANGE_SHIFT) /* 1011: around 48 MHz */ + +#define RCC_CR_HSION (1 << 8) /* Bit 8: Internal High Speed clock enable */ +#define RCC_CR_HSIKERON (1 << 9) /* Bit 9: HSI16 always enable for peripheral kernels */ +#define RCC_CR_HSIRDY (1 << 10) /* Bit 10: Internal High Speed clock ready flag */ +#define RCC_CR_HSIASFS (1 << 11) /* Bit 11: HSI automatic start from stop */ + +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */ +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */ +#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ +#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ +#define RCC_CR_PLLSAI1ON (1 << 26) /* Bit 26: PLLSAI1 enable */ +#define RCC_CR_PLLSAI1RDY (1 << 27) /* Bit 27: PLLSAI1 clock ready flag */ +#define RCC_CR_PLLSAI2ON (1 << 28) /* Bit 28: PLLSAI2 enable */ +#define RCC_CR_PLLSAI2RDY (1 << 29) /* Bit 29: PLLSAI2 clock ready flag */ + +/* Internal Clock Sources Calibration */ + +#define RCC_CR_HSITRIM_SHIFT (24) /* Bits 28-24: Internal High Speed clock trimming */ +#define RCC_CR_HSITRIM_MASK (0x1f << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSICAL_SHIFT (16) /* Bits 23-16: Internal High Speed clock Calibration */ +#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_MSITRIM_SHIFT (8) /* Bits 15-8: Internal Medium Speed clock trimming */ +#define RCC_CR_MSITRIM_MASK (0xff << RCC_CR_MSITRIM_SHIFT) +#define RCC_CR_MSICAL_SHIFT (0) /* Bits 7-0: Internal Menium Speed clock Calibration */ +#define RCC_CR_MSICAL_MASK (0xff << RCC_CR_MSICAL_SHIFT) + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 0-1: System clock Switch */ +#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_MSI (0 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSI (1 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (2 << RCC_CFGR_SW_SHIFT) /* 01: HSE selected as system clock */ +# define RCC_CFGR_SW_PLL (3 << RCC_CFGR_SW_SHIFT) /* 10: PLL selected as system clock */ + +#define RCC_CFGR_SWS_SHIFT (2) /* Bits 2-3: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_MSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSI (1 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */ +# define RCC_CFGR_SWS_HSE (2 << RCC_CFGR_SWS_SHIFT) /* 01: HSE oscillator used as system clock */ +# define RCC_CFGR_SWS_PLL (3 << RCC_CFGR_SWS_SHIFT) /* 10: PLL used as system clock */ + +#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 4-7: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ + +#define RCC_CFGR_PPRE1_SHIFT (8) /* Bits 8-10: APB Low speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT) +# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */ + +#define RCC_CFGR_PPRE2_SHIFT (11) /* Bits 11-13: APB High speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT) +# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ + +#define RCC_CFGR_STOPWUCK (1 << 15) /* Bit 15: Wakeup from Stop and CSS backup clock selection */ +# define RCC_CFGR_STOPWUCK_MSI (0 << 15) /* 0: MSI */ +# define RCC_CFGR_STOPWUCK_HSI (1 << 15) /* 0: HSI */ + +#define RCC_CFGR_MCO_SHIFT (24) /* Bits 24-26: Microcontroller Clock Output */ +#define RCC_CFGR_MCO_MASK (7 << RCC_CFGR_MCO_SHIFT) +# define RCC_CFGR_MCO_NONE (0 << RCC_CFGR_MCO_SHIFT) /* 000: Disabled */ +# define RCC_CFGR_MCO_SYSCLK (1 << RCC_CFGR_MCO_SHIFT) /* 001: SYSCLK system clock selected */ +# define RCC_CFGR_MCO_MSI (2 << RCC_CFGR_MCO_SHIFT) /* 010: MSI clock selected */ +# define RCC_CFGR_MCO_HSI (3 << RCC_CFGR_MCO_SHIFT) /* 011: HSI clock selected */ +# define RCC_CFGR_MCO_HSE (4 << RCC_CFGR_MCO_SHIFT) /* 100: HSE clock selected */ +# define RCC_CFGR_MCO_PLL (5 << RCC_CFGR_MCO_SHIFT) /* 101: Main PLL selected */ +# define RCC_CFGR_MCO_LSI (6 << RCC_CFGR_MCO_SHIFT) /* 110: LSI clock selected */ +# define RCC_CFGR_MCO_LSE (7 << RCC_CFGR_MCO_SHIFT) /* 111: LSE clock selected */ + +#define RCC_CFGR_MCOPRE_SHIFT (28) /* Bits 28-30: MCO prescaler */ +#define RCC_CFGR_MCOPRE_MASK (7 << RCC_CFGR_MCOPRE_SHIFT) +# define RCC_CFGR_MCOPRE_NONE (0 << RCC_CFGR_MCOPRE_SHIFT) /* 000: no division */ +# define RCC_CFGR_MCOPRE_DIV2 (1 << RCC_CFGR_MCOPRE_SHIFT) /* 001: division by 2 */ +# define RCC_CFGR_MCOPRE_DIV4 (2 << RCC_CFGR_MCOPRE_SHIFT) /* 010: division by 4 */ +# define RCC_CFGR_MCOPRE_DIV8 (3 << RCC_CFGR_MCOPRE_SHIFT) /* 011: division by 8 */ +# define RCC_CFGR_MCOPRE_DIV16 (4 << RCC_CFGR_MCOPRE_SHIFT) /* 100: division by 16 */ + +/* PLL configuration register */ + +#define RCC_PLLCFG_PLLSRC_SHIFT (0) /* Bit 0-1: Main PLL(PLL) and audio PLLs (PLLSAIx) + * entry clock source */ +#define RCC_PLLCFG_PLLSRC_MASK (3 << RCC_PLLCFG_PLLSRC_SHIFT) +# define RCC_PLLCFG_PLLSRC_NONE (0 << RCC_PLLCFG_PLLSRC_SHIFT) /* 000: No clock sent to PLLs */ +# define RCC_PLLCFG_PLLSRC_MSI (1 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: MSI selected as PLL source */ +# define RCC_PLLCFG_PLLSRC_HSI (2 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: HSI selected as PLL source */ +# define RCC_PLLCFG_PLLSRC_HSE (3 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: HSE selected as PLL source */ + +#define RCC_PLLCFG_PLLM_SHIFT (4) /* Bits 4-6: Main PLL (PLL) input clock divider */ +#define RCC_PLLCFG_PLLM_MASK (0x07 << RCC_PLLCFG_PLLM_SHIFT) +# define RCC_PLLCFG_PLLM(n) ((n-1) << RCC_PLLCFG_PLLM_SHIFT) /* m = 1..8 */ + +#define RCC_PLLCFG_PLLN_SHIFT (8) /* Bits 6-14: Main PLL (PLL) VCO multiplier */ +#define RCC_PLLCFG_PLLN_MASK (0x7f << RCC_PLLCFG_PLLN_SHIFT) +# define RCC_PLLCFG_PLLN(n) ((n) << RCC_PLLCFG_PLLN_SHIFT) /* n = 8..86 */ + +#define RCC_PLLCFG_PLLPEN (1 << 16) /* Bit 16: Main PLL PLLSAI3CLK output enable */ + +#define RCC_PLLCFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI3CLK */ +# define RCC_PLLCFG_PLLP_7 0 /* 0: PLLP = 7 */ +# define RCC_PLLCFG_PLLP_17 RCC_PLLCFG_PLLP /* 1: PLLP = 17 */ + +#define RCC_PLLCFG_PLLQEN (1 << 20) /* Bit 20: Main PLL PLL48M1CLK output enable */ + +#define RCC_PLLCFG_PLLQ_SHIFT (21) +#define RCC_PLLCFG_PLLQ_MASK (3 << RCC_PLLCFG_PLLQ_SHIFT) +# define RCC_PLLCFG_PLLQ(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLQ_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLCFG_PLLQ_2 (0 << RCC_PLLCFG_PLLQ_SHIFT) /* 00: PLLQ = 2 */ +# define RCC_PLLCFG_PLLQ_4 (1 << RCC_PLLCFG_PLLQ_SHIFT) /* 01: PLLQ = 4 */ +# define RCC_PLLCFG_PLLQ_6 (2 << RCC_PLLCFG_PLLQ_SHIFT) /* 10: PLLQ = 6 */ +# define RCC_PLLCFG_PLLQ_8 (3 << RCC_PLLCFG_PLLQ_SHIFT) /* 11: PLLQ = 8 */ + +#define RCC_PLLCFG_PLLREN (1 << 24) /* Bit 24: Main PLL PLLCLK output enable */ + +#define RCC_PLLCFG_PLLR_SHIFT (25) +#define RCC_PLLCFG_PLLR_MASK (3 << RCC_PLLCFG_PLLR_SHIFT) +# define RCC_PLLCFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLR_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLCFG_PLLR_2 (0 << RCC_PLLCFG_PLLR_SHIFT) /* 00: PLLR = 2 */ +# define RCC_PLLCFG_PLLR_4 (1 << RCC_PLLCFG_PLLR_SHIFT) /* 01: PLLR = 4 */ +# define RCC_PLLCFG_PLLR_6 (2 << RCC_PLLCFG_PLLR_SHIFT) /* 10: PLLR = 6 */ +# define RCC_PLLCFG_PLLR_8 (3 << RCC_PLLCFG_PLLR_SHIFT) /* 11: PLLR = 8 */ + +#define RCC_PLLCFG_RESET (0x00001000) /* PLLCFG reset value */ + +/* PLLSAI1 Configuration register */ + +#define RCC_PLLSAI1CFG_PLLN_SHIFT (8) /* Bits 6-14: SAI1 PLL (PLLSAI1) VCO multiplier */ +#define RCC_PLLSAI1CFG_PLLN_MASK (0x7f << RCC_PLLSAI1CFG_PLLN_SHIFT) +# define RCC_PLLSAI1CFG_PLLN(n) ((n) << RCC_PLLSAI1CFG_PLLN_SHIFT) /* n = 8..86 */ + +#define RCC_PLLSAI1CFG_PLLPEN (1 << 16) /* Bit 16: SAI1 PLL PLLSAI1CLK output enable */ + +#define RCC_PLLSAI1CFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI1CLK */ +# define RCC_PLLSAI1CFG_PLLP_7 0 /* 0: PLLP = 7 */ +# define RCC_PLLSAI1CFG_PLLP_17 RCC_PLLSAI1CFG_PLLP /* 1: PLLP = 17 */ + +#define RCC_PLLSAI1CFG_PLLQEN (1 << 20) /* Bit 20: Main PLL PLL48M2CLK output enable */ + +#define RCC_PLLSAI1CFG_PLLQ_SHIFT (21) +#define RCC_PLLSAI1CFG_PLLQ_MASK (3 << RCC_PLLSAI1CFG_PLLQ_SHIFT) +# define RCC_PLLSAI1CFG_PLLQ(n) ((((n)>>1)-1)<< RCC_PLLSAI1CFG_PLLQ_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLSAI1CFG_PLLQ_2 (0 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 00: PLLQ = 2 */ +# define RCC_PLLSAI1CFG_PLLQ_4 (1 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 01: PLLQ = 4 */ +# define RCC_PLLSAI1CFG_PLLQ_6 (2 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 10: PLLQ = 6 */ +# define RCC_PLLSAI1CFG_PLLQ_8 (3 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 11: PLLQ = 8 */ + +#define RCC_PLLSAI1CFG_PLLREN (1 << 24) /* Bit 24: SAI1 PLL PLLADC1CLK output enable */ + +#define RCC_PLLSAI1CFG_PLLR_SHIFT (25) +#define RCC_PLLSAI1CFG_PLLR_MASK (3 << RCC_PLLSAI1CFG_PLLR_SHIFT) +# define RCC_PLLSAI1CFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLSAI1CFG_PLLR_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLSAI1CFG_PLLR_2 (0 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 00: PLLR = 2 */ +# define RCC_PLLSAI1CFG_PLLR_4 (1 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 01: PLLR = 4 */ +# define RCC_PLLSAI1CFG_PLLR_6 (2 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 10: PLLR = 6 */ +# define RCC_PLLSAI1CFG_PLLR_8 (3 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 11: PLLR = 8 */ + +/* PLLSAI2 Configuration register */ + +#define RCC_PLLSAI2CFG_PLLN_SHIFT (8) /* Bits 6-14: SAI2 PLL (PLLSAI2) VCO multiplier */ +#define RCC_PLLSAI2CFG_PLLN_MASK (0x7f << RCC_PLLSAI2CFG_PLLN_SHIFT) +# define RCC_PLLSAI2CFG_PLLN(n) ((n) << RCC_PLLSAI2CFG_PLLN_SHIFT) /* n = 8..86 */ + +#define RCC_PLLSAI2CFG_PLLPEN (1 << 16) /* Bit 16: SAI1 PLL PLLSAI2CLK output enable */ + +#define RCC_PLLSAI2CFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI2CLK */ +# define RCC_PLLSAI2CFG_PLLP_7 0 /* 0: PLLP = 7 */ +# define RCC_PLLSAI2CFG_PLLP_17 RCC_PLLSAI2CFG_PLLP /* 1: PLLP = 17 */ + +#define RCC_PLLSAI2CFG_PLLREN (1 << 24) /* Bit 24: SAI2 PLL PLLADC2CLK output enable */ + +#define RCC_PLLSAI2CFG_PLLR_SHIFT (25) +#define RCC_PLLSAI2CFG_PLLR_MASK (3 << RCC_PLLSAI2CFG_PLLR_SHIFT) +# define RCC_PLLSAI2CFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLSAI2CFG_PLLR_SHIFT) /* n=2,4,6,8 */ +# define RCC_PLLSAI2CFG_PLLR_2 (0 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 00: PLLR = 2 */ +# define RCC_PLLSAI2CFG_PLLR_4 (1 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 01: PLLR = 4 */ +# define RCC_PLLSAI2CFG_PLLR_6 (2 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 10: PLLR = 6 */ +# define RCC_PLLSAI2CFG_PLLR_8 (3 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 11: PLLR = 8 */ + +/* Clock interrupt enable register */ + +#define RCC_CIR_LSIRDYIE (1 << 0) /* Bit 0: LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE (1 << 1) /* Bit 1: LSE Ready Interrupt Enable */ +#define RCC_CIR_MSIRDYIE (1 << 2) /* Bit 2: MSI Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE (1 << 3) /* Bit 3: HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE (1 << 4) /* Bit 4: HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE (1 << 5) /* Bit 5: PLL Ready Interrupt Enable */ +#define RCC_CIR_PLLSAI1RDYIE (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt enable */ +#define RCC_CIR_PLLSAI2RDYIE (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt enable */ +#define RCC_CIR_LSECSSIE (1 << 9) /* Bit 9: LSE Clock Security System Interrupt Enable */ + +/* Clock interrupt flag register */ + +#define RCC_CIR_LSIRDYIF (1 << 0) /* Bit 0: LSI Ready Interrupt Flag */ +#define RCC_CIR_LSERDYIF (1 << 1) /* Bit 1: LSE Ready Interrupt Flag */ +#define RCC_CIR_MSIRDYIF (1 << 2) /* Bit 2: MSI Ready Interrupt Flag */ +#define RCC_CIR_HSIRDYIF (1 << 3) /* Bit 3: HSI Ready Interrupt Flag */ +#define RCC_CIR_HSERDYIF (1 << 4) /* Bit 4: HSE Ready Interrupt Flag */ +#define RCC_CIR_PLLRDYIF (1 << 5) /* Bit 5: PLL Ready Interrupt Flag */ +#define RCC_CIR_PLLSAI1RDYIF (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt Flag */ +#define RCC_CIR_PLLSAI2RDYIF (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt Flag */ +#define RCC_CIR_CSSF (1 << 8) /* Bit 8: Clock Security System Interrupt Flag */ +#define RCC_CIR_LSECSSIF (1 << 9) /* Bit 9: LSE Clock Security System Interrupt Flag */ + +/* Clock interrupt clear register */ + +#define RCC_CIR_LSIRDYIC (1 << 0) /* Bit 0: LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYIC (1 << 1) /* Bit 1: LSE Ready Interrupt Clear */ +#define RCC_CIR_MSIRDYIC (1 << 2) /* Bit 2: MSI Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYIC (1 << 3) /* Bit 3: HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYIC (1 << 4) /* Bit 4: HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYIC (1 << 5) /* Bit 5: PLL Ready Interrupt Clear */ +#define RCC_CIR_PLLSAI1RDYIC (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt Clear */ +#define RCC_CIR_PLLSAI2RDYIC (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt Clear */ +#define RCC_CIR_CSSC (1 << 8) /* Bit 8: Clock Security System Interrupt Clear */ +#define RCC_CIR_LSECSSIC (1 << 9) /* Bit 9: LSE Clock Security System Interrupt Clear */ + +/* AHB1 peripheral reset register */ + +#define RCC_AHB1RSTR_DMA1RST (1 << 0) /* Bit 0: DMA1 reset */ +#define RCC_AHB1RSTR_DMA2RST (1 << 1) /* Bit 1: DMA2 reset */ +#define RCC_AHB1RSTR_FLASHRST (1 << 8) /* Bit 8: Flash memory interface reset */ +#define RCC_AHB1RSTR_CRCRST (1 << 12) /* Bit 12: CRC reset */ +#define RCC_AHB1RSTR_TSCRST (1 << 16) /* Bit 16: Touch Sensing Controller reset */ + +/* AHB2 peripheral reset register */ + +#define RCC_AHB2RSTR_GPIOARST (1 << 0) /* Bit 0: IO port A reset */ +#define RCC_AHB2RSTR_GPIOBRST (1 << 1) /* Bit 1: IO port B reset */ +#define RCC_AHB2RSTR_GPIOCRST (1 << 2) /* Bit 2: IO port C reset */ +#define RCC_AHB2RSTR_GPIODRST (1 << 3) /* Bit 3: IO port D reset */ +#define RCC_AHB2RSTR_GPIOERST (1 << 4) /* Bit 4: IO port E reset */ +#define RCC_AHB2RSTR_GPIOFRST (1 << 5) /* Bit 5: IO port F reset */ +#define RCC_AHB2RSTR_GPIOGRST (1 << 6) /* Bit 6: IO port G reset */ +#define RCC_AHB2RSTR_GPIOHRST (1 << 7) /* Bit 7: IO port H reset */ +#define RCC_AHB2RSTR_OTGFSRST (1 << 12) /* Bit 12: USB OTG FS module reset */ +#define RCC_AHB2RSTR_ADCRST (1 << 13) /* Bit 13: ADC interface reset (common to all ADCs) */ +#define RCC_AHB2RSTR_AESRST (1 << 16) /* Bit 16: AES Cryptographic module reset */ +#define RCC_AHB2RSTR_RNGRST (1 << 18) /* Bit 6: Random number generator module reset */ + +/* AHB3 peripheral reset register */ + +#define RCC_AHB3RSTR_FSMCRST (1 << 0) /* Bit 0: Flexible static memory controller module reset */ +#define RCC_AHB3RSTR_QSPIRST (1 << 8) /* Bit 8: Quad SPI module reset */ + +/* APB1 Peripheral reset register 1 */ + +#define RCC_APB1RSTR1_TIM2RST (1 << 0) /* Bit 0: TIM2 reset */ +#define RCC_APB1RSTR1_TIM3RST (1 << 1) /* Bit 1: TIM3 reset */ +#define RCC_APB1RSTR1_TIM4RST (1 << 2) /* Bit 2: TIM4 reset */ +#define RCC_APB1RSTR1_TIM5RST (1 << 3) /* Bit 3: TIM5 reset */ +#define RCC_APB1RSTR1_TIM6RST (1 << 4) /* Bit 4: TIM6 reset */ +#define RCC_APB1RSTR1_TIM7RST (1 << 5) /* Bit 5: TIM7 reset */ +#define RCC_APB1RSTR1_LCDRST (1 << 9) /* Bit 9: LCD controller reset */ +#define RCC_APB1RSTR1_SPI2RST (1 << 14) /* Bit 14: SPI2 reset */ +#define RCC_APB1RSTR1_SPI3RST (1 << 15) /* Bit 15: SPI3 reset */ +#define RCC_APB1RSTR1_USART2RST (1 << 17) /* Bit 17: USART2 reset */ +#define RCC_APB1RSTR1_USART3RST (1 << 18) /* Bit 18: USART3 reset */ +#define RCC_APB1RSTR1_UART4RST (1 << 19) /* Bit 19: USART4 reset */ +#define RCC_APB1RSTR1_UART5RST (1 << 20) /* Bit 20: USART5 reset */ +#define RCC_APB1RSTR1_I2C1RST (1 << 21) /* Bit 21: I2C1 reset */ +#define RCC_APB1RSTR1_I2C2RST (1 << 22) /* Bit 22: I2C2 reset */ +#define RCC_APB1RSTR1_I2C3RST (1 << 23) /* Bit 23: I2C3 reset */ +#define RCC_APB1RSTR1_CAN1RST (1 << 25) /* Bit 25: CAN1 reset */ +#define RCC_APB1RSTR1_PWRRST (1 << 28) /* Bit 28: Power interface reset */ +#define RCC_APB1RSTR1_DAC1RST (1 << 29) /* Bit 29: DAC1 reset */ +#define RCC_APB1RSTR1_OPAMPRST (1 << 30) /* Bit 30: OPAMP reset */ +#define RCC_APB1RSTR1_LPTIM1RST (1 << 31) /* Bit 31: Low-power Timer 1 reset */ + +/* APB1 Peripheral reset register 2 */ + +#define RCC_APB1RSTR2_LPUART1RST (1 << 0) /* Bit 0: Low-power UART 1 reset */ +#define RCC_APB1RSTR2_SWPMI1RST (1 << 2) /* Bit 2: Single Wire Protocol reset */ +#define RCC_APB1RSTR2_LPTIM2RST (1 << 5) /* Bit 5: Low-power Timer 2 reset */ + +/* APB2 Peripheral reset register */ + +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) /* Bit 0: System configuration controller reset */ +#define RCC_APB2RSTR_SDMMCRST (1 << 10) /* Bit 10: SDMMC reset */ +#define RCC_APB2RSTR_TIM1RST (1 << 11) /* Bit 11: TIM1 reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI1 reset */ +#define RCC_APB2RSTR_TIM8RST (1 << 13) /* Bit 13: TIM8 reset */ +#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ +#define RCC_APB2RSTR_TIM15RST (1 << 16) /* Bit 16: TIM15 reset */ +#define RCC_APB2RSTR_TIM16RST (1 << 17) /* Bit 17: TIM16 reset */ +#define RCC_APB2RSTR_TIM17RST (1 << 18) /* Bit 18: TIM17 reset */ +#define RCC_APB2RSTR_SAI1RST (1 << 21) /* Bit 21: SAI1 reset */ +#define RCC_APB2RSTR_SAI2RST (1 << 22) /* Bit 22: SAI2 reset */ +#define RCC_APB2RSTR_DFSDMRST (1 << 24) /* Bit 24: DFSDM reset */ + +/* AHB1 Peripheral Clock enable register */ + +#define RCC_AHB1ENR_DMA1EN (1 << 0) /* Bit 0: DMA1 enable */ +#define RCC_AHB1ENR_DMA2EN (1 << 1) /* Bit 1: DMA2 enable */ +#define RCC_AHB1ENR_FLASHEN (1 << 8) /* Bit 8: Flash memory interface enable */ +#define RCC_AHB1ENR_CRCEN (1 << 12) /* Bit 12: CRC enable */ +#define RCC_AHB1ENR_TSCEN (1 << 16) /* Bit 16: Touch Sensing Controller enable */ + +/* AHB2 Peripheral Clock enable register */ + +#define RCC_AHB2ENR_GPIOAEN (1 << 0) /* Bit 0: IO port A enable */ +#define RCC_AHB2ENR_GPIOBEN (1 << 1) /* Bit 1: IO port B enable */ +#define RCC_AHB2ENR_GPIOCEN (1 << 2) /* Bit 2: IO port C enable */ +#define RCC_AHB2ENR_GPIODEN (1 << 3) /* Bit 3: IO port D enable */ +#define RCC_AHB2ENR_GPIOEEN (1 << 4) /* Bit 4: IO port E enable */ +#define RCC_AHB2ENR_GPIOFEN (1 << 5) /* Bit 5: IO port F enable */ +#define RCC_AHB2ENR_GPIOGEN (1 << 6) /* Bit 6: IO port G enable */ +#define RCC_AHB2ENR_GPIOHEN (1 << 7) /* Bit 7: IO port H enable */ +#define RCC_AHB2ENR_OTGFSEN (1 << 12) /* Bit 12: USB OTG FS module enable */ +#define RCC_AHB2ENR_ADCEN (1 << 13) /* Bit 13: ADC interface enable (common to all ADCs) */ +#define RCC_AHB2ENR_AESEN (1 << 16) /* Bit 16: AES Cryptographic module enable */ +#define RCC_AHB2ENR_RNGEN (1 << 18) /* Bit 6: Random number generator module enable */ + +/* AHB3 Peripheral Clock enable register */ + +#define RCC_AHB3ENR_FSMCEN (1 << 0) /* Bit 0: Flexible static memory controller module enable */ +#define RCC_AHB3ENR_QSPIEN (1 << 8) /* Bit 8: Quad SPI module enable */ + +/* APB1 Peripheral Clock enable register 1*/ + +#define RCC_APB1ENR1_TIM2EN (1 << 0) /* Bit 0: TIM2 enable */ +#define RCC_APB1ENR1_TIM3EN (1 << 1) /* Bit 1: TIM3 enable */ +#define RCC_APB1ENR1_TIM4EN (1 << 2) /* Bit 2: TIM4 enable */ +#define RCC_APB1ENR1_TIM5EN (1 << 3) /* Bit 3: TIM5 enable */ +#define RCC_APB1ENR1_TIM6EN (1 << 4) /* Bit 4: TIM6 enable */ +#define RCC_APB1ENR1_TIM7EN (1 << 5) /* Bit 5: TIM7 enable */ +#define RCC_APB1ENR1_LCDEN (1 << 9) /* Bit 9: LCD controller enable */ +#define RCC_APB1ENR1_WWDGEN (1 << 11) /* Bit 11: Windowed Watchdog enable */ +#define RCC_APB1ENR1_SPI2EN (1 << 14) /* Bit 14: SPI2 enable */ +#define RCC_APB1ENR1_SPI3EN (1 << 15) /* Bit 15: SPI3 enable */ +#define RCC_APB1ENR1_USART2EN (1 << 17) /* Bit 17: USART2 enable */ +#define RCC_APB1ENR1_USART3EN (1 << 18) /* Bit 18: USART3 enable */ +#define RCC_APB1ENR1_UART4EN (1 << 19) /* Bit 19: USART4 enable */ +#define RCC_APB1ENR1_UART5EN (1 << 20) /* Bit 20: USART5 enable */ +#define RCC_APB1ENR1_I2C1EN (1 << 21) /* Bit 21: I2C1 enable */ +#define RCC_APB1ENR1_I2C2EN (1 << 22) /* Bit 22: I2C2 enable */ +#define RCC_APB1ENR1_I2C3EN (1 << 23) /* Bit 23: I2C3 enable */ +#define RCC_APB1ENR1_CAN1EN (1 << 25) /* Bit 25: CAN1 enable */ +#define RCC_APB1ENR1_PWREN (1 << 28) /* Bit 28: Power interface enable */ +#define RCC_APB1ENR1_DAC1EN (1 << 29) /* Bit 29: DAC1 enable */ +#define RCC_APB1ENR1_OPAMPEN (1 << 30) /* Bit 30: OPAMP enable */ +#define RCC_APB1ENR1_LPTIM1EN (1 << 31) /* Bit 31: Low-power Timer 1 enable */ + +/* APB1 Peripheral Clock enable register 2*/ + +#define RCC_APB1ENR2_LPUART1EN (1 << 0) /* Bit 0: Low-power UART 1 enable */ +#define RCC_APB1ENR2_SWPMI1EN (1 << 2) /* Bit 2: Single Wire Protocol enable */ +#define RCC_APB1ENR2_LPTIM2EN (1 << 5) /* Bit 5: Low-power Timer 2 enable */ + +/* APB2 Peripheral Clock enable register */ + +#define RCC_APB2ENR_SYSCFGEN (1 << 0) /* Bit 0: System configuration controller enable */ +#define RCC_APB2ENR_FWEN (1 << 7) /* Bit 7: Firewall enable */ +#define RCC_APB2ENR_SDMMCEN (1 << 10) /* Bit 10: SDMMC enable */ +#define RCC_APB2ENR_TIM1EN (1 << 11) /* Bit 11: TIM1 enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI1 enable */ +#define RCC_APB2ENR_TIM8EN (1 << 13) /* Bit 13: TIM8 enable */ +#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 enable */ +#define RCC_APB2ENR_TIM15EN (1 << 16) /* Bit 16: TIM15 enable */ +#define RCC_APB2ENR_TIM16EN (1 << 17) /* Bit 17: TIM16 enable */ +#define RCC_APB2ENR_TIM17EN (1 << 18) /* Bit 18: TIM17 enable */ +#define RCC_APB2ENR_SAI1EN (1 << 21) /* Bit 21: SAI1 enable */ +#define RCC_APB2ENR_SAI2EN (1 << 22) /* Bit 22: SAI2 enable */ +#define RCC_APB2ENR_DFSDMEN (1 << 24) /* Bit 24: DFSDM enable */ + +/* RCC AHB1 low power mode peripheral clock enable register */ + +#define RCC_AHB1SMENR_DMA1LPSMEN (1 << 0) /* Bit 0: DMA1 enable during Sleep mode */ +#define RCC_AHB1SMENR_DMA2LPSMEN (1 << 1) /* Bit 1: DMA2 enable during Sleep mode */ +#define RCC_AHB1SMENR_FLASHLPSMEN (1 << 8) /* Bit 8: Flash memory interface enable during Sleep mode */ +#define RCC_AHB1SMENR_SRAM1SMEN (1 << 9) /* Bit 9: SRAM1 enable during Sleep mode */ +#define RCC_AHB1SMENR_CRCLPSMEN (1 << 12) /* Bit 12: CRC enable during Sleep mode */ +#define RCC_AHB1SMENR_TSCLPSMEN (1 << 16) /* Bit 16: Touch Sensing Controller enable during Sleep mode */ + +/* RCC AHB2 low power mode peripheral clock enable register */ + +#define RCC_AHB2SMENR_GPIOASMEN (1 << 0) /* Bit 0: IO port A enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOBSMEN (1 << 1) /* Bit 1: IO port B enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOCSMEN (1 << 2) /* Bit 2: IO port C enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIODSMEN (1 << 3) /* Bit 3: IO port D enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOESMEN (1 << 4) /* Bit 4: IO port E enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOFSMEN (1 << 5) /* Bit 5: IO port F enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOGSMEN (1 << 6) /* Bit 6: IO port G enable during Sleep mode */ +#define RCC_AHB2SMENR_GPIOHSMEN (1 << 7) /* Bit 7: IO port H enable during Sleep mode */ +#define RCC_AHB2SMENR_SRAM2SMEN (1 << 9) /* Bit 9: SRAM2 enable during Sleep mode */ +#define RCC_AHB2SMENR_OTGFSSMEN (1 << 12) /* Bit 12: USB OTG FS module enable during Sleep mode */ +#define RCC_AHB2SMENR_ADCSMEN (1 << 13) /* Bit 13: ADC interface enable during Sleep mode (common to all ADCs) */ +#define RCC_AHB2SMENR_AESSMEN (1 << 16) /* Bit 16: AES Cryptographic module enable during Sleep mode */ +#define RCC_AHB2SMENR_RNGSMEN (1 << 18) /* Bit 6: Random number generator module enable during Sleep mode */ + +/* RCC AHB3 low power mode peripheral clock enable register */ + +#define RCC_AHB3SMENR_FSMCSMEN (1 << 0) /* Bit 0: Flexible static memory controller module enable during Sleep mode */ +#define RCC_AHB3SMENR_QSPISMEN (1 << 8) /* Bit 8: Quad SPI module enable during Sleep mode */ + +/* RCC APB1 low power modeperipheral clock enable register 1 */ + +#define RCC_APB1SMENR1_TIM2SMEN (1 << 0) /* Bit 0: TIM2 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM3SMEN (1 << 1) /* Bit 1: TIM3 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM4SMEN (1 << 2) /* Bit 2: TIM4 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM5SMEN (1 << 3) /* Bit 3: TIM5 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM6SMEN (1 << 4) /* Bit 4: TIM6 enable during Sleep mode */ +#define RCC_APB1SMENR1_TIM7SMEN (1 << 5) /* Bit 5: TIM7 enable during Sleep mode */ +#define RCC_APB1SMENR1_LCDSMEN (1 << 9) /* Bit 9: LCD controller enable during Sleep mode */ +#define RCC_APB1SMENR1_WWDGSMEN (1 << 11) /* Bit 11: Windowed Watchdog enable during Sleep mode */ +#define RCC_APB1SMENR1_SPI2SMEN (1 << 14) /* Bit 14: SPI2 enable during Sleep mode */ +#define RCC_APB1SMENR1_SPI3SMEN (1 << 15) /* Bit 15: SPI3 enable during Sleep mode */ +#define RCC_APB1SMENR1_USART2SMEN (1 << 17) /* Bit 17: USART2 enable during Sleep mode */ +#define RCC_APB1SMENR1_USART3SMEN (1 << 18) /* Bit 18: USART3 enable during Sleep mode */ +#define RCC_APB1SMENR1_UART4SMEN (1 << 19) /* Bit 19: USART4 enable during Sleep mode */ +#define RCC_APB1SMENR1_UART5SMEN (1 << 20) /* Bit 20: USART5 enable during Sleep mode */ +#define RCC_APB1SMENR1_I2C1SMEN (1 << 21) /* Bit 21: I2C1 enable during Sleep mode */ +#define RCC_APB1SMENR1_I2C2SMEN (1 << 22) /* Bit 22: I2C2 enable during Sleep mode */ +#define RCC_APB1SMENR1_I2C3SMEN (1 << 23) /* Bit 23: I2C3 enable during Sleep mode */ +#define RCC_APB1SMENR1_CAN1SMEN (1 << 25) /* Bit 25: CAN1 enable during Sleep mode */ +#define RCC_APB1SMENR1_PWRSMEN (1 << 28) /* Bit 28: Power interface enable during Sleep mode */ +#define RCC_APB1SMENR1_DAC1SMEN (1 << 29) /* Bit 29: DAC1 enable during Sleep mode */ +#define RCC_APB1SMENR1_OPAMPSMEN (1 << 30) /* Bit 30: OPAMP enable during Sleep mode */ +#define RCC_APB1SMENR1_LPTIM1SMEN (1 << 31) /* Bit 31: Low-power Timer 1 enable during Sleep mode */ + +/* RCC APB1 low power modeperipheral clock enable register 2 */ + +#define RCC_APB1SMENR2_LPUART1SMEN (1 << 0) /* Bit 0: Low-power UART 1 enable during Sleep mode */ +#define RCC_APB1SMENR2_SWPMI1SMEN (1 << 2) /* Bit 2: Single Wire Protocol enable during Sleep mode */ +#define RCC_APB1SMENR2_LPTIM2SMEN (1 << 5) /* Bit 5: Low-power Timer 2 enable during Sleep mode */ + +/* RCC APB2 low power mode peripheral clock enable register */ + +#define RCC_APB2SMENR_SYSCFGSMEN (1 << 0) /* Bit 0: System configuration controller enable during Sleep mode */ +#define RCC_APB2SMENR_SDMMCSMEN (1 << 10) /* Bit 10: SDMMC enable during Sleep mode */ +#define RCC_APB2SMENR_TIM1SMEN (1 << 11) /* Bit 11: TIM1 enable during Sleep mode */ +#define RCC_APB2SMENR_SPI1SMEN (1 << 12) /* Bit 12: SPI1 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM8SMEN (1 << 13) /* Bit 13: TIM8 enable during Sleep mode */ +#define RCC_APB2SMENR_USART1SMEN (1 << 14) /* Bit 14: USART1 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM15SMEN (1 << 16) /* Bit 16: TIM15 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM16SMEN (1 << 17) /* Bit 17: TIM16 enable during Sleep mode */ +#define RCC_APB2SMENR_TIM17SMEN (1 << 18) /* Bit 18: TIM17 enable during Sleep mode */ +#define RCC_APB2SMENR_SAI1SMEN (1 << 21) /* Bit 21: SAI1 enable during Sleep mode */ +#define RCC_APB2SMENR_SAI2SMEN (1 << 22) /* Bit 22: SAI2 enable during Sleep mode */ +#define RCC_APB2SMENR_DFSDMSMEN (1 << 24) /* Bit 24: DFSDM enable during Sleep mode */ + +/* Peripheral Independent Clock Configuration register */ + +#define RCC_CCIPR_USART1SEL_SHIFT (0) +#define RCC_CCIPR_USART1SEL_MASK (3 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_PCLK (0 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_SYSCLK (1 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_HSI (2 << RCC_CCIPR_USART1SEL_SHIFT) +# define RCC_CCIPR_USART1SEL_LSE (3 << RCC_CCIPR_USART1SEL_SHIFT) + +#define RCC_CCIPR_USART2SEL_SHIFT (2) +#define RCC_CCIPR_USART2SEL_MASK (3 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_PCLK (0 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_SYSCLK (1 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_HSI (2 << RCC_CCIPR_USART2SEL_SHIFT) +# define RCC_CCIPR_USART2SEL_LSE (3 << RCC_CCIPR_USART2SEL_SHIFT) + +#define RCC_CCIPR_USART3SEL_SHIFT (4) +#define RCC_CCIPR_USART3SEL_MASK (3 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_PCLK (0 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_SYSCLK (1 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_HSI (2 << RCC_CCIPR_USART3SEL_SHIFT) +# define RCC_CCIPR_USART3SEL_LSE (3 << RCC_CCIPR_USART3SEL_SHIFT) + +#define RCC_CCIPR_UART4SEL_SHIFT (6) +#define RCC_CCIPR_UART4SEL_MASK (3 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_PCLK (0 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_SYSCLK (1 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_HSI (2 << RCC_CCIPR_UART4SEL_SHIFT) +# define RCC_CCIPR_UART4SEL_LSE (3 << RCC_CCIPR_UART4SEL_SHIFT) + +#define RCC_CCIPR_UART5SEL_SHIFT (8) +#define RCC_CCIPR_UART5SEL_MASK (3 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_PCLK (0 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_SYSCLK (1 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_HSI (2 << RCC_CCIPR_UART5SEL_SHIFT) +# define RCC_CCIPR_UART5SEL_LSE (3 << RCC_CCIPR_UART5SEL_SHIFT) + +#define RCC_CCIPR_LPUART1SEL_SHIFT (10) +#define RCC_CCIPR_LPUART1SEL_MASK (3 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_PCLK (0 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_SYSCLK (1 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_HSI (2 << RCC_CCIPR_LPUART1SEL_SHIFT) +# define RCC_CCIPR_LPUART1SEL_LSE (3 << RCC_CCIPR_LPUART1SEL_SHIFT) + +#define RCC_CCIPR_I2C1SEL_SHIFT (12) +#define RCC_CCIPR_I2C1SEL_MASK (3 << RCC_CCIPR_I2C1SEL_SHIFT) +# define RCC_CCIPR_I2C1SEL_PCLK (0 << RCC_CCIPR_I2C1SEL_SHIFT) +# define RCC_CCIPR_I2C1SEL_SYSCLK (1 << RCC_CCIPR_I2C1SEL_SHIFT) +# define RCC_CCIPR_I2C1SEL_HSI (2 << RCC_CCIPR_I2C1SEL_SHIFT) + +#define RCC_CCIPR_I2C2SEL_SHIFT (14) +#define RCC_CCIPR_I2C2SEL_MASK (3 << RCC_CCIPR_I2C2SEL_SHIFT) +# define RCC_CCIPR_I2C2SEL_PCLK (0 << RCC_CCIPR_I2C2SEL_SHIFT) +# define RCC_CCIPR_I2C2SEL_SYSCLK (1 << RCC_CCIPR_I2C2SEL_SHIFT) +# define RCC_CCIPR_I2C2SEL_HSI (2 << RCC_CCIPR_I2C2SEL_SHIFT) + +#define RCC_CCIPR_I2C3SEL_SHIFT (16) +#define RCC_CCIPR_I2C3SEL_MASK (3 << RCC_CCIPR_I2C3SEL_SHIFT) +# define RCC_CCIPR_I2C3SEL_PCLK (0 << RCC_CCIPR_I2C3SEL_SHIFT) +# define RCC_CCIPR_I2C3SEL_SYSCLK (1 << RCC_CCIPR_I2C3SEL_SHIFT) +# define RCC_CCIPR_I2C3SEL_HSI (2 << RCC_CCIPR_I2C3SEL_SHIFT) + +#define RCC_CCIPR_LPTIM1SEL_SHIFT (18) +#define RCC_CCIPR_LPTIM1SEL_MASK (3 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_PCLK (0 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_LSI (1 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_HSI (2 << RCC_CCIPR_LPTIM1SEL_SHIFT) +# define RCC_CCIPR_LPTIM1SEL_LSE (3 << RCC_CCIPR_LPTIM1SEL_SHIFT) + +#define RCC_CCIPR_LPTIM2SEL_SHIFT (20) +#define RCC_CCIPR_LPTIM2SEL_MASK (3 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_PCLK (0 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_LSI (1 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_HSI (2 << RCC_CCIPR_LPTIM2SEL_SHIFT) +# define RCC_CCIPR_LPTIM2SEL_LSE (3 << RCC_CCIPR_LPTIM2SEL_SHIFT) + +#define RCC_CCIPR_SAI1SEL_SHIFT (22) +#define RCC_CCIPR_SAI1SEL_MASK (3 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_SAI1SEL_PLLSAI1 (0 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_SAI1SEL_PLLSAI2 (1 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_SAI1SEL_PLLMAIN (2 << RCC_CCIPR_SAI1SEL_SHIFT) +# define RCC_CCIPR_SAI1SEL_EXTCLK (3 << RCC_CCIPR_SAI1SEL_SHIFT) + +#define RCC_CCIPR_SAI2SEL_SHIFT (24) +#define RCC_CCIPR_SAI2SEL_MASK (3 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_SAI2SEL_PLLSAI1 (0 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_SAI2SEL_PLLSAI2 (1 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_SAI2SEL_PLLMAIN (2 << RCC_CCIPR_SAI2SEL_SHIFT) +# define RCC_CCIPR_SAI2SEL_EXTCLK (3 << RCC_CCIPR_SAI2SEL_SHIFT) + +#define RCC_CCIPR_CLK48SEL_SHIFT (26) +#define RCC_CCIPR_CLK48SEL_MASK (3 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_NONE (0 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_PLLSAI1 (1 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_PLLMAIN (2 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_MSI (3 << RCC_CCIPR_CLK48SEL_SHIFT) + +#define RCC_CCIPR_ADCSEL_SHIFT (28) +#define RCC_CCIPR_ADCSEL_MASK (3 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_NONE (0 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_PLLSAI1 (1 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_PLLSAI2 (2 << RCC_CCIPR_ADCSEL_SHIFT) +# define RCC_CCIPR_ADCSEL_SYSCLK (3 << RCC_CCIPR_ADCSEL_SHIFT) + +#define RCC_CCIPR_SWPMI1SEL (1 << 30) +# define RCC_CCIPR_SWPMI1SEL_PCLK 0 +# define RCC_CCIPR_SWPMI1SEL_HSI RCC_CCIPR_SWPMI1SEL + +#define RCC_CCIPR_DFSDMSEL (1 << 31) +# define RCC_CCIPR_DFSDMSEL_PCLK 0 +# define RCC_CCIPR_DFSDMSEL_SYSCLK RCC_CCIPR_DFSDMSEL + +/* Backup domain control register */ + +#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */ + +#define RCC_BDCR_LSEDRV_SHIFT (3) /* Bits 3-4: LSE oscillator drive capability */ +#define RCC_BDCR_LSEDRV_MASK (3 << DCC_BDCR_LSEDRV_SHIFT) +# define RCC_BDCR_LSEDRV_LOWER (0 << DCC_BDCR_LSEDRV_SHIFT) /* 00: Lower driving capability */ +# define RCC_BDCR_LSEDRV_MIDLOW (1 << DCC_BDCR_LSEDRV_SHIFT) /* 01: Medium Low driving capability */ +# define RCC_BDCR_LSEDRV_MIDHI (2 << DCC_BDCR_LSEDRV_SHIFT) /* 10: Medium High driving capability*/ +# define RCC_BDCR_LSEDRV_HIGER (3 << DCC_BDCR_LSEDRV_SHIFT) /* 11: Higher driving capability */ + +#define RCC_BDCR_LSECSSON (1 << 5) /* Bit 5: CSS on LSE enable */ +#define RCC_BDCR_LSECSSD (1 << 6) /* Bit 6: CSS on LSE failure Detection */ + +#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */ +#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT) +# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */ +# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */ +# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 32 used as RTC clock */ + +#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */ +#define RCC_BDCR_LSCOEN (1 << 24) /* Bit 24: Low speed clock output enable */ +#define RCC_BDCR_LSCOSEL (1 << 25) /* Bit 25: Low speed clock output selection */ +# define RCC_BCDR_LSCOSEL_LSI 0 /* LSI selected */ +# define RCC_BDCR_LSCOSEL_LSE RCC_BDCR_LSCOSEL /* LSE selected */ + +/* Control/status register */ + +#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */ + +#define RCC_CSR_MSISRANGE_SHIFT 8 +# define RCC_CSR_MSISRANGE_MASK (0x0F << RCC_CSR_MSISRANGE_SHIFT) /* MSI range after Standby mode */ +# define RCC_CSR_MSISRANGE_1M (4 << RCC_CSR_MSISRANGE_SHIFT) /* 0100: around 1 MHz */ +# define RCC_CSR_MSISRANGE_2M (5 << RCC_CSR_MSISRANGE_SHIFT) /* 0101: around 2 MHz */ +# define RCC_CSR_MSISRANGE_4M (6 << RCC_CSR_MSISRANGE_SHIFT) /* 0110: around 4 MHz */ +# define RCC_CSR_MSISRANGE_8M (7 << RCC_CSR_MSISRANGE_SHIFT) /* 0111: around 8 MHz */ + +#define RCC_CSR_RMVF (1 << 23) /* Bit 23: Remove reset flag */ +#define RCC_CSR_FWRSTF (1 << 24) /* Bit 24: Firewall reset flag */ +#define RCC_CSR_OBLRSTF (1 << 25) /* Bit 25: Option byte loader reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_BORRSTF (1 << 27) /* Bit 27: BOR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */ + +#endif /* CONFIG_STM32L4_STM32F427 || CONFIG_STM32L4_STM32F429 */ +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32F42XXX_RCC_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h new file mode 100644 index 00000000000..7e1855061d5 --- /dev/null +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h @@ -0,0 +1,318 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_CHIP_STM32L4X6XX_UART_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_USART_CR1_OFFSET 0x0000 /* Control register 1 */ +#define STM32L4_USART_CR2_OFFSET 0x0004 /* Control register 2 */ +#define STM32L4_USART_CR3_OFFSET 0x0008 /* Control register 3 */ +#define STM32L4_USART_BRR_OFFSET 0x000c /* Baud Rate register */ +#define STM32L4_USART_GTPR_OFFSET 0x0010 /* Guard time and prescaler register */ +#define STM32L4_USART_RTOR_OFFSET 0x0014 /* Receiver timeout register */ +#define STM32L4_USART_RQR_OFFSET 0x0018 /* Request register */ +#define STM32L4_USART_ISR_OFFSET 0x001c /* Interrupot and status register */ +#define STM32L4_USART_ICR_OFFSET 0x0020 /* Interrupt flag clear register */ +#define STM32L4_USART_RDR_OFFSET 0x0024 /* Receive Data register */ +#define STM32L4_USART_TDR_OFFSET 0x0028 /* Transmit Data register */ + +/* Register Addresses ***************************************************************/ + +#if STM32L4_NUSART > 0 +# define STM32L4_USART1_CR1 (STM32L4_USART1_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_USART1_CR2 (STM32L4_USART1_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_USART1_CR3 (STM32L4_USART1_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_USART1_BRR (STM32L4_USART1_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_USART1_GTPR (STM32L4_USART1_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_USART1_RTOR (STM32L4_USART1_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_USART1_RQR (STM32L4_USART1_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_USART1_ISR (STM32L4_USART1_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_USART1_ICR (STM32L4_USART1_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_USART1_RDR (STM32L4_USART1_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_USART1_TDR (STM32L4_USART1_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +#if STM32L4_NUSART > 1 +# define STM32L4_USART2_CR1 (STM32L4_USART2_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_USART2_CR2 (STM32L4_USART2_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_USART2_CR3 (STM32L4_USART2_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_USART2_BRR (STM32L4_USART2_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_USART2_GTPR (STM32L4_USART2_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_USART2_RTOR (STM32L4_USART2_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_USART2_RQR (STM32L4_USART2_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_USART2_ISR (STM32L4_USART2_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_USART2_ICR (STM32L4_USART2_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_USART2_RDR (STM32L4_USART2_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_USART2_TDR (STM32L4_USART2_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +#if STM32L4_NUSART > 2 +# define STM32L4_USART3_CR1 (STM32L4_USART3_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_USART3_CR2 (STM32L4_USART3_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_USART3_CR3 (STM32L4_USART3_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_USART3_BRR (STM32L4_USART3_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_USART3_GTPR (STM32L4_USART3_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_USART3_RTOR (STM32L4_USART3_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_USART3_RQR (STM32L4_USART3_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_USART3_ISR (STM32L4_USART3_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_USART3_ICR (STM32L4_USART3_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_USART3_RDR (STM32L4_USART3_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_USART3_TDR (STM32L4_USART3_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +#if STM32L4_NUSART > 3 +# define STM32L4_UART4_CR1 (STM32L4_UART4_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_UART4_CR2 (STM32L4_UART4_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_UART4_CR3 (STM32L4_UART4_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_UART4_BRR (STM32L4_UART4_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_UART4_GTPR (STM32L4_UART4_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_UART4_RTOR (STM32L4_UART4_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_UART4_RQR (STM32L4_UART4_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_UART4_ISR (STM32L4_UART4_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_UART4_ICR (STM32L4_UART4_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_UART4_RDR (STM32L4_UART4_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_UART4_TDR (STM32L4_UART4_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +#if STM32L4_NUSART > 4 +# define STM32L4_UART5_CR1 (STM32L4_UART5_BASE+STM32L4_USART_CR1_OFFSET) +# define STM32L4_UART5_CR2 (STM32L4_UART5_BASE+STM32L4_USART_CR2_OFFSET) +# define STM32L4_UART5_CR3 (STM32L4_UART5_BASE+STM32L4_USART_CR3_OFFSET) +# define STM32L4_UART5_BRR (STM32L4_UART5_BASE+STM32L4_USART_BRR_OFFSET) +# define STM32L4_UART5_GTPR (STM32L4_UART5_BASE+STM32L4_USART_GTPR_OFFSET) +# define STM32L4_UART5_RTOR (STM32L4_UART5_BASE+STM32L4_USART_RTOR_OFFSET) +# define STM32L4_UART5_RQR (STM32L4_UART5_BASE+STM32L4_USART_RQR_OFFSET) +# define STM32L4_UART5_ISR (STM32L4_UART5_BASE+STM32L4_USART_ISR_OFFSET) +# define STM32L4_UART5_ICR (STM32L4_UART5_BASE+STM32L4_USART_ICR_OFFSET) +# define STM32L4_UART5_RDR (STM32L4_UART5_BASE+STM32L4_USART_RDR_OFFSET) +# define STM32L4_UART5_TDR (STM32L4_UART5_BASE+STM32L4_USART_TDR_OFFSET) +#endif + +/* Register Bitfield Definitions ****************************************************/ + +/* Control register 1 */ + +#define USART_CR1_UE (1 << 0) /* Bit 0: USART Enable */ +#define USART_CR1_UESM (1 << 1) /* Bit 1: USART Enable in Stop mode*/ +#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ +#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ +#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ +#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ +#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ +#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ +#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ +#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */ +#define USART_CR1_M0 (1 << 12) /* Bit 12: word length */ +#define USART_CR1_MME (1 << 13) /* Bit 13: Mute mode enable */ +#define USART_CR1_CMIE (1 << 14) /* Bit 14: Character match interrupt enable */ +#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ + +#define USART_CR1_DEDT_SHIFT (16) /* Bits 16..20 DE deactivation delay */ +#define USART_CR1_DEDT_MASK (0x1f << USART_CR1_DEDT_SHIFT) + +#define USART_CR1_DEAT_SHIFT (21) /* Bits 21..25 DE activation delay */ +#define USART_CR1_DEAT_MASK (0x1f << USART_CR1_DEAT_SHIFT) + +#define USART_CR1_RTOIE (1 << 26) /* Bit 26: Receiver timeout interrupt enable */ +#define USART_CR1_EOBIE (1 << 27) /* Bit 27: End of block interrupt enable */ +#define USART_CR1_M1 (1 << 28) /* Bit 12: word length */ + +#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE| \ + USART_CR1_TCIE|USART_CR1_TXEIE|USART_CR1_PEIE|USART_CR1_CMIE| \ + USART_CR1_RTOIE|USART_CR1_EOBIE) + +/* Control register 2 */ + +#define USART_CR2_ADDM7 (1 << 4) /* Bit 4: */ +#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ +#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ +#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ +#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ +#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ + +#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ +#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) +# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ +# define USART_CR2_STOP0p5 (1 << USART_CR2_STOP_SHIFT) /* 01: 0.5 Stop bit */ +# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ +# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ + +#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ +#define USART_CR2_SWAP (1 << 15) /* Bit 15: Swap TX/RX pins */ +#define USART_CR2_RXINV (1 << 16) /* Bit 16: RX pin active level inversion */ +#define USART_CR2_TXINV (1 << 17) /* Bit 17: TX pin active level inversion */ +#define USART_CR2_DATAINV (1 << 18) /* Bit 18: Binary data inversion */ +#define USART_CR2_MSBFIRST (1 << 19) /* Bit 19: Most significant bit first */ +#define USART_CR2_ABREN (1 << 20) /* Bit 20: Auto Baud rate enable */ + +#define USART_CR2_ABRMOD_SHIFT (21) /* Bits 21-22: Autobaud rate mode*/ +#define USART_CR2_ABRMOD_MASK (3 << USART_CR2_ABRMOD_SHIFT) +#define USART_CR2_ABRMOD_START (0 << USART_CR2_ABRMOD_SHIFT) /* 00: Start bit */ +#define USART_CR2_ABRMOD_EDGES (1 << USART_CR2_ABRMOD_SHIFT) /* 01: Falling-to-falling edge -> frame must start with 10xxxxxx */ +#define USART_CR2_ABRMOD_7F (2 << USART_CR2_ABRMOD_SHIFT) /* 10: 0x7F */ +#define USART_CR2_ABRMOD_55 (3 << USART_CR2_ABRMOD_SHIFT) /* 11: 0x55 */ + +#define USART_CR2_RTOEN (1 << 23) /* Bit 23: Receiver timeout enable */ + +#define USART_CR2_ADD_SHIFT (24) /* Bits 24-31: Address of the USART node */ +#define USART_CR2_ADD_MASK (0xff << USART_CR2_ADD_SHIFT) + +/* Control register 3 */ + +#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ +#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ +#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ +#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ +#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ +#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ +#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ +#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ +#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ +#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ +#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ +#define USART_CR3_ONEBIT (1 << 11) /* Bit 11: One sample bit method Enable */ +#define USART_CR3_OVRDIS (1 << 12) /* Bit 12: Overrun Disable */ +#define USART_CR3_DDRE (1 << 13) /* Bit 13: DMA disable on Reception error */ +#define USART_CR3_DEM (1 << 14) /* Bit 14: Driver Enable mode */ +#define USART_CR3_DEP (1 << 15) /* Bit 15: Driver Enable polarity selection */ +#define USART_CR3_SCARCNT2_SHIFT (17) /* Bits 17-19: Smart card auto retry count */ +#define USART_CR3_SCARCNT2_MASK (7 << USART_CR3_SCARCNT2_SHIFT) +#define USART_CR3_WUS_SHIFT (20) /* Bits 20-21: Wakeup from Stop mode interrupt flag selection */ +#define USART_CR3_WUS_MASK (3 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUS_ADDRESS (0 << USART_CR3_WUS_SHIFT) /* 00: WUF active on address match */ +#define USART_CR3_WUS_START (2 << USART_CR3_WUS_SHIFT) /* 10: WUF active on Start bit detection */ +#define USART_CR3_WUS_RXNE (3 << USART_CR3_WUS_SHIFT) /* 11: WUF active on RXNE */ +#define USART_CR3_WUFIE (1 << 22) /* Bit 22: Wakeup from Stop mode interrupt enable */ + +/* Baud Rate Register */ + +#define USART_BRR_FRAC_SHIFT (0) /* Bits 3-0: fraction of USARTDIV */ +#define USART_BRR_FRAC_MASK (0x0f << USART_BRR_FRAC_SHIFT) +#define USART_BRR_MANT_SHIFT (4) /* Bits 15-4: mantissa of USARTDIV */ +#define USART_BRR_MANT_MASK (0x0fff << USART_BRR_MANT_SHIFT) + +/* Guard time and prescaler register */ + +#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ +#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ +#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) + +/* Receiver timeout register */ + +/* Request Register */ + +#define USART_CR1_SBRKQ (1 << 1) /* Bit 0: Send Break */ + +/* Interrupt and Status register */ + +#define USART_ISR_PE (1 << 0) /* Bit 0: Parity Error */ +#define USART_ISR_FE (1 << 1) /* Bit 1: Framing Error */ +#define USART_ISR_NF (1 << 2) /* Bit 2: Noise Error Flag */ +#define USART_ISR_ORE (1 << 3) /* Bit 3: OverRun Error */ +#define USART_ISR_IDLE (1 << 4) /* Bit 4: IDLE line detected */ +#define USART_ISR_RXNE (1 << 5) /* Bit 5: Read Data Register Not Empty */ +#define USART_ISR_TC (1 << 6) /* Bit 6: Transmission Complete */ +#define USART_ISR_TXE (1 << 7) /* Bit 7: Transmit Data Register Empty */ +#define USART_ISR_LBDF (1 << 8) /* Bit 8: LIN Break Detection Flag */ +#define USART_ISR_CTS (1 << 9) /* Bit 9: CTS Flag */ +#define USART_ISR_RTOF (1 << 10) /* Bit 10: Receiver timeout Flag */ +#define USART_ISR_EOBF (1 << 11) /* Bit 11: End of block Flag */ +#define USART_ISR_ABRE (1 << 12) /* Bit 12: Auto baud rate Error */ +#define USART_ISR_ABRF (1 << 14) /* Bit 14: Auto baud rate Flag */ +#define USART_ISR_BUSY (1 << 15) /* Bit 15: Busy Flag */ +#define USART_ISR_CMF (1 << 16) /* Bit 16: Character match Flag */ +#define USART_ISR_SBKF (1 << 17) /* Bit 17: Send break Flag */ +#define USART_ISR_RWU (1 << 18) /* Bit 18: Receiver wakeup from Mute mode */ +#define USART_ISR_WUF (1 << 19) /* Bit 19: Wakeup from Stop mode Flag */ +#define USART_ISR_TEACK (1 << 20) /* Bit 20: Transmit enable acknowledge Flag */ +#define USART_ISR_REACK (1 << 21) /* Bit 21: Receive enable acknowledge Flag */ + +/* ICR */ + +#define USART_ICR_PECF (1 << 0) /* Bit 0: Parity error clear flag */ +#define USART_ICR_FECF (1 << 1) /* Bit 1: Framing error clear flag */ +#define USART_ICR_NCF (1 << 2) /* Bit 2: Noise detected clear flag */ +#define USART_ICR_ORECF (1 << 3) /* Bit 3: Overrun error clear flag */ +#define USART_ICR_IDLECF (1 << 4) /* Bit 4: Idle line detected clear flag */ +#define USART_ICR_TCCF (1 << 6) /* Bit 6: Transmission complete clear flag */ +#define USART_ICR_LBDCF (1 << 8) /* Bit 8: LIN break detection clear flag */ +#define USART_ICR_CTSCF (1 << 9) /* Bit 9: CTS clear flag */ +#define USART_ICR_RTOCF (1 << 11) /* Bit 11: Receiver timeout clear flag */ +#define USART_ICR_EOBCF (1 << 12) /* Bit 12: End of block clear flag */ +#define USART_ICR_CMCF (1 << 17) /* Bit 17: Character match clear flag */ +#define USART_ICR_WUCF (1 << 20) /* Bit 20: Wakeup from Stop mode clear flag */ + +/* Receive Data register */ + +#define USART_RDR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_RDR_MASK (0xff << USART_RDR_SHIFT) + +/* Transmit Data register */ + +#define USART_TDR_SHIFT (0) /* Bits 8:0: Data value */ +#define USART_TDR_MASK (0xff << USART_TDR_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_STC_STM32L4_CHIP_STM32L4X6XX_UART_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4.h b/arch/arm/src/stm32l4/stm32l4.h new file mode 100644 index 00000000000..f8ad428d704 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4.h @@ -0,0 +1,97 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4.h + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Authors: Uros Platise + * Gregory Nutt + * + * 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_STM32L4_STM32L4_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include +#include + +#include "up_internal.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Additional Configuration *********************************************************/ +/* Custom debug settings used in the STM32L4 port. These are managed by + * STM32L4-specific logic and not the common logic in include/debug.h. + * NOTE: Some of these also depend on CONFIG_DEBUG_VERBOSE + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_DMA +# undef CONFIG_DEBUG_RTC +# undef CONFIG_DEBUG_I2C +# undef CONFIG_DEBUG_CAN +# undef CONFIG_DEBUG_PWM +# undef CONFIG_DEBUG_SENSORS +#endif + +/* Peripherals **********************************************************************/ + +#include "chip.h" +#include "stm32l4_adc.h" +//#include "stm32_bkp.h" +#include "stm32l4_can.h" +#include "stm32l4_dbgmcu.h" +#include "stm32l4_dma.h" +#include "stm32l4_exti.h" +#include "stm32l4_flash.h" +#include "stm32l4_fsmc.h" +#include "stm32l4_gpio.h" +#include "stm32l4_i2c.h" +#include "stm32l4_lcd.h" +#include "stm32l4_pwr.h" +#include "stm32l4_rcc.h" +#include "stm32l4_rtc.h" +#include "stm32l4_sdio.h" +#include "stm32l4_spi.h" +#include "stm32l4_tim.h" +#include "stm32l4_uart.h" +#include "stm32l4_usbdev.h" +#include "stm32l4_wdg.h" +#include "stm32l4_lowputc.h" + +#endif /* __ARCH_ARM_SRC_STM32_STM32_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_adc.h b/arch/arm/src/stm32l4/stm32l4_adc.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_allocateheap.c b/arch/arm/src/stm32l4/stm32l4_allocateheap.c new file mode 100644 index 00000000000..e1c2e1acafc --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_allocateheap.c @@ -0,0 +1,375 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/up_allocateheap.c + * + * Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include + +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "mpu.h" +#include "up_arch.h" +#include "up_internal.h" +#include "stm32l4_mpuinit.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Internal SRAM is available in all members of the STM32L4 family. The + * following definitions must be provided to specify the size and + * location of internal(system) SRAM: + * + * SRAM1_END 0x20018000 + * SRAM2_START 0x10000000 + * SRAM2_END 0x10008000 + * + * In addition to internal SRAM, SRAM may also be available through the FSMC. + * In order to use FSMC SRAM, the following additional things need to be + * present in the NuttX configuration file: + * + * CONFIG_STM32L4_FSMC=y : Enables the FSMC + * CONFIG_STM32L4_FSMC_SRAM=y : Indicates that SRAM is available via the + * FSMC (as opposed to an LCD or FLASH). + * CONFIG_HEAP2_BASE : The base address of the SRAM in the FSMC + * address space + * CONFIG_HEAP2_SIZE : The size of the SRAM in the FSMC + * address space + * CONFIG_MM_REGIONS : Must be set to a large enough value to + * include the FSMC SRAM (as determined by + * the rules provided below) + */ + +#ifndef CONFIG_STM32L4_FSMC +# undef CONFIG_STM32L4_FSMC_SRAM +#endif + +/* MSTM32L4x6xx have 128Kib in two banks, both accessible to DMA: + * + * 1) 96KiB of System SRAM beginning at address 0x2000:0000 - 0x2001:8000 + * 2) 32KiB of System SRAM beginning at address 0x1000:0000 - 0x1000:8000 + * + * In addition, external FSMC SRAM may be available. + */ + +/* Set the end of system SRAM */ + +#define SRAM1_END 0x20018000 + +/* Set the range of SRAM2 as well, requires a second memory region */ + +#define SRAM2_START 0x10000000 +#define SRAM2_END 0x10008000 + +/* Allocations according to the number of memory regions: + * + * 1 region available: + * - map it to SRAM1 + * - warn that SRAM2 is not available for heap + * - if FMC is enabled, warn that it is not available for heap + * + * 2 regions available: map them to SRAM1 and SRAM2 + * - map region 1 to SRAM1 + * - map region 2 to SRAM2 + * - if FMC is enabled, warn that it is not available for heap + * + * 3 or more regions + * + * - map them to SRAM1, SRAM2, FMC + */ + +#if CONFIG_MM_REGIONS < 1 +# warning heap is not usable + +#elif CONFIG_MM_REGIONS < 2 + +# warning SRAM2 (32k) is NOT available for heap, only SRAM1 (96k) : not enough MM regions +# undef SRAM2_START +# undef SRAM2_END + +# if defined(CONFIG_STM32L4_FSMC_SRAM) +# warning FMC SRAM is NOT available for heap : not enough MM regions (1) +# undef CONFIG_STM32L4_FSMC_SRAM +# endif + +#elif CONFIG_MM_REGIONS < 3 + +# if defined(CONFIG_STM32L4_FSMC_SRAM) +# warning FMC SRAM is NOT available for heap : not enough MM regions (2) +# undef CONFIG_STM32L4_FSMC_SRAM +# endif + +#elif CONFIG_MM_REGIONS > 3 + +/*Everything can be mapped but some entries wont be used -> warn and correct*/ +# warning "CONFIG_MM_REGIONS > 3 but I don't know what some of the region(s) are" +# undef CONFIG_MM_REGIONS +# define CONFIG_MM_REGIONS 3 + +#else +/*Everything can be mapped*/ +#endif + + +/* If FSMC SRAM is going to be used as heap, then verify that the starting + * address and size of the external SRAM region has been provided in the + * configuration (as CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE). + */ + +#ifdef CONFIG_STM32L4_FSMC_SRAM +# if !defined(CONFIG_HEAP2_BASE) || !defined(CONFIG_HEAP2_SIZE) +# error "CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE must be provided" +# undef CONFIG_STM32L4_FSMC_SRAM +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_heap_color + * + * Description: + * Set heap memory to a known, non-zero state to checking heap usage. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_HEAP +static inline void up_heap_color(FAR void *start, size_t size) +{ + memset(start, HEAP_COLOR, size); +} +#else +# define up_heap_color(start,size) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the user-space heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)ubase; + *heap_size = usize; + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)ubase, usize); + + /* Allow user-mode access to the user heap memory */ + + stm32l4_mpu_uheap((uintptr_t)ubase, usize); +#else + + /* Return the heap settings */ + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = SRAM1_END - g_idle_topstack; + + /* Colorize the heap for debug */ + + up_heap_color(*heap_start, *heap_size); +#endif +} + +/**************************************************************************** + * Name: up_allocate_kheap + * + * Description: + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates + * (and protects) the kernel-space heap. + * + ****************************************************************************/ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) +void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) +{ + /* Get the unaligned size and position of the user-space heap. + * This heap begins after the user-space .bss section at an offset + * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). + */ + + uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; + size_t usize = SRAM1_END - ubase; + int log2; + + DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); + + /* Adjust that size to account for MPU alignment requirements. + * NOTE that there is an implicit assumption that the SRAM1_END + * is aligned to the MPU requirement. + */ + + log2 = (int)mpu_log2regionfloor(usize); + DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); + + usize = (1 << log2); + ubase = SRAM1_END - usize; + + /* Return the kernel heap settings (i.e., the part of the heap region + * that was not dedicated to the user heap). + */ + + *heap_start = (FAR void *)USERSPACE->us_bssend; + *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend; +} +#endif + +/**************************************************************************** + * Name: up_addregion + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ + +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the SRAM2 heap */ + + stm32l4_mpu_uheap((uintptr_t)SRAM2_START, SRAM2_END-SRAM2_START); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)SRAM2_START, SRAM2_END-SRAM2_START); + + /* Add the SRAM2 user heap region. */ + + kumm_addregion((FAR void *)SRAM2_START, SRAM2_END-SRAM2_START); + +#ifdef CONFIG_STM32L4_FSMC_SRAM +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + + /* Allow user-mode access to the FSMC SRAM user heap memory */ + + stm32l4_mpu_uheap((uintptr_t)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + +#endif + + /* Colorize the heap for debug */ + + up_heap_color((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); + + /* Add the external FSMC SRAM user heap region. */ + + kumm_addregion((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE); +#endif +} +#endif diff --git a/arch/arm/src/stm32l4/stm32l4_can.h b/arch/arm/src/stm32l4/stm32l4_can.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_dbgmcu.h b/arch/arm/src/stm32l4/stm32l4_dbgmcu.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_dma.c b/arch/arm/src/stm32l4/stm32l4_dma.c new file mode 100644 index 00000000000..c1b25e64dee --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_dma.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_dma.c + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* This file is only a thin shell that includes the correct DMA implementation + * for the selected STM32 family. The correct file cannot be selected by + * the make system because it needs the intelligence that only exists in + * chip.h that can associate an STM32 part number with an STM32 family. + */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +#include "stm32l4x6xx_dma.c" +#else +# error "Unsupported STM32L4 chip" +#endif + diff --git a/arch/arm/src/stm32l4/stm32l4_dma.h b/arch/arm/src/stm32l4/stm32l4_dma.h new file mode 100644 index 00000000000..9fd36a63373 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_dma.h @@ -0,0 +1,301 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_dma.h + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_STM32L4_DMA_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_DMA_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/* Include the correct DMA register definitions for this STM32 family */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_dma.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/* These definitions provide the bit encoding of the 'status' parameter passed to the + * DMA callback function (see dma_callback_t). + */ + +# define DMA_STATUS_FEIF 0 /* (Not available in F1) */ +# define DMA_STATUS_DMEIF 0 /* (Not available in F1) */ +# define DMA_STATUS_TEIF DMA_CHAN_TEIF_BIT /* Channel Transfer Error */ +# define DMA_STATUS_HTIF DMA_CHAN_HTIF_BIT /* Channel Half Transfer */ +# define DMA_STATUS_TCIF DMA_CHAN_TCIF_BIT /* Channel Transfer Complete */ + +#define DMA_STATUS_ERROR (DMA_STATUS_FEIF|DMA_STATUS_DMEIF|DMA_STATUS_TEIF) +#define DMA_STATUS_SUCCESS (DMA_STATUS_TCIF|DMA_STATUS_HTIF) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* DMA_HANDLE provides an opaque are reference that can be used to represent a DMA + * channel (F1) or a DMA stream (F4). + */ + +typedef FAR void *DMA_HANDLE; + +/* Description: + * This is the type of the callback that is used to inform the user of the the + * completion of the DMA. + * + * Input Parameters: + * handle - Refers tot he 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 stm32l4_dmastart() was + * called. + */ + +typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg); + +#ifdef CONFIG_DEBUG_DMA +struct stm32l4_dmaregs_s +{ + uint32_t isr; + uint32_t ccr; + uint32_t cndtr; + uint32_t cpar; + uint32_t cmar; +}; +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'chan' argument. + * DMA channels are shared on the STM32: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32l4_dma.h. + * + * If the DMA channel is not available, then stm32l4_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32l4_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32l4_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * chan - Identifies the stream/channel resource + * For the STM32 F1, this is simply the channel number as provided by + * the DMACHAN_* definitions in chip/stm32f10xxx_dma.h. + * For the STM32 F4, this is a bit encoded value as provided by the + * the DMAMAP_* definitions in chip/stm32f40xxx_dma.h + * + * Returned Value: + * Provided that 'chan' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'chan' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * 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 stm32l4_dmachannel(unsigned int chan); + +/**************************************************************************** + * Name: stm32l4_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32l4_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32l4_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 stm32l4_dmafree(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32l4_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32l4_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t ccr); + +/**************************************************************************** + * Name: stm32l4_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32l4_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, + bool half); + +/**************************************************************************** + * Name: stm32l4_dmastop + * + * Description: + * Cancel the DMA. After stm32l4_dmastop() is called, the DMA channel is + * reset and stm32l4_dmasetup() must be called before stm32l4_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +void stm32l4_dmastop(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32l4_dmaresidual + * + * Description: + * Returns the number of bytes remaining to be transferred + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +size_t stm32l4_dmaresidual(DMA_HANDLE handle); + +/**************************************************************************** + * Name: stm32l4_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address with the given configuration. 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. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32L4_DMACAPABLE +bool stm32l4_dmacapable(uintptr_t maddr, uint32_t count, uint32_t ccr); +#else +# define stm32l4_dmacapable(maddr, count, ccr) (true) +#endif + +/**************************************************************************** + * Name: stm32l4_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32l4_dmasample(DMA_HANDLE handle, struct stm32l4_dmaregs_s *regs); +#else +# define stm32l4_dmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: stm32l4_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32l4_dmadump(DMA_HANDLE handle, const struct stm32l4_dmaregs_s *regs, + const char *msg); +#else +# define stm32l4_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_DMA_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_dtcm.c b/arch/arm/src/stm32l4/stm32l4_dtcm.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_dumpgpio.c b/arch/arm/src/stm32l4/stm32l4_dumpgpio.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_exti.h b/arch/arm/src/stm32l4/stm32l4_exti.h new file mode 100644 index 00000000000..87dbd78c255 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti.h @@ -0,0 +1,119 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_exti.h + * + * Copyright (C) 2009, 2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_STM32L4_EXTI_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_EXTI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "chip/stm32l4_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: stm32l4_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: gpio pin configuration + * - rising/falling edge: enables + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +xcpt_t stm32l4_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func); + +/************************************************************************************ + * Name: stm32l4_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edges + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +xcpt_t stm32l4_exti_alarm(bool risingedge, bool fallingedge, bool event, xcpt_t func); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_EXTI_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_exti_alarm.c b/arch/arm/src/stm32l4/stm32l4_exti_alarm.c new file mode 100644 index 00000000000..4ffc3763dbe --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti_alarm.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_exti_alarm.c + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Diego Sanchez + * + * 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 +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32l4_gpio.h" +#include "stm32l4_exti.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to the ALARM EXTI */ + +static xcpt_t stm32l4_exti_callback; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_alarm_isr + * + * Description: + * EXTI ALARM interrupt service routine/dispatcher + * + ****************************************************************************/ + +static int stm32l4_exti_alarm_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending EXTI interrupt */ + + putreg32(EXTI1_RTC_ALARM, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callback) + { + ret = stm32l4_exti_callback(irq, context); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_alarm + * + * Description: + * Sets/clears EXTI alarm interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edget + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32l4_exti_alarm(bool risingedge, bool fallingedge, bool event, + xcpt_t func) +{ + xcpt_t oldhandler; + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32l4_exti_callback; + stm32l4_exti_callback = func; + + /* Install external interrupt handlers (if not already attached) */ + + if (func) + { + irq_attach(STM32L4_IRQ_RTCALRM, stm32l4_exti_alarm_isr); + up_enable_irq(STM32L4_IRQ_RTCALRM); + } + else + { + up_disable_irq(STM32L4_IRQ_RTCALRM); + } + + /* Configure rising/falling edges */ + + modifyreg32(STM32L4_EXTI1_RTSR, + risingedge ? 0 : EXTI1_RTC_ALARM, + risingedge ? EXTI1_RTC_ALARM : 0); + modifyreg32(STM32L4_EXTI1_FTSR, + fallingedge ? 0 : EXTI1_RTC_ALARM, + fallingedge ? EXTI1_RTC_ALARM : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32L4_EXTI1_EMR, + event ? 0 : EXTI1_RTC_ALARM, + event ? EXTI1_RTC_ALARM : 0); + modifyreg32(STM32L4_EXTI1_IMR, + func ? 0 : EXTI1_RTC_ALARM, + func ? EXTI1_RTC_ALARM : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32l4/stm32l4_exti_gpio.c b/arch/arm/src/stm32l4/stm32l4_exti_gpio.c new file mode 100644 index 00000000000..ede05e83221 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti_gpio.c @@ -0,0 +1,358 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_exti_gpio.c + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Gregory Nutt + * Uros Platise + * + * 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 +#include +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32l4_gpio.h" +#include "stm32l4_exti.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to each EXTI */ + +static xcpt_t stm32l4_exti_callbacks[16]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Interrupt Service Routines - Dispatchers + ****************************************************************************/ + +static int stm32l4_exti0_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0001, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[0]) + { + ret = stm32l4_exti_callbacks[0](irq, context); + } + + return ret; +} + +static int stm32l4_exti1_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0002, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[1]) + { + ret = stm32l4_exti_callbacks[1](irq, context); + } + + return ret; +} + +static int stm32l4_exti2_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0004, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[2]) + { + ret = stm32l4_exti_callbacks[2](irq, context); + } + + return ret; +} + +static int stm32l4_exti3_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0008, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[3]) + { + ret = stm32l4_exti_callbacks[3](irq, context); + } + + return ret; +} + +static int stm32l4_exti4_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending interrupt */ + + putreg32(0x0010, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[4]) + { + ret = stm32l4_exti_callbacks[4](irq, context); + } + + return ret; +} + +static int stm32l4_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(STM32L4_EXTI1_PR); + + /* 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, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_callbacks[pin]) + { + int tmp = stm32l4_exti_callbacks[pin](irq, context); + if (tmp != OK) + { + ret = tmp; + } + } + } + } + + return ret; +} + +static int stm32l4_exti95_isr(int irq, void *context) +{ + return stm32l4_exti_multiisr(irq, context, 5, 9); +} + +static int stm32l4_exti1510_isr(int irq, void *context) +{ + return stm32l4_exti_multiisr(irq, context, 10, 15); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * 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 + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32l4_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func) +{ + uint32_t pin = pinset & GPIO_PIN_MASK; + uint32_t exti = STM32L4_EXTI1_BIT(pin); + int irq; + xcpt_t handler; + xcpt_t oldhandler = NULL; + int nshared; + xcpt_t *shared_cbs; + int i; + + /* Select the interrupt handler for this EXTI pin */ + + if (pin < 5) + { + irq = pin + STM32L4_IRQ_EXTI0; + nshared = 1; + shared_cbs = &stm32l4_exti_callbacks[pin]; + switch (pin) + { + case 0: + handler = stm32l4_exti0_isr; + break; + + case 1: + handler = stm32l4_exti1_isr; + break; + + case 2: + handler = stm32l4_exti2_isr; + break; + + case 3: + handler = stm32l4_exti3_isr; + break; + + default: + handler = stm32l4_exti4_isr; + break; + } + } + else if (pin < 10) + { + irq = STM32L4_IRQ_EXTI95; + handler = stm32l4_exti95_isr; + shared_cbs = &stm32l4_exti_callbacks[5]; + nshared = 5; + } + else + { + irq = STM32L4_IRQ_EXTI1510; + handler = stm32l4_exti1510_isr; + shared_cbs = &stm32l4_exti_callbacks[10]; + nshared = 6; + } + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32l4_exti_callbacks[pin]; + stm32l4_exti_callbacks[pin] = func; + + /* Install external interrupt handlers */ + + if (func) + { + irq_attach(irq, handler); + up_enable_irq(irq); + } + else + { + /* Only disable IRQ if shared handler does not have any active + * callbacks. + */ + + for (i = 0; i < nshared; i++) + { + if (shared_cbs[i] != NULL) + { + break; + } + } + + if (i == nshared) + { + up_disable_irq(irq); + } + } + + /* Configure GPIO, enable EXTI line enabled if event or interrupt is + * enabled. + */ + + if (event || func) + { + pinset |= GPIO_EXTI; + } + + stm32l4_configgpio(pinset); + + /* Configure rising/falling edges */ + + modifyreg32(STM32L4_EXTI1_RTSR, + risingedge ? 0 : exti, + risingedge ? exti : 0); + modifyreg32(STM32L4_EXTI1_FTSR, + fallingedge ? 0 : exti, + fallingedge ? exti : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32L4_EXTI1_EMR, + event ? 0 : exti, + event ? exti : 0); + modifyreg32(STM32L4_EXTI1_IMR, + func ? 0 : exti, + func ? exti : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32l4/stm32l4_exti_pwr.c b/arch/arm/src/stm32l4/stm32l4_exti_pwr.c new file mode 100644 index 00000000000..f037936c649 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti_pwr.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_exti_pwr.c + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Gregory Nutt + * Dmitry Nikolaev + * + * 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 +#include +#include + +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32l4_gpio.h" +#include "stm32l4_exti.h" +#include "stm32l4_exti_pwr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Interrupt handlers attached to the PVD EXTI */ + +static xcpt_t stm32l4_exti_pvd_callback; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_pvd_isr + * + * Description: + * EXTI PVD interrupt service routine/dispatcher + * + ****************************************************************************/ + +static int stm32l4_exti_pvd_isr(int irq, void *context) +{ + int ret = OK; + + /* Clear the pending EXTI interrupt */ + + putreg32(EXTI1_PVD_LINE, STM32L4_EXTI1_PR); + + /* And dispatch the interrupt to the handler */ + + if (stm32l4_exti_pvd_callback) + { + ret = stm32l4_exti_pvd_callback(irq, context); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_pvd + * + * Description: + * Sets/clears EXTI PVD interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edge + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32l4_exti_pvd(bool risingedge, bool fallingedge, bool event, + xcpt_t func) +{ + xcpt_t oldhandler; + + /* Get the previous GPIO IRQ handler; Save the new IRQ handler. */ + + oldhandler = stm32l4_exti_pvd_callback; + stm32l4_exti_pvd_callback = func; + + /* Install external interrupt handlers (if not already attached) */ + + if (func) + { + irq_attach(STM32L4_IRQ_PVD, stm32l4_exti_pvd_isr); + up_enable_irq(STM32L4_IRQ_PVD); + } + else + { + up_disable_irq(STM32L4_IRQ_PVD); + } + + /* Configure rising/falling edges */ + + modifyreg32(STM32L4_EXTI1_RTSR, + risingedge ? 0 : EXTI1_PVD_LINE, + risingedge ? EXTI1_PVD_LINE : 0); + modifyreg32(STM32L4_EXTI1_FTSR, + fallingedge ? 0 : EXTI1_PVD_LINE, + fallingedge ? EXTI1_PVD_LINE : 0); + + /* Enable Events and Interrupts */ + + modifyreg32(STM32L4_EXTI1_EMR, + event ? 0 : EXTI1_PVD_LINE, + event ? EXTI1_PVD_LINE : 0); + modifyreg32(STM32L4_EXTI1_IMR, + func ? 0 : EXTI1_PVD_LINE, + func ? EXTI1_PVD_LINE : 0); + + /* Return the old IRQ handler */ + + return oldhandler; +} diff --git a/arch/arm/src/stm32l4/stm32l4_exti_pwr.h b/arch/arm/src/stm32l4/stm32l4_exti_pwr.h new file mode 100644 index 00000000000..5789e370764 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_exti_pwr.h @@ -0,0 +1,71 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_exti_pwr.h + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Dmitry Nikolaev + * + * 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 STM32L4_EXTI_PWR_H_ +#define STM32L4_EXTI_PWR_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_exti_pvd + * + * Description: + * Sets/clears EXTI PVD interrupt. + * + * Parameters: + * - rising/falling edge: enables interrupt on rising/falling edge + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t stm32l4_exti_pvd(bool risingedge, bool fallingedge, bool event, + xcpt_t func); + +#endif /* STM32L4_EXTI_PWR_H_ */ diff --git a/arch/arm/src/stm32l4/stm32l4_firewall.c b/arch/arm/src/stm32l4/stm32l4_firewall.c new file mode 100644 index 00000000000..46cc3ff62de --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_firewall.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_firewall.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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 "stm32l4_firewall.h" + +int stm32l4_firewallsetup(FAR struct stm32l4_firewall_t *setup) + { + uint32_t reg; + + /* code and nvdata must be aligned to 256 bytes + * data must be aligned to 64 bytes + */ + if( (setup->codestart & 0xFF) || (setup->nvdatastart & 0xFF) || (setup->datastart & 0x3F) ) + { + return -1; + } + + /* code and nvdata length must be a multiple of 256 bytes + * data length must be a multiple of 64 bytes + */ + if( (setup->codelen & 0xFF) || (setup->nvdatalen & 0xFF) || (setup->datalen & 0x3F) ) + { + return -1; + } + + /* + * code and nvdata must be in flash + * data must be in SRAM1 + */ + if( (setup->codestart & STM32L4_REGION_MASK) != STM32L4_FLASH_BASE) + { + return -1; + } + + if( (setup->nvdatastart & STM32L4_REGION_MASK) != STM32L4_FLASH_BASE) + { + return -1; + } + + /* Define address and length registers */ + modifyreg32(STM32L4_FIREWALL_CSSA , FIREWALL_CSSADD_MASK , setup->codestart ); + modifyreg32(STM32L4_FIREWALL_CSL , FIREWALL_CSSLENG_MASK , setup->codelen ); + modifyreg32(STM32L4_FIREWALL_NVDSSA, FIREWALL_NVDSADD_MASK , setup->nvdatastart); + modifyreg32(STM32L4_FIREWALL_NVDSL , FIREWALL_NVDSLENG_MASK, setup->nvdatalen ); + modifyreg32(STM32L4_FIREWALL_VDSSA , FIREWALL_VDSADD_MASK , setup->datastart ); + modifyreg32(STM32L4_FIREWALL_VDSL , FIREWALL_VDSLENG_MASK , setup->datalen ); + + /* Define access options */ + reg = getreg32(STM32L4_FIREWALL_CR); + if(setup->datashared) + { + reg |= FIREWALL_CR_VDS; + } + if(setup->dataexec) + { + reg |= FIREWALL_CR_VDE; + } + + putreg32(reg, STM32L4_FIREWALL_CR); + + /* Enable firewall */ + reg = getreg32(STM32L4_SYSCFG_CFGR1); + reg &= ~SYSCFG_CFGR1_FWDIS; + putreg32(reg, STM32L4_SYSCFG_CFGR1); + + /* Now protected code can only be accessed by jumping to the FW gate */ + return 0; + } + diff --git a/arch/arm/src/stm32l4/stm32l4_firewall.h b/arch/arm/src/stm32l4/stm32l4_firewall.h new file mode 100644 index 00000000000..989e7e3c302 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_firewall.h @@ -0,0 +1,111 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_firewall.h + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Sebastien Lorquet + * + * 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_STM32L4_STM32L4_FIREWALL_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_FIREWALL_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include "chip.h" + +/* Include the correct firewall register definitions for this STM32L4 family */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_firewall.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +struct stm32l4_firewall_t + { + uintptr_t *codestart; + size_t codelen; + uintptr_t *nvdatastart; + size_t nvdatalen; + uintptr_t *datastart; + size_t datalen; + uint8_t datashared:1; + uint8_t dataexec :1; + }; + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_firewallsetup + * + * Description: + * Configure the STM32L4 firewall. After this, protected code will only + * be accessible via the "entry gate". + * Once enabled, the firewall cannot be enabled until the next reset. + * Returns 0 when OK, -1 when addresses and length are not properly aligned. + * + ****************************************************************************/ + +int stm32l4_firewallsetup(FAR struct stm32l4_firewall_t *setup); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_FIREWALL_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_flash.h b/arch/arm/src/stm32l4/stm32l4_flash.h new file mode 100644 index 00000000000..ecb6fccb0a9 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_flash.h @@ -0,0 +1,218 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/chip/stm32l4_flash.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * 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_STM32L4_CHIP_STM32L4_FLASH_H +#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_FLASH_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define _K(x) ((x)*1024) + +#if !defined(CONFIG_STM32L4_FLASH_CONFIG_DEFAULT) && \ + !defined(CONFIG_STM32L4_FLASH_CONFIG_C) && \ + !defined(CONFIG_STM32L4_FLASH_CONFIG_E) && \ + !defined(CONFIG_STM32L4_FLASH_CONFIG_G) +# define CONFIG_STM32L4_FLASH_CONFIG_DEFAULT +#endif + +#if defined(CONFIG_STM32L4_FLASH_CONFIG_DEFAULT) +# define STM32L4_FLASH_NPAGES 512 +# define STM32L4_FLASH_PAGESIZE 2048 +#endif /* CONFIG_STM32L4_FLASH_CONFIG_DEFAULT */ + +/* Override of the Flash Has been Chosen */ + +#if !defined(CONFIG_STM32L4_FLASH_CONFIG_DEFAULT) + +/* Define the Valid Configuration the F1 and F3 */ + +# if defined(CONFIG_STM32L4_FLASH_CONFIG_C) /* 256 kB */ +# define STM32L4_FLASH_NPAGES 128 +# define STM32L4_FLASH_PAGESIZE 2048 +# elif defined(CONFIG_STM32L4_FLASH_CONFIG_E) /* 512 kB */ +# define STM32L4_FLASH_NPAGES 256 +# define STM32L4_FLASH_PAGESIZE 2048 +# elif defined(CONFIG_STM32L4_FLASH_CONFIG_G) /* 1 MB */ +# define STM32L4_FLASH_NPAGES 512 +# define STM32L4_FLASH_PAGESIZE 2048 +# else +# endif +#endif + +#ifdef STM32L4_FLASH_PAGESIZE +# define STM32L4_FLASH_SIZE (STM32L4_FLASH_NPAGES * STM32L4_FLASH_PAGESIZE) +#endif /* def STM32L4_FLASH_PAGESIZE */ + +/* Register Offsets *****************************************************************/ + +#define STM32L4_FLASH_ACR_OFFSET 0x0000 +#define STM32L4_FLASH_PDKEYR_OFFSET 0x0004 +#define STM32L4_FLASH_KEYR_OFFSET 0x0008 +#define STM32L4_FLASH_OPTKEYR_OFFSET 0x000c +#define STM32L4_FLASH_SR_OFFSET 0x0010 +#define STM32L4_FLASH_CR_OFFSET 0x0014 +#define STM32L4_FLASH_ECCR_OFFSET 0x0018 +#define STM32L4_FLASH_OPTR_OFFSET 0x0020 +#define STM32L4_FLASH_PCROP1SR_OFFSET 0x0024 +#define STM32L4_FLASH_PCROP1ER_OFFSET 0x0028 +#define STM32L4_FLASH_WRP1AR_OFFSET 0x002c +#define STM32L4_FLASH_WRP1BR_OFFSET 0x0030 +#define STM32L4_FLASH_PCROP2SR_OFFSET 0x0044 +#define STM32L4_FLASH_PCROP2ER_OFFSET 0x0048 +#define STM32L4_FLASH_WRP2AR_OFFSET 0x004c +#define STM32L4_FLASH_WRP2BR_OFFSET 0x0050 + +/* Register Addresses ***************************************************************/ + +#define STM32L4_FLASH_ACR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_ACR_OFFSET) +#define STM32L4_FLASH_PDKEYR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PDKEYR_OFFSET) +#define STM32L4_FLASH_KEYR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_KEYR_OFFSET) +#define STM32L4_FLASH_OPTKEYR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_OPTKEYR_OFFSET) +#define STM32L4_FLASH_SR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_SR_OFFSET) +#define STM32L4_FLASH_CR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_CR_OFFSET) +#define STM32L4_FLASH_ECCR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_ECCR_OFFSET) +#define STM32L4_FLASH_OPTR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_OPTR_OFFSET) +#define STM32L4_FLASH_PCROP1SR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PCROP1SR_OFFSET) +#define STM32L4_FLASH_PCROP1ER (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PCROP1ER_OFFSET) +#define STM32L4_FLASH_WRP1AR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_WRP1AR_OFFSET) +#define STM32L4_FLASH_WRP1BR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_WRP1BR_OFFSET) +#define STM32L4_FLASH_PCROP2SR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PCROP2SR_OFFSET) +#define STM32L4_FLASH_PCROP2ER (STM32L4_FLASHIF_BASE+STM32L4_FLASH_PCROP2ER_OFFSET) +#define STM32L4_FLASH_WRP2AR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_WRP2AR_OFFSET) +#define STM32L4_FLASH_WRP2BR (STM32L4_FLASHIF_BASE+STM32L4_FLASH_WRP2BR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ +/* Flash Access Control Register (ACR) */ + +#define FLASH_ACR_LATENCY_SHIFT (0) +#define FLASH_ACR_LATENCY_MASK (7 << FLASH_ACR_LATENCY_SHIFT) +# define FLASH_ACR_LATENCY(n) ((n) << FLASH_ACR_LATENCY_SHIFT) /* n wait states , for Vcore range 1 2 */ +# define FLASH_ACR_LATENCY_0 (0 << FLASH_ACR_LATENCY_SHIFT) /* 000: Zero wait states <=16 <=6 */ +# define FLASH_ACR_LATENCY_1 (1 << FLASH_ACR_LATENCY_SHIFT) /* 001: One wait state <=32 <=12 */ +# define FLASH_ACR_LATENCY_2 (2 << FLASH_ACR_LATENCY_SHIFT) /* 010: Two wait states <=48 <=18 */ +# define FLASH_ACR_LATENCY_3 (3 << FLASH_ACR_LATENCY_SHIFT) /* 011: Three wait states <=64 <=26 */ +# define FLASH_ACR_LATENCY_4 (4 << FLASH_ACR_LATENCY_SHIFT) /* 100: Four wait states <=80 <=26 */ + +#define FLASH_ACR_PRFTEN (1 << 8) /* Bit 8: Pprefetch enable */ +#define FLASH_ACR_ICEN (1 << 9) /* Bit 9: Instruction cache enable */ +#define FLASH_ACR_DCEN (1 << 10) /* Bit 10: Data cache enable */ +#define FLASH_ACR_ICRST (1 << 11) /* Bit 11: Instruction cache reset */ +#define FLASH_ACR_DCRST (1 << 12) /* Bit 12: Data cache reset */ +#define FLASH_ACR_RUN_PD (1 << 13) /* Bit 13: Flash mode during Run */ +#define FLASH_ACR_SLEEP_PD (1 << 14) /* Bit 14: Flash mode during Sleep */ + +/* Flash Status Register (SR) */ + +#define FLASH_SR_EOP (1 << 0) /* Bit 0: End of operation */ +#define FLASH_SR_OPERR (1 << 1) /* Bit 1: Operation error */ +#define FLASH_SR_WRPERR (1 << 4) /* Bit 4: Write protection error */ +#define FLASH_SR_PGAERR (1 << 5) /* Bit 5: Programming alignment error */ +#define FLASH_SR_SIZERR (1 << 6) /* Bit 6: Size error */ +#define FLASH_SR_PGSERR (1 << 7) /* Bit 7: Programming sequence error */ +#define FLASH_SR_MISERR (1 << 8) /* Bit 8: Fast programming data miss error */ +#define FLASH_SR_FASTERR (1 << 9) /* Bit 9: Fast programming error */ +#define FLASH_SR_RDERR (1 << 14) /* Bit 14: PCROP read error */ +#define FLASH_SR_OPTVERR (1 << 15) /* Bit 15: Option validity error */ +#define FLASH_SR_BSY (1 << 16) /* Bit 16: Busy */ + +/* Flash Control Register (CR) */ + +#define FLASH_CR_PG (1 << 0) /* Bit 0 : Program Page */ +#define FLASH_CR_PER (1 << 1) /* Bit 1 : Page Erase */ +#define FLASH_CR_MER1 (1 << 2) /* Bit 2 : Mass Erase Bank 1 */ + +#define FLASH_CR_PNB_SHIFT (3) /* Bits 3-10: Page number */ +#define FLASH_CR_PNB_MASK (0xFF << FLASH_CR_PNB_SHIFT) +#define FLASH_CR_PNB(n) ((n) << FLASH_CR_PNB_SHIFT) /* Page n (if BKER=0) or n+256 (if BKER=1), n=0..255 */ + +#define FLASH_CR_BKER (1 << 11) /* Bit 11: Page number MSB (Bank selection) */ +#define FLASH_CR_MER2 (1 << 15) /* Bit 15: Mass Erase Bank 2 */ +#define FLASH_CR_START (1 << 16) /* Bit 16: Start Erase */ +#define FLASH_CR_OPTSTRT (1 << 17) /* Bit 17: Options modification Start */ +#define FLASH_CR_FSTPG (1 << 23) /* Bit 23: Fast programming */ +#define FLASH_CR_EOPIE (1 << 24) /* Bit 24: End of operation interrupt enable */ +#define FLASH_CR_ERRIE (1 << 25) /* Bit 25: Error interrupt enable */ +#define FLASH_CR_RDERRIE (1 << 26) /* Bit 26: PCROP read error interrupt enable */ +#define FLASH_CR_OBL_LAUNCH (1 << 27) /* Bit 27: Option Byte Loading */ +#define FLASH_CR_OPTLOCK (1 << 30) /* Bit 30: Option Lock */ +#define FLASH_CR_LOCK (1 << 31) /* Bit 31: Lock */ + +/* Flash ECC Register (ECCR) */ + +#define FLASH_ECCR_ADDR_ECC_SHIFT (0) /* Bits 8-15: Read protect */ +#define FLASH_ECCR_ADDR_ECC_MASK (0x07ffff << FLASH_ECCR_ADDR_ECC_SHIFT) +#define FLASH_ECCR_BK_ECC (1 << 19) /* Bit 19: ECC fail bank */ +#define FLASH_ECCR_SYSF_ECC (1 << 20) /* Bit 20: System Flash ECC fail */ +#define FLASH_ECCR_ECCCIE (1 << 24) /* Bit 24: ECC correction interrupt enable */ +#define FLASH_ECCR_ECCC (1 << 30) /* Bit 30: ECC correction */ +#define FLASH_ECCR_ECCD (1 << 31) /* Bit 31: ECC detection */ + +/* Flash Option Control Register (OPTCR) */ + +#define FLASH_OPTCR_NRST_STOP (1 << 12) /* Bit 12: Generate reset when entering the Stop mode */ +#define FLASH_OPTCR_NRST_STDBY (1 << 13) /* Bit 13: Generate reset when entering the Standby mode */ +#define FLASH_OPTCR_NRST_SHDW (1 << 14) /* Bit 14: Generate reset when entering the Shutdown mode */ +#define FLASH_OPTCR_IWDG_SW (1 << 16) /* Bit 16: Independent watchdog selection */ +#define FLASH_OPTCR_IWDG_STOP (1 << 17) /* Bit 17: Independent watchdog counter freeze in Stop mode */ +#define FLASH_OPTCR_IWDG_STDBY (1 << 18) /* Bit 18: Independent watchdog counter freeze in Standby mode*/ +#define FLASH_OPTCR_WWDG_SW (1 << 19) /* Bit 19: Window watchdog selection */ +#define FLASH_OPTCR_BFB2 (1 << 20) /* Bit 20: Dual bank boot */ +#define FLASH_OPTCR_DUALBANK (1 << 21) /* Bit 21: Dual bank enable */ +#define FLASH_OPTCR_NBOOT1 (1 << 23) /* Bit 23: Boot configuration */ +#define FLASH_OPTCR_SRAM2_PE (1 << 24) /* Bit 24: SRAM2 parity check enable */ +#define FLASH_OPTCR_SRAM2_RST (1 << 25) /* Bit 24: SRAM2 Erase when system reset */ +#define FLASH_OPTCR_BORLEV_SHIFT (8) /* Bits 8-10: BOR reset Level */ +#define FLASH_OPTCR_BORLEV_MASK (7 << FLASH_OPTCR_BORLEV_SHIFT) +#define FLASH_OPTCR_VBOR0 (0 << FLASH_OPTCR_BORLEV_SHIFT) /* 000: BOR Level 0 (1.7 V) */ +#define FLASH_OPTCR_VBOR1 (1 << FLASH_OPTCR_BORLEV_SHIFT) /* 001: BOR Level 1 (2.0 V) */ +#define FLASH_OPTCR_VBOR2 (2 << FLASH_OPTCR_BORLEV_SHIFT) /* 010: BOR Level 2 (2.2 V) */ +#define FLASH_OPTCR_VBOR3 (3 << FLASH_OPTCR_BORLEV_SHIFT) /* 011: BOR Level 3 (2.5 V) */ +#define FLASH_OPTCR_VBOR4 (4 << FLASH_OPTCR_BORLEV_SHIFT) /* 100: BOR Level 4 (2.8 V) */ +#define FLASH_OPTCR_RDP_SHIFT (0) /* Bits 0-7: Read Protection Level */ +#define FLASH_OPTCR_RDP_MASK (0xFF << FLASH_OPTCR_RDP_SHIFT) +#define FLASH_OPTCR_RDP_NONE (0xAA << FLASH_OPTCR_RDP_SHIFT) +#define FLASH_OPTCR_RDP_CHIP (0xCC << FLASH_OPTCR_RDP_SHIFT) /* WARNING, CANNOT BE REVERSED !! */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +void STM32L4_flash_lock(void); +void STM32L4_flash_unlock(void); + +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_FLASH_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_fsmc.h b/arch/arm/src/stm32l4/stm32l4_fsmc.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_gpio.c b/arch/arm/src/stm32l4/stm32l4_gpio.c new file mode 100644 index 00000000000..9f8be7fe6d5 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_gpio.c @@ -0,0 +1,458 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_gpio.c + * + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Gregory Nutt + * Uros Platise + * + * 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 +#include +#include + +#include + +#include "up_arch.h" + +#include "chip.h" +#include "stm32l4_gpio.h" + +#if defined(CONFIG_STM32L4_STM32L478XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4_syscfg.h" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ +/* Base addresses for each GPIO block */ + +const uint32_t g_gpiobase[STM32L4_NGPIO_PORTS] = +{ +#if STM32L4_NGPIO_PORTS > 0 + STM32L4_GPIOA_BASE, +#endif +#if STM32L4_NGPIO_PORTS > 1 + STM32L4_GPIOB_BASE, +#endif +#if STM32L4_NGPIO_PORTS > 2 + STM32L4_GPIOC_BASE, +#endif +#if STM32L4_NGPIO_PORTS > 3 + STM32L4_GPIOD_BASE, +#endif +#if STM32L4_NGPIO_PORTS > 4 + STM32L4_GPIOE_BASE, +#endif +#if STM32L4_NGPIO_PORTS > 5 + STM32L4_GPIOF_BASE, +#endif +#if STM32L4_NGPIO_PORTS > 6 + STM32L4_GPIOG_BASE, +#endif +#if STM32L4_NGPIO_PORTS > 7 + STM32L4_GPIOH_BASE, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: stm32l4_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32l4_start(). + * + * Assumptions: + * This function is called early in the initialization sequence so that + * no mutual exlusion is necessary. + * + ****************************************************************************/ + +void stm32l4_gpioinit(void) +{ +} + +/**************************************************************************** + * Name: stm32l4_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 stm32l4_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * A negated errono valu on invalid port, or when pin is locked as ALT + * function. + * + * To-Do: Auto Power Enable + ****************************************************************************/ + +int stm32l4_configgpio(uint32_t cfgset) +{ + uintptr_t base; + uint32_t regval; + uint32_t setting; + unsigned int regoffset; + unsigned int port; + unsigned int pin; + unsigned int pos; + unsigned int pinmode; + irqstate_t flags; + + /* Verify that this hardware supports the select GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= STM32L4_NGPIO_PORTS) + { + return -EINVAL; + } + + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and select the port configuration register for that + * pin + */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set up the mode register (and remember whether the pin mode) */ + + switch (cfgset & GPIO_MODE_MASK) + { + default: + case GPIO_INPUT: /* Input mode */ + pinmode = GPIO_MODER_INPUT; + break; + + case GPIO_OUTPUT: /* General purpose output mode */ + pinmode = GPIO_MODER_OUTPUT; + break; + + case GPIO_ALT: /* Alternate function mode */ + pinmode = GPIO_MODER_ALT; + break; + + case GPIO_ANALOG: /* Analog mode */ + pinmode = GPIO_MODER_ANALOG; + break; + } + + /* Interrupts must be disabled from here on out so that we have mutually + * exclusive access to all of the GPIO configuration registers. + */ + + flags = enter_critical_section(); + + /* Now apply the configuration to the mode register */ + + regval = getreg32(base + STM32L4_GPIO_MODER_OFFSET); + regval &= ~GPIO_MODER_MASK(pin); + regval |= ((uint32_t)pinmode << GPIO_MODER_SHIFT(pin)); + putreg32(regval, base + STM32L4_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 + STM32L4_GPIO_PUPDR_OFFSET); + regval &= ~GPIO_PUPDR_MASK(pin); + regval |= (setting << GPIO_PUPDR_SHIFT(pin)); + putreg32(regval, base + STM32L4_GPIO_PUPDR_OFFSET); + + /* Set the alternate function (Only alternate function pins) */ + + if (pinmode == GPIO_MODER_ALT) + { + setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; + } + else + { + setting = 0; + } + + if (pin < 8) + { + regoffset = STM32L4_GPIO_AFRL_OFFSET; + pos = pin; + } + else + { + regoffset = STM32L4_GPIO_AFRH_OFFSET; + pos = pin - 8; + } + + regval = getreg32(base + regoffset); + regval &= ~GPIO_AFR_MASK(pos); + regval |= (setting << GPIO_AFR_SHIFT(pos)); + putreg32(regval, base + regoffset); + + /* Set speed (Only outputs and alternate function pins) */ + + if (pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) + { + switch (cfgset & GPIO_SPEED_MASK) + { + default: + case GPIO_SPEED_2MHz: /* 2 MHz Low speed output */ + setting = GPIO_OSPEED_2MHz; + break; + + case GPIO_SPEED_25MHz: /* 25 MHz Medium speed output */ + setting = GPIO_OSPEED_25MHz; + break; + + case GPIO_SPEED_50MHz: /* 50 MHz High speed output */ + setting = GPIO_OSPEED_50MHz; + break; + + case GPIO_SPEED_100MHz: /* 100 MHz Very High speed output */ + setting = GPIO_OSPEED_100MHz; + break; + } + } + else + { + setting = 0; + } + + regval = getreg32(base + STM32L4_GPIO_OSPEED_OFFSET); + regval &= ~GPIO_OSPEED_MASK(pin); + regval |= (setting << GPIO_OSPEED_SHIFT(pin)); + putreg32(regval, base + STM32L4_GPIO_OSPEED_OFFSET); + + /* Set push-pull/open-drain (Only outputs and alternate function pins) */ + + regval = getreg32(base + STM32L4_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 + STM32L4_GPIO_OTYPER_OFFSET); + + /* If it is an output... set the pin to the correct initial state. */ + + if (pinmode == GPIO_MODER_OUTPUT) + { + bool value = ((cfgset & GPIO_OUTPUT_SET) != 0); + stm32l4_gpiowrite(cfgset, value); + } + + /* Otherwise, it is an input pin. Should it configured as an EXTI interrupt? */ + + else if ((cfgset & GPIO_EXTI) != 0) + { +#if 0 + /* "In STM32 F1 the selection of the EXTI line source is performed through + * the EXTIx bits in the AFIO_EXTICRx registers, while in F2 series this + * selection is done through the EXTIx bits in the SYSCFG_EXTICRx registers. + * + * "Only the mapping of the EXTICRx registers has been changed, without any + * changes to the meaning of the EXTIx bits. However, the range of EXTI + * bits values has been extended to 0b1000 to support the two ports added + * in F2, port H and I (in F1 series the maximum value is 0b0110)." + */ + + uint32_t regaddr; + int shift; + + /* Set the bits in the SYSCFG EXTICR register */ + + regaddr = STM32L4_SYSCFG_EXTICR(pin); + regval = getreg32(regaddr); + shift = SYSCFG_EXTICR_EXTI_SHIFT(pin); + regval &= ~(SYSCFG_EXTICR_PORT_MASK << shift); + regval |= (((uint32_t)port) << shift); + + putreg32(regval, regaddr); +#endif + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32l4_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 previsouly selected as alternative function (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from schocks, 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. + * + * Returns: + * OK on success + * A negated errno value on invalid port + * + * To-Do: Auto Power Disable + ****************************************************************************/ + +int stm32l4_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 stm32l4_configgpio(cfgset); +} + +/**************************************************************************** + * Name: stm32l4_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void stm32l4_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 < STM32L4_NGPIO_PORTS) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + + if (value) + { + bit = GPIO_BSRR_SET(pin); + } + else + { + bit = GPIO_BSRR_RESET(pin); + } + + putreg32(bit, base + STM32L4_GPIO_BSRR_OFFSET); + + } +} + +/**************************************************************************** + * Name: stm32l4_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool stm32l4_gpioread(uint32_t pinset) +{ + uint32_t base; + unsigned int port; + unsigned int pin; + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port < STM32L4_NGPIO_PORTS) + { + /* Get the port base address */ + + base = g_gpiobase[port]; + + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(base + STM32L4_GPIO_IDR_OFFSET) & (1 << pin)) != 0); + } + return 0; +} diff --git a/arch/arm/src/stm32l4/stm32l4_gpio.h b/arch/arm/src/stm32l4/stm32l4_gpio.h new file mode 100644 index 00000000000..6e28a581b87 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_gpio.h @@ -0,0 +1,377 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_gpio.h + * + * Copyright (C) 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved. + * Author: Gregory Nutt + * Sebastien Lorquet + * + * 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_STM32L4_STM32L4_GPIO_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_GPIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_gpio.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/************************************************************************************ + * Pre-Processor Declarations + ************************************************************************************/ + +/* Bit-encoded input to stm32l4_configgpio() */ + +/* Each port bit of the general-purpose I/O (GPIO) ports can be individually configured + * by software in several modes: + * + * - Input floating + * - Input pull-up + * - Input-pull-down + * - Output open-drain with pull-up or pull-down capability + * - Output push-pull with pull-up or pull-down capability + * - Alternate function push-pull with pull-up or pull-down capability + * - Alternate function open-drain with pull-up or pull-down capability + * - Analog + * + * 20-bit Encoding: 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * Inputs: MMUU .... ...X PPPP BBBB + * Outputs: MMUU .... FFOV PPPP BBBB + * Alternate Functions: MMUU AAAA FFO. PPPP BBBB + * Analog: MM.. .... .... PPPP BBBB + */ + +/* Mode: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * MM.. .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (18) /* Bits 18-19: GPIO port mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input mode */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* General purpose output mode */ +# define GPIO_ALT (2 << GPIO_MODE_SHIFT) /* Alternate function mode */ +# define GPIO_ANALOG (3 << GPIO_MODE_SHIFT) /* Analog mode */ + +/* Input/output pull-ups/downs (not used with analog): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * ..UU .... .... .... .... + */ + +#define GPIO_PUPD_SHIFT (16) /* Bits 16-17: Pull-up/pull down */ +#define GPIO_PUPD_MASK (3 << GPIO_PUPD_SHIFT) +# define GPIO_FLOAT (0 << GPIO_PUPD_SHIFT) /* No pull-up, pull-down */ +# define GPIO_PULLUP (1 << GPIO_PUPD_SHIFT) /* Pull-up */ +# define GPIO_PULLDOWN (2 << GPIO_PUPD_SHIFT) /* Pull-down */ + +/* Alternate Functions: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... AAAA .... .... .... + */ + +#define GPIO_AF_SHIFT (12) /* Bits 12-15: Alternate function */ +#define GPIO_AF_MASK (15 << GPIO_AF_SHIFT) +# define GPIO_AF(n) ((n) << GPIO_AF_SHIFT) +# define GPIO_AF0 (0 << GPIO_AF_SHIFT) +# define GPIO_AF1 (1 << GPIO_AF_SHIFT) +# define GPIO_AF2 (2 << GPIO_AF_SHIFT) +# define GPIO_AF3 (3 << GPIO_AF_SHIFT) +# define GPIO_AF4 (4 << GPIO_AF_SHIFT) +# define GPIO_AF5 (5 << GPIO_AF_SHIFT) +# define GPIO_AF6 (6 << GPIO_AF_SHIFT) +# define GPIO_AF7 (7 << GPIO_AF_SHIFT) +# define GPIO_AF8 (8 << GPIO_AF_SHIFT) +# define GPIO_AF9 (9 << GPIO_AF_SHIFT) +# define GPIO_AF10 (10 << GPIO_AF_SHIFT) +# define GPIO_AF11 (11 << GPIO_AF_SHIFT) +# define GPIO_AF12 (12 << GPIO_AF_SHIFT) +# define GPIO_AF13 (13 << GPIO_AF_SHIFT) +# define GPIO_AF14 (14 << GPIO_AF_SHIFT) +# define GPIO_AF15 (15 << GPIO_AF_SHIFT) + +/* Output/Alt function frequency selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... FF.. .... .... + */ + +#define GPIO_SPEED_SHIFT (10) /* Bits 10-11: GPIO frequency selection */ +#define GPIO_SPEED_MASK (3 << GPIO_SPEED_SHIFT) +# define GPIO_SPEED_2MHz (0 << GPIO_SPEED_SHIFT) /* 2 MHz Low speed output */ +# define GPIO_SPEED_25MHz (1 << GPIO_SPEED_SHIFT) /* 25 MHz Medium speed output */ +# define GPIO_SPEED_50MHz (2 << GPIO_SPEED_SHIFT) /* 50 MHz High speed output */ +# define GPIO_SPEED_100MHz (3 << GPIO_SPEED_SHIFT) /* 100 MHz Very High speed output */ + +/* Output/Alt function type selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ..O. .... .... + */ + +#define GPIO_OPENDRAIN (1 << 9) /* Bit9: 1=Open-drain output */ +#define GPIO_PUSHPULL (0) /* Bit9: 0=Push-pull output */ + +/* If the pin is a GPIO digital output, then this identifies the initial output value. + * If the pin is an input, this bit is overloaded to provide the qualifier to + * distinquish input pull-up and -down: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...V .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 8) /* Bit 8: If output, inital value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* External interrupt selection (GPIO inputs only): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...X .... .... + */ + +#define GPIO_EXTI (1 << 8) /* Bit 8: Configure as EXTI interrupt */ + +/* This identifies the GPIO port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... PPPP .... + */ + +#define GPIO_PORT_SHIFT (4) /* Bit 4-7: Port number */ +#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) /* GPIOA */ +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) /* GPIOB */ +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) /* GPIOC */ +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) /* GPIOF */ +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) /* GPIOG */ +# define GPIO_PORTH (7 << GPIO_PORT_SHIFT) /* GPIOH */ + +/* This identifies the bit in the port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... .... BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Base addresses for each GPIO block */ + +EXTERN const uint32_t g_gpiobase[STM32L4_NGPIO_PORTS]; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin. + * Once it is configured as Alternative (GPIO_ALT|GPIO_CNF_AFPP|...) + * function, it must be unconfigured with stm32_unconfiggpio() with + * the same cfgset first before it can be set to non-alternative function. + * + * Returns: + * OK on success + * ERROR on invalid port, or when pin is locked as ALT function. + * + ************************************************************************************/ + +int stm32l4_configgpio(uint32_t cfgset); + +/************************************************************************************ + * Name: stm32l4_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 previsouly selected as alternative function (GPIO_ALT|GPIO_CNF_AFPP|...). + * + * This is a safety function and prevents hardware from schocks, 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. + * + * Returns: + * OK on success + * ERROR on invalid port + * + ************************************************************************************/ + +int stm32l4_unconfiggpio(uint32_t cfgset); + +/************************************************************************************ + * Name: stm32l4_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +void stm32l4_gpiowrite(uint32_t pinset, bool value); + +/************************************************************************************ + * Name: stm32l4_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +bool stm32l4_gpioread(uint32_t pinset); + +/************************************************************************************ + * Name: stm32l4_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Parameters: + * - pinset: gpio pin configuration + * - rising/falling edge: enables + * - event: generate event when set + * - func: when non-NULL, generate interrupt + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +xcpt_t stm32l4_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func); + +/************************************************************************************ + * Function: stm32l4_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG +int stm32l4_dumpgpio(uint32_t pinset, const char *msg); +#else +# define stm32l4_dumpgpio(p,m) +#endif + +/************************************************************************************ + * Function: stm32l4_gpioinit + * + * Description: + * Based on configuration within the .config file, it does: + * - Remaps positions of alternative functions. + * + * Typically called from stm32l4_start(). + * + ************************************************************************************/ + +void stm32l4_gpioinit(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_GPIO_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_i2c.h b/arch/arm/src/stm32l4/stm32l4_i2c.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_idle.c b/arch/arm/src/stm32l4/stm32l4_idle.c new file mode 100644 index 00000000000..c1046508e90 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_idle.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_idle.c + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#include + +#include + +#include "chip.h" +#include "stm32l4_pm.h" +#include "up_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 Data + ****************************************************************************/ + +/**************************************************************************** + * 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(); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = irqsave(); + + /* Perform board-specific, state-dependent logic here */ + + llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(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: + stm32l4_pmstop(true); + break; + + case PM_SLEEP: + (void)stm32l4_pmstandby(); + break; + + default: + break; + } + + irqrestore(flags); + } +} +#else +# define up_idlepm() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* Perform IDLE mode power management */ + + up_idlepm(); + + /* Sleep until an interrupt occurs to save power. */ + +#if !(defined(CONFIG_DEBUG_SYMBOLS) && defined(CONFIG_STM32L4_DISABLE_IDLE_SLEEP_DURING_DEBUG)) + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); +#endif + +#endif +} diff --git a/arch/arm/src/stm32l4/stm32l4_irq.c b/arch/arm/src/stm32l4/stm32l4_irq.c new file mode 100644 index 00000000000..e12a362a6e7 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_irq.c @@ -0,0 +1,559 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_irq.c + * arch/arm/src/chip/stm32l4_irq.c + * + * Copyright (C) 2009-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#include + +#include "nvic.h" +#include "ram_vectors.h" +#include "up_arch.h" +#include "up_internal.h" +#include "stm32l4.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) + +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding CLEAR ENABLE register. + */ + +#define NVIC_ENA_OFFSET (0) +#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This is the address of current interrupt saved state data. Used for + * context switching. Only value during interrupt handling. + */ + +volatile uint32_t *current_regs; + +/* This is the address of the exception vector table (determined by the + * linker script). + */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ) +static void stm32l4_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + lldbg("NVIC (%s, irq=%d):\n", msg, irq); + lldbg(" INTCTRL: %08x VECTAB: %08x\n", + getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); +#if 0 + lldbg(" 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 + lldbg(" IRQ ENABLE: %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE)); + lldbg(" SYSH_PRIO: %08x %08x %08x\n", + getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), + getreg32(NVIC_SYSH12_15_PRIORITY)); + lldbg(" 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)); + lldbg(" %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)); + lldbg(" %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)); + lldbg(" %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)); + lldbg(" %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY)); + leave_critical_section(flags); +} +#else +# define stm32l4_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: stm32l4_nmi, stm32l4_busfault, stm32l4_usagefault, stm32l4_pendsv, + * stm32l4_dbgmonitor, stm32l4_pendsv, stm32l4_reserved + * + * Description: + * Handlers for various execptions. 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 +static int stm32l4_nmi(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int stm32l4_busfault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32l4_usagefault(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS)); + PANIC(); + return 0; +} + +static int stm32l4_pendsv(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int stm32l4_dbgmonitor(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Debug Monitor received\n"); + PANIC(); + return 0; +} + +static int stm32l4_reserved(int irq, FAR void *context) +{ + (void)up_irq_save(); + dbg("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32l4_prioritize_syscall + * + * Description: + * Set the priority of an exception. This function may be needed + * internally even if support for prioritized interrupts is not enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_USEBASEPRI +static inline void stm32l4_prioritize_syscall(int priority) +{ + uint32_t regval; + + /* SVCALL is system handler 11 */ + + regval = getreg32(NVIC_SYSH8_11_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK; + regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT); + putreg32(regval, NVIC_SYSH8_11_PRIORITY); +} +#endif + +/**************************************************************************** + * Name: stm32l4_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int stm32l4_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= STM32L4_IRQ_NMI && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= STM32L4_IRQ_FIRST) + { + if (irq < STM32L4_IRQ_FIRST + 32) + { + *regaddr = (NVIC_IRQ0_31_ENABLE + offset); + *bit = 1 << (irq - STM32L4_IRQ_FIRST); + } + else if (irq < STM32L4_IRQ_FIRST + 64) + { + *regaddr = (NVIC_IRQ32_63_ENABLE + offset); + *bit = 1 << (irq - STM32L4_IRQ_FIRST - 32); + } + else if (irq < NR_IRQS) + { + *regaddr = (NVIC_IRQ64_95_ENABLE + offset); + *bit = 1 << (irq - STM32L4_IRQ_FIRST - 64); + } + else + { + return ERROR; /* Invalid interrupt */ + } + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == STM32L4_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + else if (irq == STM32L4_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + else if (irq == STM32L4_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + else if (irq == STM32L4_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_ENABLE; + } + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int num_priority_registers; + + /* Disable all interrupts */ + + putreg32(0, NVIC_IRQ0_31_ENABLE); + putreg32(0, NVIC_IRQ32_63_ENABLE); + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 + { + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); + } +#endif + + /* The standard location for the vector table is at the beginning of FLASH + * at address 0x0800:0000. If we are using the STMicro DFU bootloader, then + * the vector table will be offset to a different location in FLASH and we + * will need to set the NVIC vector location to this alternative location. + */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + +#ifdef CONFIG_ARCH_RAMVECTORS + /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based + * vector table that requires special initialization. + */ + + up_ramvec_initialize(); +#endif + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); + putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); + + /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt + * lines that the NVIC supports: + * + * 0 -> 32 interrupt lines, 8 priority registers + * 1 -> 64 " " " ", 16 priority registers + * 2 -> 96 " " " ", 32 priority registers + * ... + */ + + num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8; + + /* Now set all of the interrupt lines to the default priority */ + + regaddr = NVIC_IRQ0_3_PRIORITY; + while (num_priority_registers--) + { + putreg32(DEFPRIORITY32, regaddr); + regaddr += 4; + } + + /* currents_regs is non-NULL only while processing an interrupt */ + + current_regs = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(STM32L4_IRQ_SVCALL, up_svcall); + irq_attach(STM32L4_IRQ_HARDFAULT, up_hardfault); + + /* Set the priority of the SVCall interrupt */ + +#ifdef CONFIG_ARCH_IRQPRIO + /* up_prioritize_irq(STM32L4_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */ +#endif +#ifdef CONFIG_ARMV7M_USEBASEPRI + stm32l4_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY); +#endif + + /* If the MPU is enabled, then attach and enable the Memory Management + * Fault handler. + */ + +#ifdef CONFIG_ARM_MPU + irq_attach(STM32L4_IRQ_MEMFAULT, up_memfault); + up_enable_irq(STM32L4_IRQ_MEMFAULT); +#endif + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG + irq_attach(STM32L4_IRQ_NMI, stm32l4_nmi); +#ifndef CONFIG_ARM_MPU + irq_attach(STM32L4_IRQ_MEMFAULT, up_memfault); +#endif + irq_attach(STM32L4_IRQ_BUSFAULT, stm32l4_busfault); + irq_attach(STM32L4_IRQ_USAGEFAULT, stm32l4_usagefault); + irq_attach(STM32L4_IRQ_PENDSV, stm32l4_pendsv); + irq_attach(STM32L4_IRQ_DBGMONITOR, stm32l4_dbgmonitor); + irq_attach(STM32L4_IRQ_RESERVED, stm32l4_reserved); +#endif + + stm32l4_dumpnvic("initial", NR_IRQS); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t regval; + uint32_t bit; + + if (stm32l4_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 >= STM32L4_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval &= ~bit; + putreg32(regval, regaddr); + } + } + + // stm32l4_dumpnvic("disable", irq); +} + +/**************************************************************************** + * 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 (stm32l4_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 >= STM32L4_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + else + { + regval = getreg32(regaddr); + regval |= bit; + putreg32(regval, regaddr); + } + } + + // stm32l4_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: up_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void up_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 >= STM32L4_IRQ_MEMFAULT && irq < NR_IRQS && + (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); + + if (irq < STM32L4_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 -= STM32L4_IRQ_FIRST; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + regval = getreg32(regaddr); + shift = ((irq & 3) << 3); + regval &= ~(0xff << shift); + regval |= (priority << shift); + putreg32(regval, regaddr); + + stm32l4_dumpnvic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/stm32l4/stm32l4_lcd.h b/arch/arm/src/stm32l4/stm32l4_lcd.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_lowputc.c b/arch/arm/src/stm32l4/stm32l4_lowputc.c new file mode 100644 index 00000000000..4d6ff260185 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_lowputc.c @@ -0,0 +1,388 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_lowputc.c + * + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 "up_internal.h" +#include "up_arch.h" + +#include "chip.h" + +#include "stm32l4.h" +#include "stm32l4_rcc.h" +#include "stm32l4_gpio.h" +#include "stm32l4_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Select USART parameters for the selected console */ + +#ifdef HAVE_CONSOLE +# if defined(CONFIG_USART1_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_USART1_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK2_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB2ENR +# define STM32L4_CONSOLE_APBEN RCC_APB2ENR_USART1EN +# define STM32L4_CONSOLE_BAUD CONFIG_USART1_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_USART1_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_USART1_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_USART1_2STOP +# define STM32L4_CONSOLE_TX GPIO_USART1_TX +# define STM32L4_CONSOLE_RX GPIO_USART1_RX +# ifdef CONFIG_USART1_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_USART1_RS485_DIR +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART2_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_USART2_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK1_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB1ENR1 +# define STM32L4_CONSOLE_APBEN RCC_APB1ENR1_USART2EN +# define STM32L4_CONSOLE_BAUD CONFIG_USART2_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_USART2_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_USART2_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_USART2_2STOP +# define STM32L4_CONSOLE_TX GPIO_USART2_TX +# define STM32L4_CONSOLE_RX GPIO_USART2_RX +# ifdef CONFIG_USART2_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_USART2_RS485_DIR +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART3_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_USART3_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK1_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB1ENR1 +# define STM32L4_CONSOLE_APBEN RCC_APB1ENR1_USART3EN +# define STM32L4_CONSOLE_BAUD CONFIG_USART3_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_USART3_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_USART3_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_USART3_2STOP +# define STM32L4_CONSOLE_TX GPIO_USART3_TX +# define STM32L4_CONSOLE_RX GPIO_USART3_RX +# ifdef CONFIG_USART3_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_USART3_RS485_DIR +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_UART4_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK1_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB1ENR1 +# define STM32L4_CONSOLE_APBEN RCC_APB1ENR1_UART4EN +# define STM32L4_CONSOLE_BAUD CONFIG_UART4_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_UART4_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_UART4_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_UART4_2STOP +# define STM32L4_CONSOLE_TX GPIO_UART4_TX +# define STM32L4_CONSOLE_RX GPIO_UART4_RX +# ifdef CONFIG_UART4_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_UART4_RS485_DIR +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define STM32L4_CONSOLE_BASE STM32L4_UART5_BASE +# define STM32L4_APBCLOCK STM32L4_PCLK1_FREQUENCY +# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB1ENR1 +# define STM32L4_CONSOLE_APBEN RCC_APB1ENR1_UART5EN +# define STM32L4_CONSOLE_BAUD CONFIG_UART5_BAUD +# define STM32L4_CONSOLE_BITS CONFIG_UART5_BITS +# define STM32L4_CONSOLE_PARITY CONFIG_UART5_PARITY +# define STM32L4_CONSOLE_2STOP CONFIG_UART5_2STOP +# define STM32L4_CONSOLE_TX GPIO_UART5_TX +# define STM32L4_CONSOLE_RX GPIO_UART5_RX +# ifdef CONFIG_UART5_RS485 +# define STM32L4_CONSOLE_RS485_DIR GPIO_UART5_RS485_DIR +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) +# define STM32L4_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32L4_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# endif + + /* CR1 settings */ + +# if STM32L4_CONSOLE_BITS == 9 +# define USART_CR1_M0_VALUE USART_CR1_M0 +# define USART_CR1_M1_VALUE 0 +# elif STM32L4_CONSOLE_BITS == 7 +# define USART_CR1_M0_VALUE 0 +# define USART_CR1_M1_VALUE USART_CR1_M1 +# else /* 8 bits */ +# define USART_CR1_M0_VALUE 0 +# define USART_CR1_M1_VALUE 0 +# endif + +# if STM32L4_CONSOLE_PARITY == 1 /* odd parity */ +# define USART_CR1_PARITY_VALUE (USART_CR1_PCE|USART_CR1_PS) +# elif STM32L4_CONSOLE_PARITY == 2 /* even parity */ +# define USART_CR1_PARITY_VALUE USART_CR1_PCE +# else /* no parity */ +# define USART_CR1_PARITY_VALUE 0 +# endif + +# define USART_CR1_CLRBITS \ + (USART_CR1_UESM | USART_CR1_RE | USART_CR1_TE | USART_CR1_PS | \ + USART_CR1_PCE | USART_CR1_WAKE | USART_CR1_M0 | USART_CR1_M1 | \ + USART_CR1_MME | USART_CR1_OVER8 | USART_CR1_DEDT_MASK | \ + USART_CR1_DEAT_MASK | USART_CR1_ALLINTS) + +# define USART_CR1_SETBITS (USART_CR1_M0_VALUE|USART_CR1_M1_VALUE|USART_CR1_PARITY_VALUE) + + /* CR2 settings */ + +# if STM32L4_CONSOLE_2STOP != 0 +# define USART_CR2_STOP2_VALUE USART_CR2_STOP2 +# else +# define USART_CR2_STOP2_VALUE 0 +# endif + +# define USART_CR2_CLRBITS \ + (USART_CR2_ADDM7 | USART_CR2_LBDL | USART_CR2_LBDIE | USART_CR2_LBCL | \ + USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_STOP_MASK | \ + USART_CR2_LINEN | USART_CR2_SWAP | USART_CR2_RXINV | USART_CR2_TXINV | \ + USART_CR2_DATAINV | USART_CR2_MSBFIRST | USART_CR2_ABREN | \ + USART_CR2_ABRMOD_MASK | USART_CR2_RTOEN | USART_CR2_ADD_MASK) + +# define USART_CR2_SETBITS USART_CR2_STOP2_VALUE + + /* CR3 settings */ + +# define USART_CR3_CLRBITS \ + (USART_CR3_EIE | USART_CR3_IREN | USART_CR3_IRLP | USART_CR3_HDSEL | \ + USART_CR3_NACK | USART_CR3_SCEN | USART_CR3_DMAR | USART_CR3_DMAT | \ + USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_CTSIE | USART_CR3_ONEBIT | \ + USART_CR3_OVRDIS | USART_CR3_DDRE | USART_CR3_DEM | USART_CR3_DEP | \ + USART_CR3_SCARCNT2_MASK | USART_CR3_WUS_MASK | USART_CR3_WUFIE) + +# define USART_CR3_SETBITS 0 + +# undef USE_OVER8 + + /* Calculate USART BAUD rate divider */ + + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / UARTDIV + * UARTDIV = fCK / baud + * + * In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / UARTDIV + * UARTDIV = 2 * fCK / baud + */ + +# define STM32L4_USARTDIV8 \ + (((STM32L4_APBCLOCK << 1) + (STM32L4_CONSOLE_BAUD >> 1)) / STM32L4_CONSOLE_BAUD) +# define STM32L4_USARTDIV16 \ + ((STM32L4_APBCLOCK + (STM32L4_CONSOLE_BAUD >> 1)) / STM32L4_CONSOLE_BAUD) + + /* Use oversamply by 8 only if the divisor is small. But what is small? */ + +# if STM32L4_USARTDIV8 > 100 +# define STM32L4_BRR_VALUE STM32L4_USARTDIV16 +# else +# define USE_OVER8 1 +# define STM32L4_BRR_VALUE \ + ((STM32L4_USARTDIV8 & 0xfff0) | ((STM32L4_USARTDIV8 & 0x000f) >> 1)) +# endif + +#endif /* HAVE_CONSOLE */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_CONSOLE + /* Wait until the TX data register is empty */ + + while ((getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_ISR_OFFSET) & USART_ISR_TXE) == 0); +#ifdef STM32L4_CONSOLE_RS485_DIR + stm32l4_gpiowrite(STM32L4_CONSOLE_RS485_DIR, STM32L4_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Then send the character */ + + putreg32((uint32_t)ch, STM32L4_CONSOLE_BASE + STM32L4_USART_TDR_OFFSET); + +#ifdef STM32L4_CONSOLE_RS485_DIR + while ((getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_ISR_OFFSET) & USART_ISR_TC) == 0); + stm32l4_gpiowrite(STM32L4_CONSOLE_RS485_DIR, !STM32L4_CONSOLE_RS485_DIR_POLARITY); +#endif + +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * Name: stm32l4_lowsetup + * + * Description: + * This performs basic initialization of the USART used for the serial + * console. Its purpose is to get the console output availabe as soon + * as possible. + * + ****************************************************************************/ + +void stm32l4_lowsetup(void) +{ +#if defined(HAVE_UART) +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint32_t cr; +#endif + +#if defined(HAVE_CONSOLE) + /* Enable USART APB1/2 clock */ + + modifyreg32(STM32L4_CONSOLE_APBREG, 0, STM32L4_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 stm32l4_rcc.c + */ + +#ifdef STM32L4_CONSOLE_TX + stm32l4_configgpio(STM32L4_CONSOLE_TX); +#endif +#ifdef STM32L4_CONSOLE_RX + stm32l4_configgpio(STM32L4_CONSOLE_RX); +#endif + +#ifdef STM32L4_CONSOLE_RS485_DIR + stm32l4_configgpio(STM32L4_CONSOLE_RS485_DIR); + stm32l4_gpiowrite(STM32L4_CONSOLE_RS485_DIR, !STM32L4_CONSOLE_RS485_DIR_POLARITY); +#endif + + /* Enable and configure the selected console device */ + +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + /* Configure CR2 */ + + cr = getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_CR2_OFFSET); + cr &= ~USART_CR2_CLRBITS; + cr |= USART_CR2_SETBITS; + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR2_OFFSET); + + /* Configure CR1 */ + + cr = getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); + cr &= ~USART_CR1_CLRBITS; + cr |= USART_CR1_SETBITS; + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); + + /* Configure CR3 */ + + cr = getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_CR3_OFFSET); + cr &= ~USART_CR3_CLRBITS; + cr |= USART_CR3_SETBITS; + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR3_OFFSET); + + /* Configure the USART Baud Rate */ + + putreg32(STM32L4_BRR_VALUE, STM32L4_CONSOLE_BASE + STM32L4_USART_BRR_OFFSET); + + /* Select oversampling by 8 */ + + cr = getreg32(STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); +#ifdef USE_OVER8 + cr |= USART_CR1_OVER8; + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); +#endif + + /* Enable Rx, Tx, and the USART */ + + cr |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + putreg32(cr, STM32L4_CONSOLE_BASE + STM32L4_USART_CR1_OFFSET); + +#endif /* HAVE_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} + diff --git a/arch/arm/src/stm32l4/stm32l4_lowputc.h b/arch/arm/src/stm32l4/stm32l4_lowputc.h new file mode 100644 index 00000000000..0ccfc39ce6d --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_lowputc.h @@ -0,0 +1,80 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_lowputc.h + * + * Copyright (C) 2009-2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_STM32L4_LOWPUTC_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: stm32l4_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * of serial console. + * + ************************************************************************************/ + +void stm32l4_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_LOWPUTC_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_mpuinit.c b/arch/arm/src/stm32l4/stm32l4_mpuinit.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_mpuinit.h b/arch/arm/src/stm32l4/stm32l4_mpuinit.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_pm.h b/arch/arm/src/stm32l4/stm32l4_pm.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_procfs_dtcm.c b/arch/arm/src/stm32l4/stm32l4_procfs_dtcm.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_pwr.h b/arch/arm/src/stm32l4/stm32l4_pwr.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_rcc.c b/arch/arm/src/stm32l4/stm32l4_rcc.c new file mode 100644 index 00000000000..c295e89fe2d --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_rcc.c @@ -0,0 +1,180 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_rcc.c + * + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Gregory Nutt + * Author: Sebastien Lorquet + * + * 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 +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32l4_rcc.h" +#include "stm32l4_flash.h" +#include "stm32l4.h" +#include "stm32l4_waste.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Allow up to 100 milliseconds for the high speed clock to become ready. + * that is a very long delay, but if the clock does not become ready we are + * hosed anyway. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Include chip-specific clocking initialization logic */ + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "stm32l4x6xx_rcc.c" +#else +# error "Unsupported STM32L4 chip" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. This + * function (by default) will reset most everything, enable the PLL, and enable + * peripheral clocking for all periperipherals enabled in the NuttX configuration + * file. + * + * If CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32l4_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32l4_clockconfig(void) +{ + /* Make sure that we are starting in the reset state */ + + rcc_reset(); + +#if defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32l4_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32l4_stdclockconfig(); + +#endif + + /* Enable peripheral clocking */ + + rcc_enableperipherals(); +} + +/************************************************************************************ + * Name: stm32l4_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 + * stm32l4_clockconfig(): It does not reset any devices, and it does not reset the + * currenlty enabled peripheral clocks. + * + * If CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32l4_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PM +void stm32l4_clockenable(void) +{ +#if defined(CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG) + + /* Invoke Board Custom Clock Configuration */ + + stm32l4_board_clockconfig(); + +#else + + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32l4_stdclockconfig(); + +#endif +} +#endif + diff --git a/arch/arm/src/stm32l4/stm32l4_rcc.h b/arch/arm/src/stm32l4/stm32l4_rcc.h new file mode 100644 index 00000000000..3dae842de86 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_rcc.h @@ -0,0 +1,230 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_rcc.h + * + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_STM32L4_RRC_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_RRC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "up_arch.h" +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_rcc.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* This symbol references the Cortex-M4 vector table (as positioned by the linker + * script, ld.script or ld.script.dfu. The standard location for the vector table is + * at the beginning of FLASH at address 0x0800:0000. If we are using the STMicro DFU + * bootloader, then the vector table will be offset to a different location in FLASH + * and we will need to set the NVIC vector location to this alternative location. + */ + +extern uint32_t _vectors[]; /* See stm32l4_vectors.S */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_mcoconfig + * + * Description: + * Selects the clock source to output on MC pin (PA8) for stm32f10xxx. + * PA8 should be configured in alternate function mode. + * + * Input Parameters: + * source - One of the definitions for the RCC_CFGR_MCO definitions from + * chip/stm32f10xxx_rcc.h {RCC_CFGR_SYSCLK, RCC_CFGR_INTCLK, RCC_CFGR_EXTCLK, + * RCC_CFGR_PLLCLKd2, RCC_CFGR_PLL2CLK, RCC_CFGR_PLL3CLKd2, RCC_CFGR_XT1, + * RCC_CFGR_PLL3CLK} + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void stm32l4_mcoconfig(uint32_t source) +{ + uint32_t regval; + + /* Set MCO source */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~(RCC_CFGR_MCO_MASK); + regval |= (source & RCC_CFGR_MCO_MASK); + putreg32(regval, STM32L4_RCC_CFGR); +} + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. This + * function (by default) will reset most everything, enable the PLL, and enable + * peripheral clocking for all periperipherals enabled in the NuttX configuration + * file. + * + * If CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32l4_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32l4_clockconfig(void); + +/************************************************************************************ + * Name: stm32l4_board_clockconfig + * + * Description: + * Any STM32L4 board may replace the "standard" board clock configuration logic with + * its own, custom clock cofiguration logic. + * + ************************************************************************************/ + +#ifdef CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG +void stm32l4_board_clockconfig(void); +#endif + +/************************************************************************************ + * Name: stm32l4_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 + * stm32l4_clockconfig(): It does not reset any devices, and it does not reset the + * currenlty enabled peripheral clocks. + * + * If CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32l4_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PM +void stm32l4_clockenable(void); +#endif + +/************************************************************************************ + * Name: stm32l4_rcc_enablelse + * + * Description: + * Enable the External Low-Speed (LSE) Oscillator and, if the RTC is + * configured, setup the LSE as the RTC clock source, and enable the RTC. + * + * For the STM32L15X family, this will also select the LSE as the clock source of + * the LCD. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +void stm32l4_rcc_enablelse(void); + +/**************************************************************************** + * Name: stm32l4_rcc_enablelsi + * + * Description: + * Enable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32l4_rcc_enablelsi(void); + +/**************************************************************************** + * Name: stm32l4_rcc_disablelsi + * + * Description: + * Disable the Internal Low-Speed (LSI) RC Oscillator. + * + ****************************************************************************/ + +void stm32l4_rcc_disablelsi(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_RCC_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_rtc.h b/arch/arm/src/stm32l4/stm32l4_rtc.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_sdio.h b/arch/arm/src/stm32l4/stm32l4_sdio.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_serial.c b/arch/arm/src/stm32l4/stm32l4_serial.c new file mode 100644 index 00000000000..734ea211d9e --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_serial.c @@ -0,0 +1,2575 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_serial.c + * + * Copyright (C) 2009-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include + +#include "chip.h" +#include "stm32l4_uart.h" +#include "stm32l4_dma.h" +#include "stm32l4_rcc.h" +#include "up_arch.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Some sanity checks *******************************************************/ +/* DMA configuration */ + +/* If DMA is enabled on any USART, then very that other pre-requisites + * have also been selected. + * UART DMA1 DMA2 + * 1 X X + * 2 X + * 3 X + * 4 X + * 5 X + */ + +#ifdef SERIAL_HAVE_DMA + +/* Verify that DMA has been enabled and the DMA channel has been defined. + */ + +# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) +# ifndef CONFIG_STM32L4_DMA1 +# error STM32 USART2/3 receive DMA requires CONFIG_STM32L4_DMA1 +# endif +# endif + +# if defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) +# ifndef CONFIG_STM32L4_DMA2 +# error STM32 USART4/5 receive DMA requires CONFIG_STM32L4_DMA2 +# endif +# endif + +/* Currently RS-485 support cannot be enabled when RXDMA is in use due to lack + * of testing - RS-485 support was developed on STM32F1x + */ + +# if (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ + (defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_RS485)) || \ + (defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_RS485)) || \ + (defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_RS485)) || \ + (defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_RS485)) +# error "RXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART" +# endif + +/* For the L4, there are alternate DMA channels for USART1. + * Logic in the board.h file make the DMA channel selection by defining + * the following in the board.h file. + */ + +# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX) +# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)" +# endif + +/* UART2-5 have no alternate channels */ + +# define DMAMAP_USART2_RX DMACHAN_USART2_RX +# define DMAMAP_USART3_RX DMACHAN_USART3_RX +# define DMAMAP_UART4_RX DMACHAN_UART4_RX +# define DMAMAP_UART5_RX DMACHAN_UART5_RX + +/* The DMA buffer size when using RX DMA to emulate a FIFO. + * + * When streaming data, the generic serial layer will be called + * every time the FIFO receives half this number of bytes. + */ + +# define RXDMA_BUFFER_SIZE 32 + +/* DMA priority */ + +# ifndef CONFIG_USART_DMAPRIO +# if defined(CONFIG_STM32L4_STM32L15XX) || defined(CONFIG_STM32L4_STM32F10XX) || \ + defined(CONFIG_STM32L4_STM32F30XX) || defined(CONFIG_STM32L4_STM32F37XX) +# define CONFIG_USART_DMAPRIO DMA_CCR_PRIMED +# elif defined(CONFIG_STM32L4_STM32F20XX) || defined(CONFIG_STM32L4_STM32F40XX) +# define CONFIG_USART_DMAPRIO DMA_SCR_PRIMED +# else +# error "Unknown STM32 DMA" +# endif +# endif +# if defined(CONFIG_STM32L4_STM32L15XX) || defined(CONFIG_STM32L4_STM32F10XX) || \ + defined(CONFIG_STM32L4_STM32F30XX) || defined(CONFIG_STM32L4_STM32F37XX) +# if (CONFIG_USART_DMAPRIO & ~DMA_CCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_USART_DMAPRIO" +# endif +# elif defined(CONFIG_STM32L4_STM32F20XX) || defined(CONFIG_STM32L4_STM32F40XX) +# if (CONFIG_USART_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_USART_DMAPRIO" +# endif +# else +# error "Unknown STM32 DMA" +# endif + +/* DMA control words */ + +# if defined(CONFIG_STM32L4_STM32F20XX) || defined(CONFIG_STM32L4_STM32F40XX) +# define SERIAL_DMA_CONTROL_WORD \ + (DMA_SCR_DIR_P2M | \ + DMA_SCR_CIRC | \ + DMA_SCR_MINC | \ + DMA_SCR_PSIZE_8BITS | \ + DMA_SCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO | \ + DMA_SCR_PBURST_SINGLE | \ + DMA_SCR_MBURST_SINGLE) +# ifdef CONFIG_SERIAL_IFLOWCONTROL +# define SERIAL_DMA_IFLOW_CONTROL_WORD \ + (DMA_SCR_DIR_P2M | \ + DMA_SCR_MINC | \ + DMA_SCR_PSIZE_8BITS | \ + DMA_SCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO | \ + DMA_SCR_PBURST_SINGLE | \ + DMA_SCR_MBURST_SINGLE) +# endif +# else +# define SERIAL_DMA_CONTROL_WORD \ + (DMA_CCR_CIRC | \ + DMA_CCR_MINC | \ + DMA_CCR_PSIZE_8BITS | \ + DMA_CCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO) +# ifdef CONFIG_SERIAL_IFLOWCONTROL +# define SERIAL_DMA_IFLOW_CONTROL_WORD \ + (DMA_CCR_MINC | \ + DMA_CCR_PSIZE_8BITS | \ + DMA_CCR_MSIZE_8BITS | \ + CONFIG_USART_DMAPRIO) +# endif +# endif + +#endif + +/* Power management definitions */ + +#if defined(CONFIG_PM) && !defined(CONFIG_PM_SERIAL_ACTIVITY) +# define CONFIG_PM_SERIAL_ACTIVITY 10 +#endif + +#ifdef USE_SERIALDRIVER +#ifdef HAVE_UART + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + struct uart_dev_s dev; /* Generic UART device */ + uint16_t ie; /* Saved interrupt mask bits value */ + uint16_t sr; /* Saved status bits */ + + /* If termios are supported, then the following fields may vary at + * runtime. + */ + +#ifdef CONFIG_SERIAL_TERMIOS + uint8_t parity; /* 0=none, 1=odd, 2=even */ + uint8_t bits; /* Number of bits (7 or 8) */ + bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + bool oflow; /* output flow control (CTS) enabled */ +#endif + uint32_t baud; /* Configured baud */ +#else + const uint8_t parity; /* 0=none, 1=odd, 2=even */ + const uint8_t bits; /* Number of bits (7 or 8) */ + const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const bool iflow; /* input flow control (RTS) enabled */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const bool oflow; /* output flow control (CTS) enabled */ +#endif + const uint32_t baud; /* Configured baud */ +#endif + + const uint8_t irq; /* IRQ associated with this USART */ + const uint32_t apbclock; /* PCLK 1 or 2 frequency */ + const uint32_t usartbase; /* Base address of USART registers */ + const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ + const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ +#ifdef CONFIG_SERIAL_IFLOWCONTROL + const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */ +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */ +#endif + +#ifdef SERIAL_HAVE_DMA + const unsigned int rxdma_channel; /* DMA channel assigned */ +#endif + + int (*const vector)(int irq, void *context); /* Interrupt handler */ + + /* RX DMA state */ + +#ifdef SERIAL_HAVE_DMA + DMA_HANDLE rxdma; /* currently-open receive DMA stream */ + bool rxenable; /* DMA-based reception en/disable */ + uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */ + char *const rxfifo; /* Receive DMA buffer */ +#endif + +#ifdef HAVE_RS485 + const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ + const bool rs485_dir_polarity; /* U[S]ART RS-485 DIR pin state for TX enabled */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +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_common(struct up_dev_s *dev); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +#ifndef SERIAL_HAVE_ONLY_DMA +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +#endif +#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); + +#ifdef SERIAL_HAVE_DMA +static int up_dma_setup(struct uart_dev_s *dev); +static void up_dma_shutdown(struct uart_dev_s *dev); +static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status); +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 + +#ifdef CONFIG_PM +static void up_pm_notify(struct pm_callback_s *cb, enum pm_state_e pmstate); +static int up_pm_prepare(struct pm_callback_s *cb, enum pm_state_e pmstate); +#endif + +#ifdef CONFIG_STM32L4_USART1 +static int up_interrupt_usart1(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_USART2 +static int up_interrupt_usart2(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_USART3 +static int up_interrupt_usart3(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_UART4 +static int up_interrupt_uart4(int irq, void *context); +#endif +#ifdef CONFIG_STM32L4_UART5 +static int up_interrupt_uart5(int irq, void *context); +#endif + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +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_txready, +}; +#endif + +#ifdef SERIAL_HAVE_DMA +static const struct uart_ops_s g_uart_dma_ops = +{ + .setup = up_dma_setup, + .shutdown = up_dma_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = 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_txready, +}; +#endif + +/* I/O buffers */ + +#ifdef CONFIG_STM32L4_USART1 +static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; +static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; +# ifdef CONFIG_USART1_RXDMA +static char g_usart1rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32L4_USART2 +static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; +static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; +# ifdef CONFIG_USART2_RXDMA +static char g_usart2rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32L4_USART3 +static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; +static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; +# ifdef CONFIG_USART3_RXDMA +static char g_usart3rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32L4_UART4 +static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; +static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; +# ifdef CONFIG_UART4_RXDMA +static char g_uart4rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32L4_UART5 +static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; +static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; +# ifdef CONFIG_UART5_RXDMA +static char g_uart5rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +/* This describes the state of the STM32 USART1 ports. */ + +#ifdef CONFIG_STM32L4_USART1 +static struct up_dev_s g_usart1priv = +{ + .dev = + { +#if CONSOLE_UART == 1 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART1_RXBUFSIZE, + .buffer = g_usart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART1_TXBUFSIZE, + .buffer = g_usart1txbuffer, + }, +#ifdef CONFIG_USART1_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart1priv, + }, + + .irq = STM32L4_IRQ_USART1, + .parity = CONFIG_USART1_PARITY, + .bits = CONFIG_USART1_BITS, + .stopbits2 = CONFIG_USART1_2STOP, + .baud = CONFIG_USART1_BAUD, + .apbclock = STM32L4_PCLK2_FREQUENCY, + .usartbase = STM32L4_USART1_BASE, + .tx_gpio = GPIO_USART1_TX, + .rx_gpio = GPIO_USART1_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART1_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART1_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART1_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART1_RTS, +#endif +#ifdef CONFIG_USART1_RXDMA + .rxdma_channel = DMAMAP_USART1_RX, + .rxfifo = g_usart1rxfifo, +#endif + .vector = up_interrupt_usart1, + +#ifdef CONFIG_USART1_RS485 + .rs485_dir_gpio = GPIO_USART1_RS485_DIR, +# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART2 port. */ + +#ifdef CONFIG_STM32L4_USART2 +static struct up_dev_s g_usart2priv = +{ + .dev = + { +#if CONSOLE_UART == 2 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART2_RXBUFSIZE, + .buffer = g_usart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART2_TXBUFSIZE, + .buffer = g_usart2txbuffer, + }, +#ifdef CONFIG_USART2_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart2priv, + }, + + .irq = STM32L4_IRQ_USART2, + .parity = CONFIG_USART2_PARITY, + .bits = CONFIG_USART2_BITS, + .stopbits2 = CONFIG_USART2_2STOP, + .baud = CONFIG_USART2_BAUD, + .apbclock = STM32L4_PCLK1_FREQUENCY, + .usartbase = STM32L4_USART2_BASE, + .tx_gpio = GPIO_USART2_TX, + .rx_gpio = GPIO_USART2_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART2_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART2_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART2_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART2_RTS, +#endif +#ifdef CONFIG_USART2_RXDMA + .rxdma_channel = DMAMAP_USART2_RX, + .rxfifo = g_usart2rxfifo, +#endif + .vector = up_interrupt_usart2, + +#ifdef CONFIG_USART2_RS485 + .rs485_dir_gpio = GPIO_USART2_RS485_DIR, +# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 USART3 port. */ + +#ifdef CONFIG_STM32L4_USART3 +static struct up_dev_s g_usart3priv = +{ + .dev = + { +#if CONSOLE_UART == 3 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_USART3_RXBUFSIZE, + .buffer = g_usart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART3_TXBUFSIZE, + .buffer = g_usart3txbuffer, + }, +#ifdef CONFIG_USART3_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_usart3priv, + }, + + .irq = STM32L4_IRQ_USART3, + .parity = CONFIG_USART3_PARITY, + .bits = CONFIG_USART3_BITS, + .stopbits2 = CONFIG_USART3_2STOP, + .baud = CONFIG_USART3_BAUD, + .apbclock = STM32L4_PCLK1_FREQUENCY, + .usartbase = STM32L4_USART3_BASE, + .tx_gpio = GPIO_USART3_TX, + .rx_gpio = GPIO_USART3_RX, +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART3_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART3_CTS, +#endif +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART3_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART3_RTS, +#endif +#ifdef CONFIG_USART3_RXDMA + .rxdma_channel = DMAMAP_USART3_RX, + .rxfifo = g_usart3rxfifo, +#endif + .vector = up_interrupt_usart3, + +#ifdef CONFIG_USART3_RS485 + .rs485_dir_gpio = GPIO_USART3_RS485_DIR, +# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART4 port. */ + +#ifdef CONFIG_STM32L4_UART4 +static struct up_dev_s g_uart4priv = +{ + .dev = + { +#if CONSOLE_UART == 4 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART4_RXBUFSIZE, + .buffer = g_uart4rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART4_TXBUFSIZE, + .buffer = g_uart4txbuffer, + }, +#ifdef CONFIG_UART4_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart4priv, + }, + + .irq = STM32L4_IRQ_UART4, + .parity = CONFIG_UART4_PARITY, + .bits = CONFIG_UART4_BITS, + .stopbits2 = CONFIG_UART4_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif + .baud = CONFIG_UART4_BAUD, + .apbclock = STM32L4_PCLK1_FREQUENCY, + .usartbase = STM32L4_UART4_BASE, + .tx_gpio = GPIO_UART4_TX, + .rx_gpio = GPIO_UART4_RX, +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .cts_gpio = 0, +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rts_gpio = 0, +#endif +#ifdef CONFIG_UART4_RXDMA + .rxdma_channel = DMAMAP_UART4_RX, + .rxfifo = g_uart4rxfifo, +#endif + .vector = up_interrupt_uart4, + +#ifdef CONFIG_UART4_RS485 + .rs485_dir_gpio = GPIO_UART4_RS485_DIR, +# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This describes the state of the STM32 UART5 port. */ + +#ifdef CONFIG_STM32L4_UART5 +static struct up_dev_s g_uart5priv = +{ + .dev = + { +#if CONSOLE_UART == 5 + .isconsole = true, +#endif + .recv = + { + .size = CONFIG_UART5_RXBUFSIZE, + .buffer = g_uart5rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART5_TXBUFSIZE, + .buffer = g_uart5txbuffer, + }, +#ifdef CONFIG_UART5_RXDMA + .ops = &g_uart_dma_ops, +#else + .ops = &g_uart_ops, +#endif + .priv = &g_uart5priv, + }, + + .irq = STM32L4_IRQ_UART5, + .parity = CONFIG_UART5_PARITY, + .bits = CONFIG_UART5_BITS, + .stopbits2 = CONFIG_UART5_2STOP, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .iflow = false, +#endif +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .oflow = false, +#endif + .baud = CONFIG_UART5_BAUD, + .apbclock = STM32L4_PCLK1_FREQUENCY, + .usartbase = STM32L4_UART5_BASE, + .tx_gpio = GPIO_UART5_TX, + .rx_gpio = GPIO_UART5_RX, +#ifdef CONFIG_SERIAL_OFLOWCONTROL + .cts_gpio = 0, +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rts_gpio = 0, +#endif +#ifdef CONFIG_UART5_RXDMA + .rxdma_channel = DMAMAP_UART5_RX, + .rxfifo = g_uart5rxfifo, +#endif + .vector = up_interrupt_uart5, + +#ifdef CONFIG_UART5_RS485 + .rs485_dir_gpio = GPIO_UART5_RS485_DIR, +# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) + .rs485_dir_polarity = false, +# else + .rs485_dir_polarity = true, +# endif +#endif +}; +#endif + +/* This table lets us iterate over the configured USARTs */ + +static struct up_dev_s * const uart_devs[STM32L4_NUSART] = +{ +#ifdef CONFIG_STM32L4_USART1 + [0] = &g_usart1priv, +#endif +#ifdef CONFIG_STM32L4_USART2 + [1] = &g_usart2priv, +#endif +#ifdef CONFIG_STM32L4_USART3 + [2] = &g_usart3priv, +#endif +#ifdef CONFIG_STM32L4_UART4 + [3] = &g_uart4priv, +#endif +#ifdef CONFIG_STM32L4_UART5 + [4] = &g_uart5priv, +#endif +}; + +#ifdef CONFIG_PM +static struct pm_callback_s g_serialcb = +{ + .notify = up_pm_notify, + .prepare = up_pm_prepare, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->usartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreusartint + ****************************************************************************/ + +static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie) +{ + uint32_t cr; + + /* Save the interrupt mask */ + + priv->ie = ie; + + /* And restore the interrupt state (see the interrupt enable/usage table above) */ + + cr = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + cr &= ~(USART_CR1_USED_INTS); + cr |= (ie & (USART_CR1_USED_INTS)); + up_serialout(priv, STM32L4_USART_CR1_OFFSET, cr); + + cr = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + cr &= ~USART_CR3_EIE; + cr |= (ie & USART_CR3_EIE); + up_serialout(priv, STM32L4_USART_CR3_OFFSET, cr); +} + +/**************************************************************************** + * Name: up_disableusartint + ****************************************************************************/ + +static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) +{ + if (ie) + { + uint32_t cr1; + uint32_t cr3; + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------ ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NF Noise Flag + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + */ + + cr1 = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + cr3 = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + + /* Return the current interrupt mask value for the used interrupts. Notice + * that this depends on the fact that none of the used interrupt enable bits + * overlap. This logic would fail if we needed the break interrupt! + */ + + *ie = (cr1 & (USART_CR1_USED_INTS)) | (cr3 & USART_CR3_EIE); + } + + /* Disable all interrupts */ + + up_restoreusartint(priv, 0); +} + +/**************************************************************************** + * Name: up_dma_nextrx + * + * Description: + * Returns the index into the RX FIFO where the DMA will place the next + * byte that it receives. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_nextrx(struct up_dev_s *priv) +{ + size_t dmaresidual; + + dmaresidual = stm32l4_dmaresidual(priv->rxdma); + + return (RXDMA_BUFFER_SIZE - (int)dmaresidual); +} +#endif + +/**************************************************************************** + * Name: up_set_format + * + * Description: + * Set the serial line format and speed. + * + ****************************************************************************/ + +#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 regval; + + /* This first implementation is for U[S]ARTs that support oversampling + * by 8 in additional to the standard oversampling by 16. + */ + + uint32_t usartdiv8; + uint32_t cr1; + uint32_t brr; + + /* In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / usartdiv8 + * usartdiv8 = 2 * fCK / baud + */ + + usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; + + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / usartdiv16 + * usartdiv16 = fCK / baud + * = 2 * usartdiv8 + */ + + /* Use oversamply by 8 only if the divisor is small. But what is small? */ + + cr1 = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + if (usartdiv8 > 100) + { + /* Use usartdiv16 */ + + brr = (usartdiv8 + 1) >> 1; + + /* Clear oversampling by 8 to enable oversampling by 16 */ + + cr1 &= ~USART_CR1_OVER8; + } + else + { + DEBUGASSERT(usartdiv8 >= 8); + + /* Perform mysterious operations on bits 0-3 */ + + brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); + + /* Set oversampling by 8 */ + + cr1 |= USART_CR1_OVER8; + } + + up_serialout(priv, STM32L4_USART_CR1_OFFSET, cr1); + up_serialout(priv, STM32L4_USART_BRR_OFFSET, brr); + + /* Configure parity mode */ + + regval = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + regval &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0 | USART_CR1_M1); + + if (priv->parity == 1) /* Odd parity */ + { + regval |= (USART_CR1_PCE | USART_CR1_PS); + } + else if (priv->parity == 2) /* Even parity */ + { + regval |= USART_CR1_PCE; + } + + /* Configure word length (parity uses one of configured bits) + * + * Default: 1 start, 8 data (no parity), n stop, OR + * 1 start, 7 data + parity, n stop + */ + + if (priv->bits == 9 || (priv->bits == 8 && priv->parity != 0)) + { + /* Select: 1 start, 8 data + parity, n stop, OR + * 1 start, 9 data (no parity), n stop. + */ + + regval |= USART_CR1_M0; + } + else if (priv->bits == 7 && priv->parity == 0) + { + /* Select: 1 start, 7 data (no parity), n stop, OR + */ + + regval |= USART_CR1_M1; + } + /* Else Select: 1 start, 7 data + parity, n stop, OR + * 1 start, 8 data (no parity), n stop. + */ + + up_serialout(priv, STM32L4_USART_CR1_OFFSET, regval); + + /* Configure STOP bits */ + + regval = up_serialin(priv, STM32L4_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK); + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + up_serialout(priv, STM32L4_USART_CR2_OFFSET, regval); + + /* Configure hardware flow control */ + + regval = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSE | USART_CR3_RTSE); + +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && !defined(CONFIG_STM32L4_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + regval |= USART_CR3_RTSE; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow && (priv->cts_gpio != 0)) + { + regval |= USART_CR3_CTSE; + } +#endif + + up_serialout(priv, STM32L4_USART_CR3_OFFSET, regval); +} +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + +/**************************************************************************** + * Name: up_set_apb_clock + * + * Description: + * Enable or disable APB clock for the USART peripheral + * + * Input parameters: + * dev - A reference to the UART driver state structure + * on - Enable clock if 'on' is 'true' and disable if 'false' + * + ****************************************************************************/ + +static void up_set_apb_clock(struct uart_dev_s *dev, bool on) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rcc_en; + uint32_t regaddr; + + /* Determine which USART to configure */ + + switch (priv->usartbase) + { + default: + return; +#ifdef CONFIG_STM32L4_USART1 + case STM32L4_USART1_BASE: + rcc_en = RCC_APB2ENR_USART1EN; + regaddr = STM32L4_RCC_APB2ENR; + break; +#endif +#ifdef CONFIG_STM32L4_USART2 + case STM32L4_USART2_BASE: + rcc_en = RCC_APB1ENR1_USART2EN; + regaddr = STM32L4_RCC_APB1ENR1; + break; +#endif +#ifdef CONFIG_STM32L4_USART3 + case STM32L4_USART3_BASE: + rcc_en = RCC_APB1ENR1_USART3EN; + regaddr = STM32L4_RCC_APB1ENR1; + break; +#endif +#ifdef CONFIG_STM32L4_UART4 + case STM32L4_UART4_BASE: + rcc_en = RCC_APB1ENR1_UART4EN; + regaddr = STM32L4_RCC_APB1ENR1; + break; +#endif +#ifdef CONFIG_STM32L4_UART5 + case STM32L4_UART5_BASE: + rcc_en = RCC_APB1ENR1_UART5EN; + regaddr = STM32L4_RCC_APB1ENR1; + break; +#endif + } + + /* Enable/disable APB 1/2 clock for USART */ + + if (on) + { + modifyreg32(regaddr, 0, rcc_en); + } + else + { + modifyreg32(regaddr, rcc_en, 0); + } +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t regval; + + /* Note: The logic here depends on the fact that that the USART module + * was enabled in stm32l4_lowsetup(). + */ + + /* Enable USART APB1/2 clock */ + + up_set_apb_clock(dev, true); + + /* Configure pins for USART use */ + + stm32l4_configgpio(priv->tx_gpio); + stm32l4_configgpio(priv->rx_gpio); + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32l4_configgpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + uint32_t config = priv->rts_gpio; + +#ifdef CONFIG_STM32L4_FLOWCONTROL_BROKEN + /* Instead of letting hw manage this pin, we will bitbang */ + + config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; +#endif + stm32l4_configgpio(config); + } +#endif + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32l4_configgpio(priv->rs485_dir_gpio); + stm32l4_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + } +#endif + + /* Configure CR2 */ + /* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */ + + regval = up_serialin(priv, STM32L4_USART_CR2_OFFSET); + regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | + USART_CR2_CPHA | USART_CR2_LBCL | USART_CR2_LBDIE); + + /* Configure STOP bits */ + + if (priv->stopbits2) + { + regval |= USART_CR2_STOP2; + } + + up_serialout(priv, STM32L4_USART_CR2_OFFSET, regval); + + /* Configure CR1 */ + /* Clear TE, REm and all interrupt enable bits */ + + regval = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + regval &= ~(USART_CR1_TE | USART_CR1_RE | USART_CR1_ALLINTS); + + up_serialout(priv, STM32L4_USART_CR1_OFFSET, regval); + + /* Configure CR3 */ + /* Clear CTSE, RTSE, and all interrupt enable bits */ + + regval = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + regval &= ~(USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | USART_CR3_EIE); + + up_serialout(priv, STM32L4_USART_CR3_OFFSET, regval); + + /* Configure the USART line format and speed. */ + + up_set_format(dev); + + /* Enable Rx, Tx, and the USART */ + + regval = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + up_serialout(priv, STM32L4_USART_CR1_OFFSET, regval); + +#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + + /* Set up the cached interrupt enables value */ + + priv->ie = 0; + return OK; +} + +/**************************************************************************** + * Name: up_dma_setup + * + * Description: + * Configure the USART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int result; + uint32_t regval; + + /* Do the basic UART setup first, unless we are the console */ + + if (!dev->isconsole) + { + result = up_setup(dev); + if (result != OK) + { + return result; + } + } + + /* Acquire the DMA channel. This should always succeed. */ + + priv->rxdma = stm32l4_dmachannel(priv->rxdma_channel); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Configure for non-circular DMA reception into the RX FIFO */ + + stm32l4_dmasetup(priv->rxdma, + priv->usartbase + STM32L4_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + } + else +#endif + { + /* Configure for circular DMA reception into the RX FIFO */ + + stm32l4_dmasetup(priv->rxdma, + priv->usartbase + STM32L4_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_CONTROL_WORD); + } + + /* Reset our DMA shadow pointer to match the address just + * programmed above. + */ + + priv->rxdmanext = 0; + + /* Enable receive DMA for the UART */ + + regval = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + regval |= USART_CR3_DMAR; + up_serialout(priv, STM32L4_USART_CR3_OFFSET, regval); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* Start the DMA channel, and arrange for callbacks at the full point + * in the FIFO. After buffer gets full, hardware flow-control kicks + * in and DMA transfer is stopped. + */ + + stm32l4_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false); + } + else +#endif + { + /* Start the DMA channel, and arrange for callbacks at the half and + * full points in the FIFO. This ensures that we have half a FIFO + * worth of time to claim bytes before they are overwritten. + */ + + stm32l4_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, true); + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + /* Disable all interrupts */ + + up_disableusartint(priv, NULL); + + /* Disable USART APB1/2 clock */ + + up_set_apb_clock(dev, false); + + /* Disable Rx, Tx, and the UART */ + + regval = up_serialin(priv, STM32L4_USART_CR1_OFFSET); + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + up_serialout(priv, STM32L4_USART_CR1_OFFSET, regval); + + /* Release pins. "If the serial-attached device is powered down, the TX + * pin causes back-powering, potentially confusing the device to the point + * of complete lock-up." + * + * REVISIT: Is unconfiguring the pins appropriate for all device? If not, + * then this may need to be a configuration option. + */ + + stm32l4_unconfiggpio(priv->tx_gpio); + stm32l4_unconfiggpio(priv->rx_gpio); + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->cts_gpio != 0) + { + stm32l4_unconfiggpio(priv->cts_gpio); + } +#endif + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->rts_gpio != 0) + { + stm32l4_unconfiggpio(priv->rts_gpio); + } +#endif + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32l4_unconfiggpio(priv->rs485_dir_gpio); + } +#endif +} + +/**************************************************************************** + * Name: up_dma_shutdown + * + * Description: + * Disable the USART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Perform the normal UART shutdown */ + + up_shutdown(dev); + + /* Stop the DMA channel */ + + stm32l4_dmastop(priv->rxdma); + + /* Release the DMA channel */ + + stm32l4_dmafree(priv->rxdma); + priv->rxdma = NULL; +} +#endif + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the USART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, priv->vector); + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the USART + */ + + up_enable_irq(priv->irq); + } + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach USART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void 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_common + * + * Description: + * This is the USART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt_common(struct up_dev_s *priv) +{ + int passes; + bool handled; + + /* Report serial activity to the power management logic */ + +#if defined(CONFIG_PM) && CONFIG_PM_SERIAL_ACTIVITY > 0 + pm_activity(CONFIG_PM_SERIAL_ACTIVITY); +#endif + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + handled = true; + for (passes = 0; passes < 256 && handled; passes++) + { + handled = false; + + /* Get the masked USART status word. */ + + priv->sr = up_serialin(priv, STM32L4_USART_ISR_OFFSET); + + /* USART interrupts: + * + * Enable Status Meaning Usage + * ------------------ --------------- ------------------------------- ---------- + * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) + * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to be Read + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR1_TCIE USART_ISR_TC Transmission Complete (used only for RS-485) + * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty + * USART_CR1_PEIE USART_ISR_PE Parity Error + * + * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) + * USART_CR3_EIE USART_ISR_FE Framing Error + * " " USART_ISR_NE Noise Error + * " " USART_ISR_ORE Overrun Error Detected + * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) + * + * NOTE: Some of these status bits must be cleared by explicity writing zero + * to the SR register: USART_ISR_CTS, USART_ISR_LBD. Note of those are currently + * being used. + */ + +#ifdef HAVE_RS485 + /* Transmission of whole buffer is over - TC is set, TXEIE is cleared. + * Note - this should be first, to have the most recent TC bit value from + * SR register - sending data affects TC, but without refresh we will not + * know that... + */ + + if ((priv->sr & USART_ISR_TC) != 0 && (priv->ie & USART_CR1_TCIE) != 0 && + (priv->ie & USART_CR1_TXEIE) == 0) + { + stm32l4_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + up_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); + } +#endif + + /* Handle incoming, receive bytes. */ + + if ((priv->sr & USART_ISR_RXNE) != 0 && (priv->ie & USART_CR1_RXNEIE) != 0) + { + /* Received data ready... process incoming bytes. NOTE the check for + * RXNEIE: We cannot call uart_recvchards of RX interrupts are disabled. + */ + + uart_recvchars(&priv->dev); + handled = true; + } + + /* We may still have to read from the DR register to clear any pending + * error conditions. + */ + + else if ((priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) != 0) + { + /* These errors are cleared by writing the corresponding bit to the + * interrupt clear register (ICR). + */ + + up_serialout(priv, STM32L4_USART_ICR_OFFSET, + (USART_ICR_NCF | USART_ICR_ORECF | USART_ICR_FECF)); + } + + /* Handle outgoing, transmit bytes */ + + if ((priv->sr & USART_ISR_TXE) != 0 && (priv->ie & USART_CR1_TXEIE) != 0) + { + /* Transmit data register empty ... process outgoing bytes */ + + uart_xmitchars(&priv->dev); + handled = true; + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +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; +#endif +#ifdef CONFIG_SERIAL_TERMIOS + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; +#endif + int ret = OK; + + 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, dev, sizeof(struct up_dev_s)); + } + } + break; +#endif + +#ifdef CONFIG_STM32L4_USART_SINGLEWIRE + case TIOCSSINGLEWIRE: + { + /* Change the TX port to be open-drain/push-pull and enable/disable + * half-duplex mode. + */ + + uint32_t cr = up_serialin(priv, STM32L4_USART_CR3_OFFSET); + +#if defined(CONFIG_STM32L4_STM32F10XX) + if (arg == SER_SINGLEWIRE_ENABLED) + { + stm32l4_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFOD); + cr |= USART_CR3_HDSEL; + } + else + { + stm32l4_configgpio((priv->tx_gpio & ~(GPIO_CNF_MASK)) | GPIO_CNF_AFPP); + cr &= ~USART_CR3_HDSEL; + } +#else + if (arg == SER_SINGLEWIRE_ENABLED) + { + stm32l4_configgpio(priv->tx_gpio | GPIO_OPENDRAIN); + cr |= USART_CR3_HDSEL; + } + else + { + stm32l4_configgpio(priv->tx_gpio | GPIO_PUSHPULL); + cr &= ~USART_CR3_HDSEL; + } +#endif + + up_serialout(priv, STM32L4_USART_CR3_OFFSET, cr); + } + break; +#endif + +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + cfsetispeed(termiosp, priv->baud); + + /* Note that since we only support 8/9 bit modes and + * there is no way to report 9-bit mode, we always claim 8. + */ + + termiosp->c_cflag = + ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0) | + ((priv->stopbits2) ? CSTOPB : 0) | +#ifdef CONFIG_SERIAL_OFLOWCONTROL + ((priv->oflow) ? CCTS_OFLOW : 0) | +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + ((priv->iflow) ? CRTS_IFLOW : 0) | +#endif + CS8; + + /* TODO: CCTS_IFLOW, CCTS_OFLOW */ + } + break; + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Perform some sanity checks before accepting any changes */ + + if (((termiosp->c_cflag & CSIZE) != CS8) +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)) +#endif + ) + { + ret = -EINVAL; + break; + } + + if (termiosp->c_cflag & PARENB) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + priv->parity = 0; + } + + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#ifdef CONFIG_SERIAL_OFLOWCONTROL + priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; +#endif + + /* Note that since there is no way to request 9-bit mode + * and no way to support 5/6/7-bit modes, we ignore them + * all here. + */ + + /* Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + priv->baud = cfgetispeed(termiosp); + + /* Effect the changes immediately - note that we do not implement + * TCSADRAIN / TCSAFLUSH + */ + + up_set_format(dev); + } + break; +#endif /* CONFIG_SERIAL_TERMIOS */ + +#ifdef CONFIG_USART_BREAKS + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + uint32_t cr2 = up_serialin(priv, STM32L4_USART_CR2_OFFSET); + up_serialout(priv, STM32L4_USART_CR2_OFFSET, cr2 | USART_CR2_LINEN); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + uint32_t cr1 = up_serialin(priv, STM32L4_USART_CR2_OFFSET); + up_serialout(priv, STM32L4_USART_CR2_OFFSET, cr2 & ~USART_CR2_LINEN); + leave_critical_section(flags); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t rdr; + + /* Get the Rx byte */ + + rdr = up_serialin(priv, STM32L4_USART_RDR_OFFSET); + + /* Get the Rx byte plux error information. Return those in status */ + + *status = priv->sr << 16 | rdr; + priv->sr = 0; + + /* Then return the actual received byte */ + + return rdr & 0xff; +} +#endif + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +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 Flag + * " " USART_ISR_ORE Overrun Error Detected + */ + + flags = enter_critical_section(); + ie = priv->ie; + if (enable) + { + /* Receive an interrupt when their is anything in the Rx data register (or an Rx + * timeout occurs). + */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS +#ifdef CONFIG_USART_ERRINTS + ie |= (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); +#else + ie |= USART_CR1_RXNEIE; +#endif +#endif + } + else + { + ie &= ~(USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); + } + + /* Then set the new interrupt state */ + + up_restoreusartint(priv, ie); + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifndef SERIAL_HAVE_ONLY_DMA +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STM32L4_USART_ISR_OFFSET) & USART_ISR_RXNE) != 0); +} +#endif + +/**************************************************************************** + * Name: up_rxflowcontrol + * + * Description: + * Called when Rx buffer is full (or exceeds configured watermark levels + * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined). + * Return true if UART activated RX flow control to block more incoming + * data + * + * Input parameters: + * dev - UART device instance + * nbuffered - the number of characters currently buffered + * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is + * not defined the value will be 0 for an empty buffer or the + * defined buffer size for a full buffer) + * upper - true indicates the upper watermark was crossed where + * false indicates the lower watermark has been crossed + * + * Returned Value: + * true if RX flow control activated. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool up_rxflowcontrol(struct uart_dev_s *dev, + unsigned int nbuffered, bool upper) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && \ + defined(CONFIG_STM32L4_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + /* Assert/de-assert nRTS set it high resume/stop sending */ + + stm32l4_gpiowrite(priv->rts_gpio, upper); + return upper; + } + +#else + if (priv->iflow) + { + /* Is the RX buffer full? */ + + if (upper) + { + /* Disable Rx interrupt to prevent more data being from + * peripheral. When hardware RTS is enabled, this will + * prevent more data from coming in. + * + * This function is only called when UART recv buffer is full, + * that is: "dev->recv.head + 1 == dev->recv.tail". + * + * Logic in "uart_read" will automatically toggle Rx interrupts + * when buffer is read empty and thus we do not have to re- + * enable Rx interrupts. + */ + + uart_disablerxint(dev); + return true; + } + + /* No.. The RX buffer is empty */ + + else + { + /* We might leave Rx interrupt disabled if full recv buffer was + * read empty. Enable Rx interrupt to make sure that more input is + * received. + */ + + uart_enablerxint(dev); + } + } +#endif + + return false; +} +#endif + +/**************************************************************************** + * Name: up_dma_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the USART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int c = 0; + + if (up_dma_nextrx(priv) != priv->rxdmanext) + { + c = priv->rxfifo[priv->rxdmanext]; + + priv->rxdmanext++; + if (priv->rxdmanext == RXDMA_BUFFER_SIZE) + { +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow) + { + /* RX DMA buffer full. RX paused, RTS line pulled up to prevent + * more input data from other end. + */ + } + else +#endif + { + priv->rxdmanext = 0; + } + } + } + + return c; +} +#endif + +/**************************************************************************** + * Name: up_dma_reenable + * + * Description: + * Call to re-enable RX DMA. + * + ****************************************************************************/ + +#if defined(SERIAL_HAVE_DMA) && defined(CONFIG_SERIAL_IFLOWCONTROL) +static void up_dma_reenable(struct up_dev_s *priv) +{ + /* Configure for non-circular DMA reception into the RX fifo */ + + stm32l4_dmasetup(priv->rxdma, + priv->usartbase + STM32L4_USART_RDR_OFFSET, + (uint32_t)priv->rxfifo, + RXDMA_BUFFER_SIZE, + SERIAL_DMA_IFLOW_CONTROL_WORD); + + /* Reset our DMA shadow pointer to match the address just + * programmed above. + */ + + priv->rxdmanext = 0; + + /* Start the DMA channel, and arrange for callbacks at the full point in + * the FIFO. After buffer gets full, hardware flow-control kicks in and + * DMA transfer is stopped. + */ + + stm32l4_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false); +} +#endif + +/**************************************************************************** + * Name: up_dma_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* En/disable DMA reception. + * + * Note that it is not safe to check for available bytes and immediately + * pass them to uart_recvchars as that could potentially recurse back + * to us again. Instead, bytes must wait until the next up_dma_poll or + * DMA event. + */ + + priv->rxenable = enable; + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && priv->rxenable && (priv->rxdmanext == RXDMA_BUFFER_SIZE)) + { + /* Re-enable RX DMA. */ + + up_dma_reenable(priv); + } +#endif +} +#endif + +/**************************************************************************** + * Name: up_dma_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static bool up_dma_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Compare our receive pointer to the current DMA pointer, if they + * do not match, then there are bytes to be received. + */ + + return (up_dma_nextrx(priv) != priv->rxdmanext); +} +#endif + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the USART + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + stm32l4_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); + } +#endif + + up_serialout(priv, STM32L4_USART_TDR_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +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_CR1_TXEIE; + + /* If RS-485 is supported on this U[S]ART, then also enable the + * transmission complete interrupt. + */ + +# ifdef HAVE_RS485 + if (priv->rs485_dir_gpio != 0) + { + ie |= USART_CR1_TCIE; + } +# endif + + up_restoreusartint(priv, ie); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + up_restoreusartint(priv, priv->ie & ~USART_CR1_TXEIE); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the transmit data register is empty + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + return ((up_serialin(priv, STM32L4_USART_ISR_OFFSET) & USART_ISR_TXE) != 0); +} + +/**************************************************************************** + * Name: up_interrupt_u[s]art[n] + * + * Description: + * Interrupt handlers for U[S]ART[n] where n=1,..,6. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32L4_USART1 +static int up_interrupt_usart1(int irq, void *context) +{ + return up_interrupt_common(&g_usart1priv); +} +#endif + +#ifdef CONFIG_STM32L4_USART2 +static int up_interrupt_usart2(int irq, void *context) +{ + return up_interrupt_common(&g_usart2priv); +} +#endif + +#ifdef CONFIG_STM32L4_USART3 +static int up_interrupt_usart3(int irq, void *context) +{ + return up_interrupt_common(&g_usart3priv); +} +#endif + +#ifdef CONFIG_STM32L4_UART4 +static int up_interrupt_uart4(int irq, void *context) +{ + return up_interrupt_common(&g_uart4priv); +} +#endif + +#ifdef CONFIG_STM32L4_UART5 +static int up_interrupt_uart5(int irq, void *context) +{ + return up_interrupt_common(&g_uart5priv); +} +#endif + +/**************************************************************************** + * Name: up_dma_rxcallback + * + * Description: + * This function checks the current DMA state and calls the generic + * serial stack when bytes appear to be available. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + struct up_dev_s *priv = (struct up_dev_s *)arg; + + if (priv->rxenable && up_dma_rxavailable(&priv->dev)) + { + uart_recvchars(&priv->dev); + +#ifdef CONFIG_SERIAL_IFLOWCONTROL + if (priv->iflow && priv->rxenable && + (priv->rxdmanext == RXDMA_BUFFER_SIZE)) + { + /* Re-enable RX DMA. */ + + up_dma_reenable(priv); + } +#endif + } +} +#endif + +/**************************************************************************** + * Name: up_pm_notify + * + * Description: + * Notify the driver of new power state. This callback is called after + * all drivers have had the opportunity to prepare for the new power state. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * None - The driver already agreed to transition to the low power + * consumption state when when it returned OK to the prepare() call. + * + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_pm_notify(struct pm_callback_s *cb, enum pm_state_e pmstate) +{ + switch (pmstate) + { + case(PM_NORMAL): + { + /* Logic for PM_NORMAL goes here */ + + } + break; + + case(PM_IDLE): + { + /* Logic for PM_IDLE goes here */ + + } + break; + + case(PM_STANDBY): + { + /* Logic for PM_STANDBY goes here */ + + } + break; + + case(PM_SLEEP): + { + /* Logic for PM_SLEEP goes here */ + + } + break; + + default: + /* Should not get here */ + break; + } +} +#endif + +/**************************************************************************** + * Name: up_pm_prepare + * + * Description: + * Request the driver to prepare for a new power state. This is a warning + * that the system is about to enter into a new power state. The driver + * should begin whatever operations that may be required to enter power + * state. The driver may abort the state change mode by returning a + * non-zero value from the callback function. + * + * Input Parameters: + * + * cb - Returned to the driver. The driver version of the callback + * structure may include additional, driver-specific state data at + * the end of the structure. + * + * pmstate - Identifies the new PM state + * + * Returned Value: + * Zero - (OK) means the event was successfully processed and that the + * driver is prepared for the PM state change. + * + * Non-zero - means that the driver is not prepared to perform the tasks + * needed achieve this power setting and will cause the state + * change to be aborted. NOTE: The prepare() method will also + * be called when reverting from lower back to higher power + * consumption modes (say because another driver refused a + * lower power state change). Drivers are not permitted to + * return non-zero values when reverting back to higher power + * consumption modes! + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static int up_pm_prepare(struct pm_callback_s *cb, enum pm_state_e pmstate) +{ + /* Logic to prepare for a reduced power state goes here. */ + + return OK; +} +#endif +#endif /* HAVE_UART */ +#endif /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_SERIALDRIVER + +/**************************************************************************** + * Name: up_earlyserialinit + * + * Description: + * Performs the low level USART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before up_serialinit. + * + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT +void up_earlyserialinit(void) +{ +#ifdef HAVE_UART + unsigned i; + + /* Disable all USART interrupts */ + + for (i = 0; i < STM32L4_NUSART; i++) + { + if (uart_devs[i]) + { + up_disableusartint(uart_devs[i], NULL); + } + } + + /* Configure whichever one is the console */ + +#if CONSOLE_UART > 0 + up_setup(&uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif /* HAVE UART */ +} +#endif + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void up_serialinit(void) +{ +#ifdef HAVE_UART + char devname[16]; + unsigned i; + unsigned minor = 0; +#ifdef CONFIG_PM + int ret; +#endif + + /* Register to receive power management callbacks */ + +#ifdef CONFIG_PM + ret = pm_register(&g_serialcb); + DEBUGASSERT(ret == OK); + UNUSED(ret); +#endif + + /* Register the console */ + +#if CONSOLE_UART > 0 + (void)uart_register("/dev/console", &uart_devs[CONSOLE_UART - 1]->dev); + +#ifndef CONFIG_SERIAL_DISABLE_REORDERING + /* If not disabled, register the console UART to ttyS0 and exclude + * it from initializing it further down + */ + + (void)uart_register("/dev/ttyS0", &uart_devs[CONSOLE_UART - 1]->dev); + minor = 1; +#endif + +#ifdef SERIAL_HAVE_CONSOLE_DMA + /* If we need to re-initialise the console to enable DMA do that here. */ + + up_dma_setup(&uart_devs[CONSOLE_UART - 1]->dev); +#endif +#endif /* CONSOLE_UART > 0 */ + + /* Register all remaining USARTs */ + + strcpy(devname, "/dev/ttySx"); + + for (i = 0; i < STM32L4_NUSART; i++) + { + /* Don't create a device for non-configured ports. */ + + if (uart_devs[i] == 0) + { + continue; + } + +#ifndef CONFIG_SERIAL_DISABLE_REORDERING + /* Don't create a device for the console - we did that above */ + + if (uart_devs[i]->dev.isconsole) + { + continue; + } +#endif + + /* Register USARTs as devices in increasing order */ + + devname[9] = '0' + minor++; + (void)uart_register(devname, &uart_devs[i]->dev); + } +#endif /* HAVE UART */ +} + +/**************************************************************************** + * Name: stm32l4_serial_dma_poll + * + * Description: + * Checks receive DMA buffers for received bytes that have not accumulated + * to the point where the DMA half/full interrupt has triggered. + * + * This function should be called from a timer or other periodic context. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32l4_serial_dma_poll(void) +{ + irqstate_t flags; + + flags = enter_critical_section(); + +#ifdef CONFIG_USART1_RXDMA + if (g_usart1priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart1priv.rxdma, 0, &g_usart1priv); + } +#endif + +#ifdef CONFIG_USART2_RXDMA + if (g_usart2priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart2priv.rxdma, 0, &g_usart2priv); + } +#endif + +#ifdef CONFIG_USART3_RXDMA + if (g_usart3priv.rxdma != NULL) + { + up_dma_rxcallback(g_usart3priv.rxdma, 0, &g_usart3priv); + } +#endif + +#ifdef CONFIG_UART4_RXDMA + if (g_uart4priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart4priv.rxdma, 0, &g_uart4priv); + } +#endif + +#ifdef CONFIG_UART5_RXDMA + if (g_uart5priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart5priv.rxdma, 0, &g_uart5priv); + } +#endif + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if CONSOLE_UART > 0 + struct up_dev_s *priv = uart_devs[CONSOLE_UART - 1]; + uint16_t ie; + + up_disableusartint(priv, &ie); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); + up_restoreusartint(priv, ie); +#endif + return ch; +} + +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#if CONSOLE_UART > 0 + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + up_lowputc('\r'); + } + + up_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/stm32l4/stm32l4_spi.c b/arch/arm/src/stm32l4/stm32l4_spi.c new file mode 100644 index 00000000000..d718d8cd560 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_spi.c @@ -0,0 +1,1495 @@ +/************************************************************************************ + * arm/arm/src/stm32l4/stm32l4_spi.c + * + * Copyright (C) 2009-2013, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ************************************************************************************/ + +/************************************************************************************ + * The external functions, stm32l4_spi1/2/3select and stm32l4_spi1/2/3status must be + * provided by board-specific logic. They are implementations of the select + * and status methods of the SPI interface defined by struct spi_ops_s (see + * include/nuttx/spi/spi.h). All other methods (including stm32l4_spibus_initialize()) + * are provided by common STM32 logic. To use this common SPI logic on your + * board: + * + * 1. Provide logic in stm32l4_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32l4_spi1/2/3select() and stm32l4_spi1/2/3status() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. Add a calls to stm32l4_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by stm32l4_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************c********************************/ + +/* + * This driver is ported from the stm32 one, which only supports 8 and 16 bits + * transfers. The STM32L4 family supports frame size from 4 to 16 bits, but we do not + * support that yet. For the moment, we replace uses of the CR1_DFF bit with a check + * of the CR2_DS[0..3] bits. If the value is SPI_CR2_DS_16BIT it means 16 bits, else 8 bits. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32l4.h" +#include "stm32l4_gpio.h" +#include "stm32l4_dma.h" +#include "stm32l4_spi.h" + +#if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || defined(CONFIG_STM32L4_SPI3) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* SPI interrupts */ + +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS +# error "Interrupt driven SPI not yet supported" +#endif + +/* Can't have both interrupt driven SPI and SPI DMA */ + +#if defined(CONFIG_STM32L4_SPI_INTERRUPTS) && defined(CONFIG_STM32L4_SPI_DMA) +# error "Cannot enable both interrupt mode and DMA mode for SPI" +#endif + +/* SPI DMA priority */ + +#ifdef CONFIG_STM32L4_SPI_DMA + +# if defined(CONFIG_SPI_DMAPRIO) +# define SPI_DMA_PRIO CONFIG_SPI_DMAPRIO +# else +# define SPI_DMA_PRIO DMA_CCR_PRIMED +# endif + +# if (SPI_DMA_PRIO & ~DMA_CCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SPI_DMAPRIO" +# endif + +#endif + +/* DMA channel configuration */ + +#define SPI_RXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC ) +#define SPI_RXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC ) +#define SPI_RXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS ) +#define SPI_RXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS ) +#define SPI_TXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC|DMA_CCR_DIR) +#define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC|DMA_CCR_DIR) +#define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS |DMA_CCR_DIR) +#define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_DIR) + + +/* Debug ****************************************************************************/ +/* Check if (non-standard) SPI debug is enabled */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# undef CONFIG_DEBUG_SPI +#endif + +#ifdef CONFIG_DEBUG_SPI +# define spidbg lldbg +# ifdef CONFIG_DEBUG_VERBOSE +# define spivdbg lldbg +# else +# define spivdbg(x...) +# endif +#else +# define spidbg(x...) +# define spivdbg(x...) +#endif + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +struct stm32l4_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t spibase; /* SPIn base address */ + uint32_t spiclock; /* Clocking for the SPI module */ +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS + uint8_t spiirq; /* SPI IRQ number */ +#endif +#ifdef CONFIG_STM32L4_SPI_DMA + volatile uint8_t rxresult; /* Result of the RX DMA */ + volatile uint8_t txresult; /* Result of the RX DMA */ + uint8_t rxch; /* The RX DMA channel number */ + uint8_t txch; /* The TX DMA channel number */ + DMA_HANDLE rxdma; /* DMA channel handle for RX transfers */ + DMA_HANDLE txdma; /* DMA channel handle for TX transfers */ + sem_t rxsem; /* Wait for RX DMA to complete */ + sem_t txsem; /* Wait for TX DMA to complete */ + uint32_t txccr; /* DMA control register for TX transfers */ + uint32_t rxccr; /* DMA control register for RX transfers */ +#endif + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + int8_t nbits; /* Width of word in bits (8 or 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +/************************************************************************************ + * Private Function Prototypes + ************************************************************************************/ + +/* Helpers */ + +static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset); +static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset, + uint16_t value); +static inline uint16_t spi_readword(FAR struct stm32l4_spidev_s *priv); +static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t byte); +static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv); + +/* DMA support */ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv); +static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv); +static inline void spi_dmarxwakeup(FAR struct stm32l4_spidev_s *priv); +static inline void spi_dmatxwakeup(FAR struct stm32l4_spidev_s *priv); +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg); +static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg); +static void spi_dmarxsetup(FAR struct stm32l4_spidev_s *priv, + FAR void *rxbuffer, FAR void *rxdummy, size_t nwords); +static void spi_dmatxsetup(FAR struct stm32l4_spidev_s *priv, + FAR const void *txbuffer, FAR const void *txdummy, size_t nwords); +static inline void spi_dmarxstart(FAR struct stm32l4_spidev_s *priv); +static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv); +#endif + +/* SPI methods */ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd); +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + size_t nwords); +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, + size_t nwords); +#endif + +/* Initialization */ + +static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv); + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI1 +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = stm32l4_spi1select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = 0, /* Not supported */ +#endif + .status = stm32l4_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32l4_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32l4_spi1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct stm32l4_spidev_s g_spi1dev = +{ + .spidev = { &g_spi1ops }, + .spibase = STM32L4_SPI1_BASE, + .spiclock = STM32L4_PCLK2_FREQUENCY, +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS + .spiirq = STM32L4_IRQ_SPI1, +#endif +#ifdef CONFIG_STM32L4_SPI_DMA + /* lines must be configured in board.h */ + .rxch = DMACHAN_SPI1_RX, + .txch = DMACHAN_SPI1_TX, +#endif +}; +#endif + +#ifdef CONFIG_STM32L4_SPI2 +static const struct spi_ops_s g_spi2ops = +{ + .lock = spi_lock, + .select = stm32l4_spi2select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = stm32l4_spi2status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32l4_spi2cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32l4_spi2register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32l4_spidev_s g_spi2dev = +{ + .spidev = { &g_spi2ops }, + .spibase = STM32L4_SPI2_BASE, + .spiclock = STM32L4_PCLK1_FREQUENCY, +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS + .spiirq = STM32L4_IRQ_SPI2, +#endif +#ifdef CONFIG_STM32L4_SPI_DMA + .rxch = DMACHAN_SPI2_RX, + .txch = DMACHAN_SPI2_TX, +#endif +}; +#endif + +#ifdef CONFIG_STM32L4_SPI3 +static const struct spi_ops_s g_spi3ops = +{ + .lock = spi_lock, + .select = stm32l4_spi3select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, + .status = stm32l4_spi3status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32l4_spi3cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32l4_spi3register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32l4_spidev_s g_spi3dev = +{ + .spidev = { &g_spi3ops }, + .spibase = STM32L4_SPI3_BASE, + .spiclock = STM32L4_PCLK1_FREQUENCY, +#ifdef CONFIG_STM32L4_SPI_INTERRUPTS + .spiirq = STM32L4_IRQ_SPI3, +#endif +#ifdef CONFIG_STM32L4_SPI_DMA + .rxch = DMACHAN_SPI3_RX, + .txch = DMACHAN_SPI3_TX, +#endif +}; +#endif + +/*endif?*/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: spi_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 16-bit register + * + ************************************************************************************/ + +static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset) +{ + return getreg16(priv->spibase + offset); +} + +/************************************************************************************ + * Name: spi_putreg + * + * Description: + * Write a 16-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + * Returned Value: + * The contents of the 16-bit register + * + ************************************************************************************/ + +static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset, uint16_t value) +{ + putreg16(value, priv->spibase + offset); +} + +/************************************************************************************ + * Name: spi_readword + * + * Description: + * Read one byte from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Byte as read + * + ************************************************************************************/ + +static inline uint16_t spi_readword(FAR struct stm32l4_spidev_s *priv) +{ + /* Wait until the receive buffer is not empty */ + + while ((spi_getreg(priv, STM32L4_SPI_SR_OFFSET) & SPI_SR_RXNE) == 0); + + /* Then return the received byte */ + + return spi_getreg(priv, STM32L4_SPI_DR_OFFSET); +} + +/************************************************************************************ + * Name: spi_writeword + * + * Description: + * Write one byte to SPI + * + * Input Parameters: + * priv - Device-specific state data + * byte - Byte to send + * + * Returned Value: + * None + * + ************************************************************************************/ + +static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t word) +{ + /* Wait until the transmit buffer is empty */ + + while ((spi_getreg(priv, STM32L4_SPI_SR_OFFSET) & SPI_SR_TXE) == 0); + + /* Then send the byte */ + + spi_putreg(priv, STM32L4_SPI_DR_OFFSET, word); +} + +/************************************************************************************ + * Name: spi_16bitmode + * + * Description: + * Check if the SPI is operating in 16-bit mode + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * true: 16-bit mode, false: 8-bit mode + * + ************************************************************************************/ + +static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv) +{ + return ((spi_getreg(priv, STM32L4_SPI_CR2_OFFSET) & SPI_CR2_DS_MASK) == SPI_CR2_DS_16BIT); +} + +/************************************************************************************ + * Name: spi_dmarxwaitw + * + * Description: + * Wait for DMA to complete. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv) +{ + /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA + * must not really have completed??? + */ + + while (sem_wait(&priv->rxsem) != 0 || priv->rxresult == 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} +#endif + +/************************************************************************************ + * Name: spi_dmatxwait + * + * Description: + * Wait for DMA to complete. + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv) +{ + /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA + * must not really have completed??? + */ + + while (sem_wait(&priv->txsem) != 0 || priv->txresult == 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} +#endif + +/************************************************************************************ + * Name: spi_dmarxwakeup + * + * Description: + * Signal that DMA is complete + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static inline void spi_dmarxwakeup(FAR struct stm32l4_spidev_s *priv) +{ + (void)sem_post(&priv->rxsem); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxwakeup + * + * Description: + * Signal that DMA is complete + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static inline void spi_dmatxwakeup(FAR struct stm32l4_spidev_s *priv) +{ + (void)sem_post(&priv->txsem); +} +#endif + +/************************************************************************************ + * Name: spi_dmarxcallback + * + * Description: + * Called when the RX DMA completes + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)arg; + + /* Wake-up the SPI driver */ + + priv->rxresult = isr | 0x080; /* OR'ed with 0x80 to assure non-zero */ + spi_dmarxwakeup(priv); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxcallback + * + * Description: + * Called when the RX DMA completes + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)arg; + + /* Wake-up the SPI driver */ + + priv->txresult = isr | 0x080; /* OR'ed with 0x80 to assure non-zero */ + spi_dmatxwakeup(priv); +} +#endif + +/************************************************************************************ + * Name: spi_dmarxsetup + * + * Description: + * Setup to perform RX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmarxsetup(FAR struct stm32l4_spidev_s *priv, FAR void *rxbuffer, + FAR void *rxdummy, size_t nwords) +{ + /* 8- or 16-bit mode? */ + + if (spi_16bitmode(priv)) + { + /* 16-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + priv->rxccr = SPI_RXDMA16_CONFIG; + } + else + { + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA16NULL_CONFIG; + } + } + else + { + /* 8-bit mode -- is there a buffer to receive data in? */ + + if (rxbuffer) + { + priv->rxccr = SPI_RXDMA8_CONFIG; + } + else + { + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA8NULL_CONFIG; + } + } + + /* Configure the RX DMA */ + + stm32l4_dmasetup(priv->rxdma, priv->spibase + STM32L4_SPI_DR_OFFSET, + (uint32_t)rxbuffer, nwords, priv->rxccr); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxsetup + * + * Description: + * Setup to perform TX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_dmatxsetup(FAR struct stm32l4_spidev_s *priv, FAR const void *txbuffer, + FAR const void *txdummy, size_t nwords) +{ + /* 8- or 16-bit mode? */ + + if (spi_16bitmode(priv)) + { + /* 16-bit mode -- is there a buffer to transfer data from? */ + + if (txbuffer) + { + priv->txccr = SPI_TXDMA16_CONFIG; + } + else + { + txbuffer = txdummy; + priv->txccr = SPI_TXDMA16NULL_CONFIG; + } + } + else + { + /* 8-bit mode -- is there a buffer to transfer data from? */ + + if (txbuffer) + { + priv->txccr = SPI_TXDMA8_CONFIG; + } + else + { + txbuffer = txdummy; + priv->txccr = SPI_TXDMA8NULL_CONFIG; + } + } + + /* Setup the TX DMA */ + + stm32l4_dmasetup(priv->txdma, priv->spibase + STM32L4_SPI_DR_OFFSET, + (uint32_t)txbuffer, nwords, priv->txccr); +} +#endif + +/************************************************************************************ + * Name: spi_dmarxstart + * + * Description: + * Start RX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static inline void spi_dmarxstart(FAR struct stm32l4_spidev_s *priv) +{ + priv->rxresult = 0; + stm32l4_dmastart(priv->rxdma, spi_dmarxcallback, priv, false); +} +#endif + +/************************************************************************************ + * Name: spi_dmatxstart + * + * Description: + * Start TX DMA + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv) +{ + priv->txresult = 0; + stm32l4_dmastart(priv->txdma, spi_dmatxcallback, priv, false); +} +#endif + +/************************************************************************************ + * Name: spi_modifycr + * + * Description: + * Clear and set bits in the CR1 or CR2 register + * + * Input Parameters: + * priv - Device-specific state data + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_modifycr(uint32_t addr, FAR struct stm32l4_spidev_s *priv, uint16_t setbits, uint16_t clrbits) +{ + uint16_t cr1; + cr1 = spi_getreg(priv, addr); + cr1 &= ~clrbits; + cr1 |= setbits; + spi_putreg(priv, addr, cr1); +} + +/************************************************************************************ + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ************************************************************************************/ + +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; +} + +/************************************************************************************ + * Name: spi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + uint16_t setbits; + uint32_t actual; + + /* Limit to max possible (if STM32L4_SPI_CLK_MAX is defined in board.h) */ + + if (frequency > STM32L4_SPI_CLK_MAX) + { + frequency = STM32L4_SPI_CLK_MAX; + } + + /* Has the frequency changed? */ + + if (frequency != priv->frequency) + { + /* Choices are limited by PCLK frequency with a set of divisors */ + + if (frequency >= priv->spiclock >> 1) + { + /* More than fPCLK/2. This is as fast as we can go */ + + setbits = SPI_CR1_FPCLCKd2; /* 000: fPCLK/2 */ + actual = priv->spiclock >> 1; + } + else if (frequency >= priv->spiclock >> 2) + { + /* Between fPCLCK/2 and fPCLCK/4, pick the slower */ + + setbits = SPI_CR1_FPCLCKd4; /* 001: fPCLK/4 */ + actual = priv->spiclock >> 2; + } + else if (frequency >= priv->spiclock >> 3) + { + /* Between fPCLCK/4 and fPCLCK/8, pick the slower */ + + setbits = SPI_CR1_FPCLCKd8; /* 010: fPCLK/8 */ + actual = priv->spiclock >> 3; + } + else if (frequency >= priv->spiclock >> 4) + { + /* Between fPCLCK/8 and fPCLCK/16, pick the slower */ + + setbits = SPI_CR1_FPCLCKd16; /* 011: fPCLK/16 */ + actual = priv->spiclock >> 4; + } + else if (frequency >= priv->spiclock >> 5) + { + /* Between fPCLCK/16 and fPCLCK/32, pick the slower */ + + setbits = SPI_CR1_FPCLCKd32; /* 100: fPCLK/32 */ + actual = priv->spiclock >> 5; + } + else if (frequency >= priv->spiclock >> 6) + { + /* Between fPCLCK/32 and fPCLCK/64, pick the slower */ + + setbits = SPI_CR1_FPCLCKd64; /* 101: fPCLK/64 */ + actual = priv->spiclock >> 6; + } + else if (frequency >= priv->spiclock >> 7) + { + /* Between fPCLCK/64 and fPCLCK/128, pick the slower */ + + setbits = SPI_CR1_FPCLCKd128; /* 110: fPCLK/128 */ + actual = priv->spiclock >> 7; + } + else + { + /* Less than fPCLK/128. This is as slow as we can go */ + + setbits = SPI_CR1_FPCLCKd256; /* 111: fPCLK/256 */ + actual = priv->spiclock >> 8; + } + + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, SPI_CR1_BR_MASK); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0); + + /* Save the frequency selection so that subsequent reconfigurations will be + * faster. + */ + + spivdbg("Frequency %d->%d\n", frequency, actual); + + priv->frequency = frequency; + priv->actual = actual; + } + + return priv->actual; +} + +/************************************************************************************ + * Name: spi_setmode + * + * Description: + * Set the SPI mode. see enum spi_mode_e for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * Returns the actual frequency selected + * + ************************************************************************************/ + +static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + uint16_t setbits; + uint16_t clrbits; + + spivdbg("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Yes... Set CR1 appropriately */ + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + setbits = 0; + clrbits = SPI_CR1_CPOL | SPI_CR1_CPHA; + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + setbits = SPI_CR1_CPHA; + clrbits = SPI_CR1_CPOL; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + setbits = SPI_CR1_CPOL; + clrbits = SPI_CR1_CPHA; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + setbits = SPI_CR1_CPOL | SPI_CR1_CPHA; + clrbits = 0; + break; + + default: + return; + } + + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, clrbits); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0); + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + } +} + +/************************************************************************************ + * Name: spi_setbits + * + * Description: + * Set the number of bits per word. With STM32L4, this is not restricted to 8 or 16, + * but can be any value between 4 and 16. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requested, negative value means LSB first. + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + uint16_t setbits1, setbits2; + uint16_t clrbits1, clrbits2; + + spivdbg("nbits=%d\n", nbits); + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + + /* Yes... Set CR1/2 appropriately */ + + /* negative sign means LSBFIRST, set this in CR1*/ + if(nbits<0) + { + setbits1 = SPI_CR1_LSBFIRST; + clrbits1 = 0; + nbits = -nbits; + } + else + { + setbits1 = 0; + clrbits1 = SPI_CR1_LSBFIRST; + } + + /* set the number of bits (valid range 4-16) */ + if(nbits<4 || nbits>16) + { + return; + } + + clrbits2 = SPI_CR2_DS_MASK; + setbits2 = SPI_CR2_DS_VAL(nbits); + + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits1, clrbits1); + spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits2, clrbits2); + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0); + + /* Save the selection so the subsequence re-configurations will be faster */ + + priv->nbits = nbits; + } +} + +/************************************************************************************ + * Name: spi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ************************************************************************************/ + +static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + uint32_t regval; + uint16_t ret; + + DEBUGASSERT(priv && priv->spibase); + + spi_writeword(priv, wd); + ret = spi_readword(priv); + + /* Check and clear any error flags (Reading from the SR clears the error flags) */ + + regval = spi_getreg(priv, STM32L4_SPI_SR_OFFSET); + + spivdbg("Sent: %04x Return: %04x Status: %02x\n", wd, ret, regval); + UNUSED(regval); + + return ret; +} + +/************************************************************************************ + * Name: spi_exchange (no DMA). aka spi_exchange_nodma + * + * Description: + * Exchange a block of data on SPI without using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchaned in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if !defined(CONFIG_STM32L4_SPI_DMA) || defined(CONFIG_STM32L4_DMACAPABLE) +#if !defined(CONFIG_STM32L4_SPI_DMA) +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +#else +static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +#endif +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + DEBUGASSERT(priv && priv->spibase); + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* 8- or 16-bit mode? */ + + if (spi_16bitmode(priv)) + { + /* 16-bit mode */ + + const uint16_t *src = (const uint16_t *)txbuffer; + uint16_t *dest = (uint16_t *)rxbuffer; + uint16_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xffff; + } + + /* Exchange one word */ + + word = spi_send(dev, word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } + else + { + /* 8-bit mode */ + + const uint8_t *src = (const uint8_t *)txbuffer; + uint8_t *dest = (uint8_t *)rxbuffer; + uint8_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xff; + } + + /* Exchange one word */ + + word = (uint8_t)spi_send(dev, (uint16_t)word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } +} +#endif /* !CONFIG_STM32L4_SPI_DMA || CONFIG_STM32L4_DMACAPABLE */ + +/**************************************************************************** + * Name: spi_exchange (with DMA capability) + * + * Description: + * Exchange a block of data on SPI using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI_DMA +static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +{ + FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; + +#ifdef CONFIG_STM32L4_DMACAPABLE + if ((txbuffer && !stm32l4_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) || + (rxbuffer && !stm32l4_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr))) + { + /* Unsupported memory region, fall back to non-DMA method. */ + + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + } + else +#endif + { + static uint16_t rxdummy = 0xffff; + static const uint16_t txdummy = 0xffff; + + spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + DEBUGASSERT(priv && priv->spibase); + + /* Setup DMAs */ + + spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords); + spi_dmatxsetup(priv, txbuffer, &txdummy, nwords); + + /* Start the DMAs */ + + spi_dmarxstart(priv); + spi_dmatxstart(priv); + + /* Then wait for each to complete */ + + spi_dmarxwait(priv); + spi_dmatxwait(priv); + } +} +#endif /* CONFIG_STM32L4_SPI_DMA */ + +/**************************************************************************** + * Name: spi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, size_t nwords) +{ + spivdbg("txbuffer=%p nwords=%d\n", txbuffer, nwords); + return spi_exchange(dev, txbuffer, NULL, nwords); +} +#endif + +/************************************************************************************ + * Name: spi_recvblock + * + * Description: + * Receive a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to recieve data + * nwords - the length of data that can be received in the buffer in number + * of words. The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t nwords) +{ + spivdbg("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + return spi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/************************************************************************************ + * Name: spi_bus_initialize + * + * Description: + * Initialize the selected SPI bus in its default state (Master, 8-bit, mode 0, etc.) + * + * Input Parameter: + * priv - private SPI device structure + * + * Returned Value: + * None + * + ************************************************************************************/ + +static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv) +{ + uint16_t setbits; + uint16_t clrbits; + + /* Configure CR1 and CR2. Default configuration: + * Mode 0: CR1.CPHA=0 and CR1.CPOL=0 + * Master: CR1.MSTR=1 + * 8-bit: CR2.DS=7 + * MSB tranmitted first: CR1.LSBFIRST=0 + * Replace NSS with SSI & SSI=1: CR1.SSI=1 CR1.SSM=1 (prevents MODF error) + * Two lines full duplex: CR1.BIDIMODE=0 CR1.BIDIOIE=(Don't care) and CR1.RXONLY=0 + */ + + clrbits = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_MASK | SPI_CR1_LSBFIRST | + SPI_CR1_RXONLY | SPI_CR1_BIDIOE | SPI_CR1_BIDIMODE; + setbits = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM; + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, clrbits); + + clrbits = SPI_CR2_DS_MASK; + setbits = SPI_CR2_DS_8BIT; + spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits, clrbits); + + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; + + /* Select a default frequency of approx. 400KHz */ + + spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* CRCPOLY configuration */ + + spi_putreg(priv, STM32L4_SPI_CRCPR_OFFSET, 7); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + sem_init(&priv->exclsem, 0, 1); + +#ifdef CONFIG_STM32L4_SPI_DMA + /* Initialize the SPI semaphores that is used to wait for DMA completion */ + + sem_init(&priv->rxsem, 0, 0); + sem_init(&priv->txsem, 0, 0); + + /* Get DMA channels. NOTE: stm32l4_dmachannel() will always assign the DMA channel. + * if the channel is not available, then stm32l4_dmachannel() will block and wait + * until the channel becomes available. WARNING: If you have another device sharing + * a DMA channel with SPI and the code never releases that channel, then the call + * to stm32l4_dmachannel() will hang forever in this function! Don't let your + * design do that! + */ + + priv->rxdma = stm32l4_dmachannel(priv->rxch); + priv->txdma = stm32l4_dmachannel(priv->txch); + DEBUGASSERT(priv->rxdma && priv->txdma); + + spi_putreg(priv, STM32L4_SPI_CR2_OFFSET, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); +#endif + + /* Enable spi */ + + spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0); +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_spibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameter: + * Port number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *stm32l4_spibus_initialize(int bus) +{ + FAR struct stm32l4_spidev_s *priv = NULL; + + irqstate_t flags = enter_critical_section(); + +#ifdef CONFIG_STM32L4_SPI1 + if (bus == 1) + { + /* Select SPI1 */ + + priv = &g_spi1dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32L4_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI1 pins: SCK, MISO, and MOSI */ + + stm32l4_configgpio(GPIO_SPI1_SCK); + stm32l4_configgpio(GPIO_SPI1_MISO); + stm32l4_configgpio(GPIO_SPI1_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_STM32L4_SPI2 + if (bus == 2) + { + /* Select SPI2 */ + + priv = &g_spi2dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32L4_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI2 pins: SCK, MISO, and MOSI */ + + stm32l4_configgpio(GPIO_SPI2_SCK); + stm32l4_configgpio(GPIO_SPI2_MISO); + stm32l4_configgpio(GPIO_SPI2_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_STM32L4_SPI3 + if (bus == 3) + { + /* Select SPI3 */ + + priv = &g_spi3dev; + + /* Only configure if the bus is not already configured */ + + if ((spi_getreg(priv, STM32L4_SPI_CR1_OFFSET) & SPI_CR1_SPE) == 0) + { + /* Configure SPI3 pins: SCK, MISO, and MOSI */ + + stm32l4_configgpio(GPIO_SPI3_SCK); + stm32l4_configgpio(GPIO_SPI3_MISO); + stm32l4_configgpio(GPIO_SPI3_MOSI); + + /* Set up default configuration: Master, 8-bit, etc. */ + + spi_bus_initialize(priv); + } + } + else +#endif + { + spidbg("ERROR: Unsupbused SPI bus: %d\n", bus); + return NULL; + } + + leave_critical_section(flags); + return (FAR struct spi_dev_s *)priv; +} + +#endif /* CONFIG_STM32L4_SPI1 || CONFIG_STM32L4_SPI2 || CONFIG_STM32L4_SPI3 */ + diff --git a/arch/arm/src/stm32l4/stm32l4_spi.h b/arch/arm/src/stm32l4/stm32l4_spi.h new file mode 100644 index 00000000000..242a81f184b --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_spi.h @@ -0,0 +1,181 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_spi.h + * + * Copyright (C) 2009, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STM32L4_STM32L4_SPI_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_SPI_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" +#include "chip/stm32l4_spi.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +struct spi_dev_s; +enum spi_dev_e; + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_spibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameter: + * bus number (for hardware that has mutiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on succcess; a NULL on failure + * + ************************************************************************************/ + +FAR struct spi_dev_s *stm32l4_spibus_initialize(int bus); + +/************************************************************************************ + * Name: stm32l4_spi1/2/...select and stm32l4_spi1/2/...status + * + * Description: + * The external functions, stm32l4_spi1/2/...select, stm32l4_spi1/2/...status, and + * stm32l4_spi1/2/...cmddata must be provided by board-specific logic. These are + * implementations of the select, status, and cmddata methods of the SPI interface + * defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods + * (including stm32l4_spibus_initialize()) are provided by common STM32 logic. To use this + * common SPI logic on your board: + * + * 1. Provide logic in stm32l4_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32l4_spi1/2/...select() and stm32l4_spi1/2/...status() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file, then + * provide stm32l4_spi1/2/...cmddata() functions in your board-specific logic. + * These functions will perform cmd/data selection operations using GPIOs in the + * way your board is configured. + * 4. Add a calls to stm32l4_spibus_initialize() in your low level application + * initialization logic + * 5. The handle returned by stm32l4_spibus_initialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ************************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI1 +void stm32l4_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32l4_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32l4_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef CONFIG_STM32L4_SPI2 +void stm32l4_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32l4_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32l4_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +#ifdef CONFIG_STM32L4_SPI3 +void stm32l4_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); +uint8_t stm32l4_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); +int stm32l4_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); +#endif + +/************************************************************************************ + * Name: stm32l4_spi1/2/...register + * + * Description: + * If the board supports a card detect callback to inform the SPI-based MMC/SD + * driver when an SD card is inserted or removed, then CONFIG_SPI_CALLBACK should + * be defined and the following function(s) must be implemented. These functions + * implements the registercallback method of the SPI interface (see + * include/nuttx/spi/spi.h for details) + * + * Input Parameters: + * dev - Device-specific state data + * callback - The function to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CALLBACK +#ifdef CONFIG_STM32L4_SPI1 +int stm32l4_spi1register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32L4_SPI2 +int stm32l4_spi2register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif + +#ifdef CONFIG_STM32L4_SPI3 +int stm32l4_spi3register(FAR struct spi_dev_s *dev, spi_mediachange_t callback, + FAR void *arg); +#endif +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_SPI_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_start.c b/arch/arm/src/stm32l4/stm32l4_start.c new file mode 100644 index 00000000000..ee1f894d8d3 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_start.c @@ -0,0 +1,363 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_start.c + * arch/arm/src/chip/stm32l4_start.c + * + * Copyright (C) 2009, 2011-2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "stm32l4.h" +#include "stm32l4_gpio.h" +#include "stm32l4_userspace.h" + +#ifdef CONFIG_ARCH_FPU +# include "nvic.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Memory Map ***************************************************************/ +/* + * 0x0800:0000 - Beginning of the internal FLASH. Address of vectors. + * Mapped as boot memory address 0x0000:0000 at reset. + * 0x080f:ffff - End of flash region (assuming the max of 2MiB of FLASH). + * 0x1000:0000 - Start of internal SRAM2 + * 0x1000:7fff - End of internal SRAM2 + * 0x2000:0000 - Start of internal SRAM and start of .data (_sdata) + * - End of .data (_edata) and start of .bss (_sbss) + * - End of .bss (_ebss) and bottom of idle stack + * - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack, + * start of heap. NOTE that the ARM uses a decrement before + * store stack so that the correct initial value is the end of + * the stack + 4; + * 0x2001:7fff - End of internal SRAM and end of heap + */ + +#define IDLE_STACK ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4) +#define HEAP_BASE ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ + +const uintptr_t g_idle_topstack = HEAP_BASE; + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +static inline void stm32l4_fpuconfig(void); +#endif +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) + __attribute__ ((naked, no_instrument_function, noreturn)); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the UART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +# define showprogress(c) up_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_STACKCHECK +/* we need to get r10 set before we can allow instrumentation calls */ + +void __start(void) __attribute__ ((no_instrument_function)); +#endif + +/**************************************************************************** + * Name: stm32l4_fpuconfig + * + * Description: + * Configure the FPU. Relative bit settings: + * + * CPACR: Enables access to CP10 and CP11 + * CONTROL.FPCA: Determines whether the FP extension is active in the + * current context: + * FPCCR.ASPEN: Enables automatic FP state preservation, then the + * processor sets this bit to 1 on successful completion of any FP + * instruction. + * FPCCR.LSPEN: Enables lazy context save of FP state. When this is + * done, the processor reserves space on the stack for the FP state, + * but does not save that state information to the stack. + * + * Software must not change the value of the ASPEN bit or LSPEN bit while either: + * - the CPACR permits access to CP10 and CP11, that give access to the FP + * extension, or + * - the CONTROL.FPCA bit is set to 1 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +#if defined(CONFIG_ARMV7M_CMNVECTOR) && !defined(CONFIG_ARMV7M_LAZYFPU) + +static inline void stm32l4_fpuconfig(void) +{ + uint32_t regval; + + /* Set CONTROL.FPCA so that we always get the extended context frame + * with the volatile FP registers stacked above the basic context. + */ + + regval = getcontrol(); + regval |= (1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to turn on CONTROL.FPCA for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#else + +static inline void stm32l4_fpuconfig(void) +{ + uint32_t regval; + + /* Clear CONTROL.FPCA so that we do not get the extended context frame + * with the volatile FP registers stacked in the saved context. + */ + + regval = getcontrol(); + regval &= ~(1 << 2); + setcontrol(regval); + + /* Ensure that FPCCR.LSPEN is disabled, so that we don't have to contend + * with the lazy FP context save behaviour. Clear FPCCR.ASPEN since we + * are going to keep CONTROL.FPCA off for all contexts. + */ + + regval = getreg32(NVIC_FPCCR); + regval &= ~((1 << 31) | (1 << 30)); + putreg32(regval, NVIC_FPCCR); + + /* Enable full access to CP10 and CP11 */ + + regval = getreg32(NVIC_CPACR); + regval |= ((3 << (2*10)) | (3 << (2*11))); + putreg32(regval, NVIC_CPACR); +} + +#endif + +#else +# define stm32l4_fpuconfig() +#endif + +/**************************************************************************** + * Name: go_os_start + * + * Description: + * Set the IDLE stack to the + * + ****************************************************************************/ + +#ifdef CONFIG_STACK_COLORATION +static void go_os_start(void *pv, unsigned int nbytes) +{ + /* Set the IDLE stack to the stack coloration value then jump to + * os_start(). We take extreme care here because were currently + * executing on this stack. + * + * We want to avoid sneak stack access generated by the compiler. + */ + + __asm__ __volatile__ + ( + "\tmovs r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */ + "\tbeq 2f\n" /* (should not happen) */ + + "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */ + "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */ + "\tmovt r2, #0xdead\n" + + "1:\n" /* Top of the loop */ + "\tsub r1, r1, #1\n" /* R1 nwords-- */ + "\tcmp r1, #0\n" /* Check (nwords == 0) */ + "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */ + "\tbne 1b\n" /* Bottom of the loop */ + + "2:\n" + "\tmov r14, #0\n" /* LR = return address (none) */ + "\tb os_start\n" /* Branch to os_start */ + ); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +void __start(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 + + /* Configure the UART so that we can get debug output as soon as possible */ + + stm32l4_clockconfig(); + stm32l4_fpuconfig(); + stm32l4_lowsetup(); + stm32l4_gpioinit(); + showprogress('A'); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + showprogress('C'); + + /* Perform early serial initialization */ + +#ifdef USE_EARLYSERIALINIT + up_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 + stm32l4_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + stm32l4_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); + +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into os_start() */ + + go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); +#else + /* Call os_start() */ + + os_start(); + + /* Shoulnd't get here */ + + for (; ; ); +#endif +} diff --git a/arch/arm/src/stm32l4/stm32l4_tim.h b/arch/arm/src/stm32l4/stm32l4_tim.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_timerisr.c b/arch/arm/src/stm32l4/stm32l4_timerisr.c new file mode 100644 index 00000000000..ee02fc01fa6 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_timerisr.c @@ -0,0 +1,166 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_timerisr.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32l4.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The RCC feeds the Cortex System Timer (SysTick) with the AHB clock (HCLK) + * divided by 8. The SysTick can work either with this clock or with the + * Cortex clock (HCLK), configurable in the SysTick Control and Status + * register. + */ + +#undef CONFIG_STM32L4_SYSTICK_HCLKd8 /* Power up default is HCLK, not HCLK/8 */ + /* And I don't know now to re-configure it yet */ + +#ifdef CONFIG_STM32L4_SYSTICK_HCLKd8 +# define SYSTICK_RELOAD ((STM32L4_HCLK_FREQUENCY / 8 / CLK_TCK) - 1) +#else +# define SYSTICK_RELOAD ((STM32L4_HCLK_FREQUENCY / CLK_TCK) - 1) +#endif + +/* The size of the reload field is 24 bits. Verify that the reload value + * will fit in the reload register. + */ + +#if SYSTICK_RELOAD > 0x00ffffff +# error SYSTICK_RELOAD exceeds the range of the RELOAD register +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, uint32_t *regs) +{ + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + + /* Set the SysTick interrupt to the default priority */ + + regval = getreg32(NVIC_SYSH12_15_PRIORITY); + regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK; + regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT); + putreg32(regval, NVIC_SYSH12_15_PRIORITY); + + /* Make sure that the SYSTICK clock source is set correctly */ + +#if 0 /* Does not work. Comes up with HCLK source and I can't change it */ + regval = getreg32(NVIC_SYSTICK_CTRL); +#ifdef CONFIG_STM32L4_SYSTICK_HCLKd8 + regval &= ~NVIC_SYSTICK_CTRL_CLKSOURCE; +#else + regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; +#endif + putreg32(regval, NVIC_SYSTICK_CTRL); +#endif + + /* Configure SysTick to interrupt at the requested rate */ + + putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(STM32L4_IRQ_SYSTICK, (xcpt_t)up_timerisr); + + /* Enable SysTick interrupts */ + + putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT | + NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL); + + /* And enable the timer interrupt */ + + up_enable_irq(STM32L4_IRQ_SYSTICK); +} + diff --git a/arch/arm/src/stm32l4/stm32l4_uart.h b/arch/arm/src/stm32l4/stm32l4_uart.h new file mode 100644 index 00000000000..24fc9bd3136 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_uart.h @@ -0,0 +1,263 @@ +/************************************************************************************ + * arch/arm/src/stm32l4/stm32l4_uart.h + * + * Copyright (C) 2009, 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_STC_STM32L4_STM32L4_UART_H +#define __ARCH_ARM_STC_STM32L4_STM32L4_UART_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) +# include "chip/stm32l4x6xx_uart.h" +#else +# error "Unsupported STM32L4 chip" +#endif + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Make sure that we have not enabled more U[S]ARTs than are supported by the + * device. + */ + +#if STM32L4_NUSART < 5 || !defined(CONFIG_STM32L4_HAVE_UART5) +# undef CONFIG_STM32L4_UART5 +#endif +#if STM32L4_NUSART < 4 || !defined(CONFIG_STM32L4_HAVE_UART4) +# undef CONFIG_STM32L4_UART4 +#endif +#if STM32L4_NUSART < 3 || !defined(CONFIG_STM32L4_HAVE_USART3) +# undef CONFIG_STM32L4_USART3 +#endif +#if STM32L4_NUSART < 2 +# undef CONFIG_STM32L4_USART2 +#endif +#if STM32L4_NUSART < 1 +# undef CONFIG_STM32L4_USART1 +#endif + +/* Is there a USART enabled? */ + +#if defined(CONFIG_STM32L4_USART1) || defined(CONFIG_STM32L4_USART2) || \ + defined(CONFIG_STM32L4_USART3) || defined(CONFIG_STM32L4_UART4) || \ + defined(CONFIG_STM32L4_UART5) +# define HAVE_UART 1 +#endif + +/* Is there a serial console? */ + +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART1) +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 1 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART2) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 2 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART3) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 3 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_UART4) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 4 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_UART5) +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# define CONSOLE_UART 5 +# define HAVE_CONSOLE 1 +#else +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# define CONSOLE_UART 0 +# undef HAVE_CONSOLE +#endif + +/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX configuration */ + +#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) +# undef CONFIG_USART1_RXDMA +# undef CONFIG_USART2_RXDMA +# undef CONFIG_USART3_RXDMA +# undef CONFIG_UART4_RXDMA +# undef CONFIG_UART5_RXDMA +#endif + +/* Disable the DMA configuration on all unused USARTs */ + +#ifndef CONFIG_STM32L4_USART1 +# undef CONFIG_USART1_RXDMA +#endif + +#ifndef CONFIG_STM32L4_USART2 +# undef CONFIG_USART2_RXDMA +#endif + +#ifndef CONFIG_STM32L4_USART3 +# undef CONFIG_USART3_RXDMA +#endif + +#ifndef CONFIG_STM32L4_UART4 +# undef CONFIG_UART4_RXDMA +#endif + +#ifndef CONFIG_STM32L4_UART5 +# undef CONFIG_UART5_RXDMA +#endif + +/* Is DMA available on any (enabled) USART? */ + +#undef SERIAL_HAVE_DMA +#if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \ + defined(CONFIG_USART3_RXDMA) || defined(CONFIG_UART4_RXDMA) || \ + defined(CONFIG_UART5_RXDMA) +# define SERIAL_HAVE_DMA 1 +#endif + +/* Is DMA used on the console UART? */ + +#undef SERIAL_HAVE_CONSOLE_DMA +#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#endif + +/* Is DMA used on all (enabled) USARTs */ + +#define SERIAL_HAVE_ONLY_DMA 1 +#if defined(CONFIG_STM32L4_USART1) && !defined(CONFIG_USART1_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32L4_USART2) && !defined(CONFIG_USART2_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32L4_USART3) && !defined(CONFIG_USART3_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32L4_UART4) && !defined(CONFIG_UART4_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32L4_UART5) && !defined(CONFIG_UART5_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#endif + +/* Is RS-485 used? */ + +#if defined(CONFIG_USART1_RS485) || defined(CONFIG_USART2_RS485) || \ + defined(CONFIG_USART3_RS485) || defined(CONFIG_UART4_RS485) || \ + defined(CONFIG_UART5_RS485) +# define HAVE_RS485 1 +#endif + +#ifdef HAVE_RS485 +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE | USART_CR1_TCIE) +#else +# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE) +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_serial_dma_poll + * + * Description: + * Must be called periodically if any STM32 UART is configured for DMA. The DMA + * callback is triggered for each fifo size/2 bytes, but this can result in some + * bytes being transferred but not collected if the incoming data is not a whole + * multiple of half the FIFO size. + * + * May be safely called from either interrupt or thread context. + * + ************************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void stm32l4_serial_dma_poll(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_STC_STM32L4_STM32L4_UART_H */ + diff --git a/arch/arm/src/stm32l4/stm32l4_usbdev.h b/arch/arm/src/stm32l4/stm32l4_usbdev.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_userspace.c b/arch/arm/src/stm32l4/stm32l4_userspace.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_userspace.h b/arch/arm/src/stm32l4/stm32l4_userspace.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4_waste.c b/arch/arm/src/stm32l4/stm32l4_waste.c new file mode 100644 index 00000000000..cb710380ea5 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_waste.c @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_waste.c + * + * Copyright (C) 2011 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * 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 "stm32l4_waste.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +uint32_t idle_wastecounter = 0; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_waste(void) +{ + idle_wastecounter++; +} diff --git a/arch/arm/src/stm32l4/stm32l4_waste.h b/arch/arm/src/stm32l4/stm32l4_waste.h new file mode 100644 index 00000000000..e14459c045e --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4_waste.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4_waste.h + * + * Copyright (C) 2011, 2015 Uros Platise. All rights reserved. + * Author: Uros Platise + * + * 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_STM32L4_STM32L4_WASTE_H +#define __ARCH_ARM_SRC_STM32L4_STM32L4_WASTE_H + +/* Waste CPU Time */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/** Waste CPU Time + * + * up_waste() is the logic that will be executed when portions of kernel + * or user-app is polling some register or similar, waiting for desired + * status. This time is wasted away. This function offers a measure of + * badly written piece of software or some undesired behavior. + * + * At the same time this function adds to some IDLE time which portion + * cannot be used for other purposes (yet). + **/ + +void up_waste(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_WASTE_H */ diff --git a/arch/arm/src/stm32l4/stm32l4_wdg.h b/arch/arm/src/stm32l4/stm32l4_wdg.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/stm32l4/stm32l4x6xx_dma.c b/arch/arm/src/stm32l4/stm32l4x6xx_dma.c new file mode 100644 index 00000000000..2e6afa2b3b6 --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4x6xx_dma.c @@ -0,0 +1,758 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4x6xx_dma.c + * + * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "sched/sched.h" +#include "chip.h" +#include "stm32l4_dma.h" +#include "stm32l4.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMA1_NCHANNELS 7 +#if STM32L4_NDMA > 1 +# define DMA2_NCHANNELS 7 +# define DMA_NCHANNELS (DMA1_NCHANNELS+DMA2_NCHANNELS) +#else +# define DMA_NCHANNELS DMA1_NCHANNELS +#endif + +#ifndef CONFIG_DMA_PRI +# define CONFIG_DMA_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +/* Convert the DMA channel base address to the DMA register block address */ + +#define DMA_BASE(ch) (ch & 0xfffffc00) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure descibes one DMA channel */ + +struct stm32l4_dma_s +{ + uint8_t chan; /* DMA channel number (0-6) */ + uint8_t function; /* DMA peripheral connected to this channel (0-7) */ + uint8_t irq; /* DMA channel IRQ number */ + sem_t sem; /* Used to wait for DMA channel to become available */ + 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 */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This array describes the state of each DMA */ + +static struct stm32l4_dma_s g_dma[DMA_NCHANNELS] = +{ + { + .chan = 0, + .irq = STM32L4_IRQ_DMA1CH1, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(0), + }, + { + .chan = 1, + .irq = STM32L4_IRQ_DMA1CH2, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(1), + }, + { + .chan = 2, + .irq = STM32L4_IRQ_DMA1CH3, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(2), + }, + { + .chan = 3, + .irq = STM32L4_IRQ_DMA1CH4, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(3), + }, + { + .chan = 4, + .irq = STM32L4_IRQ_DMA1CH5, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(4), + }, + { + .chan = 5, + .irq = STM32L4_IRQ_DMA1CH6, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(5), + }, + { + .chan = 6, + .irq = STM32L4_IRQ_DMA1CH7, + .base = STM32L4_DMA1_BASE + STM32L4_DMACHAN_OFFSET(6), + }, +#if STM32L4_NDMA > 1 + { + .chan = 0, + .irq = STM32L4_IRQ_DMA2CH1, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(0), + }, + { + .chan = 1, + .irq = STM32L4_IRQ_DMA2CH2, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(1), + }, + { + .chan = 2, + .irq = STM32L4_IRQ_DMA2CH3, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(2), + }, + { + .chan = 3, + .irq = STM32L4_IRQ_DMA2CH4, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(3), + }, + { + .chan = 4, + .irq = STM32L4_IRQ_DMA2CH5, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(4), + }, + { + .chan = 5, + .irq = STM32L4_IRQ_DMA2CH6, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(5), + }, + { + .chan = 6, + .irq = STM32L4_IRQ_DMA2CH7, + .base = STM32L4_DMA2_BASE + STM32L4_DMACHAN_OFFSET(6), + }, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * DMA register access functions + ****************************************************************************/ + +/* Get non-channel register from DMA1 or DMA2 */ + +static inline uint32_t dmabase_getreg(struct stm32l4_dma_s *dmach, uint32_t offset) +{ + return getreg32(DMA_BASE(dmach->base) + offset); +} + +/* Write to non-channel register in DMA1 or DMA2 */ + +static inline void dmabase_putreg(struct stm32l4_dma_s *dmach, uint32_t offset, uint32_t value) +{ + putreg32(value, DMA_BASE(dmach->base) + offset); +} + +/* Get channel register from DMA1 or DMA2 */ + +static inline uint32_t dmachan_getreg(struct stm32l4_dma_s *dmach, uint32_t offset) +{ + return getreg32(dmach->base + offset); +} + +/* Write to channel register in DMA1 or DMA2 */ + +static inline void dmachan_putreg(struct stm32l4_dma_s *dmach, uint32_t offset, uint32_t value) +{ + putreg32(value, dmach->base + offset); +} + +/************************************************************************************ + * Name: stm32l4_dmatake() and stm32l4_dmagive() + * + * Description: + * Used to get exclusive access to a DMA channel. + * + ************************************************************************************/ + +static void stm32l4_dmatake(FAR struct stm32l4_dma_s *dmach) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&dmach->sem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void stm32l4_dmagive(FAR struct stm32l4_dma_s *dmach) +{ + (void)sem_post(&dmach->sem); +} + +/************************************************************************************ + * Name: stm32l4_dmachandisable + * + * Description: + * Disable the DMA channel + * + ************************************************************************************/ + +static void stm32l4_dmachandisable(struct stm32l4_dma_s *dmach) +{ + uint32_t regval; + + /* Disable all interrupts at the DMA controller */ + + regval = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + regval &= ~DMA_CCR_ALLINTS; + + /* Disable the DMA channel */ + + regval &= ~DMA_CCR_EN; + dmachan_putreg(dmach, STM32L4_DMACHAN_CCR_OFFSET, regval); + + /* Clear pending channel interrupts */ + + dmabase_putreg(dmach, STM32L4_DMA_IFCR_OFFSET, DMA_ISR_CHAN_MASK(dmach->chan)); +} + +/************************************************************************************ + * Name: stm32l4_dmainterrupt + * + * Description: + * DMA interrupt handler + * + ************************************************************************************/ + +static int stm32l4_dmainterrupt(int irq, void *context) +{ + struct stm32l4_dma_s *dmach; + uint32_t isr; + int chndx = 0; + + /* Get the channel structure from the interrupt number */ + + if (irq >= STM32L4_IRQ_DMA1CH1 && irq <= STM32L4_IRQ_DMA1CH7) + { + chndx = irq - STM32L4_IRQ_DMA1CH1; + } + else +#if STM32L4_NDMA > 1 + if (irq >= STM32L4_IRQ_DMA2CH1 && irq <= STM32L4_IRQ_DMA2CH5) + { + chndx = irq - STM32L4_IRQ_DMA2CH1 + DMA1_NCHANNELS; + } + else if (irq >= STM32L4_IRQ_DMA2CH6 && irq <= STM32L4_IRQ_DMA2CH7) + { + chndx = irq - STM32L4_IRQ_DMA2CH6 + DMA1_NCHANNELS + 5; + } +#endif + else + { + PANIC(); + } + dmach = &g_dma[chndx]; + + /* Get the interrupt status (for this channel only) */ + + isr = dmabase_getreg(dmach, STM32L4_DMA_ISR_OFFSET) & DMA_ISR_CHAN_MASK(dmach->chan); + + /* Clear the interrupts we are handling */ + + dmabase_putreg(dmach, STM32L4_DMA_IFCR_OFFSET, isr); + + /* Invoke the callback */ + + if (dmach->callback) + { + dmach->callback(dmach, isr >> DMA_ISR_CHAN_SHIFT(dmach->chan), dmach->arg); + } + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_dmainitialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function up_dmainitialize(void) +{ + struct stm32l4_dma_s *dmach; + int chndx; + + /* Initialize each DMA channel */ + + for (chndx = 0; chndx < DMA_NCHANNELS; chndx++) + { + dmach = &g_dma[chndx]; + sem_init(&dmach->sem, 0, 1); + + /* Attach DMA interrupt vectors */ + + (void)irq_attach(dmach->irq, stm32l4_dmainterrupt); + + /* Disable the DMA channel */ + + stm32l4_dmachandisable(dmach); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(dmach->irq); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(dmach->irq, CONFIG_DMA_PRI); +#endif + } +} + +/**************************************************************************** + * Name: stm32l4_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'chndx' argument. + * DMA channels are shared on the STM32L4: Devices sharing the same DMA + * channel cannot do DMA concurrently! See the DMACHAN_* definitions in + * stm32l4_dma.h. + * + * If the DMA channel is not available, then stm32l4_dmachannel() will wait + * until the holder of the channel relinquishes the channel by calling + * stm32l4_dmafree(). WARNING: If you have two devices sharing a DMA + * channel and the code never releases the channel, the stm32l4_dmachannel + * call for the other will hang forever in this function! Don't let your + * design do that! + * + * Hmm.. I suppose this interface could be extended to make a non-blocking + * version. Feel free to do that if that is what you need. + * + * Input parameter: + * chndx - Identifies the stream/channel resource. For the STM32 F1, this + * is simply the channel number as provided by the DMACHAN_* definitions + * in chip/stm32f10xxx_dma.h. + * + * Returned Value: + * Provided that 'chndx' is valid, this function ALWAYS returns a non-NULL, + * void* DMA channel handle. (If 'chndx' is invalid, the function will + * assert if debug is enabled or do something ignorant otherwise). + * + * 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 stm32l4_dmachannel(unsigned int chndef) +{ + int chndx = (chndef & DMACHAN_SETTING_CHANNEL_MASK) >> DMACHAN_SETTING_CHANNEL_SHIFT; + + struct stm32l4_dma_s *dmach = &g_dma[chndx]; + + DEBUGASSERT(chndx < DMA_NCHANNELS); + + /* Get exclusive access to the DMA channel -- OR wait until the channel + * is available if it is currently being used by another driver + */ + + stm32l4_dmatake(dmach); + + /* The caller now has exclusive use of the DMA channel */ + + /* Define the peripheral that will use the channel. This is stored until + * dmasetup is called. + */ + dmach->function = (chndef & DMACHAN_SETTING_FUNCTION_MASK) >> DMACHAN_SETTING_FUNCTION_SHIFT; + + return (DMA_HANDLE)dmach; +} + +/**************************************************************************** + * Name: stm32l4_dmafree + * + * Description: + * Release a DMA channel. If another thread is waiting for this DMA channel + * in a call to stm32l4_dmachannel, then this function will re-assign the + * DMA channel to that thread and wake it up. NOTE: The 'handle' used + * in this argument must NEVER be used again until stm32l4_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 stm32l4_dmafree(DMA_HANDLE handle) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + + DEBUGASSERT(handle != NULL); + + /* Release the channel */ + + stm32l4_dmagive(dmach); +} + +/**************************************************************************** + * Name: stm32l4_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32l4_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t ccr) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + uint32_t regval; + + /* Then DMA_CNDTRx register can only be modified if the DMA channel is + * disabled. + */ + + regval = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + regval &= ~(DMA_CCR_EN); + dmachan_putreg(dmach, STM32L4_DMACHAN_CCR_OFFSET, regval); + + /* Set the peripheral register address in the DMA_CPARx register. The data + * will be moved from/to this address to/from the memory after the + * peripheral event. + */ + + dmachan_putreg(dmach, STM32L4_DMACHAN_CPAR_OFFSET, paddr); + + /* Set the memory address in the DMA_CMARx register. The data will be + * written to or read from this memory after the peripheral event. + */ + + dmachan_putreg(dmach, STM32L4_DMACHAN_CMAR_OFFSET, maddr); + + /* Configure the total number of data to be transferred in the DMA_CNDTRx + * register. After each peripheral event, this value will be decremented. + */ + + dmachan_putreg(dmach, STM32L4_DMACHAN_CNDTR_OFFSET, ntransfers); + + /* Configure the channel priority using the PL[1:0] bits in the DMA_CCRx + * register. Configure data transfer direction, circular mode, peripheral & memory + * incremented mode, peripheral & memory data size, and interrupt after + * half and/or full transfer in the DMA_CCRx register. + */ + + regval = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + regval &= ~(DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK | + DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | + DMA_CCR_DIR); + ccr &= (DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK | + DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | + DMA_CCR_DIR); + regval |= ccr; + dmachan_putreg(dmach, STM32L4_DMACHAN_CCR_OFFSET, regval); + +#warning TODO define peripheral by using dmach->function +} + +/**************************************************************************** + * Name: stm32l4_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32l4_dmastart(DMA_HANDLE handle, dma_callback_t callback, + void *arg, bool half) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + uint32_t ccr; + + DEBUGASSERT(handle != NULL); + + /* Save the callback info. This will be invoked when the DMA commpletes */ + + dmach->callback = callback; + dmach->arg = arg; + + /* Activate the channel by setting the ENABLE bit in the DMA_CCRx register. + * As soon as the channel is enabled, it can serve any DMA request from the + * peripheral connected on the channel. + */ + + ccr = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + ccr |= DMA_CCR_EN; + + /* In normal mode, interrupt at either half or full completion. In circular mode, + * always interrupt on buffer wrap, and optionally interrupt at the halfway point. + */ + + if ((ccr & DMA_CCR_CIRC) == 0) + { + /* Once half of the bytes are transferred, the half-transfer flag (HTIF) is + * set and an interrupt is generated if the Half-Transfer Interrupt Enable + * bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag + * (TCIF) is set and an interrupt is generated if the Transfer Complete + * Interrupt Enable bit (TCIE) is set. + */ + + ccr |= (half ? (DMA_CCR_HTIE | DMA_CCR_TEIE) : (DMA_CCR_TCIE | DMA_CCR_TEIE)); + } + else + { + /* In nonstop mode, when the transfer completes it immediately resets + * and starts again. The transfer-complete interrupt is thus always + * enabled, and the half-complete interrupt can be used in circular + * mode to determine when the buffer is half-full, or in double-buffered + * mode to determine when one of the two buffers is full. + */ + + ccr |= (half ? DMA_CCR_HTIE : 0) | DMA_CCR_TCIE | DMA_CCR_TEIE; + } + + dmachan_putreg(dmach, STM32L4_DMACHAN_CCR_OFFSET, ccr); +} + +/**************************************************************************** + * Name: stm32l4_dmastop + * + * Description: + * Cancel the DMA. After stm32l4_dmastop() is called, the DMA channel is + * reset and stm32l4_dmasetup() must be called before stm32l4_dmastart() can be + * called again + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +void stm32l4_dmastop(DMA_HANDLE handle) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + stm32l4_dmachandisable(dmach); +} + +/**************************************************************************** + * Name: stm32l4_dmaresidual + * + * Description: + * Returns the number of bytes remaining to be transferred + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +size_t stm32l4_dmaresidual(DMA_HANDLE handle) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + + return dmachan_getreg(dmach, STM32L4_DMACHAN_CNDTR_OFFSET); +} + +/**************************************************************************** + * Name: stm32l4_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. + * + * Returned value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32L4_DMACAPABLE +bool stm32l4_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) +{ + uint32_t transfer_size; + uint32_t mend; + + /* 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 RM0090 rev4, section 9.3.11 + * + * Compute mend inline to avoid a possible non-constant integer + * multiply. + */ + + switch (ccr & DMA_CCR_MSIZE_MASK) + { + case DMA_CCR_MSIZE_8BITS: + transfer_size = 1; + mend = maddr + count - 1; + break; + + case DMA_CCR_MSIZE_16BITS: + transfer_size = 2; + mend = maddr + (count << 1) - 1; + break; + + case DMA_CCR_MSIZE_32BITS: + transfer_size = 4; + mend = maddr + (count << 2) - 1; + break; + + default: + return false; + } + + if ((maddr & (transfer_size - 1)) != 0) + { + return false; + } + + /* Verify that the transfer is to a memory region that supports DMA. */ + + if ((maddr & STM32L4_REGION_MASK) != (mend & STM32L4_REGION_MASK)) + { + return false; + } + + switch (maddr & STM32L4_REGION_MASK) + { +#if defined(CONFIG_STM32L4_STM32F10XX) + case STM32L4_FSMC_BANK1: + case STM32L4_FSMC_BANK2: + case STM32L4_FSMC_BANK3: + case STM32L4_FSMC_BANK4: +#endif + case STM32L4_SRAM_BASE: + case STM32L4_CODE_BASE: + /* All RAM and flash is supported */ + + return true; + + default: + /* Everything else is unsupported by DMA */ + + return false; + } +} +#endif + +/**************************************************************************** + * Name: stm32l4_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32l4_dmasample(DMA_HANDLE handle, struct stm32l4_dmaregs_s *regs) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + irqstate_t flags; + + flags = irqsave(); + regs->isr = dmabase_getreg(dmach, STM32L4_DMA_ISR_OFFSET); + regs->ccr = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); + regs->cndtr = dmachan_getreg(dmach, STM32L4_DMACHAN_CNDTR_OFFSET); + regs->cpar = dmachan_getreg(dmach, STM32L4_DMACHAN_CPAR_OFFSET); + regs->cmar = dmachan_getreg(dmach, STM32L4_DMACHAN_CMAR_OFFSET); + irqrestore(flags); +} +#endif + +/**************************************************************************** + * Name: stm32l4_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32l4_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void stm32l4_dmadump(DMA_HANDLE handle, const struct stm32l4_dmaregs_s *regs, + const char *msg) +{ + struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; + uint32_t dmabase = DMA_BASE(dmach->base); + + dmadbg("DMA Registers: %s\n", msg); + dmadbg(" ISRC[%08x]: %08x\n", dmabase + STM32L4_DMA_ISR_OFFSET, regs->isr); + dmadbg(" CCR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CCR_OFFSET, regs->ccr); + dmadbg(" CNDTR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CNDTR_OFFSET, regs->cndtr); + dmadbg(" CPAR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CPAR_OFFSET, regs->cpar); + dmadbg(" CMAR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CMAR_OFFSET, regs->cmar); +} +#endif + diff --git a/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c new file mode 100644 index 00000000000..f5e776a2ddc --- /dev/null +++ b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c @@ -0,0 +1,766 @@ +/**************************************************************************** + * arch/arm/src/stm32l4/stm32l4x6xx_rcc.c + * + * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Author: Gregory Nutt + * Sebastien Lorquet + * + * 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 "stm32l4_pwr.h" +#include "stm32l4_flash.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 (STM32L4_HSE_FREQUENCY + 500000) / 1000000 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * 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; + + /* Enable the Internal High Speed clock (HSI) */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_HSION; + putreg32(regval, STM32L4_RCC_CR); + + /* Reset CFGR register */ + + putreg32(0x00000000, STM32L4_RCC_CFGR); + + /* Reset HSION, HSEON, CSSON and PLLON bits */ + + regval = getreg32(STM32L4_RCC_CR); + regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); + putreg32(regval, STM32L4_RCC_CR); + + /* Reset PLLCFGR register to reset default */ + + putreg32(RCC_PLLCFG_RESET, STM32L4_RCC_PLLCFG); + + /* Reset HSEBYP bit */ + + regval = getreg32(STM32L4_RCC_CR); + regval &= ~RCC_CR_HSEBYP; + putreg32(regval, STM32L4_RCC_CR); + + /* Disable all interrupts */ + + putreg32(0x00000000, STM32L4_RCC_CIER); +} + +/**************************************************************************** + * Name: rcc_enableahb1 + * + * Description: + * Enable selected AHB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB1ENR register to enabled the + * selected AHB1 peripherals. + */ + + regval = getreg32(STM32L4_RCC_AHB1ENR); + +#ifdef CONFIG_STM32L4_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHB1ENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32L4_DMA2 + /* DMA 2 clock enable */ + + regval |= RCC_AHB1ENR_DMA2EN; +#endif + +#ifdef CONFIG_STM32L4_CRC + /* CRC clock enable */ + + regval |= RCC_AHB1ENR_CRCEN; +#endif + +#ifdef CONFIG_STM32L4_TSC + /* TSC clock enable */ + + regval |= RCC_AHB1ENR_TSCEN; +#endif + + putreg32(regval, STM32L4_RCC_AHB1ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb2 + * + * Description: + * Enable selected AHB2 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB2ENR register to enabled the + * selected AHB2 peripherals. + */ + + regval = getreg32(STM32L4_RCC_AHB2ENR); + + /* Enable GPIOA, GPIOB, .... GPIOI */ + +#if STM32L4_NGPIO > 0 + regval |= (RCC_AHB2ENR_GPIOAEN +#if STM32L4_NGPIO > 16 + | RCC_AHB2ENR_GPIOBEN +#endif +#if STM32L4_NGPIO > 32 + | RCC_AHB2ENR_GPIOCEN +#endif +#if STM32L4_NGPIO > 48 + | RCC_AHB2ENR_GPIODEN +#endif +#if STM32L4_NGPIO > 64 + | RCC_AHB2ENR_GPIOEEN +#endif +#if STM32L4_NGPIO > 80 + | RCC_AHB2ENR_GPIOFEN +#endif +#if STM32L4_NGPIO > 96 + | RCC_AHB2ENR_GPIOGEN +#endif +#if STM32L4_NGPIO > 112 + | RCC_AHB2ENR_GPIOHEN +#endif + ); +#endif + +#ifdef CONFIG_STM32L4_OTGFS + /* USB OTG FS clock enable */ + + regval |= RCC_AHB2ENR_OTGFSEN; +#endif + +#if defined(CONFIG_STM32L4_ADC1) || defined(CONFIG_STM32L4_ADC2) || defined(CONFIG_STM32L4_ADC3) + /* ADC clock enable */ + + regval |= RCC_AHB2ENR_ADCEN; +#endif + +#ifdef CONFIG_STM32L4_AES + /* Cryptographic modules clock enable */ + + regval |= RCC_AHB2ENR_AESEN; +#endif + +#ifdef CONFIG_STM32L4_RNG + /* Random number generator clock enable */ + + regval |= RCC_AHB2ENR_RNGEN; +#endif + + putreg32(regval, STM32L4_RCC_AHB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableahb3 + * + * Description: + * Enable selected AHB3 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb3(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the AHB3ENR register to enabled the + * selected AHB3 peripherals. + */ + + regval = getreg32(STM32L4_RCC_AHB3ENR); + +#ifdef CONFIG_STM32L4_FSMC + /* Flexible static memory controller module clock enable */ + + regval |= RCC_AHB3ENR_FMCEN; +#endif + + +#ifdef CONFIG_STM32L4_QUADSPI + /* QuadSPI module clock enable */ + + regval |= RCC_AHB3ENR_QSPIEN; +#endif + + putreg32(regval, STM32L4_RCC_AHB3ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB1 peripherals + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB1 peripherals. + */ + + regval = getreg32(STM32L4_RCC_APB1ENR1); + +#ifdef CONFIG_STM32L4_TIM2 + /* TIM2 clock enable */ + + regval |= RCC_APB1ENR1_TIM2EN; +#endif + +#ifdef CONFIG_STM32L4_TIM3 + /* TIM3 clock enable */ + + regval |= RCC_APB1ENR1_TIM3EN; +#endif + +#ifdef CONFIG_STM32L4_TIM4 + /* TIM4 clock enable */ + + regval |= RCC_APB1ENR1_TIM4EN; +#endif + +#ifdef CONFIG_STM32L4_TIM5 + /* TIM5 clock enable */ + + regval |= RCC_APB1ENR1_TIM5EN; +#endif + +#ifdef CONFIG_STM32L4_TIM6 + /* TIM6 clock enable */ + + regval |= RCC_APB1ENR1_TIM6EN; +#endif + +#ifdef CONFIG_STM32L4_TIM7 + /* TIM7 clock enable */ + + regval |= RCC_APB1ENR1_TIM7EN; +#endif + +#ifdef CONFIG_STM32L4_LCD + /* LCD clock enable */ + + regval |= RCC_APB1ENR1_LCDEN; +#endif + +#ifdef CONFIG_STM32L4_SPI2 + /* SPI2 clock enable */ + + regval |= RCC_APB1ENR1_SPI2EN; +#endif + +#ifdef CONFIG_STM32L4_SPI3 + /* SPI3 clock enable */ + + regval |= RCC_APB1ENR1_SPI3EN; +#endif + +#ifdef CONFIG_STM32L4_USART2 + /* USART 2 clock enable */ + + regval |= RCC_APB1ENR1_USART2EN; +#endif + +#ifdef CONFIG_STM32L4_USART3 + /* USART3 clock enable */ + + regval |= RCC_APB1ENR1_USART3EN; +#endif + +#ifdef CONFIG_STM32L4_UART4 + /* UART4 clock enable */ + + regval |= RCC_APB1ENR1_UART4EN; +#endif + +#ifdef CONFIG_STM32L4_UART5 + /* UART5 clock enable */ + + regval |= RCC_APB1ENR1_UART5EN; +#endif + +#ifdef CONFIG_STM32L4_I2C1 + /* I2C1 clock enable */ + + regval |= RCC_APB1ENR1_I2C1EN; +#endif + +#ifdef CONFIG_STM32L4_I2C2 + /* I2C2 clock enable */ + + regval |= RCC_APB1ENR1_I2C2EN; +#endif + +#ifdef CONFIG_STM32L4_I2C3 + /* I2C3 clock enable */ + + regval |= RCC_APB1ENR1_I2C3EN; +#endif + +#ifdef CONFIG_STM32L4_CAN1 + /* CAN 1 clock enable */ + + regval |= RCC_APB1ENR1_CAN1EN; +#endif + + /* Power interface clock enable. The PWR block is always enabled so that + * we can set the internal voltage regulator as required. + */ + + regval |= RCC_APB1ENR1_PWREN; + +#if defined (CONFIG_STM32L4_DAC1) || defined(CONFIG_STM32L4_DAC2) + /* DAC interface clock enable */ + + regval |= RCC_APB1ENR1_DACEN; +#endif + +#ifdef CONFIG_STM32L4_OPAMP + /* OPAMP clock enable */ + + regval |= RCC_APB1ENR1_OPAMPEN; +#endif + + putreg32(regval, STM32L4_RCC_APB1ENR1); /* Enable peripherals */ + + /* Second APB1 register */ + + regval = getreg32(STM32L4_RCC_APB1ENR2); + +#ifdef CONFIG_STM32L4_LPTIM1 + /* OPAMP clock enable */ + + regval |= RCC_APB1ENR2_LPTIM1EN; +#endif + +#ifdef CONFIG_STM32L4_LPUART1 + /* OPAMP clock enable */ + + regval |= RCC_APB1ENR2_LPUART1EN; +#endif + +#ifdef CONFIG_STM32L4_SWPMI + /* OPAMP clock enable */ + + regval |= RCC_APB1ENR2_SWPMI1EN; +#endif + +#ifdef CONFIG_STM32L4_LPTIM2 + /* OPAMP clock enable */ + + regval |= RCC_APB1ENR2_LPTIM2EN; +#endif + + putreg32(regval, STM32L4_RCC_APB1ENR2); /* 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 APB2ENR register to enabled the + * selected APB2 peripherals. + */ + + regval = getreg32(STM32L4_RCC_APB2ENR); + +#ifdef CONFIG_STM32L4_SYSCFG + /* System configuration controller clock enable */ + + regval |= RCC_APB2ENR_SYSCFGEN; +#endif + +#ifdef CONFIG_STM32L4_FIREWALL + /* Firewall clock enable */ + + regval |= RCC_APB2ENR_FWEN; +#endif + +#ifdef CONFIG_STM32L4_SDMMC + /* SDMMC clock enable */ + + regval |= RCC_APB2ENR_SDMMCEN; +#endif + +#ifdef CONFIG_STM32L4_TIM1 + /* TIM1 clock enable */ + + regval |= RCC_APB2ENR_TIM1EN; +#endif + +#ifdef CONFIG_STM32L4_SPI1 + /* SPI1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32L4_TIM8 + /* TIM8 clock enable */ + + regval |= RCC_APB2ENR_TIM8EN; +#endif + +#ifdef CONFIG_STM32L4_USART1 + /* USART1 clock enable */ + + regval |= RCC_APB2ENR_USART1EN; +#endif + +#ifdef CONFIG_STM32L4_TIM15 + /* TIM15 clock enable */ + + regval |= RCC_APB2ENR_TIM15EN; +#endif + +#ifdef CONFIG_STM32L4_TIM16 + /* TIM16 clock enable */ + + regval |= RCC_APB2ENR_TIM16EN; +#endif + +#ifdef CONFIG_STM32L4_TIM17 + /* TIM17 clock enable */ + + regval |= RCC_APB2ENR_TIM17EN; +#endif + +#ifdef CONFIG_STM32L4_SAI1 + /* SAI1 clock enable */ + + regval |= RCC_APB2ENR_SAI1EN; +#endif + +#ifdef CONFIG_STM32L4_SAI2 + /* SAI2 clock enable */ + + regval |= RCC_APB2ENR_SAI2EN; +#endif + +#ifdef CONFIG_STM32L4_DFSDM + /* DFSDM clock enable */ + + regval |= RCC_APB2ENR_DFSDMEN; +#endif + + putreg32(regval, STM32L4_RCC_APB2ENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: stm32l4_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h + * + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + ****************************************************************************/ + +#ifndef CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG +static void stm32l4_stdclockconfig(void) +{ + uint32_t regval; + volatile int32_t timeout; + +#ifdef STM32L4_BOARD_USEHSI + /* Enable Internal High-Speed Clock (HSI) */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_HSION; /* Enable HSI */ + putreg32(regval, STM32L4_RCC_CR); + + /* Wait until the HSI is ready (or until a timeout elapsed) */ + + for (timeout = HSIRDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSIRDY flag is the set in the CR */ + + if ((getreg32(STM32L4_RCC_CR) & RCC_CR_HSIRDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } + +#else /* if STM32L4_BOARD_USEHSE */ + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32L4_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is the set in the CR */ + + if ((getreg32(STM32L4_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then break-out with timeout > 0 */ + + break; + } + } +#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) + { +#warning todo: regulator voltage according to clock freq +#if 0 + /* Select regulator voltage output Scale 1 mode to support system + * frequencies up to 168 MHz. + */ + + regval = getreg32(STM32L4_RCC_APB1ENR); + regval |= RCC_APB1ENR_PWREN; + putreg32(regval, STM32L4_RCC_APB1ENR); + + regval = getreg32(STM32L4_PWR_CR); + regval &= ~PWR_CR_VOS_MASK; + regval |= PWR_CR_VOS_SCALE_1; + putreg32(regval, STM32L4_PWR_CR); +#endif + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32L4_RCC_CFGR_HPRE; + putreg32(regval, STM32L4_RCC_CFGR); + + /* Set the PCLK2 divider */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE2_MASK; + regval |= STM32L4_RCC_CFGR_PPRE2; + putreg32(regval, STM32L4_RCC_CFGR); + + /* Set the PCLK1 divider */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE1_MASK; + regval |= STM32L4_RCC_CFGR_PPRE1; + putreg32(regval, STM32L4_RCC_CFGR); + +#ifdef CONFIG_RTC_HSECLOCK + /* Set the RTC clock divisor */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_RTCPRE_MASK; + regval |= RCC_CFGR_RTCPRE(HSE_DIVISOR); + putreg32(regval, STM32L4_RCC_CFGR); +#endif + + /* Set the PLL source and main divider */ + + regval = getreg32(STM32L4_RCC_PLLCFG); + + /* Configure Main PLL */ + + /* Set the PLL dividers and multipliers to configure the main PLL */ + + regval = (STM32L4_PLLCFG_PLLM | STM32L4_PLLCFG_PLLN | STM32L4_PLLCFG_PLLP + | STM32L4_PLLCFG_PLLQ | STM32L4_PLLCFG_PLLR); + +#ifdef STM32L4_PLLCFG_PLLP_ENABLED + regval |= RCC_PLLCFG_PLLPEN; +#endif +#ifdef STM32L4_PLLCFG_PLLQ_ENABLED + regval |= RCC_PLLCFG_PLLQEN; +#endif +#ifdef STM32L4_PLLCFG_PLLR_ENABLED + regval |= RCC_PLLCFG_PLLREN; +#endif + +#ifdef STM32L4_BOARD_USEHSI + regval |= RCC_PLLCFG_PLLSRC_HSI; +#else /* if STM32L4_BOARD_USEHSE */ + regval |= RCC_PLLCFG_PLLSRC_HSE; +#endif + + putreg32(regval, STM32L4_RCC_PLLCFG); + + /* Enable the main PLL */ + + regval = getreg32(STM32L4_RCC_CR); + regval |= RCC_CR_PLLON; + putreg32(regval, STM32L4_RCC_CR); + + /* Wait until the PLL is ready */ + + while ((getreg32(STM32L4_RCC_CR) & RCC_CR_PLLRDY) == 0) + { + } + +#ifdef CONFIG_STM32L4_SAI1PLL + /* Configure SAI1 PLL */ + regval = getreg32(STM32L4_RCC_PLLSAI1CFG); + + /* Enable the SAI1 PLL */ +#warning PLLSAI1 TODO + /* Wait until the PLL is ready */ +#endif + +#ifdef CONFIG_STM32L4_SAI2PLL + /* Configure SAI2 PLL */ + + regval = getreg32(STM32L4_RCC_PLLSAI2CFG); + + /* Enable the SAI2 PLL */ +#warning PLLSAI2 TODO + /* Wait until the PLL is ready */ +#endif + + /* Enable FLASH prefetch, instruction cache, data cache, and 5 wait states */ + +#ifdef CONFIG_STM32L4_FLASH_PREFETCH + regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN); +#else + regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN); +#endif + putreg32(regval, STM32L4_FLASH_ACR); + + /* Select the main PLL as system clock source */ + + regval = getreg32(STM32L4_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= RCC_CFGR_SW_PLL; + putreg32(regval, STM32L4_RCC_CFGR); + + /* Wait until the PLL source is used as the system clock source */ + + while ((getreg32(STM32L4_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL) + { + } + +#if defined(CONFIG_STM32L4_IWDG) || defined(CONFIG_RTC_LSICLOCK) + /* Low speed internal clock source LSI */ + + stm32l4_rcc_enablelsi(); +#endif + +#if defined(CONFIG_RTC_LSECLOCK) + /* Low speed external clock source LSE + * + * TODO: There is another case where the LSE needs to + * be enabled: if the MCO1 pin selects LSE as source. + */ + + stm32l4_rcc_enablelse(); +#endif + } +} +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableahb1(); + rcc_enableahb2(); + rcc_enableahb3(); + rcc_enableapb1(); + rcc_enableapb2(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/