* Mock S60 * cleanup * Start refactor of OLED init * Setup timers roughly * Set Vector table offset correctly Update system_stm32f1xx.c * Update OLED.cpp * Update stm32f1xx_hal_msp.c * Update configuration.h * I2C init before GPIO From Errata Update stm32f1xx_hal_msp.c Update Software_I2C.h Allow no hardware I2C * I2C BB run bus unlock at init * cleanups * Software I2C for now * Mildly more graceful Interpolate * Handle is powered by DC Update Power.cpp Update drawPowerSourceIcon.cpp Update configuration.h Update Setup.cpp * Cleanup HomeScreen * Segment remap oled at init * Cleanup * Update MOVThread.cpp * Fix PWM Init * Fix adc2 trigger * Update configs * Fixup warning * Saner default config * Update ThermoModel.cpp * Util for current@voltage * Hub238 warning * Add hub238 handling in power mode * Update USBPDDebug_FUSB.cpp * HUSB238 debug * Hook PSU Limit * Use wrapping section of GRAM for scroll Update OLED.hpp * Update NTC table * Fix HUB voltage picker * Cleanup * Larger tip filter * Calibrate in a bunch closer Update ThermoModel.cpp * Update configuration.h * Update HUB238.cpp * Update configuration.h * Movement Pin * Update BSP.cpp * tim2 irq * Rough timer conversion (adc broken) but movement working * Fix tim2 start * Faster base PWM * Ensure utils grabs config * Add wattage limiter tolerance for device * Speed up PWM and enable PWM current limiting * tune for 12v * Prevent start until PD done * Update configuration.h * Add HUB238 check for have re-negotiated * Adjust timer to avoid noise when its possible
202 lines
5.6 KiB
C++
202 lines
5.6 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 "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()) {
|
|
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) {
|
|
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
|
|
}
|
|
}
|