Files
IronOS/source/Core/Threads/MOVThread.cpp
Ben V. Brown d9c88c9e71 Sequre T55 Support (#1928)
* Add T55 to build

* Approx in T55

* Update ThermoModel.cpp

* use PT1000 lookup logic

* Handle no accelerometer

* Setup for temp reading

* Lock max temp

* No movement pin

* Compensate for heater coil resistance change

* Fix min offset for T55

* Fixup font for T55

* Update draw_profile_advanced.cpp

* Update draw_temperature_change.cpp

---------

Co-authored-by: discip <53649486+discip@users.noreply.github.com>
2024-07-24 19:06:26 +10:00

227 lines
6.3 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() {
#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) {
#ifdef NO_ACCEL
DetectedAccelerometerVersion = AccelType::None;
for (;;) {
osDelay(2 * TICKS_SECOND);
}
#endif
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;
#ifdef ACCEL_EXITS_ON_MOVEMENT
uint16_t tripCounter = 0;
#endif
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
bool overThreshold = error > threshold;
#ifdef ACCEL_EXITS_ON_MOVEMENT
if (overThreshold) {
tripCounter++;
if (tripCounter > 2) {
lastMovementTime = xTaskGetTickCount();
}
} else if (tripCounter > 0) {
tripCounter = 0;
}
#else
if (overThreshold) {
lastMovementTime = xTaskGetTickCount();
}
#endif
vTaskDelay(TICKS_100MS); // Slow down update rate
}
}