should be working state (untested)

This commit is contained in:
Lars Wilko Sentse
2024-06-11 17:30:01 +02:00
parent 19415d1ada
commit 126cf9ff4a
4 changed files with 298 additions and 18 deletions

View File

@@ -1,4 +1,4 @@
#include <sta/drivers/BMI088.hpp>
#include <sta/drivers/bmi088.hpp>
#include <sta/debug/assert.hpp>
@@ -7,21 +7,192 @@ namespace sta
BMI088::BMI088(STM32SPIDevice* gyro_device, STM32SPIDevice* accel_device)
: gyro_device{gyro_device}, accel_device(accel_device)
{
STA_ASSERT(device != nullptr);
STA_ASSERT(gyro_device != nullptr);
STA_ASSERT(accel_device != nullptr);
}
bool BMI088::init()
{
return false;
uint8_t id;
busRead(GYROSCOPE, BMI088_REG_GYRO_CHIP_ID, &id);
if(id != BMI088_GYRO_CHIP_ID) return false;
busRead(ACCELEROMETER, BMI088_REG_ACC_CHIP_ID, &id);
if(id != BMI088_ACC_CHIP_ID) return false;
return true;
}
bool BMI088::busRead(Part part, uint8_t reg, uint8_t * buffer, size_t length)
void BMI088::setGyroscopeMode(GyroMode mode)
{
return false;
busWrite(GYROSCOPE, BMI088_REG_GYRO_LPM1, mode);
}
void BMI088::setGyroscopeRange(GyroRange range)
{
busWrite(GYROSCOPE, BMI088_REG_GYRO_RANGE, range);
switch(range)
{
case TWOTHOUSAND:
f_gyro_range = 2000;
break;
case ONETHOUSAND:
f_gyro_range = 1000;
break;
case FIVEHUNDRED:
f_gyro_range = 500;
break;
case TWOFIFTY:
f_gyro_range = 250;
break;
case ONETWENTYFIVE:
f_gyro_range = 125;
break;
default:
f_gyro_range = 0;
break;
}
}
void BMI088::setGyroscopeBandwidth(GyroBandwidth bandwidth)
{
busWrite(GYROSCOPE, BMI088_REG_GYRO_BANDWIDTH, bandwidth);
}
void BMI088::getRawRotation(uint16_t* x, uint16_t* y, uint16_t* z)
{
uint8_t x_lsb, x_msb, y_lsb, y_msb, z_lsb, z_msb;
busRead(GYROSCOPE, BMI088_REG_GYRO_RATE_X_LSB, &x_lsb);
busRead(GYROSCOPE, BMI088_REG_GYRO_RATE_X_MSB, &x_msb);
*x = ((uint16_t)x_msb)<<8 | (uint16_t)x_lsb;
busRead(GYROSCOPE, BMI088_REG_GYRO_RATE_Y_LSB, &y_lsb);
busRead(GYROSCOPE, BMI088_REG_GYRO_RATE_Y_MSB, &y_msb);
*y = ((uint16_t)y_msb)<<8 | (uint16_t)y_lsb;
busRead(GYROSCOPE, BMI088_REG_GYRO_RATE_Z_LSB, &z_lsb);
busRead(GYROSCOPE, BMI088_REG_GYRO_RATE_Z_MSB, &z_msb);
*z = ((uint16_t)z_msb)<<8 | (uint16_t)z_lsb;
}
void BMI088::getRotation(float* x, float* y, float* z)
{
uint16_t i_x,i_y,i_z;
getRawRotation(&i_x, &i_y, &i_z);
convertRawToActual(&i_x, x, f_gyro_range);
convertRawToActual(&i_y, y, f_gyro_range);
convertRawToActual(&i_z, z, f_gyro_range);
}
bool BMI088::busWrite(Part part, uint8_t reg, uint8_t * buffer, size_t length)
void BMI088::setAccelerometerMode(AccelMode mode)
{
return false;
busWrite(ACCELEROMETER, BMI088_REG_ACC_PWR_CTRL, mode);
}
void BMI088::setAccelerometerRange(AccelRange range)
{
busWrite(ACCELEROMETER, BMI088_REG_ACC_RANGE, range);
switch(range)
{
case THREEG:
f_accel_range = 3*9.80665;
break;
case SIXG:
f_accel_range = 6*9.80665;
break;
case TWELVEG:
f_accel_range = 12*9.80665;
break;
case TWENTYFOURG:
f_accel_range = 24*9.80665;
break;
default:
break;
}
}
void BMI088::setAccelerometerBandwidth(AccelBandwidth bandwidth, AccelODR odr)
{
uint8_t data = bandwidth<<4 | odr;//TODO are your sure? shift three or four times?
busWrite(ACCELEROMETER, BMI088_REG_ACC_CONF, data);
}
void BMI088::getRawAcceleration(uint16_t* x, uint16_t* y, uint16_t* z)
{
uint8_t x_lsb, x_msb, y_lsb, y_msb, z_lsb, z_msb;
busRead(ACCELEROMETER, BMI088_REG_ACC_X_LSB, &x_lsb);
busRead(ACCELEROMETER, BMI088_REG_ACC_X_MSB, &x_msb);
*x = ((uint16_t)x_msb)<<8 | (uint16_t)x_lsb;
busRead(ACCELEROMETER, BMI088_REG_ACC_Y_LSB, &y_lsb);
busRead(ACCELEROMETER, BMI088_REG_ACC_Y_MSB, &y_msb);
*y = ((uint16_t)y_msb)<<8 | (uint16_t)y_lsb;
busRead(ACCELEROMETER, BMI088_REG_ACC_Z_LSB, &z_lsb);
busRead(ACCELEROMETER, BMI088_REG_ACC_Z_MSB, &z_msb);
*z = ((uint16_t)z_msb)<<8 | (uint16_t)z_lsb;
}
void BMI088::getAcceleration(float* x, float* y, float* z)
{
uint16_t i_x,i_y,i_z;
getRawRotation(&i_x, &i_y, &i_z);
convertRawToActual(&i_x, x, f_accel_range);
convertRawToActual(&i_y, y, f_accel_range);
convertRawToActual(&i_z, z, f_accel_range);
}
bool BMI088::busRead(Part part, uint8_t reg, uint8_t * buffer)
{
if(part == GYROSCOPE)
{
uint8_t data[1] = { (uint8_t)( reg | BMI088_READ_MASK ) };
gyro_device->beginTransmission();
gyro_device->transfer(data, 1);
gyro_device->receive(buffer, 1);
gyro_device->endTransmission();
}
if(part == ACCELEROMETER)
{
uint8_t data[2] = { (uint8_t)( reg | BMI088_READ_MASK ), 0x00 };
accel_device->beginTransmission();
accel_device->transfer(data, 2);
accel_device->receive(buffer, 1);
accel_device->endTransmission();
}
return true;
}
bool BMI088::busWrite(Part part, uint8_t reg, uint8_t value)
{
uint8_t data[2] = { reg, value };//apperently only supports writing 8bit at a time
if(part == GYROSCOPE)
{
gyro_device->beginTransmission();
gyro_device->transfer(data, 2);
gyro_device->endTransmission();
}
if(part == ACCELEROMETER)
{
accel_device->beginTransmission();
accel_device->transfer(data, 2);
accel_device->endTransmission();
}
return true;
}
void BMI088::convertRawToActual(uint16_t* i, float* f, float f_range){
int16_t sign = (int16_t)((*i & 0b1000000000000000) >> 15);
if(sign)
{//negative
uint16_t value = ~(*i) & 0b0111111111111111;
*f = ((float)value / (float)0b0111111111111111) *-f_range;
}
else
{//positive
uint16_t value = *i & 0b0111111111111111;
*f = ((float)value / (float)0b0111111111111111) *f_range;
}
}
} // namespace sta