@@ -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,22 @@ 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 * , struct gpio_callback * , uint32_t )
163
166
{
164
- configure_power_pin_interrupt (power_pin_callback_poweroff , GPIO_INT_EDGE_RISING );
167
+ static K_WORK_DEFINE (work , slm_enter_sleep_work_fn ) ;
168
+
169
+ LOG_INF ("Power off triggered." );
170
+ k_work_submit (& work );
165
171
}
166
172
167
173
#endif /* POWER_PIN_IS_ENABLED */
@@ -237,25 +243,18 @@ static void indicate_stop(void)
237
243
static void power_pin_callback_enable_poweroff (const struct device * dev ,
238
244
struct gpio_callback * gpio_callback , uint32_t )
239
245
{
240
- static K_WORK_DELAYABLE_DEFINE (work , poweroff_interrupt_enabler ) ;
241
-
242
246
LOG_DBG ("Enabling the poweroff interrupt shortly..." );
243
247
gpio_remove_callback (dev , gpio_callback );
244
248
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 ));
249
+ configure_power_pin_interrupt (power_pin_callback_poweroff , GPIO_INT_EDGE_RISING );
249
250
}
250
251
251
- static void power_pin_callback_wakeup (const struct device * dev ,
252
- struct gpio_callback * gpio_callback , uint32_t )
252
+ static void power_pin_callback_wakeup_work_fn (struct k_work * )
253
253
{
254
- static atomic_t callback_running ;
255
254
int err ;
256
255
257
256
/* Prevent level triggered interrupt running this multiple times. */
258
- if (!atomic_cas (& callback_running , false, true)) {
257
+ if (!atomic_cas (& callback_wakeup_running , false, true)) {
259
258
return ;
260
259
}
261
260
@@ -271,17 +270,34 @@ static void power_pin_callback_wakeup(const struct device *dev,
271
270
}
272
271
err = slm_at_host_power_on ();
273
272
if (err ) {
274
- atomic_set (& callback_running , false);
273
+ /* We couldn't wake up SLM device. Re-enable wakeup functionality. */
274
+ configure_power_pin_interrupt (power_pin_callback_wakeup , GPIO_INT_LEVEL_LOW );
275
+ atomic_set (& callback_wakeup_running , false);
275
276
LOG_ERR ("Failed to power on uart: %d" , err );
276
277
return ;
277
278
}
278
279
279
- gpio_remove_callback (dev , gpio_callback );
280
-
281
280
/* Enable the poweroff interrupt only when the pin will be back to a nonactive state. */
282
281
configure_power_pin_interrupt (power_pin_callback_enable_poweroff , GPIO_INT_EDGE_RISING );
283
282
284
- atomic_set (& callback_running , false);
283
+ atomic_set (& callback_wakeup_running , false);
284
+ }
285
+
286
+ static void power_pin_callback_wakeup (const struct device * dev ,
287
+ struct gpio_callback * gpio_callback , uint32_t )
288
+ {
289
+ static K_WORK_DEFINE (work , power_pin_callback_wakeup_work_fn ) ;
290
+
291
+ /* Prevent level triggered interrupt running this multiple times. */
292
+ if (!atomic_cas (& callback_wakeup_running , false, true)) {
293
+ LOG_WRN ("power_pin_callback_wakeup_work_fn already running." );
294
+ return ;
295
+ }
296
+
297
+ LOG_INF ("Resuming from idle shortly..." );
298
+ gpio_remove_callback (dev , gpio_callback );
299
+
300
+ k_work_submit (& work );
285
301
}
286
302
287
303
void slm_enter_idle (void )
0 commit comments