diff --git a/src/entrypoints/asm330lhh_test.cpp b/src/entrypoints/asm330lhh_test.cpp index 87d8f415f60048953e9972184e59e57cda09cbe4..4863a5a125c3bb0ec5fea58e35348367121bfa18 100644 --- a/src/entrypoints/asm330lhh_test.cpp +++ b/src/entrypoints/asm330lhh_test.cpp @@ -33,7 +33,15 @@ int main(){ cs.high(); - ASM330LHH sensor(bus, cs); + asm330lhh_params params; + + params.accel_odr = ASM330LHH::ODR::_26HZ; + params.gyro_odr = ASM330LHH::ODR::_26HZ; + params.bdu = ASM330LHH::BDU::UPDATE_AFTER_READ; + params.accel_fs = ASM330LHH::ACCEL_FS::_8G; + params.gyro_fs = ASM330LHH::GYRO_FS::_250DPS; + + ASM330LHH sensor(bus, cs, params); bool success = sensor.init(); if(success){ diff --git a/src/shared/sensors/ASM330LHH/ASM330LHH.h b/src/shared/sensors/ASM330LHH/ASM330LHH.h index 6411cb9a13c57d74d07c5cd2aeddf590e2e7fd13..ebca244c93e40394ca09e1f276e17b5ac694c458 100644 --- a/src/shared/sensors/ASM330LHH/ASM330LHH.h +++ b/src/shared/sensors/ASM330LHH/ASM330LHH.h @@ -25,46 +25,138 @@ #include "sensors/Sensor.h" #include "Common.h" #include "drivers/spi/SPIDriver.h" +#include "ASM330LHHData.h" using miosix::getTick; using miosix::TICK_FREQ; + + +/** +* @brief IMU parameters: +* gyroscope odr (from power down up to 6667Hz) +* gyroscope full scale (from +-125dps up to +-4000dps) +* accelerometer odr (from power down up do 6667hz) +* accelerometer full scale (from +-2g up to +-16g) +* bdu (continuous update or update after read) +*/ +struct asm330lhh_params +{ + uint8_t gyro_odr = 0; + uint8_t gyro_fs = 0; + uint8_t accel_odr = 0; + uint8_t accel_fs = 0; + uint8_t bdu = 0; +}; + class ASM330LHH : public virtual Sensor { public: + + /** + * @brief Constructor + * + * @param bus the SPI bus + * @param chip_select CS pin + * @param params Sensor params (bdu, accelerometer and gyroscope odr and sensitivity) + * + **/ ASM330LHH(SPIBusInterface& bus, - GpioPin chip_select) : - spi_slave(bus, chip_select, {}) + GpioPin chip_select, asm330lhh_params params) : + spi_slave(bus, chip_select, {}), params(params) { spi_slave.config.clock_div = SPIClockDivider::DIV64; // used to set the spi baud rate (maximum is 10 Mhz) } - ASM330LHH(SPIBusInterface& bus, + /** + * @brief Constructor + * + * @param bus the SPI bus + * @param chip_select CS pin + * @param config SPI bus configuration + * @param params Sensor parameters (bdu, accelerometer and gyroscope odr and sensitivity) + * + **/ + ASM330LHH(SPIBusInterface& bus, GpioPin chip_select, - SPIBusConfig config) : - spi_slave(bus, chip_select, config) {} + SPIBusConfig config, + asm330lhh_params params) : + spi_slave(bus, chip_select, config), params(params) {} ~ASM330LHH() {} - + + /** + * @brief Initialize the sensor. + * + * @return boolean value indicating whether the operation succeded or not + */ bool init() override { - miosix::Thread::sleep(10); + miosix::Thread::sleep(100); setup_device(); if(!check_whoami()){ TRACE("Whoami check failed!\n"); + last_error = ERR_NOT_ME; return false; } + + setup_accel(params.accel_odr, params.accel_odr); + setup_gyro(params.gyro_odr, params.gyro_fs); + set_bdu(params.bdu); + return true; } - + + /** + * @brief Read new data from accelerometer, gyroscope and temperature sensor. + * Accelerometer unit of measure: mg + * Gyroscope unit of measure: mdps + * Temperature sensor unit of measure: °C + * + * + * @return boolean value indicating whether the operation succeded or not + */ bool onSimpleUpdate() override { + uint16_t buffer[14]; + asm330lhh_data new_data; + + SPITransaction spi(spi_slave); + spi.read(OUT_TEMP_L_REG, (uint8_t*) buffer, 14); + + int16_t val = buffer[0] | buffer[1]<<8; + new_data.temperature = ((float) val)/TSen + Toff; + + val = buffer[2] | buffer[3]<<8; + new_data.gyro_x = ((float) val)*G_So[params.gyro_fs]; + + val = buffer[4] | buffer[5]<<8; + new_data.gyro_y = ((float) val)*G_So[params.gyro_fs]; + + val = buffer[6] | buffer[7]<<8; + new_data.gyro_z = ((float) val)*G_So[params.gyro_fs]; + + val = buffer[8] | buffer[9]<<8; + new_data.accel_x = ((float) val)*LA_So[params.accel_fs]; + + val = buffer[10] | buffer[11]<<8; + new_data.accel_y = ((float) val)*LA_So[params.accel_fs]; + + val = buffer[12] | buffer[13]<<8; + new_data.accel_x = ((float) val)*LA_So[params.accel_fs]; + + data = new_data; return true; } - + + /** + * @brief Check if the sensor is working. + * + * @return boolean indicating whether the sensor is correctly working or not + */ bool selfTest() override { // check that the sensor is properly working @@ -75,9 +167,9 @@ class ASM330LHH : public virtual Sensor // not a Sensor class method: you should // define methods to get the sampled data - float getData() + asm330lhh_data getData() { - return 0; + return data; } private: @@ -110,7 +202,6 @@ class ASM330LHH : public virtual Sensor // Read and update CTRL4_C uint8_t ctrl4_c_val = spi.read(CTRL4_C_REG); - TRACE("ctrl4_c_val: %u\n", ctrl4_c_val); uint8_t i2c_disable_bit = 4; // 0b00000100 ctrl4_c_val |= i2c_disable_bit; spi.write(CTRL4_C_REG, ctrl4_c_val); @@ -118,16 +209,132 @@ class ASM330LHH : public virtual Sensor // Read and update CTRL9_XL uint8_t ctrl9_xl_val = spi.read(CTRL9_XL_REG); - TRACE("ctrl9_xl_val: %u\n", ctrl9_xl_val); uint8_t device_conf = 2; // 0b00000010 ctrl9_xl_val |= device_conf; spi.write(CTRL9_XL_REG, ctrl9_xl_val); } + + void setup_accel(uint8_t odr, uint8_t fs) { + SPITransaction spi(spi_slave); + + assert(odr>=0 && odr<=10); + assert(fs>=0 && fs <=3); + + odr = odr & 15; // 0b1111 + odr = odr << 4; + + fs = fs & 3; // 0b11 + fs = fs << 2; + + uint8_t ctrl1_xl_value = spi.read(CTRL1_XL_REG); + ctrl1_xl_value &= 3; // 0b00000011 + ctrl1_xl_value |= odr; + ctrl1_xl_value |= fs; + spi.write(CTRL1_XL_REG, ctrl1_xl_value); + } + + void setup_gyro(uint8_t odr, uint8_t fs) { + SPITransaction spi(spi_slave); + + assert(odr>=0 && odr<=10); //0b1010 + assert(fs>=0 && fs<=5); + + odr = odr & 15; // 0b1111 + odr = odr << 4; + + // if fs is 125 or 4000 ctrl2_g register values [1:0] + // must be set accordingly, otherwise those must be 00 + if(fs==0) + // FS_125 bit = 1 + // FS_4000 bit = 0 + fs = 2; // 0b10 + else if(fs==5) + // FS_125 bit = 0 + // FS_4000 bit = 1 + fs = 1; // 0b01 + else { + // Set ctrl2_g[3:2] + fs = fs - 1; + fs = fs << 2; + } + + uint8_t ctrl2_g_value = spi.read(CTRL2_G_REG); + ctrl2_g_value &= 0; + ctrl2_g_value |= odr; + ctrl2_g_value |= fs; + spi.write(CTRL2_G_REG, ctrl2_g_value); + } + + void set_bdu(uint8_t bdu){ + assert(bdu==1 || bdu==0); + + SPITransaction spi(spi_slave); + + uint8_t ctrl3_c_value = spi.read(CTRL3_C_REG); + ctrl3_c_value &=0xbf; // 0b10111111 + bdu &= 1; + bdu = bdu << 6; + ctrl3_c_value |= bdu; + spi.write(CTRL3_C_REG, ctrl3_c_value); + } + + public: + + /** + * @brief Accelerometer possible values for full scale + */ + enum ACCEL_FS { + _2G = 0, + _16G = 1, + _4G = 2, + _8G = 3 + }; + + /** + * @brief Gyroscope possible values for full scale + */ + enum GYRO_FS { + _125DPS = 0, + _250DPS = 1, + _500DPS = 2, + _1000DPS = 3, + _2000DPS = 4, + _4000DPS = 5, + }; + + /** + * @brief ODR possible values for both Accelerometer and Gyroscope + */ + enum ODR { + _POWER_DOWN = 0, + _12_5HZ = 1, + _26HZ = 2, + _52HZ = 3, + _104HZ = 4, + _208HZ = 5, + _417HZ = 6, + _833HZ = 7, + _1667HZ = 8, + _3333HZ = 9, + _6667HZ = 10 + }; + + /** + * BDU options: continuous update or update after read + */ + enum BDU { + CONTINUOUS_UPDATE = 0, + UPDATE_AFTER_READ = 1, + }; // Constant values private: const uint8_t WHO_AM_I_DEFAULT_VALUE = 0x6b; + const float LA_So[4] = {0.061, 0.122, 0.244, 0.488}; + const float G_So[6] = {4.37, 8.75, 17.5, 35.0, 70.0, 140.0}; + const float TSen = 256; + const float Toff = 25; private: @@ -136,11 +343,30 @@ class ASM330LHH : public virtual Sensor */ enum REG { WHO_AM_I_REG = 0x0f, + CTRL1_XL_REG = 0x10, + CTRL2_G_REG = 0x11, + CTRL3_C_REG = 0x12, CTRL4_C_REG = 0x13, CTRL9_XL_REG = 0x18, + OUT_TEMP_L_REG = 0x20, + OUT_TEMP_H_REG = 0X21, + OUTX_L_G_REG = 0X22, + OUTX_H_G_REG = 0X23, + OUTY_L_G_REG = 0X24, + OUTY_H_G_REG = 0X25, + OUTZ_L_G_REG = 0X26, + OUTZ_H_G_REG = 0X27, + OUTX_L_A_REG = 0X28, + OUTX_H_A_REG = 0X29, + OUTY_L_A_REG = 0X2a, + OUTY_H_A_REG = 0X2b, + OUTZ_L_A_REG = 0X2c, + OUTZ_H_A_REG = 0X2d, }; private: + const asm330lhh_params params; SPISlave spi_slave; + asm330lhh_data data; }; \ No newline at end of file diff --git a/src/shared/sensors/ASM330LHH/ASM330LHHData.h b/src/shared/sensors/ASM330LHH/ASM330LHHData.h new file mode 100644 index 0000000000000000000000000000000000000000..03dae64a1220b0e6fef0fd75c589805ad397a631 --- /dev/null +++ b/src/shared/sensors/ASM330LHH/ASM330LHHData.h @@ -0,0 +1,14 @@ +#ifndef ASM330LHH_DATA +#define ASM330LHH_DATA + +struct asm330lhh_data { + float gyro_x; // Gyroscope x axis + float gyro_y; // Gyroscope y axis + float gyro_z; // Gyroscope z axis + float accel_x; // Accelerometer x axis + float accel_y; // Accelerometer y axis + float accel_z; // Accelerometer z axis + float temperature; // Temperature +}; + +#endif \ No newline at end of file diff --git a/src/shared/sensors/ASM330LHH/ASM330LHH_data.h b/src/shared/sensors/ASM330LHH/ASM330LHH_data.h deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000