#include "bsp/gpio.h" #include "libs/shark_task.h" #include "state.h" #include "iostate.h" typedef struct io_timer{ shark_timer_t _timer; u16 detect_cnt; u8 value; }io_timer_t; #define io_detect_intv_time 1 #define io_debounce_time 50 static io_timer_t hall_io; static io_timer_t charger_io; static io_timer_t aux_short_io; static io_timer_t dcdc_pwr_io; static void io_timer_handler(shark_timer_t *t); void io_state_init(void){ bms_state_get()->hall_detect = IS_HALL1_DETECTED()|| IS_HALL2_DETECTED(); bms_state_get()->charger_detect = IS_CHARGER_IN(); bms_state_get()->dcdc_good_detect= IS_DCDC_POWER_GOOD(); bms_state_get()->aux_lock_detect = IS_AUX_VOL_LOCKED(); hall_io._timer.handler = io_timer_handler; charger_io._timer.handler = io_timer_handler; aux_short_io._timer.handler = io_timer_handler; dcdc_pwr_io._timer.handler = io_timer_handler; 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); } 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(); } if (t == &dcdc_pwr_io){ return IS_DCDC_POWER_GOOD(); } return -1; } static void _set_io_value(io_timer_t *t){ __disable_irq(); if (t == &hall_io) { bms_state_get()->hall_detect = t->value; hall_1_detect_irq_enable(1); hall_2_detect_irq_enable(1); } if (t == &charger_io){ bms_state_get()->charger_detect = t->value; charger_detect_irq_enable(1); } if (t == &aux_short_io){ bms_state_get()->aux_lock_detect = t->value; small_current_short_irq_enable(1); } if (t == &dcdc_pwr_io){ bms_state_get()->dcdc_good_detect = t->value; dcdc_pwr_detect_irq_enable(1); } /* 可以解决丢中断的风险,如果开启中断的过程中,来IO中断,这个中断可能会被丢弃, * 所以,我们这里要再次检查io的状态和代码保存的状态是否一致,如果不一致需要重新 * 启动定时间 */ if (t->value != _get_io_value(t)){ shark_timer_post(&t->_timer, io_detect_intv_time); } __enable_irq(); } static void io_timer_handler(shark_timer_t *t){ io_timer_t *io_t = (io_timer_t *)t; 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 (io_t->detect_cnt >= io_debounce_time){ io_t->detect_cnt = 0; _set_io_value(io_t); }else{ shark_timer_post(t, io_detect_intv_time); } } void charger_detect_irq_handler(void){ charger_io.value = IS_CHARGER_IN(); charger_io.detect_cnt = 0; shark_timer_post(&charger_io._timer, io_detect_intv_time); charger_detect_irq_enable(0); } void hall1_detect_irq_handler(void){ hall_io.value = IS_HALL1_DETECTED()|| IS_HALL2_DETECTED(); hall_io.detect_cnt = 0; shark_timer_post(&hall_io._timer, io_detect_intv_time); hall_1_detect_irq_enable(0); } void hall2_detect_irq_handler(void){ hall_io.value = IS_HALL1_DETECTED()|| IS_HALL2_DETECTED(); hall_io.detect_cnt = 0; shark_timer_post(&hall_io._timer, io_detect_intv_time); hall_2_detect_irq_enable(0); } void small_current_short_handler(void){ aux_short_io.value = IS_AUX_VOL_LOCKED(); aux_short_io.detect_cnt = 0; shark_timer_post(&aux_short_io._timer, io_detect_intv_time); small_current_short_irq_enable(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, io_detect_intv_time); dcdc_pwr_detect_irq_enable(0); }