Implemented bootstrap and switching

This commit is contained in:
Thomas Kolb 2016-08-06 01:27:11 +02:00
parent b8f8b5f6a2
commit 7b02652cad
1 changed files with 100 additions and 68 deletions

View File

@ -17,6 +17,12 @@
#define TIM_CH_CONV TIM_OC1
#define TIM_CH_BOOTSTRAP TIM_OC2
enum OperState {
Bootstrap,
Convert,
Idle,
};
volatile int wait_frame = 1;
#define ADC_NUM_CHANNELS 3
@ -29,14 +35,12 @@ static void init_gpio(void)
gpio_set_af(GPIOB, GPIO_AF0, GPIO6);
// GPIO for converter switch
// FIXME: AF
gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8);
gpio_clear(GPIOA, GPIO8);
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8);
gpio_set_af(GPIOA, GPIO_AF2, GPIO8);
// GPIO for bootstrap pulse
// FIXME: AF
gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO9);
gpio_clear(GPIOA, GPIO9);
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9);
gpio_set_af(GPIOA, GPIO_AF2, GPIO9);
// GPIO for load activation
gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO15);
@ -88,7 +92,7 @@ static void init_timer(void)
timer_set_oc_mode(TIM1, TIM_CH_BOOTSTRAP, TIM_OCM_PWM1);
timer_enable_oc_output(TIM1, TIM_CH_BOOTSTRAP);
timer_enable_oc_preload(TIM1, TIM_CH_BOOTSTRAP);
timer_set_oc_polarity_low(TIM1, TIM_CH_BOOTSTRAP);
timer_set_oc_polarity_high(TIM1, TIM_CH_BOOTSTRAP);
timer_set_oc_value(TIM1, TIM_CH_CONV, 0); // no PWM by default
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0); // no PWM by default
@ -103,8 +107,11 @@ static void init_timer(void)
// auto-reload value
timer_set_period(TIM1, CONV_PWM_MAX - 1);
// enable update interrupt (triggered on timer restart)
//timer_enable_irq(TIM1, TIM_DIER_UIE);
// only generate interrupt on overflow
timer_update_on_overflow(TIM1);
// enable master output bit
timer_enable_break_main_output(TIM1);
// *** TIM3 ***
// used for the 1-millisecond system tick
@ -190,10 +197,16 @@ int main(void)
{
uint16_t cpuload = 0;
uint64_t timebase_ms = 0;
uint32_t time_in_state = 0;
char msg[128];
char number[FXP_STR_MAXLEN];
uint8_t sentSomething = 0;
enum OperState operState = Bootstrap;
enum OperState lastState = operState;
fxp_t vin, vout, current;
// Calculated values
//fxp_t VIN_SCALE = fxp_from_float(3.3f * (100 + 12.4f) / 12.4f / 4095.0f);
//fxp_t VOUT_SCALE = fxp_from_float(3.3f * (100 + 12.0f) / 12.0f / 4095.0f);
@ -214,9 +227,6 @@ int main(void)
debug_send_string("Init complete\r\n");
// boost converter PWM initial value
//timer_set_oc_value(TIM3, TIM_OC1, 0);
//init_systick(1000);
// triggered every 1 ms
@ -227,8 +237,6 @@ int main(void)
/*
// *** Do some calculations while ADC converts ***
// Ramp up target voltage
if((targetVoltage < TARGET_VOLTAGE) && (voltRampUpCountdown-- == 0)) {
targetVoltage += 2.0f;
@ -267,54 +275,7 @@ int main(void)
}
*/
//timer_set_oc_value(TIM3, TIM_OC1, pwm_value);
/*
if((timebase_ms % 500) == 10) {
sprintf(msg, "Audio PWM: %lu",
dbg_audio_pwm_value);
debug_send_string(msg);
sentSomething = 1;
}
*/
// wait for DMA transfer to complete
while(!dma_get_interrupt_flag(DMA1, DMA_CHANNEL1, DMA_TCIF) && wait_frame);
dma_clear_interrupt_flags(DMA1, DMA_CHANNEL1, DMA_TCIF);
if((timebase_ms % 500) == 0) {
debug_send_string("ADC:");
for(uint8_t i = 0; i < ADC_NUM_CHANNELS; i++) {
fxp_format_int(adc_values[i], msg);
debug_send_string(" ");
debug_send_string(msg);
}
fxp_t scaled_val;
scaled_val = fxp_mult(fxp_from_int(adc_values[0]), VIN_SCALE);
fxp_format(scaled_val, msg, 3);
debug_send_string("\r\nInput[V]: ");
debug_send_string(msg);
scaled_val = fxp_mult(fxp_from_int(adc_values[1]), VOUT_SCALE);
fxp_format(scaled_val, msg, 3);
debug_send_string("\r\nOutput[V]: ");
debug_send_string(msg);
scaled_val = fxp_mult(fxp_from_int(adc_values[2]), CURRENT_SCALE);
fxp_format(scaled_val, msg, 3);
debug_send_string("\r\nCurrent[A]: ");
debug_send_string(msg);
sentSomething = 1;
}
if(sentSomething) {
debug_send_string("\r\n");
sentSomething = 0;
}
// *** Do some calculations while ADC converts ***
if(lcd_setup()) {
lcd_process();
@ -324,15 +285,13 @@ int main(void)
lcd_set_cursor_pos(1, 0);
scaled_val = fxp_mult(fxp_from_int(adc_values[0]), VIN_SCALE);
fxp_format(scaled_val, number, 1);
fxp_format(vin, number, 1);
fxp_right_align(number, msg, 4, ' ');
lcd_send_string("I:");
lcd_send_string(msg);
lcd_send_string("V ");
scaled_val = fxp_mult(fxp_from_int(adc_values[1]), VOUT_SCALE);
fxp_format(scaled_val, number, 1);
fxp_format(vout, number, 1);
fxp_right_align(number, msg, 4, ' ');
lcd_send_string("O:");
lcd_send_string(msg);
@ -340,8 +299,7 @@ int main(void)
lcd_set_cursor_pos(0, 8);
scaled_val = fxp_mult(fxp_from_int(adc_values[2]), CURRENT_SCALE);
scaled_val = fxp_mult(scaled_val, fxp_from_int(1000)); // A -> mA
scaled_val = fxp_mult(current, fxp_from_int(1000)); // A -> mA
fxp_format(scaled_val, number, 0);
fxp_right_align(number, msg, 4, ' ');
lcd_send_string(msg);
@ -360,6 +318,80 @@ int main(void)
}
}
// wait for DMA transfer to complete
while(!dma_get_interrupt_flag(DMA1, DMA_CHANNEL1, DMA_TCIF) && wait_frame);
dma_clear_interrupt_flags(DMA1, DMA_CHANNEL1, DMA_TCIF);
// convert read values
vin = fxp_mult(fxp_from_int(adc_values[0]), VIN_SCALE);
vout = fxp_mult(fxp_from_int(adc_values[1]), VOUT_SCALE);
current = fxp_mult(fxp_from_int(adc_values[2]), CURRENT_SCALE);
// Main FSM
if(timebase_ms >= 1000) {
switch(operState) {
case Bootstrap:
// enable bootstrap pulse for 10 ns / 10 % duty cycle
// disable converter
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 48);
timer_set_oc_value(TIM1, TIM_CH_CONV, 0);
if(time_in_state > 10) { // bootstrap for 10 ms
operState = Convert;
}
break;
case Convert:
timer_set_oc_value(TIM1, TIM_CH_CONV, 800);
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0);
break;
case Idle:
// disable all PWMs
timer_set_oc_value(TIM1, TIM_CH_CONV, 0);
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0);
break;
default:
debug_send_string("Invalid state detected!");
sentSomething = 1;
operState = Idle;
break;
}
if(operState != lastState) {
time_in_state = 0;
lastState = operState;
} else {
time_in_state++;
}
}
if((timebase_ms % 500) == 0) {
debug_send_string("ADC:");
for(uint8_t i = 0; i < ADC_NUM_CHANNELS; i++) {
fxp_format_int(adc_values[i], msg);
debug_send_string(" ");
debug_send_string(msg);
}
debug_send_string("\r\n");
debug_send_string("State: ");
fxp_format_int((int)operState, msg);
debug_send_string(msg);
sentSomething = 1;
}
if(sentSomething) {
debug_send_string("\r\n");
sentSomething = 0;
}
// cpu load = timer1 value after main loop operations
cpuload += timer_get_counter(TIM3);