Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/gateway_lte/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ CONFIG_EPACKET_RECEIVE_GROUPING_MAX_HOLD_MS=1000
# Task Runner
CONFIG_TASK_RUNNER=y
CONFIG_TASK_RUNNER_AUTO_ITERATE=y
CONFIG_TASK_RUNNER_DEFAULT_SCHEDULES_ID=1
CONFIG_TASK_RUNNER_TASK_TDF_LOGGER=y
CONFIG_TASK_RUNNER_TASK_BATTERY=y
CONFIG_TASK_RUNNER_TASK_GNSS=y
Expand Down
3 changes: 2 additions & 1 deletion apps/gateway_lte/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ static const struct task_schedule schedules[] = {
.loggers = TDF_DATA_LOGGER_UDP,
.tdfs = TASK_TDF_LOGGER_LOG_ANNOUNCE | TASK_TDF_LOGGER_LOG_BATTERY |
TASK_TDF_LOGGER_LOG_AMBIENT_ENV |
TASK_TDF_LOGGER_LOG_LOCATION | TASK_TDF_LOGGER_LOG_NET_CONN,
TASK_TDF_LOGGER_LOG_LOCATION |
TASK_TDF_LOGGER_LOG_NET_CONN | TASK_TDF_LOGGER_LOG_CUSTOM,
},
},
{
Expand Down
34 changes: 31 additions & 3 deletions drivers/imu/bma4xx/bma4xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@

#include "bma4xx.h"

#define FIFO_BYTES MIN(BMA4XX_FIFO_LEN, (7 * CONFIG_INFUSE_IMU_MAX_FIFO_SAMPLES))
#define FRAME_SIZE 7
#define FIFO_BYTES MIN(BMA4XX_FIFO_LEN, (FRAME_SIZE * CONFIG_INFUSE_IMU_MAX_FIFO_SAMPLES))

struct bma4xx_config {
union bma4xx_bus bus;
Expand Down Expand Up @@ -116,6 +117,8 @@ static void bma4xx_gpio_callback(const struct device *dev, struct gpio_callback
ARG_UNUSED(cb);
ARG_UNUSED(pins);

LOG_DBG("");

data->int1_prev_timestamp = data->int1_timestamp;
data->int1_timestamp = k_uptime_ticks();
k_sem_give(&data->int1_sem);
Expand Down Expand Up @@ -250,14 +253,14 @@ int bma4xx_configure(const struct device *dev, const struct imu_config *imu_cfg,
/* FIFO configuration */
rc |= bma4xx_reg_write(dev, BMA4XX_REG_FIFO_CONFIG0,
BMA4XX_FIFO_CONFIG0_EN_XYZ | BMA4XX_FIFO_CONFIG0_DATA_12BIT);
fifo_watermark = MIN(7 * imu_cfg->fifo_sample_buffer, FIFO_BYTES);
fifo_watermark = MIN(FRAME_SIZE * imu_cfg->fifo_sample_buffer, FIFO_BYTES);
rc |= bma4xx_reg_write(dev, BMA4XX_REG_FIFO_CONFIG1, (fifo_watermark >> 0) & 0xFF);
rc |= bma4xx_reg_write(dev, BMA4XX_REG_FIFO_CONFIG2, (fifo_watermark >> 8) & 0xFF);
data->fifo_threshold = fifo_watermark;
LOG_DBG("Watermark: %d bytes", fifo_watermark);

output->expected_interrupt_period_us =
(fifo_watermark / 7) * output->accelerometer_period_us;
(fifo_watermark / FRAME_SIZE) * output->accelerometer_period_us;

/* Flush the FIFO, enable GPIO interrupts */
rc |= bma4xx_reg_write(dev, BMA4XX_REG_CMD, BMA4XX_CMD_FIFO_FLUSH);
Expand Down Expand Up @@ -300,6 +303,8 @@ int bma4xx_data_read(const struct device *dev, struct imu_sample_array *samples,
uint16_t extra_frames, interrupt_frame = 0;
uint8_t fh_mode, fh_param;
uint8_t acc_samples = 0;
bool extra_pending = false;
int64_t sim_timestamp;
int rc;

/* Init sample output */
Expand All @@ -320,12 +325,30 @@ int bma4xx_data_read(const struct device *dev, struct imu_sample_array *samples,
}
LOG_DBG("Reading %d bytes", fifo_length);

/* More data pending than we have FIFO */
if (fifo_length > sizeof(data->fifo_data_buffer)) {
/* Round down to what we can actually fit in the buffer */
fifo_length = ROUND_DOWN(sizeof(data->fifo_data_buffer), FRAME_SIZE);
extra_pending = true;
}

/* Read the FIFO data */
rc = bma4xx_reg_read(dev, BMA4XX_REG_FIFO_DATA, data->fifo_data_buffer, fifo_length);
if (rc < 0) {
goto cleanup;
}

if (extra_pending) {
/* Reset the FIFO, since handling any remaining data is questionable */
LOG_WRN("Flushing FIFO due to overrun");
rc = bma4xx_reg_write(dev, BMA4XX_REG_CMD, BMA4XX_CMD_FIFO_FLUSH);
if (rc < 0) {
LOG_WRN("FIFO flush failed");
}
(void)k_sem_take(&data->int1_sem, K_NO_WAIT);
sim_timestamp = k_uptime_ticks();
}

/* Scan through to populate data and count frames */
while (buffer_offset < fifo_length) {
/* Extract FIFO frame header params */
Expand Down Expand Up @@ -393,6 +416,11 @@ int bma4xx_data_read(const struct device *dev, struct imu_sample_array *samples,
samples->accelerometer.buffer_period_ticks =
(acc_samples - 1) * int_period_ticks / interrupt_frame;

if (extra_pending) {
/* Set the interrupt time to the FIFO flush */
data->int1_timestamp = sim_timestamp;
}

cleanup:
(void)bma4xx_bus_pm(dev, false);
return rc;
Expand Down
31 changes: 30 additions & 1 deletion drivers/imu/bmi270/bmi270.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,9 @@ int bmi270_data_read(const struct device *dev, struct imu_sample_array *samples,
uint8_t fh_mode, fh_param;
int32_t int_period_ticks;
int32_t frame_period_ticks;

bool extra_pending = false;
int64_t sim_timestamp;
uint8_t reg_val;
int rc;

/* Init sample output */
Expand All @@ -514,12 +516,33 @@ int bmi270_data_read(const struct device *dev, struct imu_sample_array *samples,
}
LOG_DBG("Reading %d bytes", fifo_length);

/* More data pending than we have FIFO */
if (fifo_length > sizeof(data->fifo_data_buffer)) {
/* Round down to what we can actually fit in the buffer.
* Partial reads don't remove the sample from the FIFO.
*/
fifo_length = sizeof(data->fifo_data_buffer);
extra_pending = true;
}

/* Read the FIFO data */
rc = bmi270_reg_read(dev, BMI270_REG_FIFO_DATA, data->fifo_data_buffer, fifo_length);
if (rc < 0) {
return rc;
}

if (extra_pending) {
/* Reset the FIFO, since handling any remaining data is questionable */
LOG_WRN("Flushing FIFO due to overrun");
reg_val = BMI270_CMD_FIFO_FLUSH;
rc = bmi270_reg_write(dev, BMI270_REG_CMD, &reg_val, 1);
if (rc < 0) {
LOG_WRN("FIFO flush failed");
}
(void)k_sem_take(&data->int1_sem, K_NO_WAIT);
sim_timestamp = k_uptime_ticks();
}

/* Scan through to count frames */
data_frames = 0;
while (buffer_offset < fifo_length) {
Expand Down Expand Up @@ -652,6 +675,12 @@ int bmi270_data_read(const struct device *dev, struct imu_sample_array *samples,
buffer_offset += 6;
}
}

if (extra_pending) {
/* Set the interrupt time to the FIFO flush */
data->int1_timestamp = sim_timestamp;
}

return 0;
}

Expand Down
6 changes: 2 additions & 4 deletions drivers/imu/lis2dw12/lis2dw12.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@

#include "lis2dw12.h"

#define FIFO_SAMPLES MIN(LIS2DW12_FIFO_FRAME_SIZE, CONFIG_INFUSE_IMU_MAX_FIFO_SAMPLES)

struct lis2dw12_config {
union lis2dw12_bus bus;
const struct lis2dw12_bus_io *bus_io;
Expand All @@ -39,7 +37,7 @@ struct lis2dw12_data {
uint16_t acc_time_scale;
uint8_t accel_range;
uint8_t fifo_threshold;
struct lis2dw12_fifo_frame fifo_data_buffer[FIFO_SAMPLES];
struct lis2dw12_fifo_frame fifo_data_buffer[LIS2DW12_FIFO_FRAME_SIZE];
};

struct sensor_config {
Expand Down Expand Up @@ -259,7 +257,7 @@ int lis2dw12_configure(const struct device *dev, const struct imu_config *imu_cf
* to read data before the FIFO is full and we lose all knowledge of how many FIFO frames
* were dropped.
*/
data->fifo_threshold = MIN((FIFO_SAMPLES - 1), imu_cfg->fifo_sample_buffer);
data->fifo_threshold = MIN((LIS2DW12_FIFO_FRAME_SIZE - 1), imu_cfg->fifo_sample_buffer);

config_regs = accel_conf(dev, imu_cfg->accelerometer.sample_rate_hz,
imu_cfg->accelerometer.full_scale_range,
Expand Down
91 changes: 91 additions & 0 deletions subsys/validation/validation_imu.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,92 @@ static int validate_sample_timing(const struct device *dev, uint8_t acc_range,
return rc == 0 ? rc2 : rc;
}

static int validate_fifo_overrun(const struct device *dev)
{
struct imu_config config = {
.accelerometer =
{
.full_scale_range = 4,
.sample_rate_hz = 400,
.low_power = false,
},
.gyroscope = {0},
.fifo_sample_buffer = CONFIG_INFUSE_IMU_MAX_FIFO_SAMPLES - 10,
};
struct imu_config_output config_output;
int32_t buffer_period_us;
int rc2;
int rc;

/* Configure IMU with maximum FIFO buffering */
rc = imu_configure(dev, &config, &config_output);
if (rc < 0) {
if (rc == -ENOTSUP) {
VALIDATION_REPORT_INFO(TEST, "Configuration not supported");
return 0;
}
VALIDATION_REPORT_ERROR(TEST, "Failed to configure (%d)", rc);
return rc;
}

int64_t int_expected = config_output.expected_interrupt_period_us;
int64_t int_threshold_min = (80 * int_expected) / 100;
int64_t int_threshold_max = (120 * int_expected) / 100;

/* Wait for the interrupt */
rc = imu_data_wait(dev, K_USEC(2 * int_expected));
if (rc < 0) {
VALIDATION_REPORT_ERROR(TEST, "Interrupt timeout");
rc = -EINVAL;
goto cleanup;
}
/* Wait another 40 samples (@ 400hz) */
k_sleep(K_MSEC(100));
rc = imu_data_read(dev, imu_samples, MAX_SAMPLES);
if (rc < 0) {
VALIDATION_REPORT_ERROR(TEST, "Data read failed (%d)", rc);
rc = -EINVAL;
goto cleanup;
}
/* Some small leeway for drivers with approximate FIFO knowledge */
if (imu_samples->accelerometer.num < CONFIG_INFUSE_IMU_MAX_FIFO_SAMPLES - 2) {
VALIDATION_REPORT_ERROR(TEST, "Unexpected number of samples read (%d < %d)",
imu_samples->accelerometer.num,
CONFIG_INFUSE_IMU_MAX_FIFO_SAMPLES - 2);
rc = -EINVAL;
goto cleanup;
}
/* Operation should continue after overrun */
rc = imu_data_wait(dev, K_USEC(2 * int_expected));
if (rc < 0) {
VALIDATION_REPORT_ERROR(TEST, "Interrupt timeout");
rc = -EINVAL;
goto cleanup;
}
rc = imu_data_read(dev, imu_samples, MAX_SAMPLES);
if (rc < 0) {
VALIDATION_REPORT_ERROR(TEST, "Data read failed (%d)", rc);
rc = -EINVAL;
goto cleanup;
}
buffer_period_us = k_ticks_to_us_near32(imu_samples->accelerometer.buffer_period_ticks);
if ((buffer_period_us < int_threshold_min) || (buffer_period_us > int_threshold_max)) {
VALIDATION_REPORT_ERROR(TEST, "Unexpected buffer period (%d < %d < %d)",
(int32_t)int_threshold_min, buffer_period_us,
(int32_t)int_threshold_max);
rc = -EINVAL;
goto cleanup;
}
cleanup:
/* Reset IMU */
rc2 = imu_configure(dev, NULL, NULL);
if (rc2 < 0) {
VALIDATION_REPORT_ERROR(TEST, "Failed to reset (%d)", rc2);
return rc2;
}
return rc == 0 ? rc2 : rc;
}

int infuse_validation_imu(const struct device *dev, uint8_t flags)
{
int rc;
Expand Down Expand Up @@ -309,6 +395,11 @@ int infuse_validation_imu(const struct device *dev, uint8_t flags)
if (rc < 0) {
goto driver_end;
}
VALIDATION_REPORT_INFO(TEST, "Driver test - FIFO overrun");
rc = validate_fifo_overrun(dev);
if (rc < 0) {
goto driver_end;
}
}
driver_end:

Expand Down