Intel® Quark™ Microcontroller Software Interface 1.4.0 Intel® Quark™ Microcontroller BSP

- Main Page
- Modules
- Data Structures
- Files

- File List

qm_rtc.c
1 /*
2 * {% copyright %}
3 */
4
5 #include "qm_rtc.h"
6 #include "clk.h"
7 #if (HAS_SOC_CONTEXT_RETENTION)
8 #include "power_states.h"
9 #endif /* HAS_SOC_CONTEXT_RETENTION */
10
11 static void (*callback[QM_RTC_NUM])(void *data);
12 static void *callback_data[QM_RTC_NUM];
13
14 #ifndef UNIT_TEST
15 qm_rtc_reg_t *qm_rtc[QM_RTC_NUM] = {(qm_rtc_reg_t *)(QM_RTC_BASE)};
16 #endif /* UNIT_TEST */
17
18 QM_ISR_DECLARE(qm_rtc_0_isr)
19 {
20 /* Disable RTC interrupt */
21 QM_RTC[QM_RTC_0]->rtc_ccr &= ~QM_RTC_CCR_INTERRUPT_ENABLE;
22
23 #if (HAS_SOC_CONTEXT_RETENTION)
24 if (QM_SCSS_GP->gps0 & QM_GPS0_POWER_STATES_MASK) {
25 qm_power_soc_restore();
26 }
27 #endif /* HAS_SOC_CONTEXT_RETENTION */
28 if (callback[QM_RTC_0]) {
29 (callback[QM_RTC_0])(callback_data[QM_RTC_0]);
30 }
31
32 /* Clear interrupt. */
33 QM_RTC[QM_RTC_0]->rtc_eoi;
34 QM_ISR_EOI(QM_IRQ_RTC_0_INT_VECTOR);
35 }
36
37 int qm_rtc_set_config(const qm_rtc_t rtc, const qm_rtc_config_t *const cfg)
38 {
39 QM_CHECK(rtc < QM_RTC_NUM, -EINVAL);
40 QM_CHECK(rtc >= QM_RTC_0, -EINVAL);
41 QM_CHECK(NULL != cfg, -EINVAL);
42
43 /* Disable the RTC before re-configuration. */
44 QM_RTC[rtc]->rtc_ccr &= ~QM_RTC_CCR_ENABLE;
45
46 QM_RTC[rtc]->rtc_clr = cfg->init_val;
47
48 /* Clear any pending interrupts. */
49 QM_RTC[rtc]->rtc_eoi;
50
51 /* Perform if the IP used has the prescaler feature. */
52 #if (HAS_RTC_PRESCALER)
53 /* With the RTC prescaler, the minimum value that can be set is 2. */
54 if (QM_RTC_MIN_PRESCALER <= cfg->prescaler) {
55 /* Enable RTC prescaler in CCR. */
56 QM_RTC[rtc]->rtc_ccr |= QM_RTC_PRESCLR_ENABLE;
57 QM_RTC[rtc]->rtc_cpsr = BIT(cfg->prescaler);
58 } else {
59 /* Disable RTC prescaler in CCR. */
60 QM_RTC[rtc]->rtc_ccr &= ~QM_RTC_PRESCLR_ENABLE;
61 }
62 #else /* HAS_RTC_PRESCALER */
63 clk_rtc_set_div(cfg->prescaler); /* Set RTC divider. */
64 #endif /* HAS_RTC_PRESCALER */
65
66 if (cfg->alarm_en) {
67 callback[rtc] = cfg->callback;
68 callback_data[rtc] = cfg->callback_data;
69 qm_rtc_set_alarm(rtc, cfg->alarm_val);
70 } else {
71 callback[rtc] = NULL;
72 callback_data[rtc] = NULL;
73 /* Disable RTC interrupt. */
74 QM_RTC[rtc]->rtc_ccr &= ~QM_RTC_CCR_INTERRUPT_ENABLE;
75 /* Internally mask the RTC interrupt. */
76 QM_RTC[rtc]->rtc_ccr |= QM_RTC_CCR_INTERRUPT_MASK;
77 }
78
79 /* Enable the RTC upon completion. */
80 QM_RTC[rtc]->rtc_ccr |= QM_RTC_CCR_ENABLE;
81
82 return 0;
83 }
84
85 int qm_rtc_set_alarm(const qm_rtc_t rtc, const uint32_t alarm_val)
86 {
87 QM_CHECK(rtc < QM_RTC_NUM, -EINVAL);
88 QM_CHECK(rtc >= QM_RTC_0, -EINVAL);
89
90 /* Enable RTC interrupt. */
91 QM_RTC[rtc]->rtc_ccr |= QM_RTC_CCR_INTERRUPT_ENABLE;
92 /* Internally unmask the RTC interrupt. */
93 QM_RTC[rtc]->rtc_ccr &= ~QM_RTC_CCR_INTERRUPT_MASK;
94
95 /* Set alarm value. */
96 QM_RTC[rtc]->rtc_cmr = alarm_val;
97
98 return 0;
99 }
100
101 int qm_rtc_read(const qm_rtc_t rtc, uint32_t *const value)
102 {
103 QM_CHECK(rtc < QM_RTC_NUM, -EINVAL);
104 QM_CHECK(rtc >= QM_RTC_0, -EINVAL);
105 QM_CHECK(NULL != value, -EINVAL);
106
107 *value = QM_RTC[rtc]->rtc_ccvr;
108
109 return 0;
110 }
111
112 #if (ENABLE_RESTORE_CONTEXT)
113 int qm_rtc_save_context(const qm_rtc_t rtc, qm_rtc_context_t *const ctx)
114 {
115 QM_CHECK(rtc < QM_RTC_NUM, -EINVAL);
116 QM_CHECK(ctx != NULL, -EINVAL);
117
118 (void)rtc;
119 (void)ctx;
120
121 return 0;
122 }
123
124 int qm_rtc_restore_context(const qm_rtc_t rtc,
125 const qm_rtc_context_t *const ctx)
126 {
127 uint32_t int_rtc_mask;
128 QM_CHECK(rtc < QM_RTC_NUM, -EINVAL);
129 QM_CHECK(ctx != NULL, -EINVAL);
130
131 (void)rtc;
132 (void)ctx;
133
134 /* The interrupt router registers are sticky and retain their
135 * values across warm resets, so we don't need to save them.
136 * But for wake capable peripherals, if their interrupts are
137 * configured to be edge sensitive, the wake event will be lost
138 * by the time the interrupt controller is reconfigured, while
139 * the interrupt is still pending. By masking and unmasking again
140 * the corresponding routing register, the interrupt is forwarded
141 * to the core and the ISR will be serviced as expected.
142 */
143 int_rtc_mask = QM_INTERRUPT_ROUTER->rtc_0_int_mask;
144 QM_INTERRUPT_ROUTER->rtc_0_int_mask = 0xFFFFFFFF;
145 QM_INTERRUPT_ROUTER->rtc_0_int_mask = int_rtc_mask;
146
147 return 0;
148 }
149 #else
150 int qm_rtc_save_context(const qm_rtc_t rtc, qm_rtc_context_t *const ctx)
151 {
152 (void)rtc;
153 (void)ctx;
154
155 return 0;
156 }
157
158 int qm_rtc_restore_context(const qm_rtc_t rtc,
159 const qm_rtc_context_t *const ctx)
160 {
161 (void)rtc;
162 (void)ctx;
163
164 return 0;
165 }
166 #endif /* ENABLE_RESTORE_CONTEXT */
qm_power_soc_restore
void qm_power_soc_restore(void)
Restore system state after sleep or deep sleep.
Definition: power_states.c:402
qm_rtc_read
int qm_rtc_read(const qm_rtc_t rtc, uint32_t *const value)
Read the RTC register value.
Definition: qm_rtc.c:101
clk_rtc_set_div
int clk_rtc_set_div(const clk_rtc_div_t div)
Change divider value of RTC.
Definition: clk.c:306
QM_ISR_DECLARE
QM_ISR_DECLARE(qm_rtc_0_isr)
ISR for RTC 0 interrupt.
Definition: qm_rtc.c:18
qm_rtc_config_t::callback_data
void * callback_data
Callback user data.
Definition: qm_rtc.h:58
qm_rtc_config_t::alarm_val
uint32_t alarm_val
Alarm value in RTC clocks.
Definition: qm_rtc.h:42
qm_rtc_set_alarm
int qm_rtc_set_alarm(const qm_rtc_t rtc, const uint32_t alarm_val)
Set Alarm value.
Definition: qm_rtc.c:85
qm_rtc_restore_context
int qm_rtc_restore_context(const qm_rtc_t rtc, const qm_rtc_context_t *const ctx)
Restore RTC context.
Definition: qm_rtc.c:124
qm_rtc_config_t::prescaler
clk_rtc_div_t prescaler
RTC Clock prescaler.
Definition: qm_rtc.h:50
qm_rtc_config_t::init_val
uint32_t init_val
Initial value in RTC clocks.
Definition: qm_rtc.h:40
qm_rtc_reg_t
RTC register map.
Definition: qm_soc_regs.h:821
qm_rtc_t
qm_rtc_t
Number of RTC controllers.
Definition: qm_soc_regs.h:818
qm_rtc_set_config
int qm_rtc_set_config(const qm_rtc_t rtc, const qm_rtc_config_t *const cfg)
Set RTC configuration.
Definition: qm_rtc.c:37
qm_rtc_config_t::alarm_en
bool alarm_en
Alarm enable.
Definition: qm_rtc.h:41
qm_rtc_save_context
int qm_rtc_save_context(const qm_rtc_t rtc, qm_rtc_context_t *const ctx)
Save RTC context.
Definition: qm_rtc.c:113
qm_rtc_config_t::callback
void(* callback)(void *data)
User callback.
Definition: qm_rtc.h:57
qm_rtc_config_t
QM RTC configuration type.
Definition: qm_rtc.h:39