From fde92710afb75118bda5d9fb622d12f57a2656da Mon Sep 17 00:00:00 2001 From: arighi Date: Fri, 4 Feb 2011 17:48:11 +0000 Subject: [PATCH] STM32-P103: add real-time clock (RTC) driver git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4682 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/cortex-m3/drv/clock_stm32.h | 8 ++ bertos/cpu/cortex-m3/drv/rtc_stm32.c | 148 +++++++++++++++++++++++++ bertos/cpu/cortex-m3/io/stm32_pwr.h | 51 +++++++++ bertos/drv/rtc.h | 56 ++++++++++ 4 files changed, 263 insertions(+) create mode 100644 bertos/cpu/cortex-m3/drv/rtc_stm32.c create mode 100644 bertos/cpu/cortex-m3/io/stm32_pwr.h create mode 100644 bertos/drv/rtc.h diff --git a/bertos/cpu/cortex-m3/drv/clock_stm32.h b/bertos/cpu/cortex-m3/drv/clock_stm32.h index 2e7c09a3..e91753d6 100644 --- a/bertos/cpu/cortex-m3/drv/clock_stm32.h +++ b/bertos/cpu/cortex-m3/drv/clock_stm32.h @@ -240,6 +240,14 @@ #define RCC_APB2_SPI1 (0x00001000) #define RCC_APB2_USART1 (0x00004000) #define RCC_APB2_ALL (0x00005E7D) + +/** + * RCC register: BCDR + */ +#define RCC_BDCR_LSEON (0x00000001) +#define RCC_BDCR_LSERDY (0x00000002) +#define RCC_BDCR_RTCSEL (0x00000300) +#define RCC_BDCR_RTCEN (0x00008000) /*\}*/ /* Crystal frequency of the main oscillator (8MHz) */ diff --git a/bertos/cpu/cortex-m3/drv/rtc_stm32.c b/bertos/cpu/cortex-m3/drv/rtc_stm32.c new file mode 100644 index 00000000..76aae3dd --- /dev/null +++ b/bertos/cpu/cortex-m3/drv/rtc_stm32.c @@ -0,0 +1,148 @@ +/** + * \file + * + * + * \brief STM32 RTC driver. + * + * \author Andrea Righi + */ + +#include "clock_stm32.h" + +#include +#include + +#include +#include + +#include // cpu_relax() + +#include + +/* PWR registers base */ +static struct PWR *PWR = (struct PWR *)PWR_BASE; + +/* RTC clock source: LSE */ +#define RTC_CLKSRC 0x00000100 +/* RTC clock: 32768 Hz */ +#define RTC_CLOCK 32768 +/* RTC clock period (in ms) */ +#define RTC_PERIOD 1000 + +/* RTC control register */ +#define RTC_CRH (*(reg16_t *)(RTC_BASE + 0x00)) +#define RTC_CRL (*(reg16_t *)(RTC_BASE + 0x04)) + +#define RTC_CRL_SECIE BV(0) +#define RTC_CRL_ALRIE BV(1) +#define RTC_CRL_OWIE BV(2) + +#define RTC_CRL_SECF BV(0) +#define RTC_CRL_ALRF BV(1) +#define RTC_CRL_OWF BV(2) +#define RTC_CRL_RSF BV(3) +#define RTC_CRL_CNF BV(4) +#define RTC_CRL_RTOFF BV(5) + +/* RTC prescaler load register */ +#define RTC_PRLH (*(reg16_t *)(RTC_BASE + 0x08)) +#define RTC_PRLL (*(reg16_t *)(RTC_BASE + 0x0c)) + +/* RTC prescaler divider register */ +#define RTC_DIVH (*(reg16_t *)(RTC_BASE + 0x10)) +#define RTC_DIVL (*(reg16_t *)(RTC_BASE + 0x14)) + +/* RTC counter register */ +#define RTC_CNTH (*(reg16_t *)(RTC_BASE + 0x18)) +#define RTC_CNTL (*(reg16_t *)(RTC_BASE + 0x1c)) + +/* RTC alarm register */ +#define RTC_ALRH (*(reg16_t *)(RTC_BASE + 0x20)) +#define RTC_ALRL (*(reg16_t *)(RTC_BASE + 0x24)) + +static void rtc_enterConfig(void) +{ + /* Enter configuration mode */ + RTC_CRL |= RTC_CRL_CNF; +} + +static void rtc_exitConfig(void) +{ + /* Exit from configuration mode */ + RTC_CRL &= ~RTC_CRL_CNF; + while (!(RTC_CRL & RTC_CRL_RTOFF)) + cpu_relax(); +} + +uint32_t rtc_time(void) +{ + return (RTC_CNTH << 16) | RTC_CNTL; +} + +void rtc_setTime(uint32_t val) +{ + rtc_enterConfig(); + RTC_CNTH = (val >> 16) & 0xffff; + RTC_CNTL = val & 0xffff; + rtc_exitConfig(); +} + +/* Initialize the RTC clock */ +int rtc_init(void) +{ + /* Enable clock for Power interface */ + RCC->APB1ENR |= RCC_APB1_PWR; + + /* Enable access to RTC registers */ + PWR->CR |= PWR_CR_DBP; + + /* Enable LSE */ + RCC->BDCR |= RCC_BDCR_LSEON; + /* Wait for LSE ready */ + while (!(RCC->BDCR & RCC_BDCR_LSERDY)) + cpu_relax(); + + /* Set clock source and enable RTC peripheral */ + RCC->BDCR |= RTC_CLKSRC | RCC_BDCR_RTCEN; + + rtc_enterConfig(); + + /* Set prescaler */ + RTC_PRLH = ((RTC_PERIOD * RTC_CLOCK / 1000 - 1) >> 16) & 0xff; + RTC_PRLL = ((RTC_PERIOD * RTC_CLOCK / 1000 - 1)) & 0xffff; + + rtc_exitConfig(); + + /* Disable access to the RTC registers */ + PWR->CR &= ~PWR_CR_DBP; + + return 0; +} diff --git a/bertos/cpu/cortex-m3/io/stm32_pwr.h b/bertos/cpu/cortex-m3/io/stm32_pwr.h new file mode 100644 index 00000000..6f17e929 --- /dev/null +++ b/bertos/cpu/cortex-m3/io/stm32_pwr.h @@ -0,0 +1,51 @@ +/** + * \file + * + * + * \brief STM32 Power Control. + * + * \author Andrea Righi + */ +#ifndef STM32_PWR_H +#define STM32_PWR_H + +#include + +/* Power Control */ +struct PWR +{ + reg32_t CR; + reg32_t CSR; +}; + +#define PWR_CR_DBP 0x00000100 + +#endif /* STM32_PWR_H */ diff --git a/bertos/drv/rtc.h b/bertos/drv/rtc.h new file mode 100644 index 00000000..d8c8fae9 --- /dev/null +++ b/bertos/drv/rtc.h @@ -0,0 +1,56 @@ +/** + * \file + * + * + * \brief Real-time clock interface + * + * Abstract real-time clock interface. + * + * \attention The API is work in progress and may change in future versions. + * + * $WIZ$ module_name = "rtc" + * $WIZ$ module_supports = "stm32" + */ + +#ifndef RTC_H +#define RTC_H + +#include + +typedef uint32_t rtc_clock_t; + +rtc_clock_t rtc_time(void); + +void rtc_setTime(rtc_clock_t date); + +int rtc_init(void); + +#endif /* RTC_H */ -- 2.25.1