|
@@ -8,29 +8,100 @@
|
|
|
#include "iostate.h"
|
|
#include "iostate.h"
|
|
|
|
|
|
|
|
static bms_state_t _bms_state;
|
|
static bms_state_t _bms_state;
|
|
|
|
|
+static shark_task_t _bms_main_task;
|
|
|
static void _current_notify(void);
|
|
static void _current_notify(void);
|
|
|
static void _voltage_notify(void);
|
|
static void _voltage_notify(void);
|
|
|
static void _temperature_notify(void);
|
|
static void _temperature_notify(void);
|
|
|
|
|
+static u32 _bms_main_task_handler(void);
|
|
|
|
|
|
|
|
void bms_state_init(void){
|
|
void bms_state_init(void){
|
|
|
_bms_state.cell_index_of_max_vol = 0xff;
|
|
_bms_state.cell_index_of_max_vol = 0xff;
|
|
|
|
|
+ _bms_main_task.handler = _bms_main_task_handler;
|
|
|
measure_task_init(_current_notify, _voltage_notify, _temperature_notify);
|
|
measure_task_init(_current_notify, _voltage_notify, _temperature_notify);
|
|
|
io_state_init();
|
|
io_state_init();
|
|
|
health_init();
|
|
health_init();
|
|
|
|
|
+ shark_task_add(&_bms_main_task);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bms_state_t *bms_state_get(void){
|
|
bms_state_t *bms_state_get(void){
|
|
|
return &_bms_state;
|
|
return &_bms_state;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static debounce_t _charging_detect = {.count = 0, .max_count = 10};
|
|
|
|
|
-static void check_charging(){
|
|
|
|
|
- if (bms_health()->charger_over_current || bms_health()->load_current_short) {
|
|
|
|
|
|
|
+#define Health_Success 0
|
|
|
|
|
+#define Health_Discharger_Failt 1
|
|
|
|
|
+#define Health_charger_Fault 2
|
|
|
|
|
+#define Health_aux_Fault 4
|
|
|
|
|
+
|
|
|
|
|
+static s32 _process_unheath(void){
|
|
|
|
|
+ if (bms_health()->load_current_short) {//短路检测后,关闭充放电mos
|
|
|
ml5238_enable_discharger_mosfet(0);
|
|
ml5238_enable_discharger_mosfet(0);
|
|
|
ml5238_enable_charger_mosfet(0); //disable charger mosfet
|
|
ml5238_enable_charger_mosfet(0); //disable charger mosfet
|
|
|
_bms_state.charging = 0;
|
|
_bms_state.charging = 0;
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ _bms_state.discharging = 0;
|
|
|
|
|
+ return (Health_Discharger_Failt | Health_charger_Fault);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (bms_health()->charger_over_current || bms_health()->charger_over_temp || bms_health()->charger_lower_temp){
|
|
|
|
|
+ ml5238_enable_charger_mosfet(0); //disable charger mosfet
|
|
|
|
|
+ _bms_state.charging = 0;
|
|
|
|
|
+ return Health_charger_Fault;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (bms_health()->discharger_over_temp || bms_health()->discharger_lower_temp || bms_health()->discharger_lower_voltage){
|
|
|
|
|
+ ml5238_enable_discharger_mosfet(0); //disable charger mosfet
|
|
|
|
|
+ _bms_state.discharging = 0;
|
|
|
|
|
+ return Health_Discharger_Failt;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (io_state()->aux_lock_detect && AUX_VOL_IS_OPEN()) {
|
|
|
|
|
+ AUX_VOL_OPEN(0);
|
|
|
|
|
+ return Health_aux_Fault;
|
|
|
|
|
+ }
|
|
|
|
|
+ return Health_Success;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+//处理PS100/310/320/360,充电底座,充电柜的指令或者bms自己发给自己的指令
|
|
|
|
|
+static void _process_user_request(s32 health){
|
|
|
|
|
+ if (_bms_state.user_request & USER_REQUEST_PENDING){
|
|
|
|
|
+ if ((health & Health_charger_Fault) == 0){
|
|
|
|
|
+ ml5238_enable_charger_mosfet(!!(_bms_state.user_request & USER_REQUEST_CHARGER));
|
|
|
|
|
+ }
|
|
|
|
|
+ if ((health & Health_Discharger_Failt) == 0){
|
|
|
|
|
+ ml5238_enable_discharger_mosfet(!!(_bms_state.user_request & USER_REQUEST_DISCHARGER));
|
|
|
|
|
+ }
|
|
|
|
|
+ if ((health & Health_aux_Fault) == 0){
|
|
|
|
|
+ AUX_VOL_OPEN(!!(_bms_state.user_request & USER_REQUEST_SMALLCURRENT));
|
|
|
|
|
+ }
|
|
|
|
|
+ _bms_state.user_request = 0;//clear user request
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void _process_power_down(void){
|
|
|
|
|
+ if (bms_health()->powerdown_lower_voltage){
|
|
|
|
|
+ ml5238_enable_charger_detect(1);
|
|
|
|
|
+ delay_us(2* 1000);
|
|
|
|
|
+ if (!ml5238_charger_is_disconnect()){//have charger, do'nt power down
|
|
|
|
|
+ bms_health()->powerdown_lower_voltage = 0;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ AUX_VOL_OPEN(0);
|
|
|
|
|
+ CS1180_PWR_ENABLE(0);
|
|
|
|
|
+ ml5238_enable_discharger_mosfet(0);
|
|
|
|
|
+ ml5238_enable_charger_mosfet(0);
|
|
|
|
|
+ ml5238_power_down();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static u32 _bms_main_task_handler(void){
|
|
|
|
|
+ s32 unhealth = _process_unheath();
|
|
|
|
|
+ _process_user_request(unhealth);
|
|
|
|
|
+ _process_power_down();
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static debounce_t _charging_detect = {.count = 0, .max_count = 10};
|
|
|
|
|
+static void check_charging(){
|
|
|
if (!_bms_state.charging) {
|
|
if (!_bms_state.charging) {
|
|
|
if (measure_value()->load_current >= MIN_START_CHARGER_CURRENT) {
|
|
if (measure_value()->load_current >= MIN_START_CHARGER_CURRENT) {
|
|
|
debounce_inc(_charging_detect);
|
|
debounce_inc(_charging_detect);
|
|
@@ -62,12 +133,12 @@ static void _current_notify(void){
|
|
|
check_charging();
|
|
check_charging();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 充电电流小于一定值,认为充满的时候,需要检查电芯的电压,如果发现有电芯电压过高,需要开启被动均衡
|
|
|
|
|
|
|
+/* 需要检查电芯的电压,如果发现有电芯电压过高,需要开启被动均衡
|
|
|
* 充电过程中考虑balance,主要是希望cell 电压扩散后,保证1. 单电芯不能过压, 2. 单电芯不能比平均电压过低,导致
|
|
* 充电过程中考虑balance,主要是希望cell 电压扩散后,保证1. 单电芯不能过压, 2. 单电芯不能比平均电压过低,导致
|
|
|
* 木桶效应,目标是电压最高的那个cell,尽量压制,不让电压再升高,或者升高的尽量慢一些
|
|
* 木桶效应,目标是电压最高的那个cell,尽量压制,不让电压再升高,或者升高的尽量慢一些
|
|
|
*/
|
|
*/
|
|
|
static debounce_t _cell_balance = {.count = 10, .max_count = 20};
|
|
static debounce_t _cell_balance = {.count = 10, .max_count = 20};
|
|
|
-static void check_cell_balance(void){
|
|
|
|
|
|
|
+static void check_cell_balance(uint8_t current_max_index){
|
|
|
if (!_bms_state.charging){ //not charging, need not do balance
|
|
if (!_bms_state.charging){ //not charging, need not do balance
|
|
|
if (_bms_state.pack_balancing){
|
|
if (_bms_state.pack_balancing){
|
|
|
_bms_state.pack_balancing = 0;
|
|
_bms_state.pack_balancing = 0;
|
|
@@ -76,7 +147,9 @@ static void check_cell_balance(void){
|
|
|
}
|
|
}
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+ if (!_bms_state.pack_balancing && _bms_state.cell_min_vol < CELL_FUSION_VOLTAGE){
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
if (_bms_state.cell_max_vol - _bms_state.cell_min_vol >= MAX_DIFF_BETWEEN_MIN_MAX_CELL){
|
|
if (_bms_state.cell_max_vol - _bms_state.cell_min_vol >= MAX_DIFF_BETWEEN_MIN_MAX_CELL){
|
|
|
debounce_inc(_cell_balance);
|
|
debounce_inc(_cell_balance);
|
|
|
}else {
|
|
}else {
|
|
@@ -88,9 +161,13 @@ static void check_cell_balance(void){
|
|
|
_bms_state.pack_balancing = 0;
|
|
_bms_state.pack_balancing = 0;
|
|
|
ml5238_cell_start_balance(0);
|
|
ml5238_cell_start_balance(0);
|
|
|
}
|
|
}
|
|
|
|
|
+ if (_bms_state.pack_balancing && (current_max_index != _bms_state.cell_index_of_max_vol)){
|
|
|
|
|
+ ml5238_cell_start_balance(BIT(current_max_index));
|
|
|
|
|
+ }
|
|
|
|
|
+ _bms_state.cell_index_of_max_vol = current_max_index;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void _voltage_notify(void){
|
|
|
|
|
|
|
+static uint8_t calc_cell_voltage(void){
|
|
|
uint16_t voltage = 0;
|
|
uint16_t voltage = 0;
|
|
|
uint16_t max_cell = 0;
|
|
uint16_t max_cell = 0;
|
|
|
uint16_t min_cell = 0xf000;
|
|
uint16_t min_cell = 0xf000;
|
|
@@ -108,12 +185,13 @@ static void _voltage_notify(void){
|
|
|
_bms_state.pack_voltage = voltage;
|
|
_bms_state.pack_voltage = voltage;
|
|
|
_bms_state.cell_max_vol = max_cell;
|
|
_bms_state.cell_max_vol = max_cell;
|
|
|
_bms_state.cell_min_vol = min_cell;
|
|
_bms_state.cell_min_vol = min_cell;
|
|
|
|
|
+ return max_index;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void _voltage_notify(void){
|
|
|
|
|
+ uint8_t max_index = calc_cell_voltage();
|
|
|
check_voltage_state(); //check health of cell voltage
|
|
check_voltage_state(); //check health of cell voltage
|
|
|
- check_cell_balance();
|
|
|
|
|
- if (_bms_state.pack_balancing && (max_index != _bms_state.cell_index_of_max_vol)){
|
|
|
|
|
- ml5238_cell_start_balance(BIT(max_index));
|
|
|
|
|
- }
|
|
|
|
|
- _bms_state.cell_index_of_max_vol = max_index;
|
|
|
|
|
|
|
+ check_cell_balance(max_index);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void _temperature_notify(void){
|
|
static void _temperature_notify(void){
|