From ad8df08bb8f21cbd0386720ee1acc4f77f193625 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Fri, 18 Sep 2020 21:58:36 +1000 Subject: [PATCH] Rough pass updating to add BMA223 support --- .../TS100/Core/BSP/Pine64/Model_Config.h | 1 + workspace/TS100/Core/Drivers/BMA223.cpp | 37 +++++++++- workspace/TS100/Core/Drivers/BMA223_defines.h | 67 +++++++++++++++++++ workspace/TS100/Core/Threads/MOVThread.cpp | 64 +++++++++++------- 4 files changed, 145 insertions(+), 24 deletions(-) create mode 100644 workspace/TS100/Core/Drivers/BMA223_defines.h diff --git a/workspace/TS100/Core/BSP/Pine64/Model_Config.h b/workspace/TS100/Core/BSP/Pine64/Model_Config.h index 3a3e0afd..6a64a04f 100644 --- a/workspace/TS100/Core/BSP/Pine64/Model_Config.h +++ b/workspace/TS100/Core/BSP/Pine64/Model_Config.h @@ -19,6 +19,7 @@ #define POW_PD #define POW_QC #define TEMP_TMP36 +#define ACCEL_BMA #endif #endif /* BSP_MINIWARE_MODEL_CONFIG_H_ */ diff --git a/workspace/TS100/Core/Drivers/BMA223.cpp b/workspace/TS100/Core/Drivers/BMA223.cpp index 9b415f28..b15161b3 100644 --- a/workspace/TS100/Core/Drivers/BMA223.cpp +++ b/workspace/TS100/Core/Drivers/BMA223.cpp @@ -6,13 +6,48 @@ */ #include - +#include "BMA223_defines.h" +#include +#define BMA223_ADDRESS 0b00110000 bool BMA223::detect() { + return FRToSI2C::probe(BMA223_ADDRESS); } +static const FRToSI2C::I2C_REG i2c_registers[] = { // + // + { BMA223_PMU_RANGE, 0b0011, 0 }, //2G range + { BMA223_PMU_BW, 0b1101, 0 }, //250Hz filter + { BMA223_PMU_LPW, 0x00, 0 }, //Full power + { BMA223_ACCD_HBW, 0b01000000, 0 }, //filtered data out + { BMA223_INT_OUT_CTRL, 0b1111, 0 }, //interrupt active high and OD to get it hi-z + { BMA223_OFC_CTRL, 0b00000111, 0 }, //High pass en + + // + }; void BMA223::initalize() { + //Setup acceleration readings + //2G range + //bandwidth = 250Hz + //High pass filter on (Slow compensation) + //Turn off IRQ output pins + //Orientation recognition in symmetrical mode + // Hysteresis is set to ~ 16 counts + //Theta blocking is set to 0b10 + + FRToSI2C::writeRegistersBulk(BMA223_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0])); + } void BMA223::getAxisReadings(int16_t& x, int16_t& y, int16_t& z) { + //The BMA is odd in that its output data width is only 8 bits + //And yet there are MSB and LSB registers _sigh_. + uint8_t sensorData[6]; + + FRToSI2C::Mem_Read(BMA223_ADDRESS, BMA223_ACCD_X_LSB, sensorData, 6); + + x = sensorData[1] << 2; + y = sensorData[3] << 2; + z = sensorData[5] << 2; + } diff --git a/workspace/TS100/Core/Drivers/BMA223_defines.h b/workspace/TS100/Core/Drivers/BMA223_defines.h new file mode 100644 index 00000000..12481300 --- /dev/null +++ b/workspace/TS100/Core/Drivers/BMA223_defines.h @@ -0,0 +1,67 @@ +/* + * BMA223_defines.h + * + * Created on: 18 Sep. 2020 + * Author: Ralim + */ + +#ifndef CORE_DRIVERS_BMA223_DEFINES_H_ +#define CORE_DRIVERS_BMA223_DEFINES_H_ + +#define BMA223_BGW_CHIPID 0x00 +#define BMA223_ACCD_X_LSB 0x02 +#define BMA223_ACCD_X_MSB 0x03 +#define BMA223_ACCD_Y_LSB 0x04 +#define BMA223_ACCD_Y_MSB 0x05 +#define BMA223_ACCD_Z_LSB 0x06 +#define BMA223_ACCD_Z_MSB 0x07 +#define BMA223_ACCD_TEMP 0x08 +#define BMA223_INT_STATUS_0 0x09 +#define BMA223_INT_STATUS_1 0x0A +#define BMA223_INT_STATUS_2 0x0B +#define BMA223_INT_STATUS_3 0x0C +#define BMA223_FIFO_STATUS 0x0E +#define BMA223_PMU_RANGE 0x0F +#define BMA223_PMU_BW 0x10 +#define BMA223_PMU_LPW 0x11 +#define BMA223_PMU_LOW_POWER 0x012 +#define BMA223_ACCD_HBW 0x13 +#define BMA223_BGW_SOFTRESET 0x14 +#define BMA223_INT_EN_0 0x16 +#define BMA223_INT_EN_1 0x17 +#define BMA223_INT_EN_2 0x18 +#define BMA223_INT_MAP_0 0x19 +#define BMA223_INT_MAP_1 0x1A +#define BMA223_INT_MAP_2 0x1B +#define BMA223_INT_SRC 0x1E +#define BMA223_INT_OUT_CTRL 0x20 +#define BMA223_INT_RST_LATCH 0x21 +#define BMA223_INT_0 0x22 +#define BMA223_INT_1 0x23 +#define BMA223_INT_2 0x24 +#define BMA223_INT_3 0x25 +#define BMA223_INT_4 0x26 +#define BMA223_INT_5 0x27 +#define BMA223_INT_6 0x28 +#define BMA223_INT_7 0x29 +#define BMA223_INT_8 0x2A +#define BMA223_INT_9 0x2B +#define BMA223_INT_A 0x2C +#define BMA223_INT_B 0x2D +#define BMA223_INT_C 0x2E +#define BMA223_INT_D 0x2F +#define BMA223_FIFO_CONFIG_0 0x30 +#define BMA223_PMU_SELF_TEST 0x32 +#define BMA223_TRIM_NVM_CTRL 0x33 +#define BMA223_BGW_SPI3_WDT 0x34 +#define BMA223_OFC_CTRL 0x36 +#define BMA223_OFC_SETTING 0x37 +#define BMA223_OFC_OFFSET_X 0x38 +#define BMA223_OFC_OFFSET_Y 0x39 +#define BMA223_OFC_OFFSET_Z 0x3A +#define BMA223_TRIM_GP0 0x3B +#define BMA223_TRIM_GP1 0x3C +#define BMA223_FIFO_CONFIG_1 0x3E +#define BMA223_FIFO_DATA 0x3F + +#endif /* CORE_DRIVERS_BMA223_DEFINES_H_ */ diff --git a/workspace/TS100/Core/Threads/MOVThread.cpp b/workspace/TS100/Core/Threads/MOVThread.cpp index 1fe57cd1..01a36b2e 100644 --- a/workspace/TS100/Core/Threads/MOVThread.cpp +++ b/workspace/TS100/Core/Threads/MOVThread.cpp @@ -18,11 +18,12 @@ #include "main.hpp" #include "power.hpp" #include "stdlib.h" +#include "BMA223.hpp" #include "task.h" #define MOVFilter 8 uint8_t accelInit = 0; uint32_t lastMovementTime = 0; -void startMOVTask(void const *argument __unused) { +void detectAccelerometerVersion() { #ifdef ACCEL_MMA if (MMA8652FC::detect()) { PCBVersion = 1; @@ -33,22 +34,53 @@ void startMOVTask(void const *argument __unused) { if (LIS2DH12::detect()) { PCBVersion = 2; // Setup the ST Accelerometer - LIS2DH12::initalize(); // startup the accelerometer + LIS2DH12::initalize();// startup the accelerometer + } else +#endif +#ifdef ACCEL_BMA + if (BMA223::detect()) { + PCBVersion = 3; + // Setup the ST Accelerometer + BMA223::initalize(); // startup the accelerometer } else #endif { - PCBVersion = 3; + PCBVersion = 99; systemSettings.SleepTime = 0; systemSettings.ShutdownTime = 0; // No accel -> disable sleep systemSettings.sensitivity = 0; } + +} +inline void readAccelerometer(int16_t& tx, int16_t& ty, int16_t& tz, Orientation &rotation) { +#ifdef ACCEL_LIS + if (PCBVersion == 2) { + LIS2DH12::getAxisReadings(tx, ty, tz); + rotation = LIS2DH12::getOrientation(); + } else +#endif +#ifdef ACCEL_MMA + if (PCBVersion == 1) { + MMA8652FC::getAxisReadings(tx, ty, tz); + rotation = MMA8652FC::getOrientation(); + } else +#endif +#ifdef ACCEL_BMA + if (PCBVersion == 3) { + BMA223::getAxisReadings(tx, ty, tz); + rotation = BMA223::getOrientation(); + } else +#endif + { + //do nothing :( + } +} +void startMOVTask(void const *argument __unused) { + postRToSInit(); OLED::setRotation(systemSettings.OrientationMode & 1); - - if ((PCBVersion == 1 - || PCBVersion == 2) - && (systemSettings.autoStartMode == 2 - || systemSettings.autoStartMode == 3)) + detectAccelerometerVersion(); + if ((systemSettings.autoStartMode == 2 || systemSettings.autoStartMode == 3)) osDelay(2000); lastMovementTime = 0; @@ -64,21 +96,7 @@ void startMOVTask(void const *argument __unused) { for (;;) { int32_t threshold = 1500 + (9 * 200); threshold -= systemSettings.sensitivity * 200; // 200 is the step size -#ifdef ACCEL_LIS - if (PCBVersion == 2) { - LIS2DH12::getAxisReadings(tx, ty, tz); - rotation = LIS2DH12::getOrientation(); - } else -#endif -#ifdef ACCEL_MMA - if (PCBVersion == 1) { - MMA8652FC::getAxisReadings(tx, ty, tz); - rotation = MMA8652FC::getOrientation(); - }else -#endif - { - //do nothing :( - } + readAccelerometer(tx, ty, tz, rotation); if (systemSettings.OrientationMode == 2) { if (rotation != ORIENTATION_FLAT) { OLED::setRotation(rotation == ORIENTATION_LEFT_HAND); // link the data through