#include "bsp/gpio.h" #include "bsp/mcu_power_sleep.h" #include "libs/shark_task.h" #include "libs/logger.h" #include "state.h" #include "health.h" #include "iostate.h" extern void bms_message_update_insert(int is_hall_detect); static io_state_t _io_state; typedef struct io_timer{ shark_timer_t _timer; u16 detect_cnt; u8 value; u16 debounce_time_zero; u16 debounce_time_one; }io_timer_t; #define io_detect_intv_time 1 #define io_debounce_time 50 static void io_timer_handler(shark_timer_t *t); static io_timer_t hall_io = {._timer.handler = io_timer_handler, .debounce_time_zero = 500, .debounce_time_one = 50}; static io_timer_t charger_io = {._timer.handler = io_timer_handler, .debounce_time_zero = 50, .debounce_time_one = 50}; static io_timer_t aux_short_io = {._timer.handler = io_timer_handler, .debounce_time_zero = 50, .debounce_time_one = 50}; static io_timer_t dcdc_pwr_io = {._timer.handler = io_timer_handler, .debounce_time_zero = 50, .debounce_time_one = 50}; void iostate_log(void){ io_debug("Hall:%d, %d, %d\n", _io_state.hall_detect, IS_HALL1_DETECTED(), IS_HALL2_DETECTED()); io_debug("AuxLocked:%d\n", _io_state.aux_lock_detect); io_debug("ChargDet:%d\n", _io_state.charger_detect); io_debug("DcdcGood:%d\n", _io_state.dcdc_good_detect); } void io_state_init(void){ set_log_level(MOD_IO, L_debug); hall_io.value = _io_state.hall_detect = IS_HALL1_DETECTED()|| IS_HALL2_DETECTED(); charger_io.value = _io_state.charger_detect = IS_CHARGER_IN(); dcdc_pwr_io.value = _io_state.dcdc_good_detect= IS_DCDC_POWER_GOOD(); aux_short_io.value = _io_state.aux_lock_detect = IS_AUX_VOL_LOCKED() && AUX_VOL_IS_OPEN(); shark_timer_post(&hall_io._timer, io_detect_intv_time); shark_timer_post(&charger_io._timer, io_detect_intv_time); shark_timer_post(&aux_short_io._timer, io_detect_intv_time); shark_timer_post(&dcdc_pwr_io._timer, io_detect_intv_time); small_current_short_irq_enable(1); charger_detect_irq_enable(1); hall_1_detect_irq_enable(1); hall_2_detect_irq_enable(1); bms_message_update_insert(_io_state.hall_detect); iostate_log(); } io_state_t *io_state(void){ return &_io_state; } static int _get_io_value(io_timer_t *t){ if (t == &hall_io) { return IS_HALL1_DETECTED()|| IS_HALL2_DETECTED(); } if (t == &charger_io){ return IS_CHARGER_IN(); } if (t == &aux_short_io){ return IS_AUX_VOL_LOCKED() && AUX_VOL_IS_OPEN(); } if (t == &dcdc_pwr_io){ return IS_DCDC_POWER_GOOD(); } return -1; } static int _get_cached_value(io_timer_t *t){ if (t == &hall_io) { return _io_state.hall_detect; } if (t == &charger_io){ return _io_state.charger_detect; } if (t == &aux_short_io){ return _io_state.aux_lock_detect; } if (t == &dcdc_pwr_io){ return _io_state.dcdc_good_detect; } return -1; } static void _set_io_value(io_timer_t *t){ if (t == &hall_io) { _io_state.hall_detect = t->value; } if (t == &charger_io){ _io_state.charger_detect = t->value; } if (t == &dcdc_pwr_io){ _io_state.dcdc_good_detect = t->value; } if (t == &aux_short_io){ _io_state.aux_lock_detect = t->value; } } static int _debounce_time_reach(io_timer_t *t){ u16 debounce_time = t->debounce_time_one; if (t->value == 0){ debounce_time = t->debounce_time_zero; } return t->detect_cnt >= debounce_time; } static void io_timer_handler(shark_timer_t *t){ io_timer_t *io_t = (io_timer_t *)t; int aux_lock_changed = 0; if (io_t->value == _get_io_value(io_t)){ io_t->detect_cnt ++; }else{ io_t->value = _get_io_value(io_t); io_t->detect_cnt = 0; } if (_debounce_time_reach(io_t)){ io_t->detect_cnt = 0; if (_get_cached_value(io_t) != io_t->value) { _set_io_value(io_t); if (io_t == &aux_short_io){ aux_lock_changed = 1; } if (io_t == &hall_io){ bms_message_update_insert(_io_state.hall_detect); } } } shark_timer_post(t, io_detect_intv_time); if (io_t == &aux_short_io && aux_lock_changed){ health_process_aux_lock(); } } static void charger_detect_irq_timer_handler(shark_timer_t *t){ _io_state.charger_detect_irq = 0; io_warning("clear charger detect irq\n"); } static void small_current_irq_timer_handler(shark_timer_t *t){ aux_short_io.value = _io_state.aux_lock_detect = IS_AUX_VOL_LOCKED() && AUX_VOL_IS_OPEN(); aux_short_io.detect_cnt = 0; health_process_aux_lock(); } static shark_timer_t _small_current_irq_timer = {.handler = small_current_irq_timer_handler}; static shark_timer_t _charger_detect_irq_timer = {.handler = charger_detect_irq_timer_handler}; void small_current_short_irq_handler(void){ if (!AUX_VOL_IS_OPEN()){ //io_debug("close aux power,cause the short irq\n"); return; } mcu_sleep_set_wakeup_source(WAKEUP_SOURCE_SMALL_POWER_SHORT); _io_state.aux_lock_irq = 1; shark_timer_post(&_small_current_irq_timer, 0); //io_debug("aux lock irq\n"); } void charger_detect_irq_handler(void){ mcu_sleep_set_wakeup_source(WAKEUP_SOURCE_CHARGER); _io_state.charger_detect_irq = 1; shark_timer_post(&_charger_detect_irq_timer, CHARGER_DETECT_IRQ_CLEAR_TIMEOUT);//延时一段时间给充电判断充足的时间 io_warning("charger detect irq\n"); } void hall1_detect_irq_handler(void){ mcu_sleep_set_wakeup_source(WAKEUP_SOURCE_HALL1); } void hall2_detect_irq_handler(void){ mcu_sleep_set_wakeup_source(WAKEUP_SOURCE_HALL2); } #if 0 void dcdc_pwr_detect_irq_handler(void) { dcdc_pwr_io.value = IS_DCDC_POWER_GOOD(); dcdc_pwr_io.detect_cnt = 0; shark_timer_post(&dcdc_pwr_io._timer, 0); dcdc_pwr_detect_irq_enable(0); io_debug("dcdc lock irq"); } #endif