Add support for dual speed PWM

This commit is contained in:
Ben V. Brown
2020-10-13 20:23:43 +11:00
parent d380cd4b9e
commit 40cf09a910
6 changed files with 76 additions and 31 deletions

View File

@@ -10,6 +10,12 @@
#include "systick.h"
#include <IRQ.h>
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<uint16_t, PID_TIM_HZ> 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);
}

View File

@@ -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)) {

View File

@@ -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,

View File

@@ -19,5 +19,6 @@ void setupFUSBIRQ();
#ifdef __cplusplus
}
#endif
extern const uint8_t holdoffTicks;
extern const uint8_t tempMeasureTicks;
#endif /* SETUP_H_ */

View File

@@ -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