* Refactor I2C_SOFT to new #define * Stitch in some of TS101 Update ShowStartupWarnings.cpp Update OLED.hpp Update stm32f1xx_hal_msp.c Update Setup.cpp Update Power.cpp Update Pins.h Update configuration.h Power Muxing Working dual input Voltage handler Scan mode required for differing injected channels Inject both dc readings Update configuration.h Update configuration.h Use htim4 for adc control on TS101 Refactor htim names Add ADC_TRIGGER Speed up BB I2C a lil Update configuration.h Update startup_stm32f103t8ux.S Update configuration.h Add LIS2DH clone LIS2DH gains another clone Create tooling to allow mapping accelerometers onto different buses Update startup_stm32f103t8ux.S Ensure PD IRQ is pulled up * Stitch in some of TS101 Update ShowStartupWarnings.cpp Update OLED.hpp Update stm32f1xx_hal_msp.c Update Setup.cpp Update Power.cpp Update Pins.h Update configuration.h Power Muxing Working dual input Voltage handler Scan mode required for differing injected channels Inject both dc readings Update configuration.h Update configuration.h Use htim4 for adc control on TS101 Refactor htim names Add ADC_TRIGGER Speed up BB I2C a lil Update configuration.h Update startup_stm32f103t8ux.S Update configuration.h Add LIS2DH clone LIS2DH gains another clone Create tooling to allow mapping accelerometers onto different buses Update startup_stm32f103t8ux.S Ensure PD IRQ is pulled up Allow toggle which button enters PD debug * Update Pins.h * Fix hard coded IRQ Pin Update stm32f1xx_it.c * Enable EPR * Tip resistance measurement * TS101 is a direct drive tip Update BSP.cpp * Add S60 and TS101 to builds Update push.yml * Update MOVThread.cpp * Refactor power menu handler * Correct prescaler Forgot to update since I changed the period * Tune in the timer divider for tip control to make PWM less audible --------- Co-authored-by: discip <53649486+discip@users.noreply.github.com>
207 lines
5.8 KiB
C++
207 lines
5.8 KiB
C++
/*
|
|
* MOVThread.cpp
|
|
*
|
|
* Created on: 29 May 2020
|
|
* Author: Ralim
|
|
*/
|
|
|
|
#include "BMA223.hpp"
|
|
#include "BSP.h"
|
|
#include "FreeRTOS.h"
|
|
#include "I2C_Wrapper.hpp"
|
|
#include "LIS2DH12.hpp"
|
|
#include "MMA8652FC.hpp"
|
|
#include "MSA301.h"
|
|
#include "Pins.h"
|
|
#include "QC3.h"
|
|
#include "SC7A20.hpp"
|
|
#include "Settings.h"
|
|
#include "TipThermoModel.h"
|
|
#include "cmsis_os.h"
|
|
#include "configuration.h"
|
|
#include "history.hpp"
|
|
#include "main.hpp"
|
|
#include "power.hpp"
|
|
#include "stdlib.h"
|
|
#include "task.h"
|
|
|
|
#define MOVFilter 8
|
|
uint8_t accelInit = 0;
|
|
TickType_t lastMovementTime = 0;
|
|
// Order matters for probe order, some Acceleromters do NOT like bad reads; and we have a bunch of overlap of addresses
|
|
void detectAccelerometerVersion() {
|
|
DetectedAccelerometerVersion = AccelType::Scanning;
|
|
|
|
#ifdef ACCEL_MMA
|
|
if (MMA8652FC::detect()) {
|
|
if (MMA8652FC::initalize()) {
|
|
DetectedAccelerometerVersion = AccelType::MMA;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef ACCEL_LIS
|
|
if (LIS2DH12::detect()) {
|
|
// Setup the ST Accelerometer
|
|
if (LIS2DH12::initalize()) {
|
|
if (LIS2DH12::isClone()) {
|
|
DetectedAccelerometerVersion = AccelType::LIS_CLONE;
|
|
} else {
|
|
DetectedAccelerometerVersion = AccelType::LIS;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef ACCEL_BMA
|
|
if (BMA223::detect()) {
|
|
// Setup the BMA223 Accelerometer
|
|
if (BMA223::initalize()) {
|
|
DetectedAccelerometerVersion = AccelType::BMA;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef ACCEL_SC7
|
|
if (SC7A20::detect()) {
|
|
// Setup the SC7A20 Accelerometer
|
|
if (SC7A20::initalize()) {
|
|
DetectedAccelerometerVersion = AccelType::SC7;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef ACCEL_MSA
|
|
if (MSA301::detect()) {
|
|
// Setup the MSA301 Accelerometer
|
|
if (MSA301::initalize()) {
|
|
DetectedAccelerometerVersion = AccelType::MSA;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef GPIO_VIBRATION
|
|
if (true) {
|
|
DetectedAccelerometerVersion = AccelType::GPIO;
|
|
return;
|
|
}
|
|
#endif
|
|
{
|
|
// disable imu sensitivity
|
|
setSettingValue(SettingsOptions::Sensitivity, 0);
|
|
DetectedAccelerometerVersion = AccelType::None;
|
|
}
|
|
}
|
|
inline void readAccelerometer(int16_t &tx, int16_t &ty, int16_t &tz, Orientation &rotation) {
|
|
#ifdef ACCEL_MMA
|
|
if (DetectedAccelerometerVersion == AccelType::MMA) {
|
|
MMA8652FC::getAxisReadings(tx, ty, tz);
|
|
rotation = MMA8652FC::getOrientation();
|
|
} else
|
|
#endif
|
|
#ifdef ACCEL_LIS
|
|
if (DetectedAccelerometerVersion == AccelType::LIS || DetectedAccelerometerVersion == AccelType::LIS_CLONE) {
|
|
LIS2DH12::getAxisReadings(tx, ty, tz);
|
|
rotation = LIS2DH12::getOrientation();
|
|
} else
|
|
#endif
|
|
#ifdef ACCEL_BMA
|
|
if (DetectedAccelerometerVersion == AccelType::BMA) {
|
|
BMA223::getAxisReadings(tx, ty, tz);
|
|
rotation = BMA223::getOrientation();
|
|
} else
|
|
#endif
|
|
#ifdef ACCEL_MSA
|
|
if (DetectedAccelerometerVersion == AccelType::MSA) {
|
|
MSA301::getAxisReadings(tx, ty, tz);
|
|
rotation = MSA301::getOrientation();
|
|
} else
|
|
#endif
|
|
#ifdef ACCEL_SC7
|
|
if (DetectedAccelerometerVersion == AccelType::SC7) {
|
|
SC7A20::getAxisReadings(tx, ty, tz);
|
|
rotation = SC7A20::getOrientation();
|
|
} else
|
|
#endif
|
|
#ifdef GPIO_VIBRATION
|
|
if (DetectedAccelerometerVersion == AccelType::GPIO) {
|
|
// TODO
|
|
if (HAL_GPIO_ReadPin(MOVEMENT_GPIO_Port, MOVEMENT_Pin) == GPIO_PIN_SET) {
|
|
// Movement
|
|
tx = ty = tz = 5000;
|
|
} else {
|
|
// No Movement
|
|
tx = ty = tz = 0;
|
|
}
|
|
rotation = Orientation::ORIENTATION_FLAT;
|
|
} else
|
|
#endif
|
|
{
|
|
// do nothing :(
|
|
}
|
|
}
|
|
void startMOVTask(void const *argument __unused) {
|
|
|
|
osDelay(TICKS_100MS / 5); // This is here as the BMA doesnt start up instantly and can wedge the I2C bus if probed too fast after boot
|
|
detectAccelerometerVersion();
|
|
osDelay(TICKS_100MS / 2); // wait ~50ms for setup of accel to finalise
|
|
lastMovementTime = 0;
|
|
// Mask 2 seconds if we are in autostart so that if user is plugging in and
|
|
// then putting in stand it doesnt wake instantly
|
|
if (getSettingValue(SettingsOptions::AutoStartMode)) {
|
|
osDelay(2 * TICKS_SECOND);
|
|
}
|
|
|
|
int16_t datax[MOVFilter] = {0};
|
|
int16_t datay[MOVFilter] = {0};
|
|
int16_t dataz[MOVFilter] = {0};
|
|
uint8_t currentPointer = 0;
|
|
int16_t tx = 0, ty = 0, tz = 0;
|
|
int32_t avgx, avgy, avgz;
|
|
Orientation rotation = ORIENTATION_FLAT;
|
|
for (;;) {
|
|
int32_t threshold = 1500 + (9 * 200);
|
|
threshold -= getSettingValue(SettingsOptions::Sensitivity) * 200; // 200 is the step size
|
|
readAccelerometer(tx, ty, tz, rotation);
|
|
if (getSettingValue(SettingsOptions::OrientationMode) == 2) {
|
|
if (rotation != ORIENTATION_FLAT) {
|
|
OLED::setRotation(rotation == ORIENTATION_LEFT_HAND); // link the data through
|
|
}
|
|
}
|
|
datax[currentPointer] = (int32_t)tx;
|
|
datay[currentPointer] = (int32_t)ty;
|
|
dataz[currentPointer] = (int32_t)tz;
|
|
if (!accelInit) {
|
|
for (uint8_t i = currentPointer + 1; i < MOVFilter; i++) {
|
|
datax[i] = (int32_t)tx;
|
|
datay[i] = (int32_t)ty;
|
|
dataz[i] = (int32_t)tz;
|
|
}
|
|
accelInit = 1;
|
|
}
|
|
currentPointer = (currentPointer + 1) % MOVFilter;
|
|
avgx = avgy = avgz = 0;
|
|
// calculate averages
|
|
for (uint8_t i = 0; i < MOVFilter; i++) {
|
|
avgx += datax[i];
|
|
avgy += datay[i];
|
|
avgz += dataz[i];
|
|
}
|
|
avgx /= MOVFilter;
|
|
avgy /= MOVFilter;
|
|
avgz /= MOVFilter;
|
|
|
|
// Sum the deltas
|
|
int32_t error = (abs(avgx - tx) + abs(avgy - ty) + abs(avgz - tz));
|
|
// So now we have averages, we want to look if these are different by more
|
|
// than the threshold
|
|
|
|
// If movement has occurred then we update the tick timer
|
|
if (error > threshold) {
|
|
lastMovementTime = xTaskGetTickCount();
|
|
}
|
|
|
|
vTaskDelay(TICKS_100MS); // Slow down update rate
|
|
}
|
|
}
|