You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2022/02/22 18:24:05 UTC
[mynewt-core] 02/02: hw/sensors: BMA400 sleep/wake notification
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit c0f7072bd7c27613c867a5a155fa8e41748f9bfd
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Fri Feb 18 14:10:48 2022 +0100
hw/sensors: BMA400 sleep/wake notification
Sleep and wake notification was not working.
For this to work interrupt pin that is dedicated to wake state
has to be re-armed for different edge since there is no
sleep-change notification and some MCUs supported in mynewt
don't have trigger for both edges so far.
---
hw/drivers/sensors/bma400/include/bma400/bma400.h | 3 +
hw/drivers/sensors/bma400/src/bma400.c | 69 +++++++++++++++++++++--
2 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/hw/drivers/sensors/bma400/include/bma400/bma400.h b/hw/drivers/sensors/bma400/include/bma400/bma400.h
index b160b79..98d445b 100755
--- a/hw/drivers/sensors/bma400/include/bma400/bma400.h
+++ b/hw/drivers/sensors/bma400/include/bma400/bma400.h
@@ -25,6 +25,7 @@
#include <sensor/sensor.h>
#include <sensor/accel.h>
#include <sensor/temperature.h>
+#include <hal/hal_gpio.h>
#include "../../src/bma400_priv.h"
#ifdef __cplusplus
@@ -475,6 +476,7 @@ struct bma400_int {
bool asleep;
/* Configured interrupts */
struct sensor_int ints[2];
+ hal_gpio_irq_trig_t armed_trigger[2];
};
/* Device private data */
@@ -490,6 +492,7 @@ struct bma400_private_driver_data {
/* Shadow copy of registers */
struct bma400_reg_cache cache;
uint8_t transact;
+ uint8_t woke;
/* Active interrupt state */
struct bma400_int intr;
diff --git a/hw/drivers/sensors/bma400/src/bma400.c b/hw/drivers/sensors/bma400/src/bma400.c
index 1c2ba1e..c13ed50 100755
--- a/hw/drivers/sensors/bma400/src/bma400.c
+++ b/hw/drivers/sensors/bma400/src/bma400.c
@@ -728,6 +728,31 @@ bma400_set_acc_cfg(struct bma400 *bma400, struct bma400_acc_cfg *cfg)
return bma400_commit(bma400);
}
+static void
+bma400_arm_interrupt(struct bma400 *bma400, bma400_int_num_t int_num, hal_gpio_irq_trig_t trig)
+{
+ struct bma400_private_driver_data *pdd;
+ pdd = &bma400->pdd;
+ int host_pin;
+ int int_ix = (int)int_num - 1;
+
+ if (int_ix >= 0 && pdd->intr.armed_trigger[int_ix] != trig) {
+ host_pin = pdd->intr.ints[int_ix].host_pin;
+ if (pdd->intr.armed_trigger[int_ix] != HAL_GPIO_TRIG_NONE) {
+ hal_gpio_irq_release(host_pin);
+ }
+
+ pdd->intr.armed_trigger[int_ix] = trig;
+ if (trig != HAL_GPIO_TRIG_NONE) {
+ hal_gpio_irq_init(host_pin,
+ bma400_interrupt_handler, bma400,
+ trig,
+ HAL_GPIO_PULL_NONE);
+ hal_gpio_irq_enable(host_pin);
+ }
+ }
+}
+
int
bma400_set_int12_cfg(struct bma400 *bma400, struct bma400_int_pin_cfg *cfg)
{
@@ -741,9 +766,7 @@ bma400_set_int12_cfg(struct bma400 *bma400, struct bma400_int_pin_cfg *cfg)
trig = cfg->int1_level ? HAL_GPIO_TRIG_RISING : HAL_GPIO_TRIG_FALLING;
bma400->pdd.intr.ints[0].host_pin = cfg->int1_host_pin;
bma400->pdd.intr.ints[0].active = cfg->int1_level;
- hal_gpio_irq_init(cfg->int1_host_pin,
- bma400_interrupt_handler,
- bma400, trig, HAL_GPIO_PULL_NONE);
+ bma400_arm_interrupt(bma400, BMA400_INT1_PIN, trig);
}
}
if (cfg->int2_host_pin != bma400->pdd.intr.ints[1].host_pin) {
@@ -754,9 +777,7 @@ bma400_set_int12_cfg(struct bma400 *bma400, struct bma400_int_pin_cfg *cfg)
trig = cfg->int1_level ? HAL_GPIO_TRIG_RISING : HAL_GPIO_TRIG_FALLING;
bma400->pdd.intr.ints[1].host_pin = cfg->int2_host_pin;
bma400->pdd.intr.ints[1].active = cfg->int2_level;
- hal_gpio_irq_init(cfg->int2_host_pin,
- bma400_interrupt_handler,
- bma400, trig, HAL_GPIO_PULL_NONE);
+ bma400_arm_interrupt(bma400, BMA400_INT2_PIN, trig);
}
}
@@ -882,6 +903,10 @@ bma400_set_wakeup(struct bma400 *bma400, struct bma400_wakeup_cfg *cfg)
bma400_set_register_field(bma400, BMA400_REG_INT1_MAP, BMA400_INT1_MAP_WKUP_INT1, cfg->int_num == BMA400_INT1_PIN);
bma400_set_register_field(bma400, BMA400_REG_INT2_MAP, BMA400_INT2_MAP_WKUP_INT2, cfg->int_num == BMA400_INT2_PIN);
+ if (cfg->int_num != BMA400_NO_INT_PIN) {
+ bma400->pdd.allowed_events |= SENSOR_EVENT_TYPE_SLEEP | SENSOR_EVENT_TYPE_WAKEUP;
+ }
+
return bma400_commit(bma400);
}
@@ -1658,8 +1683,13 @@ bma400_sensor_handle_interrupt(struct sensor *sensor)
struct bma400_private_driver_data *pdd;
struct bma400_int_status int_status;
int rc;
+ uint8_t woke;
+ int8_t wakeup_pin;
+ int wakeup_pin_state;
+ int16_t host_wakeup_pin;
bma400 = (struct bma400 *)SENSOR_GET_DEVICE(sensor);
+ wakeup_pin = (int8_t)bma400->cfg.wakeup_cfg.int_num - 1;
pdd = &bma400->pdd;
rc = bma400_get_int_status(bma400, &int_status);
@@ -1668,6 +1698,33 @@ bma400_sensor_handle_interrupt(struct sensor *sensor)
return rc;
}
+ if (wakeup_pin >= 0 &&
+ (pdd->notify_ctx.snec_evtype & (SENSOR_EVENT_TYPE_WAKEUP | SENSOR_EVENT_TYPE_SLEEP)) != 0) {
+ host_wakeup_pin = pdd->intr.ints[wakeup_pin].host_pin;
+ wakeup_pin_state = hal_gpio_read(host_wakeup_pin);
+ woke = wakeup_pin_state == pdd->intr.ints[wakeup_pin].active;
+
+ bma400_arm_interrupt(bma400, bma400->cfg.wakeup_cfg.int_num,
+ wakeup_pin_state ? HAL_GPIO_TRIG_FALLING : HAL_GPIO_TRIG_RISING);
+
+ if (woke != pdd->woke) {
+ pdd->woke = woke;
+ /*
+ * Wakeup interrupt pin stays active whole time till device goes to sleep,
+ * notify client only once.
+ */
+ if (woke) {
+ if (pdd->notify_ctx.snec_evtype & SENSOR_EVENT_TYPE_WAKEUP) {
+ sensor_mgr_put_notify_evt(&pdd->notify_ctx, SENSOR_EVENT_TYPE_WAKEUP);
+ }
+ } else {
+ if (pdd->notify_ctx.snec_evtype & SENSOR_EVENT_TYPE_SLEEP) {
+ sensor_mgr_put_notify_evt(&pdd->notify_ctx, SENSOR_EVENT_TYPE_SLEEP);
+ }
+ }
+ }
+ }
+
if ((pdd->notify_ctx.snec_evtype & SENSOR_EVENT_TYPE_SINGLE_TAP) &&
(int_status.int_stat1 & BMA400_INT_STAT1_S_TAP_INT_STAT)) {
sensor_mgr_put_notify_evt(&pdd->notify_ctx, SENSOR_EVENT_TYPE_SINGLE_TAP);