Просмотр исходного кода

cs1180 容错处理

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 5 лет назад
Родитель
Сommit
4413fc2b1c
2 измененных файлов с 76 добавлено и 44 удалено
  1. 1 1
      Application/app/sox/measure.c
  2. 75 43
      Application/bsp/cs1180.c

+ 1 - 1
Application/app/sox/measure.c

@@ -167,7 +167,7 @@ float get_pack_current(int *current_5238){
 	if (current_5238 != NULL){
 		*current_5238 = (int)current;
 	}
-	if (cs1180_change_gain(current) == 0) {
+	if (cs1180_change_gain(current) == 1) {
 		int valid = 1;
 		float cs1180_current = get_pack_current_by_cs1180(&valid);
 		if (valid == 1) {

+ 75 - 43
Application/bsp/cs1180.c

@@ -59,14 +59,21 @@ static void spi_read_reg(uint8_t reg, uint8_t *data, uint8_t len){
 	}
 }
 
-static uint8_t cs1180_dumy_read(int gain){
+static void cs1180_save_regs(int gain){
 	uint8_t *data = _cali_gain_regs + 16 * gain;
 	cs1180_cs(0);
 	spi_read_reg(0x0, data, 16);
 	cs1180_cs(1);
-	return data[0];
 }
 
+static void cs1180_dymu_read(){
+	uint8_t data[16];
+	cs1180_cs(0);
+	spi_read_reg(0x0, data, 16);
+	cs1180_cs(1);
+}
+
+
 /* 对芯片的偏移误差和增益误差进行纠正 */
 __attribute__((unused)) static void cs1180_self_calibrate(void)
 {
@@ -116,9 +123,10 @@ __attribute__((unused)) static void cs1180_sys_offset_calibrate(void)
 	cs1180_send_cmd(CS1180_OCALSYS);
 	cs1180_cs(1);
 	/* wait calibrate finished */
+	delay_us(20);
 	while (IS_CS1180_NOT_READY());
 	while (!IS_CS1180_NOT_READY());
-	delay_us(33 * 1000);
+	delay_us(1000);
 	while (IS_CS1180_NOT_READY()); //drop first data	
 }
 
@@ -147,6 +155,18 @@ static void _cs1180_adc_set_gain(int gain){
 	cs1180_cs(1);
 }
 
+static int _cs1180_check_gain(int gain){
+	uint8_t data[] = {0xFF, 0xFF, 0xFF};
+	cs1180_cs(0);
+	spi_read_reg(0x00, data, 3);
+	cs1180_cs(1);
+
+	if (data[0] == gain && data[1] == 0x01 && data[2] == 0x00){
+		return 1;
+	}
+	return 0;
+}
+
 static int cs1180_check_cali_offset(void){
 	uint32_t offset = 0;
 	cs1180_cs(0);
@@ -164,30 +184,31 @@ int cs1180_adc_set_gain_cali(int gain){
 		_cs1180_adc_set_gain(gain);
 		delay_us(10);
 
-		if (cs1180_dumy_read(gain) == gain){
+		if (_cs1180_check_gain(gain)){
 			break;
 		}
-		count ++;
-	}while(count <= 50);
-	if (count >= 50) {
-		if (cs1180_dumy_read(gain) != gain){
-			return -1;
+		if (count ++ > 50) {
+			return 0;
 		}
-	}
-	_cs1180_gain = 1 << gain;
+	}while(!_cs1180_check_gain(gain));
+	
 	cs1180_self_gain_calibrate();
-
-	delay_us(10*1000);
 	count = 0;
 	do {
 		cs1180_sys_offset_calibrate();
 		if (cs1180_check_cali_offset()){
 			break;
 		}
+		delay_us(20);
 	}while(count++ <= 5);
 	sys_debug("cs1180 cali sys offset try count %d\n", count);
-	cs1180_dumy_read(gain);
-	return 0;
+	if (!cs1180_check_cali_offset()){
+		return 0;
+	}
+	_cs1180_gain = 1 << gain;
+	delay_us(20);
+	cs1180_save_regs(gain);
+	return 1;
 }
 
 
@@ -200,22 +221,24 @@ static void cs1180_reset(void){
 }
 
 void cs1180_adc_init(void){
-	_cs1180_ready = 0;
-	CS1180_PWR_ENABLE(0);
-	delay_us(10 * 1000);
-	CS1180_PWR_ENABLE(1);
-	delay_us(20 * 1000);
-	spi1_init();
-	delay_us(10);
-#if 0	
-	cs1180_adc_set_gain_cali(CS1180_GAIN_1X);
-	cs1180_adc_set_gain_cali(CS1180_GAIN_8X);
-	cs1180_adc_set_gain_cali(CS1180_GAIN_32X);
-#endif
-	cs1180_adc_set_gain_cali(CS1180_GAIN_128X);
-	_cs1180_ready = _cali_gain_regs[16 * CS1180_NOW_GAIN] == CS1180_NOW_GAIN;
+	int count = 0;
+	do  {
+		_cs1180_ready = 0;
+		CS1180_PWR_ENABLE(0);
+		delay_us(10 * 1000);
+		CS1180_PWR_ENABLE(1);
+		delay_us(20 * 1000);
+		spi1_init();
+		delay_us(10);
+		_cs1180_ready = cs1180_adc_set_gain_cali(CS1180_GAIN_128X);
+		if (!_cs1180_ready) {
+			cs1180_adc_shutdown();
+		}
+	}while(!_cs1180_ready && count++ < 5);
+	sys_debug("cs1180 init retry %d\n", count);
 }
 
+#if 0
 int _cs1180_check_gain(int gain){
 	uint8_t data[13] = {0};
 	cs1180_cs(0);
@@ -229,36 +252,39 @@ int _cs1180_check_gain(int gain){
 	}
 	return 1;
 }
+#endif
 
+//return 1: cs1180 is OK, 0: cs1180 can not work
 int cs1180_adc_set_gain_online(int gain){
 	int count = 0;
-	if (_cali_gain_regs[16 * CS1180_NOW_GAIN] == gain){
-		return 0;
+	uint8_t *data = _cali_gain_regs + 16 * gain;
+	if (_cs1180_ready == 1){
+		return 1;
+	}
+	if (data[0] != gain || (data[7] == 0 && data[8] == 0 && data[9] == 0)){
+		/*cs1180_adc_init();*/ //没有初始化成功过,或者校准没成功过
+		return _cs1180_ready;
 	}
+	
 	do {
 		cs1180_reset();
 		delay_us(10);
-
 		cs1180_cs(0);
 		cs_delay();
 		spi_write_reg(0x0, _cali_gain_regs + 16 * gain, 13);
 		cs1180_cs(1);
 		delay_us(10);
 
-		if (_cs1180_check_gain(gain)){
-			break;
+		if (_cs1180_check_gain(gain) && cs1180_check_cali_offset()){
+			CS1180_NOW_GAIN = gain;
+			_cs1180_gain = 1 << gain;
+			_cs1180_ready = 1;
+			return 1;
 		}
 		count ++;
 	}while(count <= 5);
-	if (count >= 5) {
-		if (_cs1180_check_gain(gain) != 1){
-			return -1;
-		}
-	}
-	CS1180_NOW_GAIN = gain;
-	_cs1180_gain = 1 << gain;
-	return 0;
 
+	return 0;
 }
 
 
@@ -283,7 +309,7 @@ void cs1180_adc_shutdown(void){
 }
 static int cs1180_may_error = 0;
 void cs1180_log(void){
-	sys_error("cs1180 error %d\n", cs1180_may_error);
+	sys_error("cs1180 error %d, ready %d\n", cs1180_may_error, _cs1180_ready);
 	for (int i = 0; i < 16; i++){
 		sys_debug("Reg%d:0x%x\n", i, _cali_gain_regs[16 * CS1180_NOW_GAIN + i]);
 	}
@@ -335,6 +361,12 @@ float cs1180_adc_sample(int *valide)
 		if (cs1180_low_ff_count ++ >= 10) {
 			cs1180_low_ff_count = 0;
 			cs1180_may_error ++;
+			cs1180_dymu_read();
+			delay_us(50);
+			cs1180_dymu_read();
+			if (valide) {
+				*valide = 0;
+			}
 		}
 	}else {
 		cs1180_low_ff_count = 0;