13
13
14
14
// Set this when setting an alarm
15
15
static rtc_callback_t _callback = NULL ;
16
- static bool _alarm_repeats = false ;
16
+ static int8_t _alarm_repeats = 0 ;
17
17
18
18
bool rtc_running (void ) {
19
19
return (rtc_hw -> ctrl & RTC_CTRL_RTC_ACTIVE_BITS );
@@ -130,6 +130,11 @@ static void rtc_irq_handler(void) {
130
130
131
131
if (_alarm_repeats ) {
132
132
// If it is a repeatable alarm, re enable the alarm.
133
+ if (_alarm_repeats == -1 ) {
134
+ datetime_t tNew ;
135
+ rtc_get_datetime (& tNew );
136
+ rtc_hw -> irq_setup_1 = RTC_IRQ_SETUP_1_SEC_ENA_BITS | ((((uint )tNew .sec + 1 ) % 60 ) << RTC_IRQ_SETUP_1_SEC_LSB );
137
+ }
133
138
rtc_enable_alarm ();
134
139
}
135
140
@@ -139,48 +144,50 @@ static void rtc_irq_handler(void) {
139
144
}
140
145
}
141
146
142
- static bool rtc_alarm_repeats (const datetime_t * t ) {
143
- // If any value is set to -1 then we don't match on that value
144
- // hence the alarm will eventually repeat
145
- if (t -> year < 0 ) return true;
146
- if (t -> month < 0 ) return true;
147
- if (t -> day < 0 ) return true;
148
- if (t -> dotw < 0 ) return true;
149
- if (t -> hour < 0 ) return true;
150
- if (t -> min < 0 ) return true;
151
- if (t -> sec < 0 ) return true;
152
- return false;
147
+ // return != 0 on repeat, -1 on repeat every second
148
+ static int8_t rtc_alarm_repeats (const datetime_t * t ) {
149
+ // If any value is set to -1 then we don't match on that value
150
+ // hence the alarm will eventually repeat
151
+ if (t -> year & t -> month & t -> day & t -> dotw & t -> hour & t -> min & t -> sec < 0 )
152
+ return - 1 ;
153
+ return ((t -> year | t -> month | t -> day | t -> dotw | t -> hour | t -> min | t -> sec ) < 0 );
153
154
}
154
155
155
- bool rtc_set_alarm (datetime_t * t , rtc_callback_t user_callback ) {
156
+ bool rtc_set_alarm (const datetime_t * t , rtc_callback_t user_callback ) {
156
157
rtc_disable_alarm ();
157
158
159
+ uint32_t s0 = 0 , s1 = 0 ;
160
+
158
161
// Does it repeat? I.e. do we not match on any of the bits
159
162
_alarm_repeats = rtc_alarm_repeats (t );
160
163
161
164
if ( (!valid_datetime (t ) && !_alarm_repeats ) || !user_callback ) // none of the parameters is valid
162
165
return false;
163
166
164
- // Only add to setup if it isn't -1
165
- rtc_hw -> irq_setup_0 = ((t -> year < 0 ) ? 0 : (((uint )t -> year ) << RTC_IRQ_SETUP_0_YEAR_LSB )) |
166
- ((t -> month < 0 ) ? 0 : (((uint )t -> month ) << RTC_IRQ_SETUP_0_MONTH_LSB )) |
167
- ((t -> day < 0 ) ? 0 : (((uint )t -> day ) << RTC_IRQ_SETUP_0_DAY_LSB ));
168
- rtc_hw -> irq_setup_1 = ((t -> dotw < 0 ) ? 0 : (((uint )t -> dotw ) << RTC_IRQ_SETUP_1_DOTW_LSB )) |
169
- ((t -> hour < 0 ) ? 0 : (((uint )t -> hour ) << RTC_IRQ_SETUP_1_HOUR_LSB )) |
170
- ((t -> min < 0 ) ? 0 : (((uint )t -> min ) << RTC_IRQ_SETUP_1_MIN_LSB )) |
171
- ((t -> sec < 0 ) ? 0 : (((uint )t -> sec ) << RTC_IRQ_SETUP_1_SEC_LSB ));
172
-
173
167
// Set the match enable bits for things we care about
174
- if (t -> year >= 0 ) hw_set_bits (& rtc_hw -> irq_setup_0 , RTC_IRQ_SETUP_0_YEAR_ENA_BITS );
175
- if (t -> month >= 0 ) hw_set_bits (& rtc_hw -> irq_setup_0 , RTC_IRQ_SETUP_0_MONTH_ENA_BITS );
176
- if (t -> day >= 0 ) hw_set_bits (& rtc_hw -> irq_setup_0 , RTC_IRQ_SETUP_0_DAY_ENA_BITS );
177
- if (t -> dotw >= 0 ) hw_set_bits (& rtc_hw -> irq_setup_1 , RTC_IRQ_SETUP_1_DOTW_ENA_BITS );
178
- if (t -> hour >= 0 ) hw_set_bits (& rtc_hw -> irq_setup_1 , RTC_IRQ_SETUP_1_HOUR_ENA_BITS );
179
- if (t -> min >= 0 ) hw_set_bits (& rtc_hw -> irq_setup_1 , RTC_IRQ_SETUP_1_MIN_ENA_BITS );
180
- if (t -> sec >= 0 ) hw_set_bits (& rtc_hw -> irq_setup_1 , RTC_IRQ_SETUP_1_SEC_ENA_BITS );
168
+ if (t -> year >= 0 )
169
+ s0 |= RTC_IRQ_SETUP_0_YEAR_ENA_BITS | (((uint )t -> year ) << RTC_IRQ_SETUP_0_YEAR_LSB );
170
+ if (t -> month >= 1 )
171
+ s0 |= RTC_IRQ_SETUP_0_MONTH_ENA_BITS | (((uint )t -> month ) << RTC_IRQ_SETUP_0_MONTH_LSB );
172
+ if (t -> day >= 1 )
173
+ s0 |= RTC_IRQ_SETUP_0_DAY_ENA_BITS | (((uint )t -> day ) << RTC_IRQ_SETUP_0_DAY_LSB );
174
+ if (t -> dotw >= 0 )
175
+ s1 |= RTC_IRQ_SETUP_1_DOTW_ENA_BITS | (((uint )t -> dotw ) << RTC_IRQ_SETUP_1_DOTW_LSB );
176
+ if (t -> hour >= 0 )
177
+ s1 |= RTC_IRQ_SETUP_1_HOUR_ENA_BITS | (((uint )t -> hour ) << RTC_IRQ_SETUP_1_HOUR_LSB );
178
+ if (t -> min >= 0 )
179
+ s1 |= RTC_IRQ_SETUP_1_MIN_ENA_BITS | (((uint )t -> min ) << RTC_IRQ_SETUP_1_MIN_LSB );
180
+ if (t -> sec >= 0 )
181
+ s1 |= RTC_IRQ_SETUP_1_SEC_ENA_BITS | (((uint )t -> sec ) << RTC_IRQ_SETUP_1_SEC_LSB );
182
+ else if (_alarm_repeats == -1 ) // repeatable every second! All entries are -1
183
+ {
184
+ datetime_t tNew ;
185
+ rtc_get_datetime (& tNew );
186
+ s1 = RTC_IRQ_SETUP_1_SEC_ENA_BITS | ((((uint )tNew .sec + 1 ) % 60 ) << RTC_IRQ_SETUP_1_SEC_LSB );
187
+ }
181
188
182
- // Does it repeat? I.e. do we not match on any of the bits
183
- _alarm_repeats = rtc_alarm_repeats ( t ) ;
189
+ rtc_hw -> irq_setup_0 = s0 ;
190
+ rtc_hw -> irq_setup_1 = s1 ;
184
191
185
192
// Store function pointer we can call later
186
193
_callback = user_callback ;
0 commit comments