Skip to content

Commit 407643d

Browse files
trantanenrlubos
authored andcommitted
lib: modem_slm: Stop triggering indicate multiple times
When indicate handler is registered and indicate pin configured, thousands of callback calls were executed because the GPIO cannot be triggering on an edge due to Hw issues increasing power consumption Now there will be one callback call for one instance of incoming data or AT notifications in SLM idle state. This solution is not perfect but better than currently with thousands of callbacks. Jira: LRCS-82 Signed-off-by: Tommi Rantanen <[email protected]>
1 parent dccb45e commit 407643d

File tree

1 file changed

+68
-25
lines changed

1 file changed

+68
-25
lines changed

lib/modem_slm/modem_slm.c

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,67 @@ static const char at_usage_str[] = "Usage: slm <at_command>";
6060
/* global functions defined in different files */
6161
void slm_monitor_dispatch(const char *notif);
6262

63+
#if (CONFIG_MODEM_SLM_INDICATE_PIN >= 0)
64+
static bool indicate_pin_enabled;
65+
66+
static void gpio_cb_func(const struct device *dev, struct gpio_callback *gpio_cb, uint32_t pins);
67+
static struct gpio_callback gpio_cb;
68+
#endif
69+
70+
static int indicate_pin_enable(void)
71+
{
72+
#if (CONFIG_MODEM_SLM_INDICATE_PIN >= 0)
73+
int err = 0;
74+
75+
if (!indicate_pin_enabled) {
76+
err = gpio_pin_configure(gpio_dev, CONFIG_MODEM_SLM_INDICATE_PIN,
77+
GPIO_INPUT | GPIO_PULL_UP | GPIO_ACTIVE_LOW);
78+
if (err) {
79+
LOG_ERR("GPIO config error: %d", err);
80+
return err;
81+
}
82+
83+
gpio_init_callback(&gpio_cb, gpio_cb_func, BIT(CONFIG_MODEM_SLM_INDICATE_PIN));
84+
err = gpio_add_callback(gpio_dev, &gpio_cb);
85+
if (err) {
86+
LOG_WRN("GPIO add callback error: %d", err);
87+
}
88+
err = gpio_pin_interrupt_configure(gpio_dev, CONFIG_MODEM_SLM_INDICATE_PIN,
89+
GPIO_INT_LEVEL_LOW);
90+
if (err) {
91+
LOG_WRN("GPIO interrupt configure error: %d", err);
92+
}
93+
indicate_pin_enabled = true;
94+
LOG_DBG("Indicate pin enabled");
95+
}
96+
#endif
97+
return 0;
98+
}
99+
100+
static void indicate_pin_disable(void)
101+
{
102+
#if (CONFIG_MODEM_SLM_INDICATE_PIN >= 0)
103+
if (indicate_pin_enabled) {
104+
gpio_remove_callback(gpio_dev, &gpio_cb);
105+
gpio_pin_interrupt_configure(gpio_dev, CONFIG_MODEM_SLM_INDICATE_PIN,
106+
GPIO_INT_DISABLE);
107+
gpio_pin_configure(gpio_dev, CONFIG_MODEM_SLM_INDICATE_PIN, GPIO_DISCONNECTED);
108+
indicate_pin_enabled = false;
109+
LOG_DBG("Indicate pin disabled");
110+
}
111+
#endif
112+
}
113+
63114
static void gpio_wakeup_wk(struct k_work *work)
64115
{
65116
ARG_UNUSED(work);
66117

67118
if (gpio_pin_set(gpio_dev, CONFIG_MODEM_SLM_WAKEUP_PIN, 0) != 0) {
68119
LOG_WRN("GPIO set error");
69120
}
121+
/* When SLM is woken up, indicate pin must be enabled */
122+
(void)indicate_pin_enable();
123+
70124
LOG_INF("Stop wake-up");
71125
}
72126

@@ -323,11 +377,16 @@ static void gpio_cb_func(const struct device *dev, struct gpio_callback *gpio_cb
323377
if (k_work_delayable_is_pending(&gpio_wakeup_work)) {
324378
(void)k_work_cancel_delayable(&gpio_wakeup_work);
325379
(void)gpio_pin_set(gpio_dev, CONFIG_MODEM_SLM_WAKEUP_PIN, 0);
380+
} else {
381+
/* Disable indicate pin so that callbacks doesn't keep on coming. */
382+
indicate_pin_disable();
326383
}
327384

328385
LOG_INF("Remote indication");
329386
if (ind_handler) {
330387
ind_handler();
388+
} else {
389+
LOG_WRN("Indicate PIN configured but slm_ind_handler_t not defined");
331390
}
332391
}
333392
#endif /* CONFIG_MODEM_SLM_INDICATE_PIN */
@@ -348,27 +407,9 @@ static int gpio_init(void)
348407
return err;
349408
}
350409

351-
#if (CONFIG_MODEM_SLM_INDICATE_PIN >= 0)
352-
err = gpio_pin_configure(gpio_dev, CONFIG_MODEM_SLM_INDICATE_PIN,
353-
GPIO_INPUT | GPIO_PULL_UP | GPIO_ACTIVE_LOW);
354-
if (err) {
355-
LOG_ERR("GPIO config error: %d", err);
356-
return err;
357-
}
410+
err = indicate_pin_enable();
358411

359-
gpio_init_callback(&gpio_cb, gpio_cb_func, BIT(CONFIG_MODEM_SLM_INDICATE_PIN));
360-
err = gpio_add_callback(gpio_dev, &gpio_cb);
361-
if (err) {
362-
LOG_WRN("GPIO add callback error: %d", err);
363-
}
364-
err = gpio_pin_interrupt_configure(gpio_dev, CONFIG_MODEM_SLM_INDICATE_PIN,
365-
GPIO_INT_LEVEL_LOW);
366-
if (err) {
367-
LOG_WRN("GPIO enable callback error: %d", err);
368-
}
369-
#endif
370-
371-
return 0;
412+
return err;
372413
}
373414

374415
int modem_slm_init(slm_data_handler_t handler)
@@ -415,11 +456,8 @@ int modem_slm_uninit(void)
415456
k_sleep(K_MSEC(10));
416457

417458
gpio_pin_configure(gpio_dev, CONFIG_MODEM_SLM_WAKEUP_PIN, GPIO_DISCONNECTED);
418-
#if (CONFIG_MODEM_SLM_INDICATE_PIN >= 0)
419-
gpio_remove_callback(gpio_dev, &gpio_cb);
420-
gpio_pin_interrupt_configure(gpio_dev, CONFIG_MODEM_SLM_INDICATE_PIN, GPIO_INT_DISABLE);
421-
gpio_pin_configure(gpio_dev, CONFIG_MODEM_SLM_INDICATE_PIN, GPIO_DISCONNECTED);
422-
#endif
459+
460+
indicate_pin_disable();
423461

424462
data_handler = NULL;
425463
ind_handler = NULL;
@@ -485,6 +523,11 @@ int modem_slm_send_cmd(const char *const command, uint32_t timeout)
485523
{
486524
int ret;
487525

526+
/* Enable indicate pin when command is sent. This should not be needed but is made
527+
* currently to make sure it wouldn't be disabled forever.
528+
*/
529+
(void)indicate_pin_enable();
530+
488531
slm_at_state = AT_CMD_PENDING;
489532
ret = uart_send(command, strlen(command));
490533
if (ret < 0) {

0 commit comments

Comments
 (0)