sensord: use interrupts to improve LSM6DS3 timing accuracy (#24525)

* change LSM6DS3TR(-c) gyroscope  and accelerometer to interrupt

* add pthread for linking

* add interrupt collector thread to fetch in parallel to non interrupt based sensors

* change get_event interface to return true on successful read

* fetch sensor interrupts via gpiochip

* avoid sending empty messages (interrupt only, non interupt magn can leave a gap in the orphan block)

* add verifier script to sensor interrupts (sensor_data_to_hist.py)

* add/update sensord testsweet (test_sensord.py)

* add poll timed out check

* unexport interrupt gpio pins

* gpiochip on both edges, but skip falling edge if rising edge is detected, this is handled in the sensor as the status flag is checked if new data is availble

* add test to sensord to verify 100Hz interrupt frequency

* add sensor shutdown/low power mode functionality on sensord exit

* relax test, will be readded in the splitup PR

Co-authored-by: Kurt Nistelberger <kurt.nistelberger@gmail.com>
This commit is contained in:
Willem Melching
2022-09-13 07:29:31 +02:00
committed by GitHub
parent 56b05d55eb
commit 84a3c355e5
31 changed files with 711 additions and 58 deletions
+36 -3
View File
@@ -4,11 +4,11 @@
#include <unistd.h>
#include <cstring>
#include <linux/gpio.h>
#include <sys/ioctl.h>
#include "common/util.h"
// We assume that all pins have already been exported on boot,
// and that we have permission to write to them.
#include "common/swaglog.h"
int gpio_init(int pin_nr, bool output) {
char pin_dir_path[50];
@@ -30,3 +30,36 @@ int gpio_set(int pin_nr, bool high) {
}
return util::write_file(pin_val_path, (void*)(high ? "1" : "0"), 1);
}
int gpiochip_get_ro_value_fd(const char* consumer_label, int gpiochiop_id, int pin_nr) {
// Assumed that all interrupt pins are unexported and rights are given to
// read from gpiochip0.
std::string gpiochip_path = "/dev/gpiochip" + std::to_string(gpiochiop_id);
int fd = open(gpiochip_path.c_str(), O_RDONLY);
if (fd < 0) {
LOGE("Error opening gpiochip0 fd")
return -1;
}
// Setup event
struct gpioevent_request rq;
rq.lineoffset = pin_nr;
rq.handleflags = GPIOHANDLE_REQUEST_INPUT;
/* Requesting both edges as the data ready pulse from the lsm6ds sensor is
very short(75us) and is mostly detected as falling edge instead of rising.
So if it is detected as rising the following falling edge is skipped. */
rq.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES;
strncpy(rq.consumer_label, consumer_label, std::size(rq.consumer_label) - 1);
int ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &rq);
if (ret == -1) {
LOGE("Unable to get line event from ioctl : %s", strerror(errno));
close(fd);
return -1;
}
close(fd);
return rq.fd;
}
+12
View File
@@ -8,6 +8,11 @@
#define GPIO_UBLOX_PWR_EN 34
#define GPIO_STM_RST_N 124
#define GPIO_STM_BOOT0 134
#define GPIO_BMX_ACCEL_INT 21
#define GPIO_BMX_GYRO_INT 23
#define GPIO_BMX_MAGN_INT 87
#define GPIO_LSM_INT 84
#define GPIOCHIP_INT 0
#else
#define GPIO_HUB_RST_N 0
#define GPIO_UBLOX_RST_N 0
@@ -15,7 +20,14 @@
#define GPIO_UBLOX_PWR_EN 0
#define GPIO_STM_RST_N 0
#define GPIO_STM_BOOT0 0
#define GPIO_BMX_ACCEL_INT 0
#define GPIO_BMX_GYRO_INT 0
#define GPIO_BMX_MAGN_INT 0
#define GPIO_LSM_INT 0
#define GPIOCHIP_INT 0
#endif
int gpio_init(int pin_nr, bool output);
int gpio_set(int pin_nr, bool high);
int gpiochip_get_ro_value_fd(const char* consumer_label, int gpiochiop_id, int pin_nr);