#ifndef IMU_SENSOR_H #define IMU_SENSOR_H #include #include #include "imu/imu_calibration.h" #include "imu/imu_sample.h" typedef enum { IMU_SENSOR_NONE = 0, IMU_SENSOR_TDK_ICM42688, IMU_SENSOR_ST_LSM6DSOX, IMU_SENSOR_BACKEND_COUNT } imu_sensor_backend_t; typedef struct { /* Zero selects the active backend's safe default. A non-zero target may * be quantized to a nearby hardware ODR; diagnostics reports both values. */ uint32_t odr_hz; unsigned int accel_full_scale_g; unsigned int gyro_full_scale_dps; /* Auto-detected devices must never share board-specific calibration. */ imu_calibration_t calibration_by_backend[IMU_SENSOR_BACKEND_COUNT]; } imu_sensor_config_t; typedef struct { uint64_t irq_count; uint64_t sample_count; uint64_t invalid_sample_count; uint64_t spurious_irq_count; uint64_t queue_overflow_count; uint64_t estimated_missed_sample_count; uint64_t last_timestamp_ticks; uint32_t requested_odr_hz; uint32_t configured_odr_hz; uint8_t who_am_i; imu_sensor_backend_t backend; bool initialized; bool running; bool foreground_polling; } imu_sensor_diagnostics_t; void imu_sensor_default_config(imu_sensor_config_t* config); /* Probe the compiled backend(s), select one, validate the requested ODR/range * and prepare calibration. This does not enable data-ready interrupts. */ bool imu_sensor_init(const imu_sensor_config_t* config); /* Configure streaming and enable BSP_PMOD_IRQ. The application must attach * imu_sensor_irq_handler to the active machine-interrupt router first. */ bool imu_sensor_start(void); void imu_sensor_stop(void); /* PLIC/ISR half: read and timestamp one raw sample, then enqueue it. */ void imu_sensor_irq_handler(void); /* Foreground half. Safe no-op for the current interrupt-driven backends. */ void imu_sensor_service(void); bool imu_sensor_requires_foreground_service(void); /* Pop the oldest sample, convert to SI/common axes and apply the selected * backend's calibration. No averaging or motion decision occurs here. */ bool imu_sensor_take_measurement(imu_sample_t* measurement_out); void imu_sensor_get_diagnostics(imu_sensor_diagnostics_t* diagnostics_out); imu_sensor_backend_t imu_sensor_active_backend(void); const char* imu_sensor_backend_name(imu_sensor_backend_t backend); #endif