diff --git a/arch/Kconfig b/arch/Kconfig index 6fac6fd310..7dbad3d037 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -190,6 +190,10 @@ config ARCH_HAVE_RESET bool default n +config ARCH_HAVE_RTC_SUBSECONDS + bool + default n + config ARCH_USE_MMU bool "Enable MMU" default n diff --git a/arch/arm/include/stm32f0/chip.h b/arch/arm/include/stm32f0/chip.h index a50902d462..196a15e221 100644 --- a/arch/arm/include/stm32f0/chip.h +++ b/arch/arm/include/stm32f0/chip.h @@ -52,6 +52,7 @@ #if defined(CONFIG_ARCH_CHIP_STM32F051R8) # define STM32F051x 1 /* STM32F051x family */ # undef STM32F072x /* Not STM32F072x family */ +# undef STM32F091x /* Not STM32F091x family */ # define STM32F0_FLASH_SIZE (64*1024) /* 64Kb */ # define STM32F0_SRAM_SIZE (8*1024) /* 8Kb */ @@ -71,6 +72,7 @@ #elif defined(CONFIG_ARCH_CHIP_STM32F072C8) || defined(CONFIG_ARCH_CHIP_STM32F072CB) # undef STM32F051x /* Not STM32F051x family */ # define STM32F072x 1 /* STM32F072x family */ +# undef STM32F091x /* Not STM32F091x family */ # ifdef CONFIG_ARCH_CHIP_STM32F072C8 # define STM32F0_FLASH_SIZE (64*1024) /* 64Kb */ @@ -90,9 +92,9 @@ # define STM32F0_NCAN 1 /* One CAN controller */ # define STM32F0_NUSBDEV 1 /* One USB device controller */ # define STM32F0_NCEC 1 /* One HDMI-CEC controller */ -# define STM32F0_NADC16 1 /* One 16-bit module */ +# define STM32F0_NADC12 1 /* One 12-bit module */ # define STM32F0_NADCCHAN 10 /* Ten external channels */ -# define STM32F0_NADCEXT 3 /* Three external channels */ +# define STM32F0_NADCINT 3 /* Three internal channels */ # define STM32F0_NDAC 1 /* One DAC module */ # define STM32F0_NDACCHAN 2 /* Two DAC channels */ # define STM32F0_NCOMP 2 /* Two Analog Comparators */ @@ -102,6 +104,7 @@ #elif defined(CONFIG_ARCH_CHIP_STM32F072R8) || defined(CONFIG_ARCH_CHIP_STM32F072RB) # undef STM32F051x /* Not STM32F051x family */ # define STM32F072x 1 /* STM32F072x family */ +# undef STM32F091x /* Not STM32F091x family */ # ifdef CONFIG_ARCH_CHIP_STM32F072R8 # define STM32F0_FLASH_SIZE (64*1024) /* 64Kb */ @@ -121,9 +124,9 @@ # define STM32F0_NCAN 1 /* One CAN controller */ # define STM32F0_NUSBDEV 1 /* One USB device controller */ # define STM32F0_NCEC 1 /* One HDMI-CEC controller */ -# define STM32F0_NADC16 1 /* One 16-bit module */ +# define STM32F0_NADC12 1 /* One 12-bit module */ # define STM32F0_NADCCHAN 16 /* 16 external channels */ -# define STM32F0_NADCEXT 3 /* Three external channels */ +# define STM32F0_NADCINT 3 /* Three internal channels */ # define STM32F0_NDAC 1 /* One DAC module */ # define STM32F0_NDACCHAN 2 /* Two DAC channels */ # define STM32F0_NCOMP 2 /* Two Analog Comparators */ @@ -133,6 +136,7 @@ #elif defined(CONFIG_ARCH_CHIP_STM32F072V8) || defined(CONFIG_ARCH_CHIP_STM32F072VB) # undef STM32F051x /* Not STM32F051x family */ # define STM32F072x 1 /* STM32F072x family */ +# undef STM32F091x /* Not STM32F091x family */ # ifdef CONFIG_ARCH_CHIP_STM32F072V8 # define STM32F0_FLASH_SIZE (64*1024) /* 64Kb */ @@ -152,15 +156,84 @@ # define STM32F0_NCAN 1 /* One CAN controller */ # define STM32F0_NUSBDEV 1 /* One USB device controller */ # define STM32F0_NCEC 1 /* One HDMI-CEC controller */ -# define STM32F0_NADC16 1 /* One 16-bit module */ +# define STM32F0_NADC12 1 /* One 12-bit module */ # define STM32F0_NADCCHAN 16 /* 16 external channels */ -# define STM32F0_NADCEXT 3 /* Three external channels */ +# define STM32F0_NADCINT 3 /* Three internal channels */ # define STM32F0_NDAC 1 /* One DAC module */ # define STM32F0_NDACCHAN 2 /* Two DAC channels */ # define STM32F0_NCOMP 2 /* Two Analog Comparators */ # define STM32F0_NCAP 24 /* Capacitive sensing channels */ # define STM32F0_NPORTS 6 /* Six GPIO ports, GPIOA-F */ +#elif defined(CONFIG_ARCH_CHIP_STM32F091CB) || defined(CONFIG_ARCH_CHIP_STM32F091CC) +# undef STM32F051x /* Not STM32F051x family */ +# undef STM32F072x /* Not STM32F072x family */ +# define STM32F091x 1 /* STM32F091x family */ + +# ifdef CONFIG_ARCH_CHIP_STM32F091CB +# define STM32F0_FLASH_SIZE (128*1024) /* 128Kb */ +# else +# define STM32F0_FLASH_SIZE (256*1024) /* 256Kb */ +# endif +# define STM32F0_SRAM_SIZE (32*1024) /* 32Kb */ + +# define STM32F0_NATIM 1 /* One advanced timer TIM1 */ +# define STM32F0_NGTIM16 5 /* 16-bit general up/down timers TIM3, TIM14-17 */ +# define STM32F0_NGTIM32 1 /* 32-bit general up/down timers TIM2 */ +# define STM32F0_NBTIM 2 /* 2 basic timers: TIM6, TIM7 */ +# define STM32F0_NSPI 2 /* Two SPI modules (SPI or I2S) */ +# define STM32F0_NI2S 2 /* Two I2S modules (SPI or I2S) */ +# define STM32F0_NI2C 2 /* Two I2C modules */ +# define STM32F0_NUSART 6 /* Six USARTs modules */ +# define STM32F0_NCAN 1 /* One CAN controller */ +# define STM32F0_NUSBDEV 0 /* No USB device controller */ +# define STM32F0_NCEC 1 /* One HDMI-CEC controller */ +# define STM32F0_NADC12 1 /* One 12-bit module */ +# define STM32F0_NADCCHAN 10 /* 10 external channels */ +# define STM32F0_NADCINT 3 /* Three internal channels */ +# define STM32F0_NDAC 1 /* One DAC module */ +# define STM32F0_NDACCHAN 2 /* Two DAC channels */ +# define STM32F0_NCOMP 2 /* Two Analog Comparators */ +# define STM32F0_NCAP 17 /* Capacitive sensing channels */ +# define STM32F0_NPORTS 6 /* Six GPIO ports, GPIOA-F */ + +#elif defined(CONFIG_ARCH_CHIP_STM32F091RB) || defined(CONFIG_ARCH_CHIP_STM32F091RC) \ + || defined(CONFIG_ARCH_CHIP_STM32F091VB) || defined(CONFIG_ARCH_CHIP_STM32F091VC) +# undef STM32F051x /* Not STM32F051x family */ +# undef STM32F072x /* Not STM32F072x family */ +# define STM32F091x 1 /* STM32F091x family */ + +# if defined(CONFIG_ARCH_CHIP_STM32F091RB) || defined(CONFIG_ARCH_CHIP_STM32F091VB) +# define STM32F0_FLASH_SIZE (128*1024) /* 128Kb */ +# else +# define STM32F0_FLASH_SIZE (256*1024) /* 256Kb */ +# endif +# define STM32F0_SRAM_SIZE (32*1024) /* 32Kb */ + +# define STM32F0_NATIM 1 /* One advanced timer TIM1 */ +# define STM32F0_NGTIM16 5 /* 16-bit general up/down timers TIM3, TIM14-17 */ +# define STM32F0_NGTIM32 1 /* 32-bit general up/down timers TIM2 */ +# define STM32F0_NBTIM 2 /* 2 basic timers: TIM6, TIM7 */ +# define STM32F0_NSPI 2 /* Two SPI modules (SPI or I2S) */ +# define STM32F0_NI2S 2 /* Two I2S modules (SPI or I2S) */ +# define STM32F0_NI2C 2 /* Two I2C modules */ +# define STM32F0_NUSART 8 /* Eight USARTs modules */ +# define STM32F0_NCAN 1 /* One CAN controller */ +# define STM32F0_NUSBDEV 0 /* No USB device controller */ +# define STM32F0_NCEC 1 /* One HDMI-CEC controller */ +# define STM32F0_NADC12 1 /* One 12-bit module */ +# define STM32F0_NADCCHAN 16 /* 16 external channels */ +# define STM32F0_NADCINT 3 /* Three internal channels */ +# define STM32F0_NDAC 1 /* One DAC module */ +# define STM32F0_NDACCHAN 2 /* Two DAC channels */ +# define STM32F0_NCOMP 2 /* Two Analog Comparators */ +# if defined(CONFIG_ARCH_CHIP_STM32F091VB) || defined(CONFIG_ARCH_CHIP_STM32F091VC) +# define STM32F0_NCAP 24 /* Capacitive sensing channels */ +# else +# define STM32F0_NCAP 18 /* Capacitive sensing channels */ +# endif +# define STM32F0_NPORTS 6 /* Six GPIO ports, GPIOA-F */ + #else # error "Unsupported STM32F0xx chip" #endif diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index 262017a34b..e36b54673e 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -6362,6 +6362,7 @@ config STM32_HAVE_RTC_COUNTER config STM32_HAVE_RTC_SUBSECONDS bool + select ARCH_HAVE_RTC_SUBSECONDS default n config RTC_MAGIC_REG diff --git a/arch/arm/src/stm32/stm32_rtcc.c b/arch/arm/src/stm32/stm32_rtcc.c index b1347fd9e7..9adc62433c 100644 --- a/arch/arm/src/stm32/stm32_rtcc.c +++ b/arch/arm/src/stm32/stm32_rtcc.c @@ -928,6 +928,40 @@ int up_rtc_getdatetime(FAR struct tm *tp) } #endif +/************************************************************************************ + * Name: up_rtc_getdatetime_with_subseconds + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: This interface exposes sub-second accuracy capability of RTC hardware. + * This interface allow maintaining timing accuracy when system time needs constant + * resynchronization with RTC, for example on MCU with low-power state that + * stop system timer. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * nsec - The location to return the subsecond time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_RTC_SUBSECONDS +# ifndef CONFIG_STM32_HAVE_RTC_SUBSECONDS +# error "Invalid config, enable CONFIG_STM32_HAVE_RTC_SUBSECONDS." +# endif +int up_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec) +{ + return stm32_rtc_getdatetime_with_subseconds(tp, nsec); +} +#endif + /************************************************************************************ * Name: stm32_rtc_setdatetime * diff --git a/arch/arm/src/stm32f0/chip/stm32f05xf07x_memorymap.h b/arch/arm/src/stm32f0/chip/stm32f05xf07xf09x_memorymap.h similarity index 97% rename from arch/arm/src/stm32f0/chip/stm32f05xf07x_memorymap.h rename to arch/arm/src/stm32f0/chip/stm32f05xf07xf09x_memorymap.h index 178773b087..84bb978aaf 100644 --- a/arch/arm/src/stm32f0/chip/stm32f05xf07x_memorymap.h +++ b/arch/arm/src/stm32f0/chip/stm32f05xf07xf09x_memorymap.h @@ -1,5 +1,5 @@ /************************************************************************************ - * arch/arm/src/stm32f0/chip/stm32f05xf07x_memorymap.h + * arch/arm/src/stm32f0/chip/stm32f05xf07xf09x_memorymap.h * * Copyright (C) 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -34,8 +34,8 @@ * ************************************************************************************/ -#ifndef __ARCH_ARM_SRC_STM32F0_CHIP_ST32F05XF07X_MEMORYMAP_H -#define __ARCH_ARM_SRC_STM32F0_CHIP_ST32F05XF07X_MEMORYMAP_H +#ifndef __ARCH_ARM_SRC_STM32F0_CHIP_ST32F05XF07XF09X_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32F0_CHIP_ST32F05XF07XF09X_MEMORYMAP_H /************************************************************************************ * Pre-processor Definitions @@ -154,4 +154,4 @@ #define STM32F0_SCS_BASE 0xe000e000 #define STM32F0_DEBUGMCU_BASE 0xe0042000 -#endif /* __ARCH_ARM_SRC_STM32F0_CHIP_ST32F05XF07X_MEMORYMAP_H */ +#endif /* __ARCH_ARM_SRC_STM32F0_CHIP_ST32F05XF07XF09X_MEMORYMAP_H */ diff --git a/arch/arm/src/stm32f0/chip/stm32f09x_pinmap.h b/arch/arm/src/stm32f0/chip/stm32f09x_pinmap.h new file mode 100644 index 0000000000..b144846d95 --- /dev/null +++ b/arch/arm/src/stm32f0/chip/stm32f09x_pinmap.h @@ -0,0 +1,430 @@ +/************************************************************************************ + * arch/arm/src/stm32f0/chip/stm32f09x_pinmap.h + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Alan Carvalho de Assis + * + * 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_STM32F0_CHIP_STM32F09X_PINMAP_H +#define __ARCH_ARM_SRC_STM32F0_CHIP_STM32F09X_PINMAP_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "stm32f0_gpio.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, etc. + * Drivers, however, will use the pin selection without the numeric suffix. + * Additional definitions are required in the board.h file. For example, if + * CAN1_RX connects vis PD0 on some board, then the following definition should + * appear inthe board.h header file for that board: + * + * #define GPIO_CAN1_RX GPIO_CAN1_RX_1 + * + * The driver will then automatically configre PD0 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_ADC_IN0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN0) +#define GPIO_ADC_IN1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN1) +#define GPIO_ADC_IN2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN2) +#define GPIO_ADC_IN3 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN3) +#define GPIO_ADC_IN4 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN4) +#define GPIO_ADC_IN5 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN5) +#define GPIO_ADC_IN6 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN6) +#define GPIO_ADC_IN7 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN7) +#define GPIO_ADC_IN8 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN0) +#define GPIO_ADC_IN9 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN1) +#define GPIO_ADC_IN10 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN0) +#define GPIO_ADC_IN11 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN1) +#define GPIO_ADC_IN12 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN2) +#define GPIO_ADC_IN13 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN3) +#define GPIO_ADC_IN14 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN4) +#define GPIO_ADC_IN15 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN5) + +/* CAN */ + +#define GPIO_CAN_RX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN0) +#define GPIO_CAN_RX_2 (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_CAN_RX_3 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN8) +#define GPIO_CAN_TX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN1) +#define GPIO_CAN_TX_3 (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_CAN_TX_4 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN9) + +/* HDMI-CEC */ + +#define GPIO_CEC_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN10) +#define GPIO_CEC_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN8) +#define GPIO_CEC_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN5) + +/* Analog Comparators */ + +#define GPIO_COMP1_OUT_1 (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN0) +#define GPIO_COMP1_OUT_2 (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_COMP1_OUT_3 (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN6) + +#define GPIO_COMP2_OUT_1 (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_COMP2_OUT_2 (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN2) +#define GPIO_COMP2_OUT_3 (GPIO_ALT | GPIO_AF7 | GPIO_PORTA | GPIO_PIN7) + +/* CRS */ + +#define GPIO_CRS_SYNC_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN15) +#define GPIO_CRS_SYNC_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTF | GPIO_PIN0) +#define GPIO_CRS_SYNC_3 (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN8) + +/* Events */ + +#define GPIO_EVENTOUT_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_EVENTOUT_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_EVENTOUT_3 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_EVENTOUT_4 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN0) +#define GPIO_EVENTOUT_5 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN11) +#define GPIO_EVENTOUT_6 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN0) +#define GPIO_EVENTOUT_7 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN1) +#define GPIO_EVENTOUT_8 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN2) +#define GPIO_EVENTOUT_9 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN3) +#define GPIO_EVENTOUT_10 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN4) +#define GPIO_EVENTOUT_11 (GPIO_ALT | GPIO_AF0 | GPIO_PORTF | GPIO_PIN2) +#define GPIO_EVENTOUT_12 (GPIO_ALT | GPIO_AF0 | GPIO_PORTF | GPIO_PIN3) +#define GPIO_EVENTOUT_13 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_EVENTOUT_14 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_EVENTOUT_15 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN0) +#define GPIO_EVENTOUT_16 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN1) +#define GPIO_EVENTOUT_17 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_EVENTOUT_18 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_EVENTOUT_19 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN8) +#define GPIO_EVENTOUT_20 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN9) +#define GPIO_EVENTOUT_21 (GPIO_ALT | GPIO_AF6 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_EVENTOUT_22 (GPIO_ALT | GPIO_AF6 | GPIO_PORTA | GPIO_PIN7) + +/* I2C */ + +#define GPIO_I2C1_SCL_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN8) +#define GPIO_I2C1_SDA_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN9) +#define GPIO_I2C1_SMBA (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN5) + +#define GPIO_I2C2_SCL_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_I2C2_SDA_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN14) + +/* I2S */ + +#define GPIO_I2S1_CK_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN5) +#define GPIO_I2S1_CK_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_I2S1_CK_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN13) +#define GPIO_I2S1_MCK_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_I2S1_MCK_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_I2S1_MCK_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN14) +#define GPIO_I2S1_SD_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_I2S1_SD_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN5) +#define GPIO_I2S1_SD_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN15) +#define GPIO_I2S1_WS_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_I2S1_WS_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_I2S1_WS_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN12) + +#define GPIO_I2S2_CK_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_I2S2_CK_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN1) +#define GPIO_I2S2_CK_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN10) +#define GPIO_I2S2_MCK_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_I2S2_MCK_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN2) +#define GPIO_I2S2_MCK_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN3) +#define GPIO_I2S2_SD_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN15) +#define GPIO_I2S2_SD_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN3) +#define GPIO_I2S2_SD_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN4) +#define GPIO_I2S2_WS_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_I2S2_WS_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN0) +#define GPIO_I2S2_WS_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN9) + +/* IR */ + +#define GPIO_IR_OUT_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN9) +#define GPIO_IR_OUT_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN13) + +/* Clock output */ + +#define GPIO_MCO (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN8) + +/* SPI */ + +#define GPIO_SPI1_MISO_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_SPI1_MISO_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_SPI1_MISO_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN14) +#define GPIO_SPI1_MOSI_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_SPI1_MOSI_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN5) +#define GPIO_SPI1_MOSI_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN15) +#define GPIO_SPI1_NSS_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_SPI1_NSS_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_SPI1_NSS_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN12) +#define GPIO_SPI1_SCK_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN5) +#define GPIO_SPI1_SCK_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_SPI1_SCK_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN13) + +#define GPIO_SPI2_MISO_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_SPI2_MISO_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN2) +#define GPIO_SPI2_MISO_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN3) +#define GPIO_SPI2_MOSI_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN15) +#define GPIO_SPI2_MOSI_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN3) +#define GPIO_SPI2_MOSI_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN4) +#define GPIO_SPI2_NSS_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_SPI2_NSS_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN0) +#define GPIO_SPI2_NSS_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN9) +#define GPIO_SPI2_SCK_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_SPI2_SCK_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN1) +#define GPIO_SPI2_SCK_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN10) + +/* SWD */ + +#define GPIO_SWCLK (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN14) +#define GPIO_SWDIO (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN13) + +/* Timers */ + +#define GPIO_TIM1_BKIN_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN15) +#define GPIO_TIM1_BKIN_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_TIM1_BKIN_3 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_TIM1_CH1_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN9) +#define GPIO_TIM1_CH1_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN8) +#define GPIO_TIM1_CH1N_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN8) +#define GPIO_TIM1_CH1N_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_TIM1_CH1N_3 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_TIM1_CH2_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN11) +#define GPIO_TIM1_CH2_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN9) +#define GPIO_TIM1_CH2N_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN10) +#define GPIO_TIM1_CH2N_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN0) +#define GPIO_TIM1_CH2N_3 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_TIM1_CH3_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN13) +#define GPIO_TIM1_CH3_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN10) +#define GPIO_TIM1_CH3N_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN12) +#define GPIO_TIM1_CH3N_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN1) +#define GPIO_TIM1_CH3N_3 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN15) +#define GPIO_TIM1_CH4_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN14) +#define GPIO_TIM1_CH4_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_TIM1_ETR_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN7) +#define GPIO_TIM1_ETR_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN12) + +#define GPIO_TIM2_CH1_ETR_1 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN0) +#define GPIO_TIM2_CH1_ETR_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_TIM2_CH1_ETR_3 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN5) +#define GPIO_TIM2_CH2_1 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_TIM2_CH2_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_TIM2_CH3_1 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM2_CH3_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN10) +#define GPIO_TIM2_CH4_1 (GPIO_ALT | GPIO_AF2 | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TIM2_CH4_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN11) + +#define GPIO_TIM3_CH1_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN6) +#define GPIO_TIM3_CH1_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN3) +#define GPIO_TIM3_CH1_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_TIM3_CH1_4 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_TIM3_CH2_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN7) +#define GPIO_TIM3_CH2_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN4) +#define GPIO_TIM3_CH2_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_TIM3_CH2_4 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN5) +#define GPIO_TIM3_CH3_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN8) +#define GPIO_TIM3_CH3_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN5) +#define GPIO_TIM3_CH3_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN0) +#define GPIO_TIM3_CH4_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN9) +#define GPIO_TIM3_CH4_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN6) +#define GPIO_TIM3_CH4_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN1) +#define GPIO_TIM3_ETR_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN2) +#define GPIO_TIM3_ETR_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN2) + +#define GPIO_TIM14_CH1_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN1) +#define GPIO_TIM14_CH1_2 (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_TIM14_CH1_3 (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN7) + +#define GPIO_TIM15_BKIN_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN9) +#define GPIO_TIM15_BKIN_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_TIM15_CH1_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TIM15_CH1_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTF | GPIO_PIN9) +#define GPIO_TIM15_CH1_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_TIM15_CH1N_1 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN15) +#define GPIO_TIM15_CH1N_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_TIM15_CH2_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TIM15_CH2_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTF | GPIO_PIN10) +#define GPIO_TIM15_CH2_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTB | GPIO_PIN15) + +#define GPIO_TIM16_BKIN (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN5) +#define GPIO_TIM16_CH1_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN0) +#define GPIO_TIM16_CH1_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN8) +#define GPIO_TIM16_CH1_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_TIM16_CH1N (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN6) + +#define GPIO_TIM17_BKIN_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTA | GPIO_PIN10) +#define GPIO_TIM17_BKIN_2 (GPIO_ALT | GPIO_AF5 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_TIM17_CH1_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTE | GPIO_PIN1) +#define GPIO_TIM17_CH1_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN9) +#define GPIO_TIM17_CH1_3 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_TIM17_CH1N (GPIO_ALT | GPIO_AF2 | GPIO_PORTB | GPIO_PIN7) + +/* TSC */ + +#define GPIO_TSC_G1_IO1 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN0) +#define GPIO_TSC_G1_IO2 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_TSC_G1_IO3 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN2) +#define GPIO_TSC_G1_IO4 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN3) +#define GPIO_TSC_G2_IO1 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_TSC_G2_IO2 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN5) +#define GPIO_TSC_G2_IO3 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_TSC_G2_IO4 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN7) +#define GPIO_TSC_G3_IO1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN5) +#define GPIO_TSC_G3_IO2 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN0) +#define GPIO_TSC_G3_IO3 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN1) +#define GPIO_TSC_G3_IO4 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN2) +#define GPIO_TSC_G4_IO1 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN9) +#define GPIO_TSC_G4_IO2 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN10) +#define GPIO_TSC_G4_IO3 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_TSC_G4_IO4 (GPIO_ALT | GPIO_AF3 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_TSC_G5_IO1 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_TSC_G5_IO2 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_TSC_G5_IO3 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN6) +#define GPIO_TSC_G5_IO4 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN7) +#define GPIO_TSC_G6_IO1 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN11) +#define GPIO_TSC_G6_IO2 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_TSC_G6_IO3 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_TSC_G6_IO4 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_TSC_G7_IO1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN2) +#define GPIO_TSC_G7_IO2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN3) +#define GPIO_TSC_G7_IO3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN4) +#define GPIO_TSC_G7_IO4 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN5) +#define GPIO_TSC_G8_IO1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN12) +#define GPIO_TSC_G8_IO2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN13) +#define GPIO_TSC_G8_IO3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN14) +#define GPIO_TSC_G8_IO4 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN15) +#define GPIO_TSC_SYNC_1 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN10) +#define GPIO_TSC_SYNC_2 (GPIO_ALT | GPIO_AF3 | GPIO_PORTB | GPIO_PIN8) + +/* USARTs */ + +#define GPIO_USART1_CK (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN8) +#define GPIO_USART1_CTS (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_USART1_RTS (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_USART1_RX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN7) +#define GPIO_USART1_RX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN10) +#define GPIO_USART1_TX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTB | GPIO_PIN6) +#define GPIO_USART1_TX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN9) + +#define GPIO_USART2_CK_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN7) +#define GPIO_USART2_CK_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_USART2_CTS_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN3) +#define GPIO_USART2_CTS_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN0) +#define GPIO_USART2_RTS_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN4) +#define GPIO_USART2_RTS_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_USART2_RX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN6) +#define GPIO_USART2_RX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_USART2_RX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN3) +#define GPIO_USART2_TX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN5) +#define GPIO_USART2_TX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN14) +#define GPIO_USART2_TX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN2) + +#define GPIO_USART3_CK_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN10) +#define GPIO_USART3_CK_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_USART3_CK_3 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN0) +#define GPIO_USART3_CK_4 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN12) +#define GPIO_USART3_CTS_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN11) +#define GPIO_USART3_CTS_2 (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN6) +#define GPIO_USART3_CTS_3 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN13) +#define GPIO_USART3_RTS_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN12) +#define GPIO_USART3_RTS_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTD | GPIO_PIN2) +#define GPIO_USART3_RTS_3 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN1) +#define GPIO_USART3_RTS_4 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN14) +#define GPIO_USART3_RX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN9) +#define GPIO_USART3_RX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN11) +#define GPIO_USART3_RX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN5) +#define GPIO_USART3_RX_4 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN11) +#define GPIO_USART3_TX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN8) +#define GPIO_USART3_TX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN10) +#define GPIO_USART3_TX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN4) +#define GPIO_USART3_TX_4 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN10) + +#define GPIO_USART4_CK (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_USART4_CTS (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN7) +#define GPIO_USART4_RTS (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN15) +#define GPIO_USART4_RX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN11) +#define GPIO_USART4_RX_2 (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_USART4_TX_1 (GPIO_ALT | GPIO_AF0 | GPIO_PORTC | GPIO_PIN10) +#define GPIO_USART4_TX_2 (GPIO_ALT | GPIO_AF4 | GPIO_PORTA | GPIO_PIN0) + +#define GPIO_USART5_CK_RST_1 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN5) +#define GPIO_USART5_CK_RST_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN7) +#define GPIO_USART5_RX_1 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_USART5_RX_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTD | GPIO_PIN2) +#define GPIO_USART5_RX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN11) +#define GPIO_USART5_TX_1 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_USART5_TX_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTC | GPIO_PIN12) +#define GPIO_USART5_TX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTE | GPIO_PIN10) + +#define GPIO_USART6_TX_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN4) +#define GPIO_USART6_RX_1 (GPIO_ALT | GPIO_AF5 | GPIO_PORTA | GPIO_PIN5) +#define GPIO_USART6_TX_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTC | GPIO_PIN0) +#define GPIO_USART6_RX_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTC | GPIO_PIN1) +#define GPIO_USART6_TX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTF | GPIO_PIN9) +#define GPIO_USART6_RX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTF | GPIO_PIN10) +#define GPIO_USART6_CK_RST (GPIO_ALT | GPIO_AF2 | GPIO_PORTF | GPIO_PIN3) + +#define GPIO_USART7_TX_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN0) +#define GPIO_USART7_RX_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN1) +#define GPIO_USART7_TX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN6) +#define GPIO_USART7_RX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN7) +#define GPIO_USART7_TX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTF | GPIO_PIN2) +#define GPIO_USART7_RX_3 (GPIO_ALT | GPIO_AF1 | GPIO_PORTF | GPIO_PIN3) +#define GPIO_USART7_CK_RST_1 (GPIO_ALT | GPIO_AF2 | GPIO_PORTD | GPIO_PIN15) +#define GPIO_USART7_CK_RST_2 (GPIO_ALT | GPIO_AF2 | GPIO_PORTF | GPIO_PIN2) + +#define GPIO_USART8_TX_1 (GPIO_ALT | GPIO_AF2 | GPIO_PORTC | GPIO_PIN2) +#define GPIO_USART8_RX_1 (GPIO_ALT | GPIO_AF2 | GPIO_PORTC | GPIO_PIN3) +#define GPIO_USART8_TX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN8) +#define GPIO_USART8_RX_2 (GPIO_ALT | GPIO_AF1 | GPIO_PORTC | GPIO_PIN9) +#define GPIO_USART8_TX_3 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN8) +#define GPIO_USART8_RX_3 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN13) +#define GPIO_USART8_CK_RST (GPIO_ALT | GPIO_AF2 | GPIO_PORTD | GPIO_PIN14) + +#endif /* __ARCH_ARM_SRC_STM32F0_CHIP_STM32F09X_PINMAP_H */ diff --git a/arch/arm/src/stm32f0/chip/stm32f0_memorymap.h b/arch/arm/src/stm32f0/chip/stm32f0_memorymap.h index 7ff37fcdcd..bc2436f476 100644 --- a/arch/arm/src/stm32f0/chip/stm32f0_memorymap.h +++ b/arch/arm/src/stm32f0/chip/stm32f0_memorymap.h @@ -44,8 +44,9 @@ #include #include "chip.h" -#if defined(CONFIG_STM32F0_STM32F05X) || defined(CONFIG_STM32F0_STM32F07X) -# include "chip/stm32f05xf07x_memorymap.h" +#if defined(CONFIG_STM32F0_STM32F05X) || defined(CONFIG_STM32F0_STM32F07X) \ + || defined(CONFIG_STM32F0_STM32F09X) +# include "chip/stm32f05xf07xf09x_memorymap.h" #else # error "Unsupported STM32 memory map" #endif diff --git a/arch/arm/src/stm32f0/chip/stm32f0_pinmap.h b/arch/arm/src/stm32f0/chip/stm32f0_pinmap.h index 37893a4c12..671264c893 100644 --- a/arch/arm/src/stm32f0/chip/stm32f0_pinmap.h +++ b/arch/arm/src/stm32f0/chip/stm32f0_pinmap.h @@ -47,6 +47,8 @@ # include "chip/stm32f05x_pinmap.h" #elif defined(CONFIG_STM32F0_STM32F07X) # include "chip/stm32f07x_pinmap.h" +#elif defined(CONFIG_STM32F0_STM32F09X) +# include "chip/stm32f09x_pinmap.h" #else # error "Unsupported STM32F0 pin map" #endif diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index 8e9904a0ab..ae131dd2f1 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -1821,6 +1821,7 @@ config STM32F7_HAVE_RTC_COUNTER config STM32F7_HAVE_RTC_SUBSECONDS bool + select ARCH_HAVE_RTC_SUBSECONDS default y config RTC_MAGIC_REG diff --git a/arch/arm/src/stm32f7/stm32_rtc.c b/arch/arm/src/stm32f7/stm32_rtc.c index 4583dfaf1e..a314836427 100644 --- a/arch/arm/src/stm32f7/stm32_rtc.c +++ b/arch/arm/src/stm32f7/stm32_rtc.c @@ -1178,7 +1178,7 @@ int up_rtc_getdatetime(FAR struct tm *tp) } rtc_dumptime((FAR const struct tm *)tp, &usecs, "Returning"); -#else /* CONFIG_STM32_HAVE_RTC_SUBSECONDS */ +#else /* CONFIG_STM32F7_HAVE_RTC_SUBSECONDS */ rtc_dumptime((FAR const struct tm *)tp, NULL, "Returning"); #endif @@ -1215,6 +1215,40 @@ int up_rtc_getdatetime(FAR struct tm *tp) } #endif +/************************************************************************************ + * Name: up_rtc_getdatetime_with_subseconds + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: This interface exposes sub-second accuracy capability of RTC hardware. + * This interface allow maintaining timing accuracy when system time needs constant + * resynchronization with RTC, for example with board level power-save mode utilizing + * deep-sleep modes such as STOP on STM32 MCUs. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * nsec - The location to return the subsecond time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_RTC_SUBSECONDS +# ifndef CONFIG_STM32F7_HAVE_RTC_SUBSECONDS +# error "Invalid config, enable CONFIG_STM32F7_HAVE_RTC_SUBSECONDS." +# endif +int up_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec) +{ + return stm32_rtc_getdatetime_with_subseconds(tp, nsec); +} +#endif + /**************************************************************************** * Name: stm32_rtc_setdatetime * diff --git a/configs/nucleo-f072rb/README.txt b/configs/nucleo-f072rb/README.txt index 033b7b7560..118d24d9af 100644 --- a/configs/nucleo-f072rb/README.txt +++ b/configs/nucleo-f072rb/README.txt @@ -1,9 +1,9 @@ Nucleo-F072RB README ==================== - This README file discusess the port of NuttX to the STMicro Nucleo-F4072RB - board. That board features the STM32F072RBT6 MCU with 128KiB with 128KiB - of FLASH and 16KiB of SRAM. + This README file discusses the port of NuttX to the STMicro Nucleo-F072RB + board. That board features the STM32F072RBT6 MCU with 128KiB of FLASH + and 16KiB of SRAM. Contents ======== @@ -53,8 +53,8 @@ LEDs These LEDs are not used by the board port unless CONFIG_ARCH_LEDS is defined. In that case, the usage by the board port is defined in - include/board.h and src/sam_leds.c. The LEDs are used to encode OS-related - events as follows when the red LED (PE24) is available: + include/board.h and src/stm32_autoleds.c. The LEDs are used to encode + OS-related events as follows when the red LED (PE24) is available: SYMBOL Meaning LD2 ------------------- ----------------------- ----------- @@ -192,11 +192,11 @@ Configurations Information Common to All Configurations ---------------------------------------- - Each Clicker2 configuration is maintained in a sub-directory and can be + Each configuration is maintained in a sub-directory and can be selected as follow: cd tools - ./configure.sh nucleo-f702rb/ + ./configure.sh nucleo-f072rb/ cd - . ./setenv.sh diff --git a/fs/vfs/fs_select.c b/fs/vfs/fs_select.c index acb42b35ae..b3ba38bf42 100644 --- a/fs/vfs/fs_select.c +++ b/fs/vfs/fs_select.c @@ -133,14 +133,19 @@ int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds, } } + if (npfds <= 0) + { + errcode = EINVAL; + goto errout; + } + /* Allocate the descriptor list for poll() */ pollset = (struct pollfd *)kmm_zalloc(npfds * sizeof(struct pollfd)); if (!pollset) { - set_errno(ENOMEM); - leave_cancellation_point(); - return ERROR; + errcode = ENOMEM; + goto errout; } /* Initialize the descriptor list for poll() */ @@ -279,16 +284,16 @@ int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds, /* Did poll() fail above? */ - if (ret < 0) + if (ret >= 0) { - /* Yes.. restore the errno value */ - - set_errno(errcode); + leave_cancellation_point(); + return ret; } +errout: + set_errno(errcode); leave_cancellation_point(); - return ret; + return ERROR; } #endif /* CONFIG_DISABLE_POLL */ - diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 05597f6d59..925ae988ed 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -2185,6 +2185,35 @@ int up_rtc_gettime(FAR struct timespec *tp); int up_rtc_getdatetime(FAR struct tm *tp); #endif +/************************************************************************************ + * Name: up_rtc_getdatetime_with_subseconds + * + * Description: + * Get the current date and time from the date/time RTC. This interface + * is only supported by the date/time RTC hardware implementation. + * It is used to replace the system timer. It is only used by the RTOS during + * initialization to set up the system time when CONFIG_RTC and CONFIG_RTC_DATETIME + * are selected (and CONFIG_RTC_HIRES is not). + * + * NOTE: This interface exposes sub-second accuracy capability of RTC hardware. + * This interface allow maintaining timing accuracy when system time needs constant + * resynchronization with RTC, for example on MCU with low-power state that + * stop system timer. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * nsec - The location to return the subsecond time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#if defined(CONFIG_RTC) && defined(CONFIG_RTC_DATETIME) && \ + defined(CONFIG_ARCH_HAVE_RTC_SUBSECONDS) +int up_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec); +#endif + /************************************************************************************ * Name: up_rtc_settime * diff --git a/include/nuttx/clock.h b/include/nuttx/clock.h index 5684fef938..c6a1deafc5 100644 --- a/include/nuttx/clock.h +++ b/include/nuttx/clock.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/clock.h * - * Copyright (C) 2007-2009, 2011-2012, 2014, 2016 Gregory Nutt. + * Copyright (C) 2007-2009, 2011-2012, 2014, 2016-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * @@ -50,6 +50,7 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ + /* Configuration ************************************************************/ /* Efficient, direct access to OS global timer variables will be supported * if the execution environment has direct access to kernel global data. @@ -71,12 +72,12 @@ /* Case 1: There is no global timer data */ #elif defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__) - /* Case 3: Kernel mode of protected kernel build */ + /* Case 3: Kernel mode of protected kernel build */ # define __HAVE_KERNEL_GLOBALS 1 #elif defined(CONFIG_BUILD_KERNEL) && defined(__KERNEL__) - /* Case 3: Kernel only build */ + /* Case 3: Kernel only build */ # define __HAVE_KERNEL_GLOBALS 1 @@ -198,6 +199,14 @@ typedef uint64_t systime_t; typedef uint32_t systime_t; #endif +/* This type used to hold relative ticks that may have negative value */ + +#ifdef CONFIG_SYSTEM_TIME64 +typedef int64_t ssystime_t; +#else +typedef int32_t ssystime_t; +#endif + /**************************************************************************** * Public Data ****************************************************************************/ @@ -261,6 +270,37 @@ EXTERN volatile systime_t g_system_timer; void clock_synchronize(void); #endif +/**************************************************************************** + * Name: clock_resynchronize + * + * Description: + * Resynchronize the system timer to a hardware RTC. The user can + * explicitly re-synchronize the system timer to the RTC under certain + * conditions where the system timer is known to be in error. For example, + * in certain low-power states, the system timer may be stopped but the + * RTC will continue keep correct time. After recovering from such + * low-power state, this function should be called to restore the correct + * system time. Function also keeps monotonic clock at rate of RTC. + * + * Calling this function will not result in system time going "backward" in + * time. If setting system time with RTC would result time going "backward" + * then resynchronization is not performed. + * + * Parameters: + * diff: amount of time system-time is adjusted forward with RTC + * + * Return Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_RTC) && !defined(CONFIG_SCHED_TICKLESS) && \ + !defined(CONFIG_CLOCK_TIMEKEEPING) +void clock_resynchronize(FAR struct timespec *rtc_diff); +#endif + /**************************************************************************** * Function: clock_systimer * diff --git a/sched/clock/clock.h b/sched/clock/clock.h index cd8066615b..7e6a1c0933 100644 --- a/sched/clock/clock.h +++ b/sched/clock/clock.h @@ -1,7 +1,7 @@ /**************************************************************************** * sched/clock/clock.h * - * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2014, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -81,6 +81,10 @@ extern volatile uint32_t g_system_timer; #ifndef CONFIG_CLOCK_TIMEKEEPING extern struct timespec g_basetime; + +#ifdef CONFIG_CLOCK_MONOTONIC +extern struct timespec g_monotonic_basetime; +#endif #endif /**************************************************************************** @@ -94,9 +98,10 @@ void weak_function clock_timer(void); int clock_abstime2ticks(clockid_t clockid, FAR const struct timespec *abstime, - FAR int *ticks); -int clock_time2ticks(FAR const struct timespec *reltime, FAR int *ticks); -int clock_ticks2time(int ticks, FAR struct timespec *reltime); + FAR ssystime_t *ticks); +int clock_time2ticks(FAR const struct timespec *reltime, + FAR ssystime_t *ticks); +int clock_ticks2time(ssystime_t ticks, FAR struct timespec *reltime); void clock_timespec_add(FAR const struct timespec *ts1, FAR const struct timespec *ts2, FAR struct timespec *ts3); diff --git a/sched/clock/clock_abstime2ticks.c b/sched/clock/clock_abstime2ticks.c index d21e706e39..5ac7081a20 100644 --- a/sched/clock/clock_abstime2ticks.c +++ b/sched/clock/clock_abstime2ticks.c @@ -99,7 +99,7 @@ static long compare_timespec(FAR const struct timespec *a, ****************************************************************************/ int clock_abstime2ticks(clockid_t clockid, FAR const struct timespec *abstime, - FAR int *ticks) + FAR ssystime_t *ticks) { struct timespec currtime; struct timespec reltime; diff --git a/sched/clock/clock_gettime.c b/sched/clock/clock_gettime.c index 74ffea5be8..731c6a2ae3 100644 --- a/sched/clock/clock_gettime.c +++ b/sched/clock/clock_gettime.c @@ -100,6 +100,33 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) #else ret = clock_systimespec(tp); #endif + +#ifndef CONFIG_CLOCK_TIMEKEEPING + if (ret == OK) + { + irqstate_t flags; + + /* Add the offset time to this. The offset time allows + * CLOCK_MONOTONIC be introduced additional increases to systime. + */ + + flags = enter_critical_section(); + + tp->tv_sec += (uint32_t)g_monotonic_basetime.tv_sec; + tp->tv_nsec += (uint32_t)g_monotonic_basetime.tv_nsec; + + leave_critical_section(flags); + + /* Handle carry to seconds. */ + + if (tp->tv_nsec >= NSEC_PER_SEC) + { + carry = tp->tv_nsec / NSEC_PER_SEC; + tp->tv_sec += carry; + tp->tv_nsec -= (carry * NSEC_PER_SEC); + } + } +#endif /* CONFIG_CLOCK_TIMEKEEPING */ } else #endif @@ -129,14 +156,20 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) #ifndef CONFIG_CLOCK_TIMEKEEPING if (ret == OK) { + irqstate_t flags; + /* Add the base time to this. The base time is the time-of-day * setting. When added to the elapsed time since the time-of-day * was last set, this gives us the current time. */ + flags = enter_critical_section(); + ts.tv_sec += (uint32_t)g_basetime.tv_sec; ts.tv_nsec += (uint32_t)g_basetime.tv_nsec; + leave_critical_section(flags); + /* Handle carry to seconds. */ if (ts.tv_nsec >= NSEC_PER_SEC) diff --git a/sched/clock/clock_initialize.c b/sched/clock/clock_initialize.c index 0113e5e0fc..d8a7b13497 100644 --- a/sched/clock/clock_initialize.c +++ b/sched/clock/clock_initialize.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/clock/clock_initialize.c * - * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011-2012, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -68,6 +68,18 @@ #define SEC_PER_HOUR ((time_t)60 * SEC_PER_MIN) #define SEC_PER_DAY ((time_t)24 * SEC_PER_HOUR) +#if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_SYSTEM_TIME64) +/* Initial system timer ticks value close to maximum 32-bit value, to test + * 64-bit system-timer after going over 32-bit value. This is to make errors + * of casting 64-bit system-timer to 32-bit variables more visible. + */ + +# define INITIAL_SYSTEM_TIMER_TICKS \ + ((uint64_t)(UINT32_MAX - (TICK_PER_SEC * 5))) +#else +# define INITIAL_SYSTEM_TIMER_TICKS 0 +#endif + /**************************************************************************** * Public Data ****************************************************************************/ @@ -80,8 +92,14 @@ volatile uint32_t g_system_timer; #endif #endif +#ifndef CONFIG_CLOCK_TIMEKEEPING struct timespec g_basetime; +#ifdef CONFIG_CLOCK_MONOTONIC +struct timespec g_monotonic_basetime; +#endif +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -101,17 +119,22 @@ struct timespec g_basetime; static inline int clock_basetime(FAR struct timespec *tp) { struct tm rtctime; + long nsecs = 0; int ret; /* Get the broken-out time from the date/time RTC. */ +#ifdef CONFIG_ARCH_HAVE_RTC_SUBSECONDS + ret = up_rtc_getdatetime_with_subseconds(&rtctime, &nsecs); +#else ret = up_rtc_getdatetime(&rtctime); +#endif if (ret >= 0) { /* And use the broken-out time to initialize the system time */ tp->tv_sec = mktime(&rtctime); - tp->tv_nsec = 0; + tp->tv_nsec = nsecs; } return ret; @@ -181,8 +204,36 @@ static void clock_inittime(void) clock_basetime(&g_basetime); #endif #ifndef CONFIG_SCHED_TICKLESS - g_system_timer = 0; -#endif + g_system_timer = INITIAL_SYSTEM_TIMER_TICKS; + if (g_system_timer > 0) + { + struct timespec ts; + + (void)clock_ticks2time((ssystime_t)g_system_timer, &ts); + + /* Adjust base time to hide initial timer ticks. */ + + g_basetime.tv_sec -= ts.tv_sec; + g_basetime.tv_nsec -= ts.tv_nsec; + while (g_basetime.tv_nsec < 0) + { + g_basetime.tv_nsec += NSEC_PER_SEC; + g_basetime.tv_sec--; + } + +#ifdef CONFIG_CLOCK_MONOTONIC + /* Adjust monotonic clock offset to hide initial timer ticks. */ + + g_monotonic_basetime.tv_sec -= ts.tv_sec; + g_monotonic_basetime.tv_nsec -= ts.tv_nsec; + while (g_monotonic_basetime.tv_nsec < 0) + { + g_monotonic_basetime.tv_nsec += NSEC_PER_SEC; + g_monotonic_basetime.tv_sec--; + } +#endif /* CONFIG_CLOCK_MONOTONIC */ + } +#endif /* !CONFIG_SCHED_TICKLESS */ #else clock_inittimekeeping(); #endif @@ -256,6 +307,179 @@ void clock_synchronize(void) } #endif +/**************************************************************************** + * Name: clock_resynchronize + * + * Description: + * Resynchronize the system timer to a hardware RTC. The user can + * explicitly re-synchronize the system timer to the RTC under certain + * conditions where the system timer is known to be in error. For example, + * in certain low-power states, the system timer may be stopped but the + * RTC will continue keep correct time. After recovering from such + * low-power state, this function should be called to restore the correct + * system time. Function also keeps monotonic clock at rate of RTC. + * + * Calling this function will not result in system time going "backward" in + * time. If setting system time with RTC would result time going "backward" + * then resynchronization is not performed. + * + * Parameters: + * rtc_diff: amount of time system-time is adjusted forward with RTC + * + * Return Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#if defined(CONFIG_RTC) && !defined(CONFIG_SCHED_TICKLESS) && \ + !defined(CONFIG_CLOCK_TIMEKEEPING) +void clock_resynchronize(FAR struct timespec *rtc_diff) +{ + struct timespec rtc_time, bias, curr_ts; + struct timespec rtc_diff_tmp; + irqstate_t flags; + int32_t carry; + int ret; + + if (rtc_diff == NULL) + { + rtc_diff = &rtc_diff_tmp; + } + + /* Set the time value to match the RTC */ + + flags = enter_critical_section(); + + /* Get RTC time */ + + ret = clock_basetime(&rtc_time); + if (ret < 0) + { + /* Error reading RTC, skip resynchronization. */ + + sinfo("rtc error %d, skip resync\n", ret); + + rtc_diff->tv_sec = 0; + rtc_diff->tv_nsec = 0; + goto skip; + } + + /* Get the elapsed time since power up (in milliseconds). This is a + * bias value that we need to use to correct the base time. + */ + + (void)clock_systimespec(&bias); + + /* Add the base time to this. The base time is the time-of-day + * setting. When added to the elapsed time since the time-of-day + * was last set, this gives us the current time. + */ + + curr_ts.tv_sec = bias.tv_sec + g_basetime.tv_sec; + curr_ts.tv_nsec = bias.tv_nsec + g_basetime.tv_nsec; + + /* Handle carry to seconds. */ + + if (curr_ts.tv_nsec >= NSEC_PER_SEC) + { + carry = curr_ts.tv_nsec / NSEC_PER_SEC; + curr_ts.tv_sec += carry; + curr_ts.tv_nsec -= (carry * NSEC_PER_SEC); + } + + /* Check if RTC has advanced past system time. */ + + if (curr_ts.tv_sec > rtc_time.tv_sec || + (curr_ts.tv_sec == rtc_time.tv_sec && curr_ts.tv_nsec >= rtc_time.tv_nsec)) + { + /* Setting system time with RTC now would result time going + * backwards. Skip resynchronization. + */ + + sinfo("skip resync\n"); + + rtc_diff->tv_sec = 0; + rtc_diff->tv_nsec = 0; + } + else + { + /* Save RTC time as the new base time. */ + + g_basetime.tv_sec = rtc_time.tv_sec; + g_basetime.tv_nsec = rtc_time.tv_nsec; + + /* Subtract that bias from the basetime so that when the system + * timer is again added to the base time, the result is the current + * time relative to basetime. + */ + + if (g_basetime.tv_nsec < bias.tv_nsec) + { + g_basetime.tv_nsec += NSEC_PER_SEC; + g_basetime.tv_sec--; + } + + /* Result could be negative seconds */ + + g_basetime.tv_nsec -= bias.tv_nsec; + g_basetime.tv_sec -= bias.tv_sec; + + sinfo("basetime=(%ld,%lu) bias=(%ld,%lu)\n", + (long)g_basetime.tv_sec, (unsigned long)g_basetime.tv_nsec, + (long)bias.tv_sec, (unsigned long)bias.tv_nsec); + + /* Output difference between time at entry and new current time. */ + + rtc_diff->tv_sec = (bias.tv_sec + g_basetime.tv_sec) - curr_ts.tv_sec; + rtc_diff->tv_nsec = (bias.tv_nsec + g_basetime.tv_nsec) - curr_ts.tv_nsec; + + /* Handle carry to seconds. */ + + if (rtc_diff->tv_nsec < 0) + { + carry = -((-(rtc_diff->tv_nsec + 1)) / NSEC_PER_SEC + 1); + } + else if (rtc_diff->tv_nsec >= NSEC_PER_SEC) + { + carry = rtc_diff->tv_nsec / NSEC_PER_SEC; + } + else + { + carry = 0; + } + + if (carry) + { + rtc_diff->tv_sec += carry; + rtc_diff->tv_nsec -= (carry * NSEC_PER_SEC); + } + +#ifdef CONFIG_CLOCK_MONOTONIC + /* Monotonic clock follows wall time since system start-up. Adjust + * CLOCK_MONOTONIC same amount as CLOCK_REALTIME. + */ + + g_monotonic_basetime.tv_sec += (uint32_t)rtc_diff->tv_sec; + g_monotonic_basetime.tv_nsec += (uint32_t)rtc_diff->tv_nsec; + + /* Handle carry to seconds. */ + + if (g_monotonic_basetime.tv_nsec >= NSEC_PER_SEC) + { + carry = g_monotonic_basetime.tv_nsec / NSEC_PER_SEC; + g_monotonic_basetime.tv_sec += carry; + g_monotonic_basetime.tv_nsec -= (carry * NSEC_PER_SEC); + } +#endif + } + +skip: + leave_critical_section(flags); +} +#endif + /**************************************************************************** * Name: clock_timer * diff --git a/sched/clock/clock_ticks2time.c b/sched/clock/clock_ticks2time.c index 33353193a8..899ecd9818 100644 --- a/sched/clock/clock_ticks2time.c +++ b/sched/clock/clock_ticks2time.c @@ -63,9 +63,9 @@ * ****************************************************************************/ -int clock_ticks2time(int ticks, FAR struct timespec *reltime) +int clock_ticks2time(ssystime_t ticks, FAR struct timespec *reltime) { - int remainder; + ssystime_t remainder; reltime->tv_sec = ticks / TICK_PER_SEC; remainder = ticks - TICK_PER_SEC * reltime->tv_sec; diff --git a/sched/clock/clock_time2ticks.c b/sched/clock/clock_time2ticks.c index 5bb613b61d..5f0bc28c40 100644 --- a/sched/clock/clock_time2ticks.c +++ b/sched/clock/clock_time2ticks.c @@ -67,7 +67,8 @@ * ****************************************************************************/ -int clock_time2ticks(FAR const struct timespec *reltime, FAR int *ticks) +int clock_time2ticks(FAR const struct timespec *reltime, + FAR ssystime_t *ticks) { #ifdef CONFIG_HAVE_LONG_LONG int64_t relnsec; @@ -83,7 +84,7 @@ int clock_time2ticks(FAR const struct timespec *reltime, FAR int *ticks) * that is greater than or equal to the exact number of tick. */ - *ticks = (int)((relnsec + NSEC_PER_TICK - 1) / NSEC_PER_TICK); + *ticks = (ssystime_t)((relnsec + NSEC_PER_TICK - 1) / NSEC_PER_TICK); return OK; #else int32_t relusec; @@ -110,7 +111,7 @@ int clock_time2ticks(FAR const struct timespec *reltime, FAR int *ticks) * that is greater than or equal to the exact number of tick. */ - *ticks = (int)((relusec + USEC_PER_TICK - 1) / USEC_PER_TICK); + *ticks = (ssystime_t)((relusec + USEC_PER_TICK - 1) / USEC_PER_TICK); return OK; #endif } diff --git a/sched/mqueue/mq_timedreceive.c b/sched/mqueue/mq_timedreceive.c index 9df2a6ab61..096f057c59 100644 --- a/sched/mqueue/mq_timedreceive.c +++ b/sched/mqueue/mq_timedreceive.c @@ -230,7 +230,7 @@ ssize_t mq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen, if (mqdes->msgq->msglist.head == NULL) { - int ticks; + ssystime_t ticks; /* Convert the timespec to clock ticks. We must have interrupts * disabled here so that this time stays valid until the wait begins. diff --git a/sched/mqueue/mq_timedsend.c b/sched/mqueue/mq_timedsend.c index 83e25515eb..98f3221082 100644 --- a/sched/mqueue/mq_timedsend.c +++ b/sched/mqueue/mq_timedsend.c @@ -173,7 +173,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio, FAR struct mqueue_inode_s *msgq; FAR struct mqueue_msg_s *mqmsg = NULL; irqstate_t flags; - int ticks; + ssystime_t ticks; int result; int ret = ERROR; diff --git a/sched/pthread/pthread_condtimedwait.c b/sched/pthread/pthread_condtimedwait.c index 22ce470770..98521665fd 100644 --- a/sched/pthread/pthread_condtimedwait.c +++ b/sched/pthread/pthread_condtimedwait.c @@ -169,7 +169,7 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex, FAR struct tcb_s *rtcb = this_task(); irqstate_t flags; uint16_t oldstate; - int ticks; + ssystime_t ticks; int mypid = (int)getpid(); int ret = OK; int status; diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 4fbf646424..23ebd95489 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -358,8 +358,8 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, if (policy == SCHED_SPORADIC) { FAR struct sporadic_s *sporadic; - int repl_ticks; - int budget_ticks; + ssystime_t repl_ticks; + ssystime_t budget_ticks; /* Convert timespec values to system clock ticks */ diff --git a/sched/sched/sched_getparam.c b/sched/sched/sched_getparam.c index 155049ff1f..72833d9471 100644 --- a/sched/sched/sched_getparam.c +++ b/sched/sched/sched_getparam.c @@ -127,8 +127,10 @@ int sched_getparam (pid_t pid, FAR struct sched_param *param) param->sched_ss_low_priority = (int)sporadic->low_priority; param->sched_ss_max_repl = (int)sporadic->max_repl; - clock_ticks2time((int)sporadic->repl_period, ¶m->sched_ss_repl_period); - clock_ticks2time((int)sporadic->budget, ¶m->sched_ss_init_budget); + clock_ticks2time((ssystime_t)sporadic->repl_period, + ¶m->sched_ss_repl_period); + clock_ticks2time((ssystime_t)sporadic->budget, + ¶m->sched_ss_init_budget); } else { diff --git a/sched/sched/sched_setparam.c b/sched/sched/sched_setparam.c index 824d51b53b..93bfccfe43 100644 --- a/sched/sched/sched_setparam.c +++ b/sched/sched/sched_setparam.c @@ -134,8 +134,8 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param) { FAR struct sporadic_s *sporadic; irqstate_t flags; - int repl_ticks; - int budget_ticks; + ssystime_t repl_ticks; + ssystime_t budget_ticks; if (param->sched_ss_max_repl < 1 || param->sched_ss_max_repl > CONFIG_SCHED_SPORADIC_MAXREPL) diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c index 20026e7ec9..58fb3d0969 100644 --- a/sched/sched/sched_setscheduler.c +++ b/sched/sched/sched_setscheduler.c @@ -180,8 +180,8 @@ int sched_setscheduler(pid_t pid, int policy, case SCHED_SPORADIC: { FAR struct sporadic_s *sporadic; - int repl_ticks; - int budget_ticks; + ssystime_t repl_ticks; + ssystime_t budget_ticks; if (param->sched_ss_max_repl < 1 || param->sched_ss_max_repl > CONFIG_SCHED_SPORADIC_MAXREPL) diff --git a/sched/semaphore/sem_timedwait.c b/sched/semaphore/sem_timedwait.c index 23c16cc2d5..2ab32f6b86 100644 --- a/sched/semaphore/sem_timedwait.c +++ b/sched/semaphore/sem_timedwait.c @@ -98,7 +98,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime) { FAR struct tcb_s *rtcb = this_task(); irqstate_t flags; - int ticks; + ssystime_t ticks; int errcode; int ret = ERROR; diff --git a/sched/signal/sig_nanosleep.c b/sched/signal/sig_nanosleep.c index 5b3a461b53..1e8163e8a3 100644 --- a/sched/signal/sig_nanosleep.c +++ b/sched/signal/sig_nanosleep.c @@ -170,7 +170,7 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) { systime_t elapsed; systime_t remaining; - int ticks; + ssystime_t ticks; /* REVISIT: The conversion from time to ticks and back could * be avoided. clock_timespec_subtract() would be used instead @@ -192,16 +192,16 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp) * amount of time that we failed to wait. */ - if (elapsed >= (uint32_t)ticks) + if (elapsed >= (systime_t)ticks) { remaining = 0; } else { - remaining = (uint32_t)ticks - elapsed; + remaining = (systime_t)ticks - elapsed; } - (void)clock_ticks2time((int)remaining, rmtp); + (void)clock_ticks2time((ssystime_t)remaining, rmtp); } leave_critical_section(flags); diff --git a/sched/timer/timer_gettime.c b/sched/timer/timer_gettime.c index c1e58899b4..25e0168765 100644 --- a/sched/timer/timer_gettime.c +++ b/sched/timer/timer_gettime.c @@ -86,7 +86,7 @@ int timer_gettime(timer_t timerid, FAR struct itimerspec *value) { FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid; - int ticks; + ssystime_t ticks; if (!timer || !value) { diff --git a/sched/timer/timer_settime.c b/sched/timer/timer_settime.c index aa6007f95a..9e1fb5d4b2 100644 --- a/sched/timer/timer_settime.c +++ b/sched/timer/timer_settime.c @@ -304,7 +304,7 @@ int timer_settime(timer_t timerid, int flags, { FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid; irqstate_t intflags; - int delay; + ssystime_t delay; int ret = OK; /* Some sanity checks */ @@ -332,7 +332,11 @@ int timer_settime(timer_t timerid, int flags, if (value->it_interval.tv_sec > 0 || value->it_interval.tv_nsec > 0) { - (void)clock_time2ticks(&value->it_interval, &timer->pt_delay); + (void)clock_time2ticks(&value->it_interval, &delay); + + /* REVISIT: Should pt_delay be ssystime_t? */ + + timer->pt_delay = (int)delay; } else { @@ -379,6 +383,10 @@ int timer_settime(timer_t timerid, int flags, if (delay > 0) { + /* REVISIT: Should pt_last be ssystime_t? Should wd_start delay be + * ssystime_t? + */ + timer->pt_last = delay; ret = wd_start(timer->pt_wdog, delay, (wdentry_t)timer_timeout, 1, (uint32_t)((wdparm_t)timer));