diff --git a/Firmware/CC_Charger.c b/Firmware/CC_Charger.c index 55a2c90..054a994 100644 --- a/Firmware/CC_Charger.c +++ b/Firmware/CC_Charger.c @@ -76,8 +76,6 @@ void disable_CC_timing() { gpio_put(DIODE_ON_PIN, false); //Turn off ideal diode - // gpio_put(CC_CHARGER_EN_PIN, false); //Disable CC Charger gate driver - pio_sm_set_enabled(pio, sm_clk, false); //Disable CC Charger Clock pio_sm_exec(pio, sm_clk, pio_encode_nop() | pio_encode_sideset_opt(1, 0)); //Set Clock output to 0 pio_sm_exec(pio, sm_clk, pio_encode_irq_set(false, 0)); @@ -194,14 +192,13 @@ void CC_Charger_init(int charger_current, int cap_voltage) { //Setup PWM -> Analog pins gpio_set_function(CC_I_LIMIT_PIN, GPIO_FUNC_PWM); gpio_set_function(V_CAP_SET_PIN, GPIO_FUNC_PWM); - gpio_set_function(3, GPIO_FUNC_PWM); uint v_i_set_pwm_slice = pwm_gpio_to_slice_num(V_CAP_SET_PIN); pwm_set_wrap(v_i_set_pwm_slice, 1000); - pwm_set_chan_level(v_i_set_pwm_slice, pwm_gpio_to_channel(CC_I_LIMIT_PIN), charger_current); - pwm_set_chan_level(v_i_set_pwm_slice, pwm_gpio_to_channel(V_CAP_SET_PIN), cap_voltage); + pwm_set_gpio_level(CC_I_LIMIT_PIN, charger_current); + pwm_set_gpio_level(V_CAP_SET_PIN, cap_voltage); pwm_set_enabled(v_i_set_pwm_slice, true); @@ -217,7 +214,8 @@ void CC_Charger_init(int charger_current, int cap_voltage) { uint bias_pwm_slice_num = pwm_gpio_to_slice_num(GATE_BIAS_CLK_PIN); pwm_set_wrap(bias_pwm_slice_num, 2500); - pwm_set_chan_level(bias_pwm_slice_num, pwm_gpio_to_channel(GATE_BIAS_CLK_PIN), 1250); + pwm_set_gpio_level(GATE_BIAS_CLK_PIN, 1250); pwm_set_enabled(bias_pwm_slice_num, true); + } \ No newline at end of file diff --git a/Firmware/CC_Charger.h b/Firmware/CC_Charger.h index 1d5dc65..996d1bb 100644 --- a/Firmware/CC_Charger.h +++ b/Firmware/CC_Charger.h @@ -5,6 +5,11 @@ extern bool caps_charged; +/*! \brief Disable Constant Current Charger Gate Driver, turns off charger (timing signals still on) prevents ringing on VS_DIODE + \ingroup CC_Charger +*/ +void disable_gate_driver(); + /*! \brief Disable Constant Current Charger timing outputs, effectively turns off CC charger \ingroup CC_Charger */ diff --git a/Firmware/main.c b/Firmware/main.c index 33ea17a..ab7e194 100644 --- a/Firmware/main.c +++ b/Firmware/main.c @@ -13,7 +13,7 @@ #define OUTPUT_ON_TIME 20 #define OUTPUT_OFF_TIME 70 #define ISO_PULSE false -#define CAP_VOLTAGE_SETPOINT 70 //Don't set higher than 65 +#define CAP_VOLTAGE_SETPOINT 70 //CC Charger Parameters (don't change unless you know what you're doing) #define CHARGER_CURRENT 850 @@ -21,57 +21,57 @@ //Math stuff DO NOT EDIT #define CAP_VOLTAGE_PWM_LEVEL CAP_VOLTAGE_SETPOINT * 303 / 48 -bool os = false; - bool cut_on_off_irq(repeating_timer_t *rt) { - if(!gpio_get(CUT_nEN_PIN) && !cutting_enabled) { - cutting_enabled = true; - begin_output_pulses(OUTPUT_ON_TIME, OUTPUT_OFF_TIME, ISO_PULSE); - } else if(gpio_get(CUT_nEN_PIN)) { - cutting_enabled == false; - } + if(short_tripped) { - if(gpio_get(CUT_nEN_PIN)) { - cutting_enabled = false; - disable_gate_driver(); - } + if(gpio_get(CUT_nEN_PIN)) { - gpio_put(1, os); - os = !os; + short_tripped = false; + short_alert_off(); + + } + + } else { + + if(!gpio_get(CUT_nEN_PIN) && !cutting_enabled) { + + cutting_enabled = true; + begin_output_pulses(OUTPUT_ON_TIME, OUTPUT_OFF_TIME, ISO_PULSE); + + } else if(gpio_get(CUT_nEN_PIN)) { + + cutting_enabled == false; + disable_gate_driver(); + + } + + } return true; } void default_gpio_callback(uint gpio, uint32_t event_mask) { + gpio_acknowledge_irq(gpio, event_mask); + return; + } int main() { - // stdio_init_all(); //Start the Serial console - - // gpio_init(CUT_nEN_PIN); - // gpio_set_dir(CUT_nEN_PIN, GPIO_IN); - // gpio_set_pulls(cut_NEN, true, false); - sleep_ms(1000); - // while(gpio_get(23)) {} - CC_Charger_init(CHARGER_CURRENT, CAP_VOLTAGE_PWM_LEVEL); //Setup the CC Charger Outputs - pulse_generator_init(10); + pulse_generator_init(120); //Setup Pulse generator gpio_init(CUT_nEN_PIN); gpio_set_dir(CUT_nEN_PIN, GPIO_IN); gpio_set_pulls(CUT_nEN_PIN, false, false); - gpio_init(1); - gpio_set_dir(1, GPIO_OUT); - irq_set_enabled(IO_IRQ_BANK0, true); sleep_ms(1000); @@ -81,9 +81,6 @@ int main() { add_repeating_timer_ms(100, cut_on_off_irq, NULL, &timer); while (true) { - // sleep_us(10); - // gpio_put(3, true); - // sleep_us(10); - // gpio_put(3, false); + //All executed code is contained in interrupts / timers } } \ No newline at end of file diff --git a/Firmware/pulse_generator.c b/Firmware/pulse_generator.c index 069e553..2f9f43b 100644 --- a/Firmware/pulse_generator.c +++ b/Firmware/pulse_generator.c @@ -6,9 +6,12 @@ #define OUTPUT_EN_PIN 2 #define OUTPUT_CURRENT_TRIP_PIN 10 #define SPARK_THRESHOLD_PWM_PIN 14 +#define SHORT_ALERT_PIN 1 + +#define SHORT_THRESHOLD 410 bool cutting_enabled = false; -bool off_time_insufficient = false; +bool short_tripped = false; //Enum to keep track of where we are in the pulse sequence enum pulse_state{ WAITING_FOR_IGNITION, @@ -23,6 +26,12 @@ uint32_t pulse_off_time = 0; bool iso_pulse_mode = false; uint32_t pulse_timeout_time = 0; //time in us +alarm_id_t timeout_alarm_id; + +//Pulse history tracking (512 cycles, 1 bit per cycle) +uint32_t pulse_history[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +uint32_t pulse_counter = 0; + //Prototype functions int64_t begin_off_time(alarm_id_t id, void *user_data); @@ -31,12 +40,16 @@ int64_t change_CC_timing(alarm_id_t id, void *user_data){ LIMIT_set_timing(185, 7, true); - alarm_pool_cancel_alarm(alarm_pool_get_default(), id); - return 0; } +void short_alert_off() { + + gpio_put(SHORT_ALERT_PIN, false); + +} + void output_current_trip_irq(void) { if (gpio_get_irq_event_mask(OUTPUT_CURRENT_TRIP_PIN) & GPIO_IRQ_EDGE_RISE) { @@ -47,7 +60,12 @@ void output_current_trip_irq(void) { output_state = SPARK_ON; //Update the pulse generator state - add_alarm_in_us(pulse_on_time, begin_off_time, NULL, true); //Set alarm to turn off the pulse after the pulse on time + if(iso_pulse_mode == true){ + + cancel_alarm(timeout_alarm_id); //Turn off timeout alarm + add_alarm_in_us(pulse_on_time, begin_off_time, NULL, true); //Set alarm to turn off the pulse after the pulse on time + + } } @@ -59,34 +77,29 @@ int64_t begin_on_time(alarm_id_t id, void *user_data){ if(cutting_enabled) { //Check that cutting is still enabled + output_state = WAITING_FOR_IGNITION; //Update pulse generator state + + gpio_set_irq_enabled(OUTPUT_CURRENT_TRIP_PIN, GPIO_IRQ_EDGE_RISE, true); //Configure detection of the spark + gpio_add_raw_irq_handler(OUTPUT_CURRENT_TRIP_PIN, &output_current_trip_irq); + if(iso_pulse_mode) { //Check pulse mode is iso-pulse - add_alarm_in_us(pulse_timeout_time, begin_off_time, NULL, true); //Set the alarm in case of pulse timeout - - output_state = WAITING_FOR_IGNITION; //Update pulse generator state - - gpio_put(OUTPUT_EN_PIN, true); //Turn on output FET - - gpio_set_irq_enabled(OUTPUT_CURRENT_TRIP_PIN, GPIO_IRQ_EDGE_RISE, true);//Configure detection of the spark - gpio_add_raw_irq_handler(OUTPUT_CURRENT_TRIP_PIN, &output_current_trip_irq); + timeout_alarm_id = add_alarm_in_us(pulse_timeout_time, begin_off_time, NULL, true); //Set the alarm in case of pulse timeout } else { //If pulse mode is iso-tonic add_alarm_in_us(pulse_on_time, begin_off_time, NULL, true); //Set alarm for the off transition - output_state = SPARK_ON; //Update pulse generator state - - gpio_put(OUTPUT_EN_PIN, true); //Turn on output FET - } + + gpio_put(OUTPUT_EN_PIN, true); //Turn on output FET + } else { gpio_put(OUTPUT_EN_PIN, false); } - alarm_pool_cancel_alarm(alarm_pool_get_default(), id); - return 0; } @@ -94,43 +107,44 @@ int64_t begin_on_time(alarm_id_t id, void *user_data){ int64_t begin_off_time(alarm_id_t id, void *user_data){ - if(output_state == WAITING_FOR_IGNITION || iso_pulse_mode == false) { //Spark has timed out or if iso pulse is off, restart pulse cycle + gpio_put(OUTPUT_EN_PIN, false); //Turn off output MOSFET - gpio_put(OUTPUT_EN_PIN, false); //Turn off output MOSFET + gpio_set_irq_enabled(OUTPUT_CURRENT_TRIP_PIN, GPIO_IRQ_EDGE_RISE, false); //Disable the ignition sense irq - output_state = SPARK_OFF; //Update pulse generator state + LIMIT_set_timing(97, 7, false); //Limit CC Charger PWM duty cycle to avoid inrush (was 97) - gpio_set_irq_enabled(OUTPUT_CURRENT_TRIP_PIN, GPIO_IRQ_EDGE_RISE, false); //Disable the ignition sense irq + enable_CC_timing(); //Start CC Charger - LIMIT_set_timing(97, 7, false); //Limit CC Charger PWM duty cycle to avoid inrush (was 97) + add_alarm_in_us(15, change_CC_timing, NULL, true); //Setup the alarm to correct CC charger timing + add_alarm_in_us(pulse_off_time-11, begin_on_time, NULL, true); //Setup the alarm to turn on the output MOSFET after the off time - enable_CC_timing(); //Start CC Charger + pulse_counter -= pulse_history[0] & 1; //Subtract the 512th pulse state from the counter - add_alarm_in_us(15, change_CC_timing, NULL, true); //Setup the alarm to correct CC charger timing - add_alarm_in_us(pulse_off_time-11, begin_on_time, NULL, true); //Setup the alarm to turn on the output MOSFET after the off time + for(int i = 0; i < 7; i++) { - } else if(output_state == SPARK_ON && iso_pulse_mode == true) { //Spark is already ignited, ignore this timer callback - - //Do nothing + pulse_history[i] = ((pulse_history[i+1] & 1) << 31) + pulse_history[i] >> 1 ; //Binary shift the whole array (left shift each int and load in the first bit of the one above it) } - alarm_pool_cancel_alarm(alarm_pool_get_default(), id); + pulse_history[7] = pulse_history[7] >> 1; //Binary shift the last value, done outside the for loop because nowhere to pull the MSB from + + if(output_state == SPARK_ON) //If successful spark then load a 1 into the MSB of the shift register + pulse_history[7] = pulse_history[7] + (1 << 31); + + output_state = SPARK_OFF; //Set state machine state to SPARK_OFF + + if(pulse_counter > 410) { + cutting_enabled = false; + short_tripped = true; + disable_CC_timing(); + disable_gate_driver(); + gpio_put(SHORT_ALERT_PIN, true); + } return 0; } -void first_begin_off_time() { - - LIMIT_set_timing(97, 7, false); //Set the CC Charger PWM max duty cycle lower to prevent inrush - - enable_CC_timing(); //Start the CC Charger - - add_alarm_in_us(15, change_CC_timing, NULL, false); //Setup the alarm to correct CC charger timing - add_alarm_in_us(pulse_off_time-11, begin_on_time, NULL, true); //Setup the alarm to turn on the output MOSFET after the off time -} - void begin_output_pulses(uint32_t on_time, uint32_t off_time, bool iso_pulse) { //Load in the pulse parameters @@ -139,14 +153,7 @@ void begin_output_pulses(uint32_t on_time, uint32_t off_time, bool iso_pulse) { pulse_timeout_time = pulse_on_time / 2; iso_pulse_mode = iso_pulse; - //Update pulse state based on pulse mode - if(iso_pulse_mode) { - output_state = WAITING_FOR_IGNITION; - } else { - output_state = SPARK_OFF; - } - - first_begin_off_time(); + begin_off_time(-1, NULL); } @@ -158,7 +165,13 @@ void pulse_generator_init(uint32_t trip_current) { gpio_init(OUTPUT_CURRENT_TRIP_PIN); gpio_set_dir(OUTPUT_CURRENT_TRIP_PIN, GPIO_IN); - gpio_init(1); - gpio_set_dir(1, GPIO_OUT); + gpio_init(SHORT_ALERT_PIN); + gpio_set_dir(SHORT_ALERT_PIN, GPIO_OUT); + + gpio_set_function(SPARK_THRESHOLD_PWM_PIN, GPIO_FUNC_PWM); + + pwm_set_wrap(pwm_gpio_to_slice_num(SPARK_THRESHOLD_PWM_PIN), 1000); + + pwm_set_gpio_level(SPARK_THRESHOLD_PWM_PIN, trip_current); } \ No newline at end of file diff --git a/Firmware/pulse_generator.h b/Firmware/pulse_generator.h index d6fac5f..3d7e059 100644 --- a/Firmware/pulse_generator.h +++ b/Firmware/pulse_generator.h @@ -4,7 +4,12 @@ #include "pico/stdlib.h" extern bool cutting_enabled; -extern bool off_time_insufficient; +extern bool short_tripped; + +/*! \brief Turn off the short alert board output + \ingroup pulse_generator +*/ +void short_alert_off(); /*! \brief Start the EDM machine, ie, begin cutting \ingroup pulse_generator