From 829d6783ca913696a45653b16c816dcd288a6b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andis=20Z=C4=ABle?= Date: Wed, 31 Jul 2024 19:04:22 +0300 Subject: [PATCH] Working version No protections though --- firmware/src/dccd/dccd.cpp | 349 ++++++++++++++++++++++++-------- firmware/src/dccd/dccd.h | 10 +- firmware/src/dccd/dccd_hw.cpp | 97 ++++++--- firmware/src/dccd/dccd_hw.h | 1 + firmware/src/hw/led_display.cpp | 7 +- firmware/src/hw/out_reg.cpp | 50 ++++- firmware/src/hw/out_reg.h | 20 +- firmware/src/main.cpp | 46 +++-- firmware/src/uDCCD.cppproj | 16 ++ 9 files changed, 446 insertions(+), 150 deletions(-) diff --git a/firmware/src/dccd/dccd.cpp b/firmware/src/dccd/dccd.cpp index a77e39f..88e7bc2 100644 --- a/firmware/src/dccd/dccd.cpp +++ b/firmware/src/dccd/dccd.cpp @@ -6,6 +6,42 @@ using namespace dccd; /**** Private definitions ****/ /**** Private constants ****/ +static const uint16_t def_lock_current = 4500; +static const uint16_t def_max_hbrake_time = 0; +static const uint16_t def_btn_force_repeat_time = 300; +static const uint16_t def_btn_mode_repeat_time = 700; +static const uint8_t def_button_inputs = 1; + +static const uint8_t def_display_brigth = 100; +static const uint8_t def_display_dimm = 50; + +static const uint16_t cv_ref_resistance = 1500; +static const uint16_t cc_ref_resistance = 2000; +static const uint16_t cc_min_resistance = 1000; + +static const uint8_t bmode_image_open = 0x07; +static const uint8_t bmode_image_user = 0x1E; +static const uint8_t bmode_image_lock = 0x38; + +static const uint16_t display_keep_bmode = 2000; +static const uint16_t display_keep_userf = 1000; + +static const uint8_t user_force_step = 10; + +static const uint8_t def_btn_force = 0; +static const uint8_t def_brake_mode = 0; + +static const uint16_t def_chasis_inp_debounce = 100; +static const uint16_t def_user_inp_debounce = 20; + +static const uint16_t mem_addr_inp_mode = 0; +static const uint16_t mem_addr_force = 1; +static const uint16_t mem_addr_bmode = 2; +static const uint16_t mem_addr_dsp_brigth = 3; +static const uint16_t mem_addr_dsp_dimm = 4; +static const uint16_t mem_addr_lock_current = 5; +static const uint16_t mem_addr_hbrake_time = 7; + /**** Private variables ****/ /**** Private function declarations ****/ static uint8_t img_gen_dot10(uint8_t percent); @@ -23,53 +59,54 @@ dccd::DccdApp::~DccdApp(void) return; } -void dccd::DccdApp::init(void) +void dccd::DccdApp::init(DccdHw* dccd_hw) { - // Read settings from EEPROM + this->hardware = dccd_hw; - DccdHw::dccdHwCfg_t cfg; - cfg.handbrake_pull_up = 1; - cfg.pwm_f_khz = 16; - cfg.speed_hall = 0; + #define OVERRIDEDEDBNC + #ifdef OVERRIDEDEDBNC + this->hardware->btn_mode.dbnc_lim = def_user_inp_debounce; + this->hardware->btn_up.dbnc_lim = def_user_inp_debounce; + this->hardware->btn_down.dbnc_lim = def_user_inp_debounce; + this->hardware->handbrake.dbnc_lim = def_chasis_inp_debounce; + this->hardware->brakes.dbnc_lim = def_chasis_inp_debounce; + this->hardware->dimm.dbnc_lim = def_chasis_inp_debounce; + #endif - this->hardware.init(&cfg); + // Load saved config from memory + this->loadMemCfg(); - this->lock_current = 4500; - this->max_hbrake_time = 1500; - this->btn_repeat_time = 500; - this->button_inputs = 1; - - this->display_brigth = 100; - this->display_dimm = 50; - - this->btn_force = 0; + this->btn_force_repeat_time = def_btn_force_repeat_time; + this->btn_mode_repeat_time = def_btn_mode_repeat_time; this->pot_force = 0; - this->brake_mode = 0; - this->hardware.read(); + this->hardware->read(); + this->hardware->dimm.force_read(); + + this->hardware->outreg.write_voltage(0); + this->hardware->outreg.write_current(0); + this->hardware->outreg.write_on(1); - this->hardware.outreg.voltage = 0; - this->hardware.outreg.current = 0; - this->hardware.outreg.out_on = 1; - this->hardware.display.write(0x01); - this->hardware.display.write_backlight(50); + this->hardware->display.write(0x01); + if(this->hardware->dimm.state) this->hardware->display.write_backlight(this->display_dimm); + else this->hardware->display.write_backlight(this->display_brigth); - this->hardware.write(); + this->hardware->write(); } void dccd::DccdApp::process(void) { // Update all inputs - this->hardware.read(); + this->hardware->read(); uint8_t is_new_mode = 0; uint8_t is_new_btn_force = 0; // Process mode button - if((this->hardware.btn_mode.state==1)&&((this->hardware.btn_mode.is_new)||(this->hardware.btn_mode.time_read() >= this->btn_repeat_time))) + if((this->hardware->btn_mode.state==1)&&((this->hardware->btn_mode.is_new)||(this->hardware->btn_mode.time_read() >= this->btn_mode_repeat_time))) { - this->hardware.btn_mode.time_reset(); - this->hardware.btn_mode.is_new = 0; + this->hardware->btn_mode.time_reset(); + this->hardware->btn_mode.is_new = 0; // Change mode switch(this->brake_mode) { @@ -86,30 +123,36 @@ void dccd::DccdApp::process(void) break; } is_new_mode = 1; + this->hardware->board_hw.nvmem.write_8b(mem_addr_bmode, this->brake_mode); }; // Process user force inputs - if((this->hardware.btn_up.state==1)&&((this->hardware.btn_up.is_new)||(this->hardware.btn_up.time_read() >= this->btn_repeat_time))) + if((this->hardware->btn_up.state==1)&&((this->hardware->btn_up.is_new)||(this->hardware->btn_up.time_read() >= this->btn_force_repeat_time))) { - this->hardware.btn_up.time_reset(); - this->hardware.btn_up.is_new = 0; + this->hardware->btn_up.time_reset(); + this->hardware->btn_up.is_new = 0; // Increase user force - this->btn_force += 10; + this->btn_force += user_force_step; if(this->btn_force > 100) this->btn_force = 100; is_new_btn_force = 1; }; - if((this->hardware.btn_down.state==1)&&((this->hardware.btn_down.is_new)||(this->hardware.btn_down.time_read() >= this->btn_repeat_time))) + if((this->hardware->btn_down.state==1)&&((this->hardware->btn_down.is_new)||(this->hardware->btn_down.time_read() >= this->btn_force_repeat_time))) { - this->hardware.btn_down.time_reset(); - this->hardware.btn_down.is_new = 0; + this->hardware->btn_down.time_reset(); + this->hardware->btn_down.is_new = 0; // Decrease user force - this->btn_force -= 10; + this->btn_force -= user_force_step; if(this->btn_force > 100) this->btn_force = 0; is_new_btn_force = 1; }; - this->pot_force = this->hardware.pot.last_percent; + if(is_new_btn_force) + { + this->hardware->board_hw.nvmem.write_8b(mem_addr_force, this->btn_force); + }; + + this->pot_force = this->hardware->pot.last_percent; // Determine user force int8_t user_force; @@ -119,12 +162,18 @@ void dccd::DccdApp::process(void) // Determine next settable force int8_t next_force; - if((this->hardware.handbrake.state == 1)&&(this->hardware.handbrake.time_read() < this->max_hbrake_time)) + uint8_t hbrake_timeout = 0; + if((this->max_hbrake_time!=0)&&(this->hardware->handbrake.time_read() >= this->max_hbrake_time)) + { + hbrake_timeout = 1; + }; + + if((this->hardware->handbrake.state == 1)&&(hbrake_timeout==0)) { // Handbrake override next_force = -1; } - else if(this->hardware.brakes.state == 1) + else if(this->hardware->brakes.state == 1) { // Brakes override switch(this->brake_mode) @@ -142,7 +191,8 @@ void dccd::DccdApp::process(void) break; default: - this->brake_mode = -1; + next_force = -1; + this->brake_mode = 0; break; } } @@ -156,102 +206,227 @@ void dccd::DccdApp::process(void) if(next_force < 0) { // HiZ - this->hardware.outreg.voltage = 0; - this->hardware.outreg.current = 0; - this->hardware.outreg.out_on = 0; + this->hardware->outreg.write_voltage(0); + this->hardware->outreg.write_current(0); + this->hardware->outreg.write_on(0); + // For display + next_force = 0; } else if(next_force == 0) { // Open - this->hardware.outreg.voltage = 0; - this->hardware.outreg.current = 0; - this->hardware.outreg.out_on = 1; + this->hardware->outreg.write_voltage(0); + this->hardware->outreg.write_current(0); + this->hardware->outreg.write_on(1); } else { // Calculate current and voltage settings - this->hardware.outreg.current = util::percent_of((uint8_t)next_force, this->lock_current); - this->hardware.outreg.voltage = util::sat_mul_kilo(this->hardware.outreg.current, 2500); - this->hardware.outreg.out_on = 1; + this->hardware->outreg.write_current(util::percent_of((uint8_t)next_force, this->lock_current)); + uint16_t ref_resistance = cv_ref_resistance; + if(this->hardware->outreg.cc_mode_en) ref_resistance = cc_ref_resistance; + this->hardware->outreg.write_voltage(util::sat_mul_kilo(this->hardware->outreg.read_current(), ref_resistance)); + this->hardware->outreg.write_on(1); } // Display image if(is_new_mode) { - uint8_t image; + uint8_t bmode_image; switch(this->brake_mode) { case 0: - image = 0x07; + bmode_image = bmode_image_open; break; case 1: - image = 0x1E; + bmode_image = bmode_image_user; break; case 2: - image = 0x38; + bmode_image = bmode_image_lock; break; default: - image = 0x07; + bmode_image = bmode_image_open; + this->brake_mode = 0; break; } - this->hardware.display.write(image, 1000, 1000, 1); + this->hardware->display.write(bmode_image, display_keep_bmode, display_keep_bmode, 1); + is_new_mode = 0; } - else if(is_new_btn_force) + else if((is_new_btn_force)&&(this->button_inputs)) { - this->hardware.display.write(img_gen_dot10(this->btn_force), 500, 500, 1); + this->hardware->display.write(img_gen_dot10(this->btn_force), display_keep_userf, display_keep_userf, 1); + is_new_btn_force = 0; } - else if(this->hardware.display.is_cycle_end()) + else if(this->hardware->display.is_cycle_end()) { - this->hardware.display.write(img_gen_dot10(next_force)); + this->hardware->display.write(img_gen_dot10((uint8_t)next_force)); }; // Display backlight - if(this->hardware.dimm.is_new) + if(this->hardware->dimm.is_new) { - this->hardware.dimm.is_new = 0; - if(this->hardware.dimm.state) this->hardware.display.write_backlight(this->display_dimm); - else this->hardware.display.write_backlight(this->display_brigth); + this->hardware->dimm.is_new = 0; + if(this->hardware->dimm.state) this->hardware->display.write_backlight(this->display_dimm); + else this->hardware->display.write_backlight(this->display_brigth); }; // Execute outputs - this->hardware.write(); + this->hardware->write(); +} + +uint8_t dccd::DccdApp::loadMemCfg(void) +{ + // Load saved config from memory + uint8_t t1; + uint16_t t2; + uint8_t def_applied = 0; + + t1 = this->hardware->board_hw.nvmem.read_8b(mem_addr_inp_mode); + if(t1 > 1){this->button_inputs = def_button_inputs; def_applied=1; } + else this->button_inputs = t1; + + t1 = this->hardware->board_hw.nvmem.read_8b(mem_addr_force); + if(t1 > 100){this->btn_force = def_btn_force; def_applied=1; } + else this->btn_force = t1; + + t1 = this->hardware->board_hw.nvmem.read_8b(mem_addr_bmode); + if(t1 > 2){this->brake_mode = def_brake_mode; def_applied=1; } + else this->brake_mode = t1; + + t1 = this->hardware->board_hw.nvmem.read_8b(mem_addr_dsp_brigth); + if((t1 > 100)||(t1 == 0)){this->display_brigth = def_brake_mode; def_applied=1; } + else this->display_brigth = t1; + + t1 = this->hardware->board_hw.nvmem.read_8b(mem_addr_dsp_dimm); + if((t1 > 100)||(t1 == 0)){this->display_dimm = def_brake_mode; def_applied=1; } + else this->display_dimm = t1; + + t2 = this->hardware->board_hw.nvmem.read_16b(mem_addr_lock_current); + if((t2 > 5000)||(t2 < 1000)){this->lock_current = def_lock_current; def_applied=1; } + else this->lock_current = t2; + + t2 = this->hardware->board_hw.nvmem.read_16b(mem_addr_hbrake_time); + if((t2 > 30000)||(t2 == 0)){this->max_hbrake_time = def_max_hbrake_time; def_applied=1; } + else this->max_hbrake_time = t2; + + return def_applied; +} + +void dccd::DccdApp::saveMemCfg(void) +{ + // Save config to memory + + this->hardware->board_hw.nvmem.write_8b(mem_addr_inp_mode, this->button_inputs); + + this->hardware->board_hw.nvmem.write_8b(mem_addr_force, this->btn_force); + + this->hardware->board_hw.nvmem.write_8b(mem_addr_bmode, this->brake_mode); + + this->hardware->board_hw.nvmem.write_8b(mem_addr_dsp_brigth, this->display_brigth); + + this->hardware->board_hw.nvmem.write_8b(mem_addr_dsp_dimm, this->display_dimm); + + this->hardware->board_hw.nvmem.write_16b(mem_addr_lock_current, this->lock_current); + + this->hardware->board_hw.nvmem.write_16b(mem_addr_hbrake_time, this->max_hbrake_time); } /**** Private function definitions ***/ static uint8_t img_gen_dot10(uint8_t percent) { - if(percent<6) return 0x01; - else if(percent<16) return 0x03; - else if(percent<26) return 0x02; - else if(percent<36) return 0x06; - else if(percent<46) return 0x04; - else if(percent<56) return 0x0C; - else if(percent<66) return 0x08; - else if(percent<76) return 0x18; - else if(percent<86) return 0x10; - else if(percent<96) return 0x30; - else return 0x20; + switch(percent) + { + case 0 ... 5: + return 0x01; + + case 6 ... 15: + return 0x03; + + case 16 ... 25: + return 0x02; + + case 26 ... 35: + return 0x06; + + case 36 ... 45: + return 0x04; + + case 46 ... 55: + return 0x0C; + + case 56 ... 65: + return 0x08; + + case 66 ... 75: + return 0x18; + + case 76 ... 85: + return 0x10; + + case 86 ... 95: + return 0x30; + + case 96 ... 100: + return 0x20; + + default: + return 0x20; + } } static uint8_t img_gen_dot20(uint8_t percent) { - if(percent<11) return 0x01; - else if(percent<31) return 0x02; - else if(percent<51) return 0x04; - else if(percent<71) return 0x08; - else if(percent<91) return 0x10; - else return 0x20; + switch(percent) + { + case 0 ... 10: + return 0x01; + + case 11 ... 30: + return 0x02; + + case 31 ... 50: + return 0x04; + + case 51 ... 70: + return 0x08; + + case 71 ... 90: + return 0x10; + + case 91 ... 100: + return 0x20; + + default: + return 0x20; + } } static uint8_t img_gen_bar(uint8_t percent) { - if(percent<11) return 0x01; - else if(percent<31) return 0x03; - else if(percent<51) return 0x07; - else if(percent<71) return 0x0F; - else if(percent<91) return 0x1F; - else return 0x3F; + switch(percent) + { + case 0 ... 10: + return 0x01; + + case 11 ... 30: + return 0x03; + + case 31 ... 50: + return 0x07; + + case 51 ... 70: + return 0x0F; + + case 71 ... 90: + return 0x1F; + + case 91 ... 100: + return 0x3F; + + default: + return 0x3F; + } } diff --git a/firmware/src/dccd/dccd.h b/firmware/src/dccd/dccd.h index a723aa2..bacd4db 100644 --- a/firmware/src/dccd/dccd.h +++ b/firmware/src/dccd/dccd.h @@ -14,12 +14,13 @@ class DccdApp DccdApp(void); ~DccdApp(void); - void init(void); + void init(DccdHw* dccd_hw); void process(void); uint16_t lock_current; uint16_t max_hbrake_time; - uint16_t btn_repeat_time; + uint16_t btn_force_repeat_time; + uint16_t btn_mode_repeat_time; uint8_t button_inputs; uint8_t display_brigth; uint8_t display_dimm; @@ -28,10 +29,13 @@ class DccdApp uint8_t pot_force; uint8_t brake_mode; + uint8_t loadMemCfg(void); + void saveMemCfg(void); + #ifdef TESTING protected: #endif - dccd::DccdHw hardware; + DccdHw* hardware; }; /**** Public function declarations ****/ diff --git a/firmware/src/dccd/dccd_hw.cpp b/firmware/src/dccd/dccd_hw.cpp index 7bceec4..4270771 100644 --- a/firmware/src/dccd/dccd_hw.cpp +++ b/firmware/src/dccd/dccd_hw.cpp @@ -6,6 +6,37 @@ using namespace dccd; /**** Private definitions ****/ /**** Private constants ****/ +static const uint8_t def_dbnc_time = 10; + +static const uint16_t def_pot_dead_bot = 500; +static const uint16_t def_pot_dead_top = 4500; + +static const uint8_t def_cc_mode_en = 1; + +static const uint16_t def_cnter_us = 900; + +static const uint16_t def_out_voltage_under_treshold = 0; +static const uint16_t def_out_voltage_over_treshold = 9000; +static const uint16_t def_out_voltage_hold_time = 1000; +static const uint16_t def_out_voltage_cooldown_time = 0; + +static const uint16_t def_out_current_under_treshold = 0; +static const uint16_t def_out_current_over_treshold = 6000; +static const uint16_t def_out_current_hold_time = 200; +static const uint16_t def_out_current_cooldown_time = 1000; + +static const uint16_t def_battery_voltage_under_treshold = 9000; +static const uint16_t def_battery_voltage_over_treshold = 18000; +static const uint16_t def_battery_voltage_hold_time = 1000; +static const uint16_t def_battery_voltage_cooldown_time = 0; + +static const uint16_t def_battery_current_under_treshold = 0; +static const uint16_t def_battery_current_over_treshold = 8000; +static const uint16_t def_battery_current_hold_time = 200; +static const uint16_t def_battery_current_cooldown_time = 1000; + +static const uint16_t def_inital_bat_voltage = 12000; + /**** Private variables ****/ /**** Private function declarations ****/ /**** Public function definitions ****/ @@ -20,66 +51,68 @@ dccd::DccdHw::~DccdHw(void) } void dccd::DccdHw::init(dccdHwCfg_t* cfg) -{ +{ + // Apply config bsp::Board::boardCfg_t board_cfg; board_cfg.pwm_f_khz = cfg->pwm_f_khz; board_cfg.od_common_is_pwm = 1; this->board_hw.init(&board_cfg); - this->counter.init(0xFFFF, 900); + this->counter.init(0xFFFF, cfg->counter_step_us); + this->counter.disabled = 0; this->out_voltage.init(&(this->board_hw.out_voltage), &(this->counter)); - this->out_voltage.under_treshold = 0; - this->out_voltage.over_treshold = 9000; - this->out_voltage.hold_time = 1000; - this->out_voltage.cooldown_time = 0; + this->out_voltage.under_treshold = def_out_voltage_under_treshold; + this->out_voltage.over_treshold = def_out_voltage_over_treshold; + this->out_voltage.hold_time = def_out_voltage_hold_time; + this->out_voltage.cooldown_time = def_out_voltage_cooldown_time; this->out_voltage.update_ain = 0; this->out_voltage.auto_reset = 1; this->out_current.init(&(this->board_hw.out_current), &(this->counter)); - this->out_current.under_treshold = 0; - this->out_current.over_treshold = 6000; - this->out_current.hold_time = 200; - this->out_current.cooldown_time = 1000; + this->out_current.under_treshold = def_out_current_under_treshold; + this->out_current.over_treshold = def_out_current_over_treshold; + this->out_current.hold_time = def_out_current_hold_time; + this->out_current.cooldown_time = def_out_current_cooldown_time; this->out_current.update_ain = 0; this->out_current.auto_reset = 1; this->battery_voltage.init(&(this->board_hw.battery_voltage), &(this->counter)); - this->battery_voltage.under_treshold = 9000; - this->battery_voltage.over_treshold = 18000; - this->battery_voltage.hold_time = 1000; - this->battery_voltage.cooldown_time = 0; + this->battery_voltage.under_treshold = def_battery_voltage_under_treshold; + this->battery_voltage.over_treshold = def_battery_voltage_over_treshold; + this->battery_voltage.hold_time = def_battery_voltage_hold_time; + this->battery_voltage.cooldown_time = def_battery_voltage_cooldown_time; this->battery_voltage.update_ain = 0; this->battery_voltage.auto_reset = 1; - this->battery_voltage.last_read = 12000; + this->battery_voltage.last_read = def_inital_bat_voltage; this->battery_current.init(&(this->board_hw.battery_current), &(this->counter)); - this->battery_current.under_treshold = 0; - this->battery_current.over_treshold = 8000; - this->battery_current.hold_time = 200; - this->battery_current.cooldown_time = 1000; + this->battery_current.under_treshold = def_battery_current_under_treshold; + this->battery_current.over_treshold = def_battery_current_over_treshold; + this->battery_current.hold_time = def_battery_current_hold_time; + this->battery_current.cooldown_time = def_battery_current_cooldown_time; this->battery_current.update_ain = 0; this->battery_current.auto_reset = 1; - this->btn_up.init(&(this->board_hw.din4), 0, &(this->counter), 10); + this->btn_up.init(&(this->board_hw.din4), 0, &(this->counter), def_dbnc_time); this->btn_up.update_din = 0; - this->btn_down.init(&(this->board_hw.din3), 0, &(this->counter), 10); + this->btn_down.init(&(this->board_hw.din3), 0, &(this->counter), def_dbnc_time); this->btn_down.update_din = 0; - this->btn_mode.init(&(this->board_hw.din1), 0, &(this->counter), 10); + this->btn_mode.init(&(this->board_hw.din1), 0, &(this->counter), def_dbnc_time); this->btn_mode.update_din = 0; - this->handbrake.init(&(this->board_hw.hvdin3), 0, &(this->counter), 10); + this->handbrake.init(&(this->board_hw.hvdin3), 0, &(this->counter), def_dbnc_time); this->handbrake.update_din = 0; - this->brakes.init(&(this->board_hw.hvdin2), 1, &(this->counter), 10); + this->brakes.init(&(this->board_hw.hvdin2), 1, &(this->counter), def_dbnc_time); this->brakes.update_din = 0; - this->dimm.init(&(this->board_hw.hvdin1), 1, &(this->counter), 10); + this->dimm.init(&(this->board_hw.hvdin1), 1, &(this->counter), def_dbnc_time); this->dimm.update_din = 0; - this->pot.init(&(this->board_hw.ain2), 500, 4500); + this->pot.init(&(this->board_hw.ain2), def_pot_dead_bot, def_pot_dead_top); this->pot.update_ain = 0; hw::OutReg::outRegCfg_t outreg_cfg; @@ -89,6 +122,8 @@ void dccd::DccdHw::init(dccdHwCfg_t* cfg) outreg_cfg.uout = &this->board_hw.out_voltage; outreg_cfg.iout = &this->board_hw.out_current; this->outreg.init(&outreg_cfg); + this->outreg.cc_mode_en = def_cc_mode_en; + this->outreg.update_ain = 0; hw::LedDisplay::doutCfg_t dsp_cfg; dsp_cfg.led0_dout_ch = &(this->board_hw.od1); @@ -114,12 +149,10 @@ void dccd::DccdHw::init(dccdHwCfg_t* cfg) else this->board_hw.freq_pull.write(0); // Set initial output states - this->outreg.voltage = 0; - this->outreg.current = 0; - this->outreg.out_on = 0; - this->outreg.lock = 0; - this->outreg.cc_mode_en = 0; - this->outreg.update_ain = 0; + this->outreg.write_voltage(0); + this->outreg.write_current(0); + this->outreg.write_on(0); + this->outreg.write_lock(0); this->outreg.process(); this->display.write_backlight(100); diff --git a/firmware/src/dccd/dccd_hw.h b/firmware/src/dccd/dccd_hw.h index 6ed8897..3ccdd0c 100644 --- a/firmware/src/dccd/dccd_hw.h +++ b/firmware/src/dccd/dccd_hw.h @@ -22,6 +22,7 @@ class DccdHw uint8_t pwm_f_khz; uint8_t handbrake_pull_up; uint8_t speed_hall; + uint16_t counter_step_us; } dccdHwCfg_t; DccdHw(void); diff --git a/firmware/src/hw/led_display.cpp b/firmware/src/hw/led_display.cpp index 867e7f0..ac525f4 100644 --- a/firmware/src/hw/led_display.cpp +++ b/firmware/src/hw/led_display.cpp @@ -41,6 +41,7 @@ void hw::LedDisplay::init(doutCfg_t* dout_chs, uint8_t act_lvl, util::VCounter* this->cycle_cnt = 0; this->cycle_limit = 0; this->timestamp_start = 0; + this->image = 0x00; this->force(0x00); this->write_backlight(0); @@ -83,9 +84,10 @@ void hw::LedDisplay::write(uint8_t image) this->cycle_cnt = 0; this->cycle_limit = 0; this->timestamp_start = 0; + this->image = image; // Set initial state - this->force(image); + this->force(this->image); } void hw::LedDisplay::write(uint8_t image, uint16_t on_time, uint16_t period, uint8_t cycle_limit) @@ -95,9 +97,10 @@ void hw::LedDisplay::write(uint8_t image, uint16_t on_time, uint16_t period, uin this->period = period; this->cycle_cnt = 0; this->cycle_limit = cycle_limit; + this->image = image; // Set initial state - if(this->on_time > 0) this->force(image); + if(this->on_time > 0) this->force(this->image); else this->force(0x00); // Cycle start time diff --git a/firmware/src/hw/out_reg.cpp b/firmware/src/hw/out_reg.cpp index 2e9f8ff..da62478 100644 --- a/firmware/src/hw/out_reg.cpp +++ b/firmware/src/hw/out_reg.cpp @@ -35,6 +35,39 @@ void hw::OutReg::init(outRegCfg_t* cfg) this->cc_mode_en = 0; this->update_ain = 0; + this->cc_tolerance = 75; +} + +void hw::OutReg::write_voltage(uint16_t voltage) +{ + this->voltage = voltage; +} + +void hw::OutReg::write_current(uint16_t current) +{ + this->current = current; + this->current_bot = util::sat_subtract(current, this->cc_tolerance); + this->current_top = util::sat_add(current, this->cc_tolerance); +} + +void hw::OutReg::write_on(uint8_t state) +{ + this->out_on = state; +} + +void hw::OutReg::write_lock(uint8_t state) +{ + this->lock = state; +} + +uint16_t hw::OutReg::read_voltage(void) +{ + return this->voltage; +} + +uint16_t hw::OutReg::read_current(void) +{ + return this->current; } void hw::OutReg::process(void) @@ -61,20 +94,23 @@ void hw::OutReg::process(void) }; // Calculate next duty cycle setting - uint16_t next_duty; + uint16_t next_duty = this->pwm_high->get_set_duty(); if((this->voltage==0)||(this->current==0)) { // Off but not HiZ next_duty = 0; } - else if((this->cc_mode_en)&&(this->iout->last_read > this->current)) + else if((this->cc_mode_en)&&(this->iout->last_read > this->current_bot)) { - // Constant current mode - // Reduce voltage to be within current limit - uint32_t temp = (uint32_t)this->pwm_high->get_set_duty() * (uint32_t)this->current; - temp /= this->iout->last_read; - next_duty = util::sat_cast(temp); + // Constant current mode - Change voltage to be within current limit + if(util::is_in_range(this->iout->last_read, this->current_bot, this->current_top)==0) + { + // Current outside of tolerance. Recalculate duty cycle. + uint32_t temp = (uint32_t)this->pwm_high->get_set_duty() * (uint32_t)this->current; + temp /= this->iout->last_read; + next_duty = util::sat_cast(temp); + }; } else { diff --git a/firmware/src/hw/out_reg.h b/firmware/src/hw/out_reg.h index 2b93ab1..54ca57a 100644 --- a/firmware/src/hw/out_reg.h +++ b/firmware/src/hw/out_reg.h @@ -25,13 +25,17 @@ class OutReg void init(outRegCfg_t* cfg); - uint16_t voltage; - uint16_t current; - uint8_t out_on; - uint8_t lock; - uint8_t cc_mode_en; uint8_t update_ain; + uint16_t cc_tolerance; + + void write_voltage(uint16_t voltage); + void write_current(uint16_t current); + void write_on(uint8_t state); + void write_lock(uint8_t state); + + uint16_t read_voltage(void); + uint16_t read_current(void); void process(void); void force_off(void); @@ -44,6 +48,12 @@ class OutReg bsp::AnalogIn* ubat; bsp::AnalogIn* uout; bsp::AnalogIn* iout; + uint16_t voltage; + uint16_t current; + uint16_t current_top; + uint16_t current_bot; + uint8_t out_on; + uint8_t lock; }; /**** Public function declarations ****/ diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index 2da7942..f1f6d4c 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -1,38 +1,56 @@ /**** Includes ****/ #include "utils/utils.h" +#include "dccd/dccd_hw.h" #include "dccd/dccd.h" /**** Private definitions ****/ /**** Private constants ****/ /**** Private variables ****/ +static dccd::DccdHw dccd_hw; +static dccd::DccdApp app; /**** Private function declarations ****/ /**** Public function definitions ****/ int main(void) { // Setup - dccd::DccdApp dccd_app; + dccd::DccdHw::dccdHwCfg_t cfg; + cfg.handbrake_pull_up = 1; + cfg.pwm_f_khz = 16; + cfg.speed_hall = 0; + cfg.counter_step_us = 2000; + dccd_hw.init(&cfg); - dccd_app.init(); + app.init(&dccd_hw); - dccd_app.lock_current = 4500; - dccd_app.max_hbrake_time = 1000; - dccd_app.btn_repeat_time = 500; - dccd_app.button_inputs = 1; - dccd_app.display_brigth = 100; - dccd_app.display_dimm = 50; + //#define OVERRIDECFG + #ifdef OVERRIDECFG + // Configuration + app.lock_current = 4500; + app.max_hbrake_time = 2000; + app.button_inputs = 1; + app.display_brigth = 100; + app.display_dimm = 25; - dccd_app.btn_force = 0; - dccd_app.pot_force = 0; - dccd_app.brake_mode = 0; + // Initial values + app.btn_force = 0; + app.brake_mode = 0; + #endif + + // Save config to memory + //#define SAVECFG + #ifdef SAVECFG + app.saveMemCfg(); + #endif // Super loop while(1) { - dccd_app.process(); - - continue; // End of super loop + // Do stuff + app.process(); + // End of super loop + continue; } // Escape the matrix diff --git a/firmware/src/uDCCD.cppproj b/firmware/src/uDCCD.cppproj index 7919a1a..983558e 100644 --- a/firmware/src/uDCCD.cppproj +++ b/firmware/src/uDCCD.cppproj @@ -40,6 +40,22 @@ + com.atmel.avrdbg.tool.atmelice + J42700001490 + 0x1E9516 + + + + 249992 + + ISP + + com.atmel.avrdbg.tool.atmelice + J42700001490 + Atmel-ICE + + ISP + 249992