diff --git a/workspace/TS100/Core/BSP/BSP.h b/workspace/TS100/Core/BSP/BSP.h index f1765c0f..0ddad258 100644 --- a/workspace/TS100/Core/BSP/BSP.h +++ b/workspace/TS100/Core/BSP/BSP.h @@ -1,9 +1,10 @@ +#include +#include #include "BSP_Flash.h" #include "BSP_Power.h" #include "BSP_QC.h" #include "Defines.h" #include "Model_Config.h" -#include "stdint.h" /* * BSP.h -- Board Support * @@ -16,11 +17,19 @@ extern "C" { #endif +// maximum htim2 PWM value +extern const uint16_t powerPWM; +// htim2.Init.Period, the full PWM cycle +extern uint16_t totalPWM; + // Called first thing in main() to init the hardware void preRToSInit(); // Called once the RToS has started for any extra work void postRToSInit(); +// Called once from preRToSInit() +void BSPInit(void); + // Called to reset the hardware watchdog unit void resetWatchdog(); // Accepts a output level of 0.. to use to control the tip output PWM @@ -31,6 +40,9 @@ uint16_t getHandleTemperature(); uint16_t getTipRawTemp(uint8_t refresh); // Returns the main DC input voltage, using the adjustable divisor + sample flag uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample); +// Switch to the most suitable PWM freq given the desired period; +// returns true if the switch was performed and totalPWM changed +bool tryBetterPWM(uint8_t pwm); // Readers for the two buttons // !! Returns 1 if held down, 0 if released diff --git a/workspace/TS100/Core/BSP/Miniware/BSP.cpp b/workspace/TS100/Core/BSP/Miniware/BSP.cpp index a2afb4f3..a27609b8 100644 --- a/workspace/TS100/Core/BSP/Miniware/BSP.cpp +++ b/workspace/TS100/Core/BSP/Miniware/BSP.cpp @@ -12,6 +12,14 @@ volatile uint16_t PWMSafetyTimer = 0; volatile uint8_t pendingPWM = 0; +const uint16_t powerPWM = 255; +static const uint8_t holdoffTicks = 13; // delay of 7 ms +static const uint8_t tempMeasureTicks = 17; + +uint16_t totalPWM; //htim2.Init.Period, the full PWM cycle + +static bool fastPWM; + //2 second filter (ADC is PID_TIM_HZ Hz) history rawTempFilter = { { 0 }, 0, 0 }; void resetWatchdog() { @@ -190,6 +198,41 @@ void setTipPWM(uint8_t pulse) { pendingPWM = pulse; } +static void switchToFastPWM(void) { + fastPWM = true; + totalPWM = powerPWM + tempMeasureTicks * 2; + htim2.Instance->ARR = totalPWM; + // ~3.5 Hz rate + htim2.Instance->CCR1 = powerPWM + holdoffTicks * 2; + // 2 MHz timer clock/2000 = 1 kHz tick rate + htim2.Instance->PSC = 2000; +} + +static void switchToSlowPWM(void) { + fastPWM = false; + totalPWM = powerPWM + tempMeasureTicks; + htim2.Instance->ARR = totalPWM; + // ~1.84 Hz rate + htim2.Instance->CCR1 = powerPWM + holdoffTicks; + // 2 MHz timer clock/4000 = 500 Hz tick rate + htim2.Instance->PSC = 4000; +} + +bool tryBetterPWM(uint8_t pwm) { + if (fastPWM && pwm == powerPWM) { + // maximum power for fast PWM reached, need to go slower to get more + switchToSlowPWM(); + return true; + } else if (!fastPWM && pwm < 230) { + // 254 in fast PWM mode gives the same power as 239 in slow + // allow for some reasonable hysteresis by switching only when it goes + // below 230 (equivalent to 245 in fast mode) + switchToFastPWM(); + return true; + } + return false; +} + // These are called by the HAL after the corresponding events from the system // timers. @@ -299,6 +342,10 @@ uint8_t getButtonB() { 1 : 0; } +void BSPInit(void) { + switchToFastPWM(); +} + void reboot() { NVIC_SystemReset(); diff --git a/workspace/TS100/Core/BSP/Miniware/Setup.c b/workspace/TS100/Core/BSP/Miniware/Setup.c index fdaeb139..515b4a59 100644 --- a/workspace/TS100/Core/BSP/Miniware/Setup.c +++ b/workspace/TS100/Core/BSP/Miniware/Setup.c @@ -315,13 +315,15 @@ static void MX_TIM2_Init(void) { // Timer 2 is fairly slow as its being used to run the PWM and trigger the ADC // in the PWM off time. htim2.Instance = TIM2; - htim2.Init.Prescaler = 4000; //1mhz tick rate/800 = 1.25 KHz tick rate + // dummy value, will be reconfigured by BSPInit() + htim2.Init.Prescaler = 2000; // 2 MHz timer clock/2000 = 1 kHz tick rate // pwm out is 10k from tim3, we want to run our PWM at around 10hz or slower on the output stage - // These values give a rate of around 8Hz + // These values give a rate of around 3.5 Hz for "fast" mode and 1.84 Hz for "slow" htim2.Init.CounterMode = TIM_COUNTERMODE_UP; - htim2.Init.Period = 255 + 17; - htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 4mhz before divide + // dummy value, will be reconfigured by BSPInit() + htim2.Init.Period = 255 + 17 * 2; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 8 MHz (x2 APB1) before divide htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; htim2.Init.RepetitionCounter = 0; HAL_TIM_Base_Init(&htim2); @@ -337,7 +339,8 @@ static void MX_TIM2_Init(void) { HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig); sConfigOC.OCMode = TIM_OCMODE_PWM1; - sConfigOC.Pulse = 255 + 13; //13 -> Delay of 5ms + // dummy value, will be reconfigured by BSPInit() + sConfigOC.Pulse = 255 + 13 * 2; // 13 -> Delay of 7 ms //255 is the largest time period of the drive signal, and then offset ADC sample to be a bit delayed after this /* * It takes 4 milliseconds for output to be stable after PWM turns off. diff --git a/workspace/TS100/Core/BSP/Miniware/preRTOS.cpp b/workspace/TS100/Core/BSP/Miniware/preRTOS.cpp index 67b04f49..e1d38434 100644 --- a/workspace/TS100/Core/BSP/Miniware/preRTOS.cpp +++ b/workspace/TS100/Core/BSP/Miniware/preRTOS.cpp @@ -17,6 +17,7 @@ void preRToSInit() { */ HAL_Init(); Setup_HAL(); // Setup all the HAL objects + BSPInit(); #ifdef I2C_SOFT I2CBB::init(); #endif diff --git a/workspace/TS100/Core/Inc/power.hpp b/workspace/TS100/Core/Inc/power.hpp index 31fddd33..8998f3de 100644 --- a/workspace/TS100/Core/Inc/power.hpp +++ b/workspace/TS100/Core/Inc/power.hpp @@ -25,6 +25,4 @@ extern expMovingAverage x10WattHistory; int32_t tempToX10Watts(int32_t rawTemp); void setTipX10Watts(int32_t mw); uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample = 0); -int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample = 0); -uint32_t availableW10(uint8_t sample) ; #endif /* POWER_HPP_ */ diff --git a/workspace/TS100/Core/Src/power.cpp b/workspace/TS100/Core/Src/power.cpp index 4cceb9c5..be042aa7 100644 --- a/workspace/TS100/Core/Src/power.cpp +++ b/workspace/TS100/Core/Src/power.cpp @@ -9,8 +9,7 @@ #include #include -const uint16_t powerPWM = 255; -const uint16_t totalPWM = 255 + 17; //htim2.Init.Period, the full PWM cycle +static int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample); expMovingAverage x10WattHistory = { 0 }; @@ -30,7 +29,7 @@ void setTipX10Watts(int32_t mw) { x10WattHistory.update(actualMilliWatts); } -uint32_t availableW10(uint8_t sample) { +static uint32_t availableW10(uint8_t sample) { //P = V^2 / R, v*v = v^2 * 100 // R = R*10 // P therefore is in V^2*100/R*10 = W*10. @@ -56,15 +55,22 @@ uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample) { } // if (milliWatts > (int(systemSettings.pidPowerLimit) * 10)) // milliWatts = (int(systemSettings.pidPowerLimit) * 10); + //Calculate desired milliwatts as a percentage of availableW10 - uint32_t pwm = (powerPWM * milliWatts) / availableW10(sample); - if (pwm > powerPWM) { - pwm = powerPWM; //constrain to max PWM counter, shouldnt be possible, but small cost for safety to avoid wraps - } + uint32_t pwm; + do { + pwm = (powerPWM * milliWatts) / availableW10(sample); + if (pwm > powerPWM) { + // constrain to max PWM counter, shouldn't be possible, + // but small cost for safety to avoid wraps + pwm = powerPWM; + } + } while (tryBetterPWM(pwm)); + return pwm; } -int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample) { +static int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample) { uint32_t maxMW = availableW10(sample); //Get the milliwatts for the max pwm period //Then convert pwm into percentage of powerPWM to get the percentage of the max mw return (((uint32_t) pwm) * maxMW) / powerPWM; diff --git a/workspace/TS100/configuration.h b/workspace/TS100/configuration.h index 623a87cd..3458f2f9 100644 --- a/workspace/TS100/configuration.h +++ b/workspace/TS100/configuration.h @@ -131,7 +131,7 @@ #ifdef MODEL_TS100 const int32_t tipMass = 45; // X10 watts to raise 1 deg C in 1 second -const uint8_t tipResistance = 85; //x10 ohms, 8.5 typical for ts100, 4.5 typical for ts80 +const uint8_t tipResistance = 75; //x10 ohms, 7.5 typical for ts100 tips #endif #ifdef MODEL_TS80