From 25e4abee7df52bd35688f6f9d25f9a9140cba409 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sat, 16 Jan 2021 09:20:23 +1100 Subject: [PATCH 1/3] Split power work into own thread Completely forseeable issue. Now that we have _more_ ram available, this is a good option to split power related items out into their own thread. --- .../TS100/Core/BSP/Miniware/fusb302b.cpp | 2 -- workspace/TS100/Core/Inc/main.hpp | 1 + workspace/TS100/Core/Src/main.cpp | 25 ++++++++++------- workspace/TS100/Core/Threads/MOVThread.cpp | 2 -- workspace/TS100/Core/Threads/POWThread.cpp | 27 +++++++++++++++++++ 5 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 workspace/TS100/Core/Threads/POWThread.cpp diff --git a/workspace/TS100/Core/BSP/Miniware/fusb302b.cpp b/workspace/TS100/Core/BSP/Miniware/fusb302b.cpp index fda41003..ac5cbe76 100644 --- a/workspace/TS100/Core/BSP/Miniware/fusb302b.cpp +++ b/workspace/TS100/Core/BSP/Miniware/fusb302b.cpp @@ -244,8 +244,6 @@ void fusb_reset() { fusb_write_byte( FUSB_CONTROL0, 0x44); /* Flush the RX buffer */ fusb_write_byte( FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH); - /* Reset the PD logic */ -// fusb_write_byte( FUSB_RESET, FUSB_RESET_PD_RESET); if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { I2CBB::unlock2(); } diff --git a/workspace/TS100/Core/Inc/main.hpp b/workspace/TS100/Core/Inc/main.hpp index ede22bd5..f3a4f49b 100755 --- a/workspace/TS100/Core/Inc/main.hpp +++ b/workspace/TS100/Core/Inc/main.hpp @@ -20,6 +20,7 @@ void vApplicationStackOverflowHook(TaskHandle_t *pxTask, void startGUITask(void const *argument); void startPIDTask(void const *argument); void startMOVTask(void const *argument); +void startPOWTask(void const *argument); extern TaskHandle_t pidTaskNotification; extern uint8_t accelInit; extern TickType_t lastMovementTime; diff --git a/workspace/TS100/Core/Src/main.cpp b/workspace/TS100/Core/Src/main.cpp index c638b0d8..14d27bb5 100755 --- a/workspace/TS100/Core/Src/main.cpp +++ b/workspace/TS100/Core/Src/main.cpp @@ -24,11 +24,17 @@ osThreadId PIDTaskHandle; static const size_t PIDTaskStackSize = 512 / 4; uint32_t PIDTaskBuffer[PIDTaskStackSize]; osStaticThreadDef_t PIDTaskControlBlock; + osThreadId MOVTaskHandle; static const size_t MOVTaskStackSize = 1024 / 4; uint32_t MOVTaskBuffer[MOVTaskStackSize]; osStaticThreadDef_t MOVTaskControlBlock; +osThreadId POWTaskHandle; +static const size_t POWTaskStackSize = 512 / 4; +uint32_t POWTaskBuffer[POWTaskStackSize]; +osStaticThreadDef_t POWTaskControlBlock; + // End FreeRTOS // Main sets up the hardware then hands over to the FreeRTOS kernel int main(void) { @@ -40,20 +46,21 @@ int main(void) { settingsWereReset = restoreSettings(); // load the settings from flash resetWatchdog(); /* Create the thread(s) */ - /* definition and creation of GUITask */ - osThreadStaticDef(GUITask, startGUITask, osPriorityBelowNormal, 0, - GUITaskStackSize, GUITaskBuffer, &GUITaskControlBlock); + /* definition and creation of POWTask - Power management for QC */ + osThreadStaticDef(POWTask, startPOWTask, osPriorityAboveNormal, 0, POWTaskStackSize, POWTaskBuffer, &POWTaskControlBlock); + POWTaskHandle = osThreadCreate(osThread(POWTask), NULL); + + /* definition and creation of GUITask - The OLED control & update*/ + osThreadStaticDef(GUITask, startGUITask, osPriorityBelowNormal, 0, GUITaskStackSize, GUITaskBuffer, &GUITaskControlBlock); GUITaskHandle = osThreadCreate(osThread(GUITask), NULL); - /* definition and creation of PIDTask */ - osThreadStaticDef(PIDTask, startPIDTask, osPriorityRealtime, 0, - PIDTaskStackSize, PIDTaskBuffer, &PIDTaskControlBlock); + /* definition and creation of PIDTask - Heating control*/ + osThreadStaticDef(PIDTask, startPIDTask, osPriorityRealtime, 0, PIDTaskStackSize, PIDTaskBuffer, &PIDTaskControlBlock); PIDTaskHandle = osThreadCreate(osThread(PIDTask), NULL); - osThreadStaticDef(MOVTask, startMOVTask, osPriorityNormal, 0, - MOVTaskStackSize, MOVTaskBuffer, &MOVTaskControlBlock); + /* definition and creation of MOVTask - Accelerometer management */ + osThreadStaticDef(MOVTask, startMOVTask, osPriorityNormal, 0, MOVTaskStackSize, MOVTaskBuffer, &MOVTaskControlBlock); MOVTaskHandle = osThreadCreate(osThread(MOVTask), NULL); - resetWatchdog(); /* Start scheduler */ diff --git a/workspace/TS100/Core/Threads/MOVThread.cpp b/workspace/TS100/Core/Threads/MOVThread.cpp index c26e4294..d9d5d160 100644 --- a/workspace/TS100/Core/Threads/MOVThread.cpp +++ b/workspace/TS100/Core/Threads/MOVThread.cpp @@ -107,7 +107,6 @@ inline void readAccelerometer(int16_t &tx, int16_t &ty, int16_t &tz, Orientation } } void startMOVTask(void const *argument __unused) { - postRToSInit(); detectAccelerometerVersion(); osDelay(TICKS_100MS / 2); // wait ~50ms for setup of accel to finalise lastMovementTime = 0; @@ -168,6 +167,5 @@ void startMOVTask(void const *argument __unused) { } osDelay(TICKS_100MS); // Slow down update rate - power_check(); } } diff --git a/workspace/TS100/Core/Threads/POWThread.cpp b/workspace/TS100/Core/Threads/POWThread.cpp new file mode 100644 index 00000000..f87fed87 --- /dev/null +++ b/workspace/TS100/Core/Threads/POWThread.cpp @@ -0,0 +1,27 @@ +/* + * POWThread.cpp + * + * Created on: 16 Jan 2021 + * Author: Ralim + */ + +#include "BSP.h" +#include "FreeRTOS.h" +#include "QC3.h" +#include "Settings.h" +#include "cmsis_os.h" +#include "main.hpp" +#include "stdlib.h" +#include "task.h" + +// Small worker thread to handle power (mostly QC) related steps + + + +void startPOWTask(void const *argument __unused) { + postRToSInit(); + for (;;) { + osDelay(TICKS_100MS); // Slow down update rate + power_check(); + } +} From 5379838f2c653b053bec63dab4dcfb6bcdd08b86 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sat, 16 Jan 2021 11:22:11 +1100 Subject: [PATCH 2/3] Allow P64 i2c before rtos --- .../TS100/Core/BSP/Pine64/I2C_Wrapper.cpp | 63 ++++++++----------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/workspace/TS100/Core/BSP/Pine64/I2C_Wrapper.cpp b/workspace/TS100/Core/BSP/Pine64/I2C_Wrapper.cpp index db011a89..4e9b41f3 100755 --- a/workspace/TS100/Core/BSP/Pine64/I2C_Wrapper.cpp +++ b/workspace/TS100/Core/BSP/Pine64/I2C_Wrapper.cpp @@ -25,8 +25,7 @@ uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) { return temp; } -bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, - uint8_t *p_buffer, uint16_t number_of_byte) { +bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, uint8_t *p_buffer, uint16_t number_of_byte) { if (!lock()) return false; i2c_interrupt_disable(I2C0, I2C_INT_ERR); @@ -61,8 +60,7 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, /* enable acknowledge */ i2c_ack_config(I2C0, I2C_ACK_ENABLE); /* i2c master sends start signal only when the bus is idle */ - while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && (timeout < I2C_TIME_OUT )) { + while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT )) { timeout++; } if (timeout < I2C_TIME_OUT) { @@ -83,8 +81,7 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, break; case I2C_SEND_ADDRESS: /* i2c master sends START signal successfully */ - while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) - && (timeout < I2C_TIME_OUT )) { + while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT )) { timeout++; } if (timeout < I2C_TIME_OUT) { @@ -104,15 +101,13 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, break; case I2C_CLEAR_ADDRESS_FLAG: /* address flag set means i2c slave sends ACK */ - while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) - && (timeout < I2C_TIME_OUT )) { + while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT )) { timeout++; if (i2c_flag_get(I2C0, I2C_FLAG_AERR)) { i2c_flag_clear(I2C0, I2C_FLAG_AERR); i2c_stop_on_bus(I2C0); /* i2c master sends STOP signal successfully */ - while ((I2C_CTL0(I2C0) & 0x0200) - && (timeout < I2C_TIME_OUT )) { + while ((I2C_CTL0(I2C0) & 0x0200) && (timeout < I2C_TIME_OUT )) { timeout++; } // Address NACK'd @@ -138,8 +133,7 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, case I2C_TRANSMIT_DATA: if (0 == in_rx_cycle) { /* wait until the transmit data buffer is empty */ - while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) - && (timeout < I2C_TIME_OUT )) { + while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT )) { timeout++; } if (timeout < I2C_TIME_OUT) { @@ -152,8 +146,7 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, in_rx_cycle = 0; } /* wait until BTC bit is set */ - while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) - && (timeout < I2C_TIME_OUT )) { + while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT )) { timeout++; } if (timeout < I2C_TIME_OUT) { @@ -239,8 +232,7 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, return true; } -bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, - uint8_t *p_buffer, uint16_t number_of_byte) { +bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *p_buffer, uint16_t number_of_byte) { if (!lock()) return false; @@ -257,8 +249,7 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, switch (state) { case I2C_START: /* i2c master sends start signal only when the bus is idle */ - while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && (timeout < I2C_TIME_OUT )) { + while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT )) { timeout++; } if (timeout < I2C_TIME_OUT) { @@ -273,8 +264,7 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, break; case I2C_SEND_ADDRESS: /* i2c master sends START signal successfully */ - while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) - && (timeout < I2C_TIME_OUT )) { + while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT )) { timeout++; } if (timeout < I2C_TIME_OUT) { @@ -290,15 +280,13 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, break; case I2C_CLEAR_ADDRESS_FLAG: /* address flag set means i2c slave sends ACK */ - while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) - && (timeout < I2C_TIME_OUT )) { + while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT )) { timeout++; if (i2c_flag_get(I2C0, I2C_FLAG_AERR)) { i2c_flag_clear(I2C0, I2C_FLAG_AERR); i2c_stop_on_bus(I2C0); /* i2c master sends STOP signal successfully */ - while ((I2C_CTL0(I2C0) & 0x0200) - && (timeout < I2C_TIME_OUT )) { + while ((I2C_CTL0(I2C0) & 0x0200) && (timeout < I2C_TIME_OUT )) { timeout++; } // Address NACK'd @@ -323,8 +311,7 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, break; case I2C_TRANSMIT_DATA: /* wait until the transmit data buffer is empty */ - while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) - && (timeout < I2C_TIME_OUT )) { + while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT )) { timeout++; } if (timeout < I2C_TIME_OUT) { @@ -409,18 +396,22 @@ bool FRToSI2C::lock() { if (I2CSemaphore == nullptr) { return false; } + if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) { + return true; + } return xSemaphoreTake(I2CSemaphore, TICKS_SECOND) == pdTRUE; } void FRToSI2C::unlock() { + if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) { + return; + } xSemaphoreGive(I2CSemaphore); } -bool FRToSI2C::writeRegistersBulk(const uint8_t address, - const I2C_REG *registers, const uint8_t registersLength) { +bool FRToSI2C::writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength) { for (int index = 0; index < registersLength; index++) { - if (!I2C_RegisterWrite(address, registers[index].reg, - registers[index].val)) { + if (!I2C_RegisterWrite(address, registers[index].reg, registers[index].val)) { return false; } if (registers[index].pause_ms) { @@ -447,8 +438,7 @@ bool FRToSI2C::wakePart(uint16_t DevAddress) { switch (state) { case I2C_START: /* i2c master sends start signal only when the bus is idle */ - while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && (timeout < I2C_TIME_OUT )) { + while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT )) { timeout++; } if (timeout < I2C_TIME_OUT) { @@ -463,8 +453,7 @@ bool FRToSI2C::wakePart(uint16_t DevAddress) { break; case I2C_SEND_ADDRESS: /* i2c master sends START signal successfully */ - while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) - && (timeout < I2C_TIME_OUT )) { + while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT )) { timeout++; } if (timeout < I2C_TIME_OUT) { @@ -480,15 +469,13 @@ bool FRToSI2C::wakePart(uint16_t DevAddress) { break; case I2C_CLEAR_ADDRESS_FLAG: /* address flag set means i2c slave sends ACK */ - while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) - && (timeout < I2C_TIME_OUT )) { + while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT )) { timeout++; if (i2c_flag_get(I2C0, I2C_FLAG_AERR)) { i2c_flag_clear(I2C0, I2C_FLAG_AERR); i2c_stop_on_bus(I2C0); /* i2c master sends STOP signal successfully */ - while ((I2C_CTL0(I2C0) & 0x0200) - && (timeout < I2C_TIME_OUT )) { + while ((I2C_CTL0(I2C0) & 0x0200) && (timeout < I2C_TIME_OUT )) { timeout++; } // Address NACK'd From b961311a5ca46043a25a68701680fcc2fb2e3f6e Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sat, 16 Jan 2021 16:03:35 +1100 Subject: [PATCH 3/3] Fix ifdef for inverted accel in TS80/TS80P This should fix #768 --- workspace/TS100/Core/BSP/Miniware/Model_Config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspace/TS100/Core/BSP/Miniware/Model_Config.h b/workspace/TS100/Core/BSP/Miniware/Model_Config.h index 664208ad..f961048d 100644 --- a/workspace/TS100/Core/BSP/Miniware/Model_Config.h +++ b/workspace/TS100/Core/BSP/Miniware/Model_Config.h @@ -29,7 +29,7 @@ #define ACCEL_LIS #define POW_QC #define TEMP_TMP36 -#define ACCEL_ORI_FLIP +#define LIS_ORI_FLIP #define OLED_FLIP #define BATTFILTERDEPTH 8 #endif @@ -41,7 +41,7 @@ #define POW_QC #define TEMP_NTC #define I2C_SOFT -#define ACCEL_ORI_FLIP +#define LIS_ORI_FLIP #define OLED_FLIP #define BATTFILTERDEPTH 8 #endif