From 9913d1b6ffb81eccdc2c28ae9041872237195856 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 18 Nov 2018 11:36:01 +0000 Subject: Changes to RTCv2 driver, not finished yet. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12433 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- os/hal/ports/STM32/LLD/EXTIv1/notes.txt | 4 +- os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.h | 14 ++ os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.h | 9 +- os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c | 234 +++++++++++++++++++++++++- os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h | 47 +++++- os/hal/ports/STM32/STM32F4xx/hal_lld.h | 1 + os/hal/ports/STM32/STM32F4xx/platform.mk | 1 + os/hal/ports/STM32/STM32F4xx/stm32_registry.h | 33 ++-- 8 files changed, 318 insertions(+), 25 deletions(-) (limited to 'os/hal') diff --git a/os/hal/ports/STM32/LLD/EXTIv1/notes.txt b/os/hal/ports/STM32/LLD/EXTIv1/notes.txt index bf6aefb7f..ac83cf58d 100644 --- a/os/hal/ports/STM32/LLD/EXTIv1/notes.txt +++ b/os/hal/ports/STM32/LLD/EXTIv1/notes.txt @@ -10,5 +10,5 @@ STM32_EXTI_NUM_LINES - Number of EXTI lines, it can be between 0 and 63. STM32_EXTI_IMR1_MASK - Mask of the fixed lines that must not be handled by the driver (0..31). STM32_EXTI_IMR2_MASK - Mask of the fixed lines that must not be - handled by the driver (32..63). - \ No newline at end of file + handled by the driver (32..63). Only required + if STM32_EXTI_NUM_LINES is greater than 32. diff --git a/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.h b/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.h index bd1f53222..cb4b2826d 100644 --- a/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.h +++ b/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.h @@ -88,6 +88,20 @@ typedef uint32_t extimode_t; /* Driver macros. */ /*===========================================================================*/ +/** + * @brief From group 1 line number to mask. + * + * @param[in] line line number in range 0..31 + */ +#define EXTI_MASK1(line) (uint32_t)(1U << (line)) + +/** + * @brief From group 2 line number to mask. + * + * @param[in] line line number in range 32..63 + */ +#define EXTI_MASK2(line) (uint32_t)(1U << ((line) - 32U)) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ diff --git a/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.h b/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.h index 1903af378..821985158 100644 --- a/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.h +++ b/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.h @@ -84,11 +84,6 @@ /* Driver data structures and types. */ /*===========================================================================*/ -/** - * @brief Type of a structure representing an RTC alarm time stamp. - */ -typedef struct RTCAlarm RTCAlarm; - /** * @brief Type of an RTC event. */ @@ -104,9 +99,9 @@ typedef enum { typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); /** - * @brief Structure representing an RTC alarm time stamp. + * @brief Type of a structure representing an RTC alarm time stamp. */ -struct RTCAlarm { +typedef struct hsl_rtc_alarm { /** * @brief Seconds since UNIX epoch. */ diff --git a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c index 19ed93e14..b5798bc80 100644 --- a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c +++ b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c @@ -235,6 +235,207 @@ struct RTCDriverVMT _rtc_lld_vmt = { /* Driver interrupt handlers. */ /*===========================================================================*/ +#if defined(STM32_RTC_COMMON_HANDLER) +#if !defined(STM32_RTC_SUPPRESS_COMMON_ISR) +/** + * @brief RTC common interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_COMMON_HANDLER) { + uint32_t isr; + + OSAL_IRQ_PROLOGUE(); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = 0U; + + if (RTCD1.callback != NULL) { + if ((isr & RTC_ISR_WUTF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); + } +#if defined(RTC_ISR_ALRAF) + if ((isr & RTC_ISR_ALRAF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); + } +#endif +#if defined(RTC_ISR_ALRBF) + if ((isr & RTC_ISR_ALRBF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); + } +#endif +#if defined(RTC_ISR_ITSF) + if ((isr & RTC_ISR_ITSF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_ITS); + } +#endif +#if defined(RTC_ISR_TSF) + if ((isr & RTC_ISR_TSF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS); + } +#endif +#if defined(RTC_ISR_TSOVF) + if ((isr & RTC_ISR_TSOVF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); + } +#endif +#if defined(RTC_ISR_TAMP1F) + if ((isr & RTC_ISR_TAMP1F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if ((isr & RTC_ISR_TAMP2F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif +#if defined(RTC_ISR_TAMP3F) + if ((isr & RTC_ISR_TAMP3F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); + } +#endif + } + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_RTC_SUPPRESS_COMMON_ISR) */ + +#elif defined(STM32_RTC_TAMP_STAMP_HANDLER) && \ + defined(STM32_RTC_WKUP_HANDLER) && \ + defined(STM32_RTC_ALARM_HANDLER) +/** + * @brief RTC TAMP/STAMP interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_TAMP_STAMP_HANDLER) { + uint32_t isr, clear; + + OSAL_IRQ_PROLOGUE(); + + clear = ~(0U +#if defined(RTC_ISR_ITSF) + | RTC_ISR_ITSF +#endif +#if defined(RTC_ISR_TSF) + | RTC_ISR_TSF +#endif +#if defined(RTC_ISR_TSOVF) + | RTC_ISR_TSOVF +#endif +#if defined(RTC_ISR_TAMP1F) + | RTC_ISR_TAMP1F +#endif +#if defined(RTC_ISR_TAMP2F) + | RTC_ISR_TAMP2F +#endif +#if defined(RTC_ISR_TAMP3F) + | RTC_ISR_TAMP3F +#endif + ); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = clear; + + if (RTCD1.callback != NULL) { +#if defined(RTC_ISR_ITSF) + if ((isr & RTC_ISR_ITSF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_ITS); + } +#endif +#if defined(RTC_ISR_TSF) + if ((isr & RTC_ISR_TSF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS); + } +#endif +#if defined(RTC_ISR_TSOVF) + if ((isr & RTC_ISR_TSOVF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); + } +#endif +#if defined(RTC_ISR_TAMP1F) + if ((isr & RTC_ISR_TAMP1F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if ((isr & RTC_ISR_TAMP2F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif +#if defined(RTC_ISR_TAMP3F) + if ((isr & RTC_ISR_TAMP3F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); + } +#endif + } + + OSAL_IRQ_EPILOGUE(); +} +/** + * @brief RTC wakeup interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_WKUP_HANDLER) { + uint32_t isr; + + OSAL_IRQ_PROLOGUE(); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = ~RTC_ISR_WUTF; + + if (RTCD1.callback != NULL) { + if ((isr & RTC_ISR_WUTF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); + } + } + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief RTC alarm interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_ALARM_HANDLER) { + uint32_t isr, clear; + + OSAL_IRQ_PROLOGUE(); + + clear = ~(0U +#if defined(RTC_ISR_ALRAF) + | RTC_ISR_ALRAF +#endif +#if defined(RTC_ISR_ALRBF) + | RTC_ISR_ALRBF +#endif + ); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = clear; + + if (RTCD1.callback != NULL) { +#if defined(RTC_ISR_ALRAF) + if ((isr & RTC_ISR_ALRAF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); + } +#endif +#if defined(RTC_ISR_ALRBF) + if ((isr & RTC_ISR_ALRBF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); + } +#endif + } + + OSAL_IRQ_EPILOGUE(); +} + +#else +#error "missing required RTC handlers definitions in registry" +#endif + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -262,15 +463,28 @@ void rtc_lld_init(void) { rtc_enter_init(); - RTCD1.rtc->CR = 0; + RTCD1.rtc->CR = STM32_RTC_CR_INIT; RTCD1.rtc->ISR = RTC_ISR_INIT; /* Clearing all but RTC_ISR_INIT. */ RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; rtc_exit_init(); } - else + else { RTCD1.rtc->ISR &= ~RTC_ISR_RSF; + } + + /* Callback initially disabled.*/ + RTCD1.callback = NULL; + + /* Enabling RTC-related EXTI lines.*/ + extiEnableGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | + EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | + EXTI_MASK1(STM32_RTC_WKUP_EXTI), + EXTI_MODE_RISING_EDGE | EXTI_MODE_ACTION_INTERRUPT); + + /* IRQ vectors permanently assigned to this driver.*/ + STM32_RTC_IRQ_ENABLE(); } /** @@ -440,6 +654,22 @@ void rtc_lld_get_alarm(RTCDriver *rtcp, } #endif /* RTC_ALARMS > 0 */ +/** + * @brief Enables or disables RTC callbacks. + * @details This function enables or disables callbacks, use a @p NULL pointer + * in order to disable a callback. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] callback callback function pointer or @p NULL + * + * @notapi + */ +void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { + + rtcp->callback = callback; +} + #if STM32_RTC_HAS_PERIODIC_WAKEUPS || defined(__DOXYGEN__) /** * @brief Sets time of periodic wakeup. diff --git a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h index e6dbcbefd..7686760af 100644 --- a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h +++ b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h @@ -41,7 +41,7 @@ /** * @brief Callback support int the driver. */ -#define RTC_SUPPORTS_CALLBACKS STM32_RTC_HAS_INTERRUPTS +#define RTC_SUPPORTS_CALLBACKS TRUE /** * @brief Number of alarms available. @@ -78,6 +78,11 @@ #define RTC_ALRM_SU(n) ((n) << 0) /** @} */ +/* Requires services from the EXTI driver.*/ +#if !defined(STM32_EXTI_REQUIRED) +#define STM32_EXTI_REQUIRED +#endif + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -101,6 +106,15 @@ #if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__) #define STM32_RTC_PRESS_VALUE 1024 #endif + +/** + * @brief RTC CR register initialization value. + * @note Use this value to initialize features not directly handled by + * the RTC driver. + */ +#if !defined(STM32_RTC_CR_INIT) || defined(__DOXYGEN__) +#define STM32_RTC_CR_INIT 0 +#endif /** @} */ /*===========================================================================*/ @@ -133,10 +147,30 @@ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief Type of an RTC event. + */ +typedef enum { + RTC_EVENT_ALARM_A = 0, /** Alarm A. */ + RTC_EVENT_ALARM_B = 1, /** Alarm B. */ + RTC_EVENT_TS = 2, /** Time stamp. */ + RTC_EVENT_TS_OVF = 3, /** Time stamp overflow. */ + RTC_EVENT_TAMP1 = 4, /** Tamper 1. */ + RTC_EVENT_TAMP2 = 5, /** Tamper 2- */ + RTC_EVENT_TAMP3 = 6, /** Tamper 3. */ + RTC_EVENT_WAKEUP = 7, /** Wakeup. */ + RTC_EVENT_ITS = 8 /** Internal time stamp. */ +} rtcevent_t; + +/** + * @brief Type of a generic RTC callback. + */ +typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); + /** * @brief Type of a structure representing an RTC alarm time stamp. */ -typedef struct { +typedef struct hal_rtc_alarm { /** * @brief Type of an alarm as encoded in RTC ALRMxR registers. */ @@ -147,7 +181,7 @@ typedef struct { /** * @brief Type of a wakeup as encoded in RTC WUTR register. */ -typedef struct { +typedef struct hal_rtc_wakeup { /** * @brief Wakeup as encoded in RTC WUTR register. * @note ((WUTR == 0) || (WUCKSEL == 3)) are a forbidden combination. @@ -162,7 +196,9 @@ typedef struct { */ #define _rtc_lld_driver_fields \ /* Pointer to the RTC registers block.*/ \ - RTC_TypeDef *rtc; + RTC_TypeDef *rtc; \ + /* Callback pointer.*/ \ + rtccb_t callback; /*===========================================================================*/ /* Driver macros. */ @@ -178,6 +214,9 @@ extern "C" { void rtc_lld_init(void); void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec); void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec); +#if RTC_SUPPORTS_CALLBACKS == TRUE + void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); +#endif #if RTC_ALARMS > 0 void rtc_lld_set_alarm(RTCDriver *rtcp, rtcalarm_t alarm, diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld.h b/os/hal/ports/STM32/STM32F4xx/hal_lld.h index 102ff0992..87061fe7d 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld.h @@ -39,6 +39,7 @@ #include "mpu_v7m.h" #include "stm32_isr.h" #include "stm32_dma.h" +#include "stm32_exti.h" #include "stm32_rcc.h" /*===========================================================================*/ diff --git a/os/hal/ports/STM32/STM32F4xx/platform.mk b/os/hal/ports/STM32/STM32F4xx/platform.mk index 2643dbdaf..2b039dd46 100644 --- a/os/hal/ports/STM32/STM32F4xx/platform.mk +++ b/os/hal/ports/STM32/STM32F4xx/platform.mk @@ -26,6 +26,7 @@ include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk include $(CHIBIOS)/os/hal/ports/STM32/LLD/CRYPv1/driver.mk include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv2/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1/driver.mk include $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1/driver.mk diff --git a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h index 0e1799bd3..46135aa89 100644 --- a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h @@ -189,7 +189,7 @@ /* EXTI attributes.*/ #define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR_MASK 0x00000000U +#define STM32_EXTI_IMR1_MASK 0x00000000U /* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE @@ -572,7 +572,7 @@ /* EXTI attributes.*/ #define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR_MASK 0x00000000U +#define STM32_EXTI_IMR1_MASK 0x00000000U /* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE @@ -934,7 +934,7 @@ /* EXTI attributes.*/ #define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR_MASK 0x00000000U +#define STM32_EXTI_IMR1_MASK 0x00000000U /* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE @@ -1303,7 +1303,7 @@ /* EXTI attributes.*/ #define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR_MASK 0x00000000U +#define STM32_EXTI_IMR1_MASK 0x00000000U /* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE @@ -1688,7 +1688,7 @@ /* EXTI attributes.*/ #define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR_MASK 0x00000000U +#define STM32_EXTI_IMR1_MASK 0x00000000U /* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE @@ -2023,7 +2023,7 @@ /* EXTI attributes.*/ #define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR_MASK 0x00000000U +#define STM32_EXTI_IMR1_MASK 0x00000000U /* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE @@ -2338,7 +2338,7 @@ /* EXTI attributes.*/ #define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR_MASK 0x00000000U +#define STM32_EXTI_IMR1_MASK 0x00000000U /* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE @@ -2639,7 +2639,7 @@ /* EXTI attributes.*/ #define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR_MASK 0x00000000U +#define STM32_EXTI_IMR1_MASK 0x00000000U /* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE @@ -2699,7 +2699,20 @@ #endif #define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE #define STM32_RTC_NUM_ALARMS 2 -#define STM32_RTC_HAS_INTERRUPTS FALSE +#define STM32_RTC_TAMP_STAMP_HANDLER Vector48 +#define STM32_RTC_WKUP_HANDLER Vector49 +#define STM32_RTC_ALARM_HANDLER VectorE4 +#define STM32_RTC_TAMP_STAMP_NUMBER 2 +#define STM32_RTC_WKUP_NUMBER 3 +#define STM32_RTC_ALARM_NUMBER 41 +#define STM32_RTC_ALARM_EXTI 17 +#define STM32_RTC_TAMP_STAMP_EXTI 21 +#define STM32_RTC_WKUP_EXTI 22 +#define STM32_RTC_IRQ_ENABLE() do { \ + nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI21_PRIORITY); \ + nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI22_PRIORITY); \ + nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \ +} while (false) /* SDIO attributes.*/ #define STM32_HAS_SDIO TRUE @@ -2981,7 +2994,7 @@ /* EXTI attributes.*/ #define STM32_EXTI_NUM_LINES 23 -#define STM32_EXTI_IMR_MASK 0x00000000U +#define STM32_EXTI_IMR1_MASK 0x00000000U /* GPIO attributes.*/ #define STM32_HAS_GPIOA TRUE -- cgit v1.2.3