2929#include "py/mperrno.h"
3030#include "extmod/modmachine.h"
3131#include "shared/timeutils/timeutils.h"
32+ #include "modmachine.h"
3233#include "rtc.h"
3334#include "sys_ctrl_rtc.h"
3435
@@ -55,6 +56,27 @@ void LPRTC_IRQHandler(void) {
5556 lprtc_interrupt_disable (machine_rtc .rtc );
5657}
5758
59+ void machine_rtc_init (void ) {
60+ lprtc_interrupt_ack (machine_rtc .rtc );
61+ lprtc_interrupt_disable (machine_rtc .rtc );
62+ lprtc_interrupt_unmask (machine_rtc .rtc );
63+
64+ // Initialise the LPRTC if it's not already enabled.
65+ if (!((VBAT -> RTC_CLK_EN & RTC_CLK_ENABLE )
66+ && (machine_rtc .rtc -> LPRTC_CCR & CCR_LPRTC_EN )
67+ && (machine_rtc .rtc -> LPRTC_CPSR == LPRTC_PRESCALER_SETTING ))) {
68+ enable_lprtc_clk ();
69+ machine_rtc .rtc -> LPRTC_CCR = 0 ;
70+ lprtc_load_prescaler (machine_rtc .rtc , LPRTC_PRESCALER_SETTING );
71+ lprtc_load_count (machine_rtc .rtc , 0 );
72+ machine_rtc .rtc -> LPRTC_CCR = CCR_LPRTC_PSCLR_EN | CCR_LPRTC_EN ;
73+ }
74+
75+ NVIC_SetPriority (LPRTC_IRQ_IRQn , IRQ_PRI_RTC );
76+ NVIC_ClearPendingIRQ (LPRTC_IRQ_IRQn );
77+ NVIC_EnableIRQ (LPRTC_IRQ_IRQn );
78+ }
79+
5880// Returns the number of seconds and microseconds since the Epoch.
5981uint32_t mp_hal_time_get (uint32_t * microseconds ) {
6082 uint32_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
@@ -84,25 +106,18 @@ static mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, s
84106 // Check arguments.
85107 mp_arg_check_num (n_args , n_kw , 0 , 0 , false);
86108
87- lprtc_interrupt_disable (self -> rtc );
88- lprtc_interrupt_unmask ( self -> rtc );
109+ return MP_OBJ_FROM_PTR (self );
110+ }
89111
90- // Initialise the LPRTC if it's not already enabled.
91- if (!((VBAT -> RTC_CLK_EN & RTC_CLK_ENABLE )
92- && (self -> rtc -> LPRTC_CCR & CCR_LPRTC_EN )
93- && (self -> rtc -> LPRTC_CPSR == LPRTC_PRESCALER_SETTING ))) {
94- enable_lprtc_clk ();
95- self -> rtc -> LPRTC_CCR = 0 ;
96- lprtc_load_prescaler (self -> rtc , LPRTC_PRESCALER_SETTING );
97- lprtc_load_count (self -> rtc , 0 );
98- self -> rtc -> LPRTC_CCR = CCR_LPRTC_PSCLR_EN | CCR_LPRTC_EN ;
99- }
112+ void machine_rtc_set_wakeup (uint32_t seconds ) {
113+ LPRTC_Type * rtc = (LPRTC_Type * )LPRTC_BASE ;
100114
101- NVIC_SetPriority (LPRTC_IRQ_IRQn , IRQ_PRI_RTC );
102- NVIC_ClearPendingIRQ (LPRTC_IRQ_IRQn );
103- NVIC_EnableIRQ (LPRTC_IRQ_IRQn );
104-
105- return MP_OBJ_FROM_PTR (self );
115+ // Configure the counter match as atomically as possible.
116+ uint32_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
117+ lprtc_interrupt_ack (rtc );
118+ lprtc_load_counter_match_register (rtc , lprtc_get_count (rtc ) + seconds );
119+ lprtc_interrupt_enable (rtc );
120+ MICROPY_END_ATOMIC_SECTION (atomic_state );
106121}
107122
108123static mp_obj_t machine_rtc_datetime (mp_uint_t n_args , const mp_obj_t * args ) {
@@ -155,8 +170,6 @@ static mp_obj_t machine_rtc_alarm(size_t n_args, const mp_obj_t *pos_args, mp_ma
155170 { MP_QSTR_repeat , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
156171 };
157172
158- machine_rtc_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
159-
160173 // Parse args.
161174 mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
162175 mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (args ), allowed_args , args );
@@ -170,12 +183,7 @@ static mp_obj_t machine_rtc_alarm(size_t n_args, const mp_obj_t *pos_args, mp_ma
170183 // - if seconds >= 2 then it will always fire (when read/written close enough)
171184 seconds = MAX (2 , seconds );
172185
173- // Configure the counter match as atomically as possible.
174- uint32_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION ();
175- lprtc_interrupt_ack (self -> rtc );
176- lprtc_load_counter_match_register (self -> rtc , lprtc_get_count (self -> rtc ) + seconds );
177- lprtc_interrupt_enable (self -> rtc );
178- MICROPY_END_ATOMIC_SECTION (atomic_state );
186+ machine_rtc_set_wakeup (seconds );
179187 } else {
180188 mp_raise_ValueError (MP_ERROR_TEXT ("invalid argument(s)" ));
181189 }
0 commit comments