Added pulse state tracking and short alert functionality

This commit is contained in:
DragonflyPS 2024-01-30 23:27:18 -08:00
parent 402ae2c0e7
commit 1d688e737d
5 changed files with 106 additions and 88 deletions

View File

@ -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);
}

View File

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

View File

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

View File

@ -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);
}

View File

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