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
26 changes: 19 additions & 7 deletions Drivers/bmi270-module/include/drivers/bmi270.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#pragma once

#include <stdint.h>
#include <tactility/drivers/imu.h>
#include <tactility/error.h>

struct Device;
Expand All @@ -15,18 +16,29 @@ struct Bmi270Config {
uint8_t address;
};

struct Bmi270Data {
float ax, ay, az; // acceleration in g (±8g range)
float gx, gy, gz; // angular rate in °/s (±2000°/s range)
};
/**
* Read accelerometer data only.
* @param[in] device bmi270 device
* @param[out] data Pointer to ImuAccelData structure to store the data (±8g range)
* @return ERROR_NONE on success
*/
error_t bmi270_read_accel(struct Device* device, struct ImuAccelData* data);

/**
* Read gyroscope data only.
* @param[in] device bmi270 device
* @param[out] data Pointer to ImuGyroData structure to store the data (±2000°/s range)
* @return ERROR_NONE on success
*/
error_t bmi270_read_gyro(struct Device* device, struct ImuGyroData* data);

/**
* Read accelerometer and gyroscope data.
* Read the chip's on-die temperature.
* @param[in] device bmi270 device
* @param[out] data Pointer to Bmi270Data structure to store the data
* @param[out] temperature_c Pointer to store the temperature, in °C
* @return ERROR_NONE on success
*/
error_t bmi270_read(struct Device* device, struct Bmi270Data* data);
error_t bmi270_read_temperature(struct Device* device, float* temperature_c);

#ifdef __cplusplus
}
Expand Down
62 changes: 49 additions & 13 deletions Drivers/bmi270-module/source/bmi270.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
static constexpr uint8_t REG_CHIP_ID = 0x00; // read: expect 0x24
static constexpr uint8_t REG_DATA_ACC = 0x0C; // 6 bytes: acc X/Y/Z LSB/MSB
static constexpr uint8_t REG_DATA_GYR = 0x12; // 6 bytes: gyr X/Y/Z LSB/MSB
static constexpr uint8_t REG_TEMPERATURE = 0x22; // 2 bytes: on-die temperature, 0x8000 = invalid
static constexpr uint8_t REG_INTERNAL_ST = 0x21; // bit0: init done
static constexpr uint8_t REG_ACC_CONF = 0x40; // ODR + BWP + filter_perf
static constexpr uint8_t REG_ACC_RANGE = 0x41; // range selector
Expand Down Expand Up @@ -152,38 +153,73 @@ static error_t stop(Device* device) {

extern "C" {

error_t bmi270_read(Device* device, Bmi270Data* data) {
error_t bmi270_read_accel(Device* device, ImuAccelData* data) {
auto* i2c_controller = device_get_parent(device);

auto address = GET_CONFIG(device)->address;

// Burst-read 12 bytes: acc X/Y/Z (6 bytes) + gyro X/Y/Z (6 bytes)
// Registers: 0x0C–0x17 are contiguous for acc+gyro in I2C mode (no dummy byte)
uint8_t buffer[12] = {};
uint8_t buffer[6] = {};
error_t error = i2c_controller_read_register(i2c_controller, address, REG_DATA_ACC, buffer, sizeof(buffer), I2C_TIMEOUT_TICKS);
if (error != ERROR_NONE) return error;

auto toI16 = [](uint8_t lo, uint8_t hi) -> int16_t {
return static_cast<int16_t>(static_cast<uint16_t>(hi) << 8 | lo);
};

data->ax = toI16(buffer[0], buffer[1]) * ACCEL_SCALE;
data->ay = toI16(buffer[2], buffer[3]) * ACCEL_SCALE;
data->az = toI16(buffer[4], buffer[5]) * ACCEL_SCALE;
data->gx = toI16(buffer[6], buffer[7]) * GYRO_SCALE;
data->gy = toI16(buffer[8], buffer[9]) * GYRO_SCALE;
data->gz = toI16(buffer[10], buffer[11]) * GYRO_SCALE;
data->ax = toI16(buffer[0], buffer[1]) * ACCEL_SCALE;
data->ay = toI16(buffer[2], buffer[3]) * ACCEL_SCALE;
data->az = toI16(buffer[4], buffer[5]) * ACCEL_SCALE;

return ERROR_NONE;
}

error_t bmi270_read_gyro(Device* device, ImuGyroData* data) {
auto* i2c_controller = device_get_parent(device);
auto address = GET_CONFIG(device)->address;

uint8_t buffer[6] = {};
error_t error = i2c_controller_read_register(i2c_controller, address, REG_DATA_GYR, buffer, sizeof(buffer), I2C_TIMEOUT_TICKS);
if (error != ERROR_NONE) return error;

auto toI16 = [](uint8_t lo, uint8_t hi) -> int16_t {
return static_cast<int16_t>(static_cast<uint16_t>(hi) << 8 | lo);
};

data->gx = toI16(buffer[0], buffer[1]) * GYRO_SCALE;
data->gy = toI16(buffer[2], buffer[3]) * GYRO_SCALE;
data->gz = toI16(buffer[4], buffer[5]) * GYRO_SCALE;

return ERROR_NONE;
}

error_t bmi270_read_temperature(Device* device, float* temperature_c) {
auto* i2c_controller = device_get_parent(device);
auto address = GET_CONFIG(device)->address;

uint8_t buffer[2] = {};
error_t error = i2c_controller_read_register(i2c_controller, address, REG_TEMPERATURE, buffer, sizeof(buffer), I2C_TIMEOUT_TICKS);
if (error != ERROR_NONE) return error;

uint16_t raw = static_cast<uint16_t>(buffer[1]) << 8 | buffer[0];
if (raw == 0x8000) return ERROR_NOT_FOUND; // sensor reports "invalid" (not enabled/not ready)

// Datasheet: temperature = raw / 512 + 23 (°C), raw is a signed 16-bit value
*temperature_c = static_cast<int16_t>(raw) / 512.0f + 23.0f;
return ERROR_NONE;
}

ImuApi bmi270_imu_api = {
.read_accel = bmi270_read_accel,
.read_gyro = bmi270_read_gyro,
.read_temperature = bmi270_read_temperature
};

Driver bmi270_driver = {
.name = "bmi270",
.compatible = (const char*[]) { "bosch,bmi270", nullptr},
.start_device = start,
.stop_device = stop,
.api = nullptr,
.device_type = nullptr,
.api = &bmi270_imu_api,
.device_type = &IMU_TYPE,
.owner = &bmi270_module,
.internal = nullptr
};
Expand Down
5 changes: 1 addition & 4 deletions Drivers/bmi270-module/source/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ static Driver* const bmi270_drivers[] = {
nullptr
};

extern const ModuleSymbol bmi270_module_symbols[];

Module bmi270_module = {
.name = "bmi270",
.drivers = bmi270_drivers,
.symbols = bmi270_module_symbols
.drivers = bmi270_drivers
};

}
8 changes: 0 additions & 8 deletions Drivers/bmi270-module/source/symbols.c

This file was deleted.

26 changes: 19 additions & 7 deletions Drivers/mpu6886-module/include/drivers/mpu6886.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#pragma once

#include <stdint.h>
#include <tactility/drivers/imu.h>
#include <tactility/error.h>

struct Device;
Expand All @@ -15,18 +16,29 @@ struct Mpu6886Config {
uint8_t address;
};

struct Mpu6886Data {
float ax, ay, az; // acceleration in g (±8g range)
float gx, gy, gz; // angular rate in °/s (±2000°/s range)
};
/**
* Read accelerometer data only.
* @param[in] device mpu6886 device
* @param[out] data Pointer to ImuAccelData to populate (±8g range)
* @return ERROR_NONE on success
*/
error_t mpu6886_read_accel(struct Device* device, struct ImuAccelData* data);

/**
* Read gyroscope data only.
* @param[in] device mpu6886 device
* @param[out] data Pointer to ImuGyroData to populate (±2000°/s range)
* @return ERROR_NONE on success
*/
error_t mpu6886_read_gyro(struct Device* device, struct ImuGyroData* data);

/**
* Read accelerometer and gyroscope data.
* Read the chip's on-die temperature.
* @param[in] device mpu6886 device
* @param[out] data Pointer to Mpu6886Data to populate
* @param[out] temperature_c Pointer to store the temperature, in °C
* @return ERROR_NONE on success
*/
error_t mpu6886_read(struct Device* device, struct Mpu6886Data* data);
error_t mpu6886_read_temperature(struct Device* device, float* temperature_c);

#ifdef __cplusplus
}
Expand Down
5 changes: 1 addition & 4 deletions Drivers/mpu6886-module/source/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ static Driver* const mpu6886_drivers[] = {
nullptr
};

extern const ModuleSymbol mpu6886_module_symbols[];

Module mpu6886_module = {
.name = "mpu6886",
.drivers = mpu6886_drivers,
.symbols = mpu6886_module_symbols,
.drivers = mpu6886_drivers
};

} // extern "C"
55 changes: 45 additions & 10 deletions Drivers/mpu6886-module/source/mpu6886.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ static constexpr uint8_t REG_ACCEL_CONFIG2 = 0x1D; // accel low-pass filter
static constexpr uint8_t REG_INT_PIN_CFG = 0x37; // interrupt pin config
static constexpr uint8_t REG_INT_ENABLE = 0x38; // interrupt enable
static constexpr uint8_t REG_ACCEL_XOUT_H = 0x3B; // first accel output register
static constexpr uint8_t REG_TEMP_OUT_H = 0x41; // temperature output register
static constexpr uint8_t REG_GYRO_XOUT_H = 0x43; // first gyro output register
static constexpr uint8_t REG_USER_CTRL = 0x6A; // user control (DMP, FIFO, I2C)
static constexpr uint8_t REG_PWR_MGMT_1 = 0x6B; // power management 1
Expand Down Expand Up @@ -126,38 +127,72 @@ static error_t stop(Device* device) {

extern "C" {

error_t mpu6886_read(Device* device, Mpu6886Data* data) {
error_t mpu6886_read_accel(Device* device, ImuAccelData* data) {
auto* i2c_controller = device_get_parent(device);
auto address = GET_CONFIG(device)->address;

// MPU6886 is big-endian (MSB first), unlike BMI270
auto toI16 = [](uint8_t hi, uint8_t lo) -> int16_t {
return static_cast<int16_t>(static_cast<uint16_t>(hi) << 8 | lo);
};

// Burst read: accel (6) + temp (2) + gyro (6) = 14 bytes at 0x3B
uint8_t buf[14] = {};
uint8_t buf[6] = {};
error_t error = i2c_controller_read_register(i2c_controller, address, REG_ACCEL_XOUT_H, buf, sizeof(buf), I2C_TIMEOUT_TICKS);
if (error != ERROR_NONE) return error;

data->ax = toI16(buf[0], buf[1]) * ACCEL_SCALE;
data->ay = toI16(buf[2], buf[3]) * ACCEL_SCALE;
data->az = toI16(buf[4], buf[5]) * ACCEL_SCALE;
// buf[6..7] = temperature (skipped)
data->gx = toI16(buf[8], buf[9]) * GYRO_SCALE;
data->gy = toI16(buf[10], buf[11]) * GYRO_SCALE;
data->gz = toI16(buf[12], buf[13]) * GYRO_SCALE;

return ERROR_NONE;
}

error_t mpu6886_read_gyro(Device* device, ImuGyroData* data) {
auto* i2c_controller = device_get_parent(device);
auto address = GET_CONFIG(device)->address;

auto toI16 = [](uint8_t hi, uint8_t lo) -> int16_t {
return static_cast<int16_t>(static_cast<uint16_t>(hi) << 8 | lo);
};

uint8_t buf[6] = {};
error_t error = i2c_controller_read_register(i2c_controller, address, REG_GYRO_XOUT_H, buf, sizeof(buf), I2C_TIMEOUT_TICKS);
if (error != ERROR_NONE) return error;

data->gx = toI16(buf[0], buf[1]) * GYRO_SCALE;
data->gy = toI16(buf[2], buf[3]) * GYRO_SCALE;
data->gz = toI16(buf[4], buf[5]) * GYRO_SCALE;

return ERROR_NONE;
}

error_t mpu6886_read_temperature(Device* device, float* temperature_c) {
auto* i2c_controller = device_get_parent(device);
auto address = GET_CONFIG(device)->address;

uint8_t buf[2] = {};
error_t error = i2c_controller_read_register(i2c_controller, address, REG_TEMP_OUT_H, buf, sizeof(buf), I2C_TIMEOUT_TICKS);
if (error != ERROR_NONE) return error;

auto raw = static_cast<int16_t>(static_cast<uint16_t>(buf[0]) << 8 | buf[1]);

// Datasheet: temperature = raw / 326.8 + 25 (°C)
*temperature_c = static_cast<float>(raw) / 326.8f + 25.0f;
return ERROR_NONE;
}

ImuApi mpu6886_imu_api = {
.read_accel = mpu6886_read_accel,
.read_gyro = mpu6886_read_gyro,
.read_temperature = mpu6886_read_temperature
};

Driver mpu6886_driver = {
.name = "mpu6886",
.compatible = (const char*[]) { "invensense,mpu6886", nullptr },
.start_device = start,
.stop_device = stop,
.api = nullptr,
.device_type = nullptr,
.api = &mpu6886_imu_api,
.device_type = &IMU_TYPE,
.owner = &mpu6886_module,
.internal = nullptr
};
Expand Down
8 changes: 0 additions & 8 deletions Drivers/mpu6886-module/source/symbols.c

This file was deleted.

26 changes: 19 additions & 7 deletions Drivers/qmi8658-module/include/drivers/qmi8658.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#pragma once

#include <stdint.h>
#include <tactility/drivers/imu.h>
#include <tactility/error.h>

struct Device;
Expand All @@ -15,18 +16,29 @@ struct Qmi8658Config {
uint8_t address;
};

struct Qmi8658Data {
float ax, ay, az; // acceleration in g (±8g range)
float gx, gy, gz; // angular rate in °/s (±2048°/s range)
};
/**
* Read accelerometer data only.
* @param[in] device qmi8658 device
* @param[out] data Pointer to ImuAccelData to populate (±8g range)
* @return ERROR_NONE on success
*/
error_t qmi8658_read_accel(struct Device* device, struct ImuAccelData* data);

/**
* Read gyroscope data only.
* @param[in] device qmi8658 device
* @param[out] data Pointer to ImuGyroData to populate (±2048°/s range)
* @return ERROR_NONE on success
*/
error_t qmi8658_read_gyro(struct Device* device, struct ImuGyroData* data);

/**
* Read accelerometer and gyroscope data.
* Read the chip's on-die temperature.
* @param[in] device qmi8658 device
* @param[out] data Pointer to Qmi8658Data to populate
* @param[out] temperature_c Pointer to store the temperature, in °C
* @return ERROR_NONE on success
*/
error_t qmi8658_read(struct Device* device, struct Qmi8658Data* data);
error_t qmi8658_read_temperature(struct Device* device, float* temperature_c);

#ifdef __cplusplus
}
Expand Down
5 changes: 1 addition & 4 deletions Drivers/qmi8658-module/source/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ static Driver* const qmi8658_drivers[] = {
nullptr
};

extern const ModuleSymbol qmi8658_module_symbols[];

Module qmi8658_module = {
.name = "qmi8658",
.drivers = qmi8658_drivers,
.symbols = qmi8658_module_symbols,
.drivers = qmi8658_drivers
};

} // extern "C"
Loading
Loading