|
|
@@ -7,6 +7,9 @@
|
|
|
#include "bsp/temp_lookup_tab.h"
|
|
|
#include "bsp/shark_bsp.h"
|
|
|
#include "libs/logger.h"
|
|
|
+#include "Least_Square.h"
|
|
|
+#include "app/sox/state.h"
|
|
|
+
|
|
|
/* measure the temp & current & voltage for battery pack by using
|
|
|
* ms5238 & cs1180(only used when bms is in small current loading)
|
|
|
*/
|
|
|
@@ -27,6 +30,17 @@ static float imon_gain_now;
|
|
|
static float vim0_10x = 0.0f;
|
|
|
static float vim0_50x = 0.0f;
|
|
|
static float vim0_now;
|
|
|
+static float ml5238_10x_a = 1.0f;
|
|
|
+static float ml5238_50x_a = 1.0f;
|
|
|
+
|
|
|
+static float ml5238_10x_b = 0.0f;
|
|
|
+static float ml5238_50x_b = 0.0f;
|
|
|
+
|
|
|
+static float ml5238_now_a = 1.0f;
|
|
|
+static float ml5238_now_b = 0.0f;
|
|
|
+
|
|
|
+static float cs1180_a = 1.0f;
|
|
|
+static float cs1180_b = 0.0f;
|
|
|
|
|
|
#define gain_default_50x 1
|
|
|
#define CS1180_MAX_CURRENT 4500 //MA, cs1180的最大电流,超过这个使用ML5238
|
|
|
@@ -37,6 +51,7 @@ static const float max_gd_adc = 4095.0f;//65536.0f;
|
|
|
static const float v_cs1180_ref = 1235.0f;//cs1180 vref = 1.235v
|
|
|
static const float max_cs1180_adc = 0x7FFFF;//
|
|
|
static const float small_cur_r_sense = 360.0f;//欧姆
|
|
|
+static least_square_t adc_cali[2]; // y = ax + b
|
|
|
|
|
|
#define GD32_ADC_READ_TIMES 128
|
|
|
|
|
|
@@ -45,10 +60,14 @@ static void __inline__ select_gain_10x(int select){
|
|
|
ML5238_IMON_OUT_10X();
|
|
|
imon_gain_now = imon_gain_10x;
|
|
|
vim0_now = vim0_10x;
|
|
|
+ ml5238_now_a = ml5238_10x_a;
|
|
|
+ ml5238_now_b = ml5238_10x_b;
|
|
|
}else {
|
|
|
ML5238_IMON_OUT_50X();
|
|
|
imon_gain_now = imon_gain_50x;
|
|
|
vim0_now = vim0_50x;
|
|
|
+ ml5238_now_a = ml5238_50x_a;
|
|
|
+ ml5238_now_b = ml5238_50x_b;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -115,6 +134,13 @@ void measure_adc_init(void){
|
|
|
set_log_level(MOD_SYSTEM, L_debug);
|
|
|
}
|
|
|
|
|
|
+static float get_current_by_ml5238(void){
|
|
|
+ float adc = adc_sample_avg(ADC_CHAN_IMON, GD32_ADC_READ_TIMES);
|
|
|
+ float cali_adc = ML5238_V_RSENSER(adc, vim0_now, imon_gain_now);
|
|
|
+
|
|
|
+ return (int)((cali_adc / max_gd_adc) * v_gd_ref / r_sense * 1000);
|
|
|
+}
|
|
|
+
|
|
|
/* get battery pack's current (mA) */
|
|
|
static float get_pack_current_by_gd(void){
|
|
|
float adc = adc_sample_avg(ADC_CHAN_IMON, GD32_ADC_READ_TIMES);
|
|
|
@@ -139,6 +165,7 @@ static float get_pack_current_by_cs1180(int *valid){
|
|
|
|
|
|
float get_pack_current(int *current_5238){
|
|
|
float current = get_pack_current_by_gd();
|
|
|
+ current = ml5238_now_a * current + ml5238_now_b;
|
|
|
if (current_5238 != NULL){
|
|
|
*current_5238 = (int)current;
|
|
|
}
|
|
|
@@ -146,7 +173,7 @@ float get_pack_current(int *current_5238){
|
|
|
int valid = 1;
|
|
|
float cs1180_current = get_pack_current_by_cs1180(&valid);
|
|
|
if (valid == 1) {
|
|
|
- current = cs1180_current;
|
|
|
+ current = cs1180_current * cs1180_a + cs1180_b;
|
|
|
}
|
|
|
}
|
|
|
return current;
|
|
|
@@ -195,3 +222,56 @@ int get_pack_temperature(int index){
|
|
|
return get_temp_by_adc((adc<<4)&0xFFFF);
|
|
|
}
|
|
|
|
|
|
+int measure_start_cali(uint8_t adc, uint8_t gain, uint8_t samples){
|
|
|
+ bms_work_mode_set(WORK_MODE_CALIBRATE, 1);
|
|
|
+ least_square_init(&adc_cali[adc], samples);
|
|
|
+ sys_debug("start cali %d, %d, %d\n", adc, gain, samples);
|
|
|
+ if (adc == GD32_ADC) {
|
|
|
+ if (gain == 10) {
|
|
|
+ select_gain_10x(1);
|
|
|
+ }else if (gain == 50) {
|
|
|
+ select_gain_10x(0);
|
|
|
+ }else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+int measure_continue_cali(uint8_t adc, uint16_t voltage, int16_t current) {
|
|
|
+ float x = 0;
|
|
|
+ float y = current;
|
|
|
+ sys_debug("continue cali %d, %d, %d\n", adc, voltage, current);
|
|
|
+ if (adc == GD32_ADC) {
|
|
|
+ x = get_current_by_ml5238();
|
|
|
+ }else {
|
|
|
+ x = get_pack_current_by_cs1180(NULL);
|
|
|
+ }
|
|
|
+ least_square_put(&adc_cali[adc], x, y);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+int measure_stop_cali(uint8_t adc, uint8_t gain){
|
|
|
+ bms_work_mode_set(WORK_MODE_CALIBRATE, 0);
|
|
|
+ sys_debug("continue stop %d, %d\n", adc, gain);
|
|
|
+ if (adc_cali[adc].finished ) {
|
|
|
+ if (adc == GD32_ADC) {
|
|
|
+ if (gain == 10) {
|
|
|
+ ml5238_10x_a = adc_cali[adc].Cb;
|
|
|
+ ml5238_10x_b = adc_cali[adc].Ka;
|
|
|
+ }else if (gain == 50) {
|
|
|
+ ml5238_50x_a = adc_cali[adc].Cb;
|
|
|
+ ml5238_50x_b = adc_cali[adc].Ka;
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ cs1180_a = adc_cali[adc].Cb;
|
|
|
+ cs1180_b = adc_cali[adc].Ka;
|
|
|
+ }
|
|
|
+ sys_debug("stop %f, %f\n", adc_cali[adc].Cb, adc_cali[adc].Ka);
|
|
|
+ }
|
|
|
+ select_gain_10x(0);
|
|
|
+ return adc_cali[adc].finished;
|
|
|
+}
|
|
|
+
|
|
|
+
|