rtc_stm32.c
Go to the documentation of this file.00001
00038 #include "clock_stm32.h"
00039
00040 #include <cfg/compiler.h>
00041 #include <cfg/module.h>
00042 #include <cfg/debug.h>
00043
00044 #include <io/stm32.h>
00045 #include <io/stm32_pwr.h>
00046
00047 #include <cpu/power.h>
00048
00049 #include <drv/rtc.h>
00050
00051
00052 static struct PWR *PWR = (struct PWR *)PWR_BASE;
00053
00054
00055 #define RTC_CLKSRC 0x00000100
00056
00057 #define RTC_CLOCK 32768
00058
00059 #define RTC_PERIOD 1000
00060
00061
00062 #define RTC_CRH (*(reg16_t *)(RTC_BASE + 0x00))
00063 #define RTC_CRL (*(reg16_t *)(RTC_BASE + 0x04))
00064
00065 #define RTC_CRL_SECIE BV(0)
00066 #define RTC_CRL_ALRIE BV(1)
00067 #define RTC_CRL_OWIE BV(2)
00068
00069 #define RTC_CRL_SECF BV(0)
00070 #define RTC_CRL_ALRF BV(1)
00071 #define RTC_CRL_OWF BV(2)
00072 #define RTC_CRL_RSF BV(3)
00073 #define RTC_CRL_CNF BV(4)
00074 #define RTC_CRL_RTOFF BV(5)
00075
00076
00077 #define RTC_PRLH (*(reg16_t *)(RTC_BASE + 0x08))
00078 #define RTC_PRLL (*(reg16_t *)(RTC_BASE + 0x0c))
00079
00080
00081 #define RTC_DIVH (*(reg16_t *)(RTC_BASE + 0x10))
00082 #define RTC_DIVL (*(reg16_t *)(RTC_BASE + 0x14))
00083
00084
00085 #define RTC_CNTH (*(reg16_t *)(RTC_BASE + 0x18))
00086 #define RTC_CNTL (*(reg16_t *)(RTC_BASE + 0x1c))
00087
00088
00089 #define RTC_ALRH (*(reg16_t *)(RTC_BASE + 0x20))
00090 #define RTC_ALRL (*(reg16_t *)(RTC_BASE + 0x24))
00091
00092 static void rtc_enterConfig(void)
00093 {
00094
00095 RTC_CRL |= RTC_CRL_CNF;
00096 }
00097
00098 static void rtc_exitConfig(void)
00099 {
00100
00101 RTC_CRL &= ~RTC_CRL_CNF;
00102 while (!(RTC_CRL & RTC_CRL_RTOFF))
00103 cpu_relax();
00104 }
00105
00106 uint32_t rtc_time(void)
00107 {
00108 return (RTC_CNTH << 16) | RTC_CNTL;
00109 }
00110
00111 void rtc_setTime(uint32_t val)
00112 {
00113 rtc_enterConfig();
00114 RTC_CNTH = (val >> 16) & 0xffff;
00115 RTC_CNTL = val & 0xffff;
00116 rtc_exitConfig();
00117 }
00118
00119
00120 int rtc_init(void)
00121 {
00122 #if CONFIG_KERN
00123 MOD_CHECK(proc);
00124 #endif
00125
00126 RCC->APB1ENR |= RCC_APB1_PWR;
00127
00128
00129 PWR->CR |= PWR_CR_DBP;
00130
00131
00132 RCC->BDCR |= RCC_BDCR_LSEON;
00133
00134 while (!(RCC->BDCR & RCC_BDCR_LSERDY))
00135 cpu_relax();
00136
00137
00138 RCC->BDCR |= RTC_CLKSRC | RCC_BDCR_RTCEN;
00139
00140 rtc_enterConfig();
00141
00142
00143 RTC_PRLH = ((RTC_PERIOD * RTC_CLOCK / 1000 - 1) >> 16) & 0xff;
00144 RTC_PRLL = ((RTC_PERIOD * RTC_CLOCK / 1000 - 1)) & 0xffff;
00145
00146 rtc_exitConfig();
00147
00148
00149 PWR->CR &= ~PWR_CR_DBP;
00150
00151 return 0;
00152 }