dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_rtc.c
Go to the documentation of this file.
1 
16 /*
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 3 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful, but
23  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25  * for more details.
26  *
27  * You should have received a copy of the GNU General Public License along
28  * with this program; if not, see <http://www.gnu.org/licenses/>
29  */
30 
31 /* Project Includes */
32 #include "pios.h"
33 
34 #if defined(PIOS_INCLUDE_RTC)
35 #include <pios_rtc_priv.h>
36 
37 #ifndef PIOS_RTC_PRESCALER
38 #define PIOS_RTC_PRESCALER 100
39 #endif
40 
41 struct rtc_callback_entry {
42  void (*fn)(uintptr_t);
43  uintptr_t data;
44 };
45 
46 #define PIOS_RTC_MAX_CALLBACKS 3
48 static uint8_t rtc_callback_next = 0;
49 
50 void PIOS_RTC_Init(const struct pios_rtc_cfg * cfg)
51 {
52  RCC_BackupResetCmd(ENABLE);
53  RCC_BackupResetCmd(DISABLE);
54  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
55  PWR_BackupAccessCmd(ENABLE);
56  // Divide external 8 MHz clock by 32 to 250kHz
57  RCC_RTCCLKConfig(cfg->clksrc);
58  RCC_RTCCLKCmd(ENABLE);
59 
60  RTC_WakeUpCmd(DISABLE);
61  // Divide 250kHz Mhz clock by 16 to 15625Hz
62  RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);
63  // Divide 15625Hz by 25 to get 625 Hz
64  RTC_SetWakeUpCounter(cfg->prescaler); //cfg->prescaler);
65  RTC_WakeUpCmd(ENABLE);
66 
67  /* Configure and enable the RTC Second interrupt */
68  EXTI_InitTypeDef ExtiInit = {
69  .EXTI_Line = EXTI_Line20, // matches above GPIO pin
70  .EXTI_Mode = EXTI_Mode_Interrupt,
71  .EXTI_Trigger = EXTI_Trigger_Rising,
72  .EXTI_LineCmd = ENABLE,
73  };
74  EXTI_Init((EXTI_InitTypeDef*)&ExtiInit);
75  NVIC_Init((NVIC_InitTypeDef*)&cfg->irq.init);
76  RTC_ITConfig(RTC_IT_WUT, ENABLE);
77 
78  RTC_ClearFlag(RTC_FLAG_WUTF);
79 }
80 
81 uint32_t PIOS_RTC_Counter()
82 {
83  return RTC_GetWakeUpCounter();
84 }
85 
86 /* FIXME: This shouldn't use hard-coded clock rates, dividers or prescalers.
87  * Should get these from the cfg struct passed to init.
88  */
89 float PIOS_RTC_Rate()
90 {
91  return (float) (8e6 / 128) / (1 + PIOS_RTC_PRESCALER);
92 }
93 
94 float PIOS_RTC_MsPerTick()
95 {
96  return 1000.0f / PIOS_RTC_Rate();
97 }
98 
99 /* TODO: This needs a mutex around rtc_callbacks[] */
100 bool PIOS_RTC_RegisterTickCallback(void (*fn)(uintptr_t id), uintptr_t data)
101 {
102  struct rtc_callback_entry * cb;
103  if (rtc_callback_next >= PIOS_RTC_MAX_CALLBACKS) {
104  return false;
105  }
106 
107  cb = &rtc_callback_list[rtc_callback_next++];
108 
109  cb->fn = fn;
110  cb->data = data;
111  return true;
112 }
113 
114 void PIOS_RTC_irq_handler (void)
115 {
117 
118  if (RTC_GetITStatus(RTC_IT_WUT))
119  {
120  /* Call all registered callbacks */
121  for (uint8_t i = 0; i < rtc_callback_next; i++) {
122  struct rtc_callback_entry * cb = &rtc_callback_list[i];
123  if (cb->fn) {
124  (cb->fn)(cb->data);
125  }
126  }
127 
128  /* Clear the RTC Second interrupt */
129  RTC_ClearITPendingBit(RTC_IT_WUT);
130  }
131 
132  if (EXTI_GetITStatus(EXTI_Line20) != RESET)
133  EXTI_ClearITPendingBit(EXTI_Line20);
134 
136 }
137 #endif
138 
Main PiOS header to include all the compiled in PiOS options.
uint32_t PIOS_RTC_Counter()
#define PIOS_IRQ_Epilogue()
Definition: pios_irq.h:46
Definition: pios_delay.c:41
bool PIOS_RTC_RegisterTickCallback(void(*fn)(uintptr_t id), uintptr_t data)
Definition: pios_delay.c:185
uint8_t data[XFER_BYTES_PER_PACKET]
Definition: bl_messages.h:129
static struct rtc_callback_entry rtc_callback_list[PIOS_RTC_MAX_CALLBACKS]
Definition: pios_delay.c:46
static struct flyingpicmd_cfg_fa cfg
Definition: main.c:49
float PIOS_RTC_MsPerTick()
Definition: pios_delay.c:180
float PIOS_RTC_Rate()
Definition: pios_delay.c:175
uintptr_t data
Definition: pios_delay.c:43
void(* fn)(uintptr_t)
Definition: pios_delay.c:42
uint8_t i
Definition: msp_messages.h:97
NVIC_InitTypeDef init
Definition: pios_stm32.h:36
uint32_t prescaler
Definition: pios_rtc_priv.h:38
void PIOS_RTC_Init(const struct pios_rtc_cfg *cfg)
#define PIOS_RTC_MAX_CALLBACKS
Definition: pios_delay.c:39
struct stm32_irq irq
Definition: pios_rtc_priv.h:39
void PIOS_RTC_irq_handler(void)
#define PIOS_IRQ_Prologue()
Definition: pios_irq.h:45
uint32_t clksrc
Definition: pios_rtc_priv.h:37