diff --git a/workspace/TS100/Core/BSP/Pine64/BSP.cpp b/workspace/TS100/Core/BSP/Pine64/BSP.cpp index 7eef4672..391c1bf6 100644 --- a/workspace/TS100/Core/BSP/Pine64/BSP.cpp +++ b/workspace/TS100/Core/BSP/Pine64/BSP.cpp @@ -10,6 +10,12 @@ #include "systick.h" #include +const uint16_t powerPWM = 255; +const uint8_t holdoffTicks = 13; // delay of 7 ms +const uint8_t tempMeasureTicks = 17; + +uint16_t totalPWM; //htim2.Init.Period, the full PWM cycle + //2 second filter (ADC is PID_TIM_HZ Hz) history rawTempFilter = { { 0 }, 0, 0 }; void resetWatchdog() { @@ -58,7 +64,6 @@ uint16_t getHandleTemperature() { } uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) { - static uint8_t preFillneeded = 10; static uint32_t samples[BATTFILTERDEPTH]; static uint8_t index = 0; @@ -84,24 +89,24 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) { } void unstick_I2C() { - /* configure SDA/SCL for GPIO */ - GPIO_BC(GPIOB) |= SDA_Pin|SCL_Pin; - gpio_init(SDA_GPIO_Port,GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SDA_Pin | SCL_Pin); - asm ("nop"); - asm ("nop"); - asm ("nop"); - asm ("nop"); - asm ("nop"); - GPIO_BOP(GPIOB) |= SCL_Pin; - asm ("nop"); - asm ("nop"); - asm ("nop"); - asm ("nop"); - asm ("nop"); - GPIO_BOP(GPIOB) |= SDA_Pin; - /* connect PB6 to I2C0_SCL */ - /* connect PB7 to I2C0_SDA */ - gpio_init(SDA_GPIO_Port, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, SDA_Pin | SCL_Pin); + /* configure SDA/SCL for GPIO */ + GPIO_BC(GPIOB) |= SDA_Pin | SCL_Pin; + gpio_init(SDA_GPIO_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SDA_Pin | SCL_Pin); + asm ("nop"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + GPIO_BOP(GPIOB) |= SCL_Pin; + asm ("nop"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + asm ("nop"); + GPIO_BOP(GPIOB) |= SDA_Pin; + /* connect PB6 to I2C0_SCL */ + /* connect PB7 to I2C0_SDA */ + gpio_init(SDA_GPIO_Port, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, SDA_Pin | SCL_Pin); } uint8_t getButtonA() { @@ -120,3 +125,5 @@ void reboot() { void delay_ms(uint16_t count) { delay_1ms(count); } + + diff --git a/workspace/TS100/Core/BSP/Pine64/IRQ.cpp b/workspace/TS100/Core/BSP/Pine64/IRQ.cpp index 8a726beb..f9654cfd 100644 --- a/workspace/TS100/Core/BSP/Pine64/IRQ.cpp +++ b/workspace/TS100/Core/BSP/Pine64/IRQ.cpp @@ -55,13 +55,54 @@ void TIMER1_IRQHandler(void) { } void setTipPWM(uint8_t pulse) { - PWMSafetyTimer = 10; -// This is decremented in the handler for PWM so that the tip pwm is -// disabled if the PID task is not scheduled often enough. - + PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is + // disabled if the PID task is not scheduled often enough. pendingPWM = pulse; } +static bool fastPWM; +static void switchToFastPWM(void) { + fastPWM = true; + totalPWM = powerPWM + tempMeasureTicks * 2; + TIMER_CAR(TIMER1) = (uint32_t)totalPWM; + + // ~3.5 Hz rate + TIMER_CH0CV(TIMER1) = powerPWM + holdoffTicks * 2; + //1 kHz tick rate + TIMER_PSC(TIMER1) = 12000; + /* generate an update event */ + TIMER_SWEVG(TIMER1) |= (uint32_t) TIMER_SWEVG_UPG; + +} + +static void switchToSlowPWM(void) { + fastPWM = false; + totalPWM = powerPWM + tempMeasureTicks; + TIMER_CAR(TIMER1) = (uint32_t)totalPWM; + // ~1.84 Hz rate + TIMER_CH0CV(TIMER1) = powerPWM + holdoffTicks; + // 500 Hz tick rate + TIMER_PSC(TIMER1) = 24000; + /* generate an update event */ + TIMER_SWEVG(TIMER1) |= (uint32_t) TIMER_SWEVG_UPG; + +} + +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; +} + void EXTI5_9_IRQHandler(void) { #ifdef POW_PD if (RESET != exti_interrupt_flag_get(EXTI_5)) { diff --git a/workspace/TS100/Core/BSP/Pine64/Setup.c b/workspace/TS100/Core/BSP/Pine64/Setup.c index 3dd25f03..f48862be 100644 --- a/workspace/TS100/Core/BSP/Pine64/Setup.c +++ b/workspace/TS100/Core/BSP/Pine64/Setup.c @@ -211,7 +211,7 @@ void setup_timers() { timer_initpara.prescaler = 24000; timer_initpara.alignedmode = TIMER_COUNTER_EDGE; timer_initpara.counterdirection = TIMER_COUNTER_UP; - timer_initpara.period = 255 + 17; + timer_initpara.period = powerPWM + tempMeasureTicks; timer_initpara.clockdivision = TIMER_CKDIV_DIV4; timer_initpara.repetitioncounter = 0; timer_init(TIMER1, &timer_initpara); @@ -222,7 +222,7 @@ void setup_timers() { timer_ocintpara.outputstate = TIMER_CCX_ENABLE; timer_channel_output_config(TIMER1, TIMER_CH_0, &timer_ocintpara); - timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_0, 255 + 13); + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_0, powerPWM + holdoffTicks); timer_channel_output_mode_config(TIMER1, TIMER_CH_0, TIMER_OC_MODE_PWM1); timer_channel_output_shadow_config(TIMER1, TIMER_CH_0, diff --git a/workspace/TS100/Core/BSP/Pine64/Setup.h b/workspace/TS100/Core/BSP/Pine64/Setup.h index 8bc6fdeb..47d19dbe 100644 --- a/workspace/TS100/Core/BSP/Pine64/Setup.h +++ b/workspace/TS100/Core/BSP/Pine64/Setup.h @@ -19,5 +19,6 @@ void setupFUSBIRQ(); #ifdef __cplusplus } #endif - +extern const uint8_t holdoffTicks; +extern const uint8_t tempMeasureTicks; #endif /* SETUP_H_ */ diff --git a/workspace/TS100/Core/BSP/Pine64/logo.cpp b/workspace/TS100/Core/BSP/Pine64/logo.cpp index 1001e712..9d82ca36 100644 --- a/workspace/TS100/Core/BSP/Pine64/logo.cpp +++ b/workspace/TS100/Core/BSP/Pine64/logo.cpp @@ -9,7 +9,6 @@ #include "OLED.hpp" // Second last page of flash set aside for logo image. #define FLASH_LOGOADDR (0x8000000 | 0xF800) -//TODO // Logo header signature. #define LOGO_HEADER_VALUE 0xF00DAA55 diff --git a/workspace/TS100/Core/Src/power.cpp b/workspace/TS100/Core/Src/power.cpp index be042aa7..5620f50c 100644 --- a/workspace/TS100/Core/Src/power.cpp +++ b/workspace/TS100/Core/Src/power.cpp @@ -33,7 +33,7 @@ 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. - uint32_t v = getInputVoltageX10(systemSettings.voltageDiv, sample); // 100 = 10v + uint32_t v = getInputVoltageX10(systemSettings.voltageDiv, sample); // 100 = 10v uint32_t availableWattsX10 = (v * v) / tipResistance; //However, 100% duty cycle is not possible as there is a dead time while the ADC takes a reading //Therefore need to scale available milliwats by this @@ -53,8 +53,6 @@ uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample) { getInputVoltageX10(systemSettings.voltageDiv, sample); return 0; } - // if (milliWatts > (int(systemSettings.pidPowerLimit) * 10)) -// milliWatts = (int(systemSettings.pidPowerLimit) * 10); //Calculate desired milliwatts as a percentage of availableW10 uint32_t pwm; @@ -74,5 +72,4 @@ 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; - }