From 7b02652cad4912813234c0604a8023406a8f6d40 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sat, 6 Aug 2016 01:27:11 +0200 Subject: [PATCH] Implemented bootstrap and switching --- src/main.c | 168 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 68 deletions(-) diff --git a/src/main.c b/src/main.c index 832ab0d..b539caf 100644 --- a/src/main.c +++ b/src/main.c @@ -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);