@@ -43,9 +43,12 @@ BUILD_ASSERT(!IS_ENABLED(CONFIG_SLM_START_SLEEP),
43
43
static struct k_work_delayable indicate_work ;
44
44
45
45
struct k_work_q slm_work_q ;
46
+ static atomic_t callback_wakeup_running ;
46
47
47
48
/* Forward declarations */
48
49
static void indicate_wk (struct k_work * work );
50
+ static void power_pin_callback_wakeup (const struct device * dev ,
51
+ struct gpio_callback * gpio_callback , uint32_t );
49
52
50
53
NRF_MODEM_LIB_ON_INIT (lwm2m_init_hook , on_modem_lib_init , NULL );
51
54
NRF_MODEM_LIB_ON_DFU_RES (main_dfu_hook , on_modem_dfu_res , NULL );
@@ -149,19 +152,24 @@ static int configure_power_pin_interrupt(gpio_callback_handler_t handler, gpio_f
149
152
return err ;
150
153
}
151
154
152
- LOG_DBG ("Configured interrupt (0x%x) on power pin (%u)." , flags , pin );
155
+ LOG_DBG ("Configured interrupt (0x%x) on power pin (%u) with handler (%p)." ,
156
+ flags , pin , handler );
153
157
return 0 ;
154
158
}
155
159
156
- static void power_pin_callback_poweroff ( const struct device * , struct gpio_callback * , uint32_t )
160
+ static void slm_enter_sleep_work_fn ( struct k_work * )
157
161
{
158
- LOG_INF ("Power off triggered." );
159
162
slm_enter_sleep ();
160
163
}
161
164
162
- static void poweroff_interrupt_enabler (struct k_work * )
165
+ static void power_pin_callback_poweroff (const struct device * dev ,
166
+ struct gpio_callback * gpio_callback , uint32_t )
163
167
{
164
- configure_power_pin_interrupt (power_pin_callback_poweroff , GPIO_INT_EDGE_RISING );
168
+ static K_WORK_DEFINE (work , slm_enter_sleep_work_fn ) ;
169
+
170
+ LOG_INF ("Power off triggered." );
171
+ gpio_remove_callback (dev , gpio_callback );
172
+ k_work_submit (& work );
165
173
}
166
174
167
175
#endif /* POWER_PIN_IS_ENABLED */
@@ -237,28 +245,16 @@ static void indicate_stop(void)
237
245
static void power_pin_callback_enable_poweroff (const struct device * dev ,
238
246
struct gpio_callback * gpio_callback , uint32_t )
239
247
{
240
- static K_WORK_DELAYABLE_DEFINE (work , poweroff_interrupt_enabler ) ;
241
-
242
248
LOG_DBG ("Enabling the poweroff interrupt shortly..." );
243
249
gpio_remove_callback (dev , gpio_callback );
244
250
245
- /* Enable the poweroff interrupt after a small delay
246
- * so that it doesn't fire right away (which it does if enabled here).
247
- */
248
- k_work_schedule (& work , K_MSEC (1 ));
251
+ configure_power_pin_interrupt (power_pin_callback_poweroff , GPIO_INT_EDGE_RISING );
249
252
}
250
253
251
- static void power_pin_callback_wakeup (const struct device * dev ,
252
- struct gpio_callback * gpio_callback , uint32_t )
254
+ static void power_pin_callback_wakeup_work_fn (struct k_work * )
253
255
{
254
- static atomic_t callback_running ;
255
256
int err ;
256
257
257
- /* Prevent level triggered interrupt running this multiple times. */
258
- if (!atomic_cas (& callback_running , false, true)) {
259
- return ;
260
- }
261
-
262
258
LOG_INF ("Resuming from idle." );
263
259
if (k_work_delayable_is_pending (& indicate_work )) {
264
260
k_work_cancel_delayable (& indicate_work );
@@ -271,17 +267,32 @@ static void power_pin_callback_wakeup(const struct device *dev,
271
267
}
272
268
err = slm_at_host_power_on ();
273
269
if (err ) {
274
- atomic_set (& callback_running , false);
275
- LOG_ERR ("Failed to power on uart: %d" , err );
270
+ LOG_ERR ("Failed to power on uart: %d. Resetting SLM." , err );
271
+ gpio_remove_callback (gpio_dev , & gpio_cb );
272
+ slm_reset ();
273
+ return ;
274
+ }
275
+
276
+ atomic_set (& callback_wakeup_running , false);
277
+ }
278
+
279
+ static void power_pin_callback_wakeup (const struct device * dev ,
280
+ struct gpio_callback * gpio_callback , uint32_t )
281
+ {
282
+ static K_WORK_DEFINE (work , power_pin_callback_wakeup_work_fn ) ;
283
+
284
+ /* Prevent level triggered interrupt running this multiple times. */
285
+ if (!atomic_cas (& callback_wakeup_running , false, true)) {
276
286
return ;
277
287
}
278
288
289
+ LOG_INF ("Resuming from idle shortly..." );
279
290
gpio_remove_callback (dev , gpio_callback );
280
291
281
292
/* Enable the poweroff interrupt only when the pin will be back to a nonactive state. */
282
293
configure_power_pin_interrupt (power_pin_callback_enable_poweroff , GPIO_INT_EDGE_RISING );
283
294
284
- atomic_set ( & callback_running , false );
295
+ k_work_submit ( & work );
285
296
}
286
297
287
298
void slm_enter_idle (void )
0 commit comments