From 3bb1b7bc323ab9caddba2ef6e259634b36517388 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" <5425387+Ralim@users.noreply.github.com> Date: Thu, 16 Jun 2022 20:21:46 +1000 Subject: [PATCH] Startup behaviour fixes (#1306) * Reduce PPS max to 20V to avoid instability Some PSU's cant actually run at 21V * Creating a rough draft of a "pre start check" concept * Newer alpine * Cleaning up MHP detection * Cleanup comments * PID: Run prestart based on ADC IRQ rather than times * MHP30: Far better startup for detecting tip gain * Newer alpine for github CI --- Dockerfile | 2 + source/Core/BSP/BSP.h | 4 + source/Core/BSP/MHP30/BSP.cpp | 134 ++++++++++++++----------- source/Core/BSP/MHP30/ThermoModel.cpp | 3 +- source/Core/BSP/Miniware/BSP.cpp | 3 +- source/Core/BSP/Pine64/BSP.cpp | 2 + source/Core/BSP/Pine64/configuration.h | 2 +- source/Core/Threads/GUIThread.cpp | 8 +- source/Core/Threads/PIDThread.cpp | 13 ++- 9 files changed, 98 insertions(+), 73 deletions(-) diff --git a/Dockerfile b/Dockerfile index b1351a5a..d420b12b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,8 @@ RUN apk add --no-cache gcc-riscv-none-elf gcc-arm-none-eabi newlib-riscv-none-el # Install Python3 packages RUN python3 -m pip install bdflib black +# Git trust +RUN git config --global --add safe.directory /build/source COPY . /build/source COPY ./ci /build/ci diff --git a/source/Core/BSP/BSP.h b/source/Core/BSP/BSP.h index b7b2cb7d..6060f5f0 100644 --- a/source/Core/BSP/BSP.h +++ b/source/Core/BSP/BSP.h @@ -86,6 +86,10 @@ enum StatusLED { }; void setStatusLED(const enum StatusLED state); +// preStartChecks are run until they return 0 +// By the PID, after each ADC sample comes in +// For example, on the MHP30 this is used to figure out the resistance of the hotplate +uint8_t preStartChecks(); #ifdef __cplusplus } #endif diff --git a/source/Core/BSP/MHP30/BSP.cpp b/source/Core/BSP/MHP30/BSP.cpp index 12dac966..c1feab5c 100644 --- a/source/Core/BSP/MHP30/BSP.cpp +++ b/source/Core/BSP/MHP30/BSP.cpp @@ -13,13 +13,15 @@ #include WS2812 ws2812; -volatile uint16_t PWMSafetyTimer = 0; -volatile uint8_t pendingPWM = 0; -uint16_t totalPWM = 255; -const uint16_t powerPWM = 255; +volatile uint16_t PWMSafetyTimer = 0; +volatile uint8_t pendingPWM = 0; +uint16_t totalPWM = 255; +const uint16_t powerPWM = 255; +uint16_t tipSenseResistancex10Ohms = 0; +volatile bool tipMeasurementOccuring = false; +history rawTempFilter = {{0}, 0, 0}; -history rawTempFilter = {{0}, 0, 0}; -void resetWatchdog() { HAL_IWDG_Refresh(&hiwdg); } +void resetWatchdog() { HAL_IWDG_Refresh(&hiwdg); } #ifdef TEMP_NTC // Lookup table for the NTC @@ -208,7 +210,8 @@ uint16_t getHandleTemperature(uint8_t sample) { uint16_t getTipInstantTemperature() { return getADC(2); } uint16_t getTipRawTemp(uint8_t refresh) { - if (refresh) { + if (refresh && (tipMeasurementOccuring == false)) { + uint16_t lastSample = getTipInstantTemperature(); rawTempFilter.update(lastSample); return lastSample; @@ -348,69 +351,82 @@ void setPlatePullup(bool pullingUp) { HAL_GPIO_Init(PLATE_SENSOR_PULLUP_GPIO_Port, &GPIO_InitStruct); } -uint16_t tipSenseResistancex10Ohms = 0; -bool isTipDisconnected() { - static bool lastTipDisconnectedState = true; - static uint16_t adcReadingPD1Set = 0; - static TickType_t lastMeas = 0; +void performTipMeasurementStep(bool start) { + static uint16_t adcReadingPD1Set = 0; + static TickType_t lastMeas = 0; + // Inter state that performs the steps to measure the resistor on the tip + // Return 1 if a measurement is ongoing + + // We want to perform our startup measurements of the tip resistance until we detect one fitted + + // Step 1; if not setup, we turn on pullup and then wait + if (tipMeasurementOccuring == false && (start || tipSenseResistancex10Ohms == 0 || lastMeas == 0)) { + tipMeasurementOccuring = true; + tipSenseResistancex10Ohms = 0; + lastMeas = xTaskGetTickCount(); + adcReadingPD1Set = 0; + setPlatePullup(true); + return; + } + + // Wait 100ms for settle time + if ((xTaskGetTickCount() - lastMeas) < (TICKS_100MS)) { + return; + } + + lastMeas = xTaskGetTickCount(); + // We are sensing the resistance + if (adcReadingPD1Set == 0) { + // We will record the reading for PD1 being set + adcReadingPD1Set = getADC(3); + setPlatePullup(false); + return; + } + // Taking reading two + uint16_t adcReadingPD1Cleared = getADC(3); + uint32_t a = ((int)adcReadingPD1Set - (int)adcReadingPD1Cleared); + a *= 10000; + uint32_t b = ((int)adcReadingPD1Cleared + (32768 - (int)adcReadingPD1Set)); + if (b) { + tipSenseResistancex10Ohms = a / b; + } else { + tipSenseResistancex10Ohms = adcReadingPD1Set = lastMeas = 0; + } + if (tipSenseResistancex10Ohms > 1100 || tipSenseResistancex10Ohms < 900) { + tipSenseResistancex10Ohms = 0; // out of range + adcReadingPD1Set = 0; + lastMeas = 0; + return; + } + tipMeasurementOccuring = false; +} +bool isTipDisconnected() { + static bool lastDisconnectedState = false; // For the MHP30 we want to include a little extra logic in here // As when the tip is first connected we want to measure the ~100 ohm resistor on the base of the tip // And likewise if its removed we want to clear that measurement /* * plate_sensor_res = ((adc5_value_PD1_set - adc5_value_PD1_cleared) / (adc5_value_PD1_cleared + 4096 - adc5_value_PD1_set)) * 1000.0; * */ - - bool tipDisconnected = getADC(2) > (4090 * 8); - // We have to handle here that this ^ will trip while measuring the gain resistor - if (xTaskGetTickCount() - lastMeas < (TICKS_100MS * 2 + (TICKS_100MS / 2))) { - tipDisconnected = false; + if (tipMeasurementOccuring) { + performTipMeasurementStep(false); + return true; // We fake no tip disconnection during the measurement cycle to mask it } - if (tipDisconnected != lastTipDisconnectedState) { - if (tipDisconnected) { - // Tip is now disconnected - tipSenseResistancex10Ohms = 0; // zero out the resistance - adcReadingPD1Set = 0; - lastMeas = 0; - } - lastTipDisconnectedState = tipDisconnected; + // If we are too close to the top, most likely disconnected tip + bool tipDisconnected = getTipInstantTemperature() > (4090 * 8); + if (tipDisconnected == false && lastDisconnectedState == true) { + // Tip is now disconnected + performTipMeasurementStep(true); } - if (!tipDisconnected) { - if (tipSenseResistancex10Ohms == 0) { - if (lastMeas == 0) { - lastMeas = xTaskGetTickCount(); - setPlatePullup(true); - } else if (xTaskGetTickCount() - lastMeas > (TICKS_100MS)) { - lastMeas = xTaskGetTickCount(); - // We are sensing the resistance - if (adcReadingPD1Set == 0) { - // We will record the reading for PD1 being set - adcReadingPD1Set = getADC(3); - setPlatePullup(false); - } else { - // We have taken reading one - uint16_t adcReadingPD1Cleared = getADC(3); - uint32_t a = ((int)adcReadingPD1Set - (int)adcReadingPD1Cleared); - a *= 10000; - uint32_t b = ((int)adcReadingPD1Cleared + (32768 - (int)adcReadingPD1Set)); - if (b) { - tipSenseResistancex10Ohms = a / b; - } else { - tipSenseResistancex10Ohms = adcReadingPD1Set = lastMeas = 0; - } - if (tipSenseResistancex10Ohms > 1100 || tipSenseResistancex10Ohms < 900) { - tipSenseResistancex10Ohms = 0; // out of range - adcReadingPD1Set = 0; - lastMeas = 0; - } - } - } - return true; // we fake tip being disconnected until this is measured - } - } - + lastDisconnectedState = tipDisconnected; return tipDisconnected; } + +uint8_t preStartChecks() { + performTipMeasurementStep(false); + return tipMeasurementOccuring ? 1 : 0; +} void setBuzzer(bool on) { if (on) { htim3.Instance->CCR2 = 128; diff --git a/source/Core/BSP/MHP30/ThermoModel.cpp b/source/Core/BSP/MHP30/ThermoModel.cpp index 19c0e499..f43499a0 100644 --- a/source/Core/BSP/MHP30/ThermoModel.cpp +++ b/source/Core/BSP/MHP30/ThermoModel.cpp @@ -10,7 +10,8 @@ #include "configuration.h" extern uint16_t tipSenseResistancex10Ohms; uint32_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) { - // For the MHP30, we are mimicing the original code and using the resistor fitted to the base of the heater head, this is measured in the isTipDisconnected() function + // For the MHP30, we are mimicing the original code and using the resistor fitted to the base of the heater head, + // this is measured at boot in pid task and in the disconnected tip check if tip is removed if (tipSenseResistancex10Ohms > 900 && tipSenseResistancex10Ohms <= 1100) { int32_t a = ((tipSenseResistancex10Ohms / 10) + 300) * (3300000 - tipuVDelta); int32_t b = a / 1000000; diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp index 1d77a8c7..d40a7e17 100644 --- a/source/Core/BSP/Miniware/BSP.cpp +++ b/source/Core/BSP/Miniware/BSP.cpp @@ -282,4 +282,5 @@ bool isTipDisconnected() { return tipTemp > tipDisconnectedThres; } -void setStatusLED(const enum StatusLED state) {} +void setStatusLED(const enum StatusLED state) {} +uint8_t preStartChecks() { return 0; } \ No newline at end of file diff --git a/source/Core/BSP/Pine64/BSP.cpp b/source/Core/BSP/Pine64/BSP.cpp index 4b06fae3..2c7de076 100644 --- a/source/Core/BSP/Pine64/BSP.cpp +++ b/source/Core/BSP/Pine64/BSP.cpp @@ -90,3 +90,5 @@ bool isTipDisconnected() { } void setStatusLED(const enum StatusLED state) {} + +uint8_t preStartChecks() { return 0; } \ No newline at end of file diff --git a/source/Core/BSP/Pine64/configuration.h b/source/Core/BSP/Pine64/configuration.h index 09033126..27dcd4cc 100644 --- a/source/Core/BSP/Pine64/configuration.h +++ b/source/Core/BSP/Pine64/configuration.h @@ -124,7 +124,7 @@ #define POWER_LIMIT_STEPS 5 // #define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_PINECIL // Uses TS100 resistors #define TEMP_uV_LOOKUP_HAKKO // Use Hakko lookup table -#define USB_PD_VMAX 21 // Maximum voltage for PD to negotiate +#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate #define PID_TIM_HZ (8) // Tick rate of the PID loop #define MAX_TEMP_C 450 // Max soldering temp selectable °C #define MAX_TEMP_F 850 // Max soldering temp selectable °F diff --git a/source/Core/Threads/GUIThread.cpp b/source/Core/Threads/GUIThread.cpp index 822b34b6..544aa172 100644 --- a/source/Core/Threads/GUIThread.cpp +++ b/source/Core/Threads/GUIThread.cpp @@ -172,7 +172,7 @@ static void gui_drawBatteryIcon() { } static void gui_solderingTempAdjust() { uint32_t lastChange = xTaskGetTickCount(); - currentTempTargetDegC = 0; + currentTempTargetDegC = 0; // Turn off header while adjusting temp uint32_t autoRepeatTimer = 0; uint8_t autoRepeatAcceleration = 0; bool waitForRelease = false; @@ -511,12 +511,8 @@ static void gui_solderingMode(uint8_t jumpToSleep) { boostModeOn = false; break; case BUTTON_BOTH: - // exit - return; - break; case BUTTON_B_LONG: return; // exit on back long hold - break; case BUTTON_F_LONG: // if boost mode is enabled turn it on if (getSettingValue(SettingsOptions::BoostTemp)) @@ -665,8 +661,6 @@ static void gui_solderingMode(uint8_t jumpToSleep) { // If we have tripped thermal runaway, turn off heater and show warning if (heaterThermalRunaway) { currentTempTargetDegC = 0; // heater control off - // TODO WARNING - warnUser(translatedString(Tr->WarningThermalRunaway), 10 * TICKS_SECOND); heaterThermalRunaway = false; return; diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index 4c56372c..161fa365 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -39,21 +39,26 @@ void startPIDTask(void const *argument __unused) { pidTaskNotification = xTaskGetCurrentTaskHandle(); uint32_t PIDTempTarget = 0; // Pre-seed the adc filters - for (int i = 0; i < 128; i++) { - osDelay(5); + for (int i = 0; i < 32; i++) { + ulTaskNotifyTake(pdTRUE, 5); TipThermoModel::getTipInC(true); getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 1); } + + while (preStartChecks() != 0) { + ulTaskNotifyTake(pdTRUE, 2000); + } + int32_t x10WattsOut = 0; for (;;) { x10WattsOut = 0; // This is a call to block this thread until the ADC does its samples - if (ulTaskNotifyTake(pdTRUE, 2000)) { + if (ulTaskNotifyTake(pdTRUE, TICKS_SECOND * 2)) { // Do the reading here to keep the temp calculations churning along uint32_t currentTipTempInC = TipThermoModel::getTipInC(true); PIDTempTarget = currentTempTargetDegC; - if (PIDTempTarget) { + if (PIDTempTarget > 0) { // Cap the max set point to 450C if (PIDTempTarget > (450)) { // Maximum allowed output