Parcourir la source

update adc driver

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui il y a 4 ans
Parent
commit
3417c7504f
4 fichiers modifiés avec 56 ajouts et 199 suppressions
  1. 41 127
      Applications/bsp/adc.c
  2. 5 33
      Applications/bsp/adc.h
  3. 10 37
      Applications/foc/phase_current.c
  4. 0 2
      Applications/foc/phase_current.h

+ 41 - 127
Applications/bsp/adc.c

@@ -1,30 +1,55 @@
 #include "bsp/adc.h"
 #include "libs/utils.h"
 #include "os/co_task.h"
+
 static void _gpio_init(void);
-static void _adc0_init(void);
-static void _adc0_insert_chan_init(void);
-static void _adc0_regular_chan_init(void);
-static void _adc1_init(void);
-static void _adc1_insert_chan_init(void);
-static void _adc1_regular_chan_init(void);
-/*
-ADC0 inserted 采集母线电流
-ADC1 inserted 采集三相电流
-每次同时发送母线电流和响应的相电流,通过母线电流给相电流采集的MOS内阻校准
-可以理解为FOC工作在三电阻采样模式下,只是需要不停的校准MOS的内阻
-*/
+
 void adc_init(void){
 	/* init adc input gpio */
 	_gpio_init();
     /* config ADC clock */
     rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4); //APB2 clk 120M, adc clk 30M
 
-	_adc0_init();
+	rcu_periph_clock_enable(RCU_ADC0);
+	rcu_periph_clock_enable(RCU_ADC1);
 
-	_adc1_init();
+	adc_mode_config(ADC_DAUL_INSERTED_PARALLEL);
+    /* ADC scan mode function enable */
+    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
+    adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);
 
-	adc_config_trigger(ADC_TRIGGER_PHASE);
+    /* configure ADC data alignment */
+    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
+    adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);
+	
+    /* configure ADC inserted channel trigger */
+    adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, ADC_TRIGGER_PHASE);
+    /* configure ADC inserted channel length */
+    adc_channel_length_config(ADC0, ADC_INSERTED_CHANNEL, 1);
+    /* configure ADC inserted channel trigger */
+    adc_external_trigger_source_config(ADC1, ADC_INSERTED_CHANNEL, ADC0_1_2_EXTTRIG_INSERTED_NONE);
+    /* configure ADC inserted channel length */
+    adc_channel_length_config(ADC1, ADC_INSERTED_CHANNEL, 1);
+    /* configure ADC inserted channel */
+    adc_inserted_channel_config(ADC0, 0, U_PHASE_I_CHAN, ADC_SAMPLE_TIME);
+    adc_inserted_channel_config(ADC1, 0, V_PHASE_I_CHAN, ADC_SAMPLE_TIME);
+
+    /* ADC external trigger enable */
+    adc_external_trigger_config(ADC0, ADC_INSERTED_CHANNEL, ENABLE);
+    adc_external_trigger_config(ADC1, ADC_INSERTED_CHANNEL, ENABLE);
+    adc_interrupt_enable(ADC0, ADC_INT_EOIC);
+
+    /* configure ADC regular channel trigger */
+    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
+    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
+
+    /* enable ADC interface */
+    adc_enable(ADC0);
+    adc_enable(ADC1);
+
+    /* ADC calibration and reset calibration */
+    adc_calibration_enable(ADC0);
+    adc_calibration_enable(ADC1);
 
 	nvic_irq_enable(ADC0_1_IRQn, ADC_IRQ_PRIORITY, 0);
 
@@ -38,109 +63,6 @@ static void _gpio_init(void) {
 	gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0|GPIO_PIN_1);
 }
 
-static void _adc0_init(void) {
-	u32 adc_dev = ADC0;
-    /* enable ADC1 clock */
-    rcu_periph_clock_enable(RCU_ADC0);
-    /* ADC mode config,adc0 master, adc1 slave */
-    adc_mode_config(ADC_DAUL_INSERTED_PARALLEL);
-    /* ADC special function config */
-    adc_special_function_config(adc_dev, ADC_SCAN_MODE, ENABLE);
-    adc_special_function_config(adc_dev, ADC_CONTINUOUS_MODE, DISABLE);  
-    /* ADC data alignment config */
-    adc_data_alignment_config(adc_dev, ADC_DATAALIGN_RIGHT);
-	/* init insert chans*/
-	_adc0_insert_chan_init();
-	/* init regular chans*/
-	_adc0_regular_chan_init();
-	adc_interrupt_disable(adc_dev, ADC_INT_EOIC);
-	adc_interrupt_disable(adc_dev, ADC_INT_EOC);
-	adc_interrupt_disable(adc_dev, ADC_INT_WDE);	
-    /* enable ADC interface */
-    adc_enable(adc_dev);
-    delay_ms(1);
-    /* ADC calibration and reset calibration */
-    adc_calibration_enable(adc_dev);
-}
-
-static void _adc1_init(void) {
-	u32 adc_dev = ADC1;
-    /* enable ADC1 clock */
-    rcu_periph_clock_enable(RCU_ADC1);
-    /* ADC special function config */
-    adc_special_function_config(adc_dev, ADC_SCAN_MODE, ENABLE);
-    adc_special_function_config(adc_dev, ADC_CONTINUOUS_MODE, DISABLE);  
-    /* ADC data alignment config */
-    adc_data_alignment_config(adc_dev, ADC_DATAALIGN_RIGHT);
-	/* init insert chans*/
-	_adc1_insert_chan_init();
-	/* init regular chans*/
-	_adc1_regular_chan_init();
-	adc_interrupt_disable(adc_dev, ADC_INT_EOIC);
-	adc_interrupt_disable(adc_dev, ADC_INT_EOC);
-	adc_interrupt_disable(adc_dev, ADC_INT_WDE);
-    /* enable ADC interface */
-    adc_enable(adc_dev);
-    delay_ms(1);
-    /* ADC calibration and reset calibration */
-    adc_calibration_enable(adc_dev);
-
-}
-
-/* ADC0 insert chan sample phase I(use two chan, selected by foc) */
-static void _adc0_insert_chan_init(void) {
-	u32 adc_dev = ADC0;
-	//adc_discontinuous_mode_config(adc_dev, ADC_CHANNEL_DISCON_DISABLE, 0);	
-    /* ADC channel length config */
-    adc_channel_length_config(adc_dev, ADC_INSERTED_CHANNEL, 1);
-    /* ADC inserted channel ran config, use ISQ2,ISQ3 */
-	adc_update_insert_sample_rank(adc_dev, U_PHASE_I_CHAN);
-	/* config inserted channel sample time */
-	adc_update_insert_sample_time(adc_dev, U_PHASE_I_CHAN, ADC_SAMPLE_TIME);
-	adc_update_insert_sample_time(adc_dev, V_PHASE_I_CHAN, ADC_SAMPLE_TIME);
-	adc_update_insert_sample_time(adc_dev, W_PHASE_I_CHAN, ADC_SAMPLE_TIME);
-    /* ADC trigger config */
-    adc_external_trigger_source_config(adc_dev, ADC_INSERTED_CHANNEL, ADC0_1_EXTTRIG_INSERTED_T0_CH3); 
-	/* ADC external trigger enable */
-    adc_external_trigger_config(adc_dev, ADC_INSERTED_CHANNEL, DISABLE);	
-}
-
-/* ADC1 insert chan sample vbus I */
-static void _adc1_insert_chan_init(void) {
-	u32 adc_dev = ADC1;
-	//adc_discontinuous_mode_config(adc_dev, ADC_CHANNEL_DISCON_DISABLE, 0);
-    /* ADC channel length config */
-    adc_channel_length_config(adc_dev, ADC_INSERTED_CHANNEL, 1);
-    /* ADC inserted channel config */
-	adc_update_insert_sample_rank(adc_dev, V_PHASE_I_CHAN);
-	/* config inserted channel sample time */
-	adc_update_insert_sample_time(adc_dev, U_PHASE_I_CHAN, ADC_SAMPLE_TIME);
-	adc_update_insert_sample_time(adc_dev, V_PHASE_I_CHAN, ADC_SAMPLE_TIME);
-	adc_update_insert_sample_time(adc_dev, W_PHASE_I_CHAN, ADC_SAMPLE_TIME);
-
-    /* ADC trigger config, slave must config to software trigger */
-    adc_external_trigger_source_config(adc_dev, ADC_INSERTED_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); 
-	/* ADC external trigger enable */
-    adc_external_trigger_config(adc_dev, ADC_INSERTED_CHANNEL, DISABLE);
-}
-
-static void _adc0_regular_chan_init(void) {
-	adc_discontinuous_mode_config(ADC0, ADC_REGULAR_CHANNEL, 1); //每次转化一个
-	/* ADC channel length config */
-	adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);
-	adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
-	adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); 
-	adc_regular_channel_config(ADC0, 0, MOTOR_TEMP_CHAN, ADC_SAMPLETIME_55POINT5);
-}
-
-static void _adc1_regular_chan_init(void) {
-	adc_discontinuous_mode_config(ADC1, ADC_REGULAR_CHANNEL, 1); //每次转化一个
-	/* ADC channel length config */
-	adc_channel_length_config(ADC1, ADC_REGULAR_CHANNEL, 1);
-	adc_external_trigger_config(ADC1, ADC_REGULAR_CHANNEL, ENABLE);
-	adc_external_trigger_source_config(ADC1, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
-	adc_regular_channel_config(ADC1, 0, W_PHASE_V_CHAN, ADC_SAMPLETIME_55POINT5);
-}
 
 void adc_start_insert_convert(void) {
     /* clear the ADC flag */
@@ -153,14 +75,12 @@ void adc_start_insert_convert(void) {
 	
     /* enable ADC interrupt */
     adc_interrupt_enable(ADC0, ADC_INT_EOIC);
-	//adc_interrupt_enable(ADC1, ADC_INT_EOIC);
 }
 
 void adc_stop_insert_convert(void) {
 	adc_disable_ext_trigger();
     /* enable ADC interrupt */
     adc_interrupt_disable(ADC0, ADC_INT_EOIC);
-	//adc_interrupt_disable(ADC1, ADC_INT_EOIC);
 
     /* clear the ADC flag */
     adc_flag_clear(ADC0, ADC_FLAG_EOIC);
@@ -169,16 +89,13 @@ void adc_stop_insert_convert(void) {
 
 
 s32 adc_sample_regular_channel(int channel, int times) {
-#if 0
 	u32 adc_device = ADC0;
-	if (channel >= W_PHASE_V_CHAN && channel <= U_PHASE_V_CHAN) {
-		adc_device = ADC1;
-	}
 	int value = 0;
 	int count = 0;
 	int min = 0xFFFFF;
 	int max = -0xFFFFF;
 	u64 start_time;
+	adc_channel_length_config(adc_device, ADC_REGULAR_CHANNEL, 1);
 	adc_regular_channel_config(adc_device, 0, channel, ADC_SAMPLETIME_55POINT5);
 	while(count < times){
 restart:		
@@ -204,8 +121,5 @@ restart:
 		return value/times;
 	}
 	return (value - min - max)/(times-2);
-#else
-	return 0;
-#endif
 }
 

+ 5 - 33
Applications/bsp/adc.h

@@ -22,6 +22,8 @@ inserted ADC 由timer0 ch3触发,
 #define IL_OFFSET   20
 
 #define ADC_SAMPLE_TIME ADC_SAMPLETIME_7POINT5
+#define ADC_TRIGGER_PHASE ADC0_1_EXTTRIG_INSERTED_T0_CH3
+#define ADC_TRIGGER_VBUS ADC0_1_EXTTRIG_INSERTED_T1_CH0
 
 //#define ADC_RANK_CHANNEL(c1, c2, l) ((c1)<<ISQ2_OFFSET | (c2)<<ISO3_OFFSET | (l)<<IL_OFFSET)
 #define ADC_RANK_CHANNEL(c)  ((c)<<ISO3_OFFSET | (0)<<IL_OFFSET) 
@@ -84,12 +86,8 @@ static void __inline adc_cali_current_read(s32 *v1, s32 *v2) {
 
 
 static void __inline adc_phase_inserted_config(u8 sector) {
-	ADC_CTL0(ADC0) &= ~(ADC_CTL0_SYNCM);
-
 	ADC_ISQ(ADC0) = adc0_rank_channels[sector];
 	ADC_ISQ(ADC1) = adc1_rank_channels[sector];
-
-	ADC_CTL0(ADC0) |= ADC_DAUL_INSERTED_PARALLEL;
 }
 
 
@@ -98,34 +96,12 @@ static void __inline adc_cali_inserted_config(u8 invert) {
 	ADC_ISQ(ADC1) = adc1_cali_rank_channels[invert];
 }
 
-#define ADC_TRIGGER_PHASE ADC0_1_EXTTRIG_INSERTED_T0_CH3
-#define ADC_TRIGGER_VBUS ADC0_1_EXTTRIG_INSERTED_T1_CH0
-
-
-static void __inline adc_config_trigger(u32 trigger) {
-	ADC_CTL1(ADC0) &= ~((uint32_t)ADC_CTL1_ETSIC);
-	ADC_CTL1(ADC0) |= (uint32_t)trigger;
-
-	ADC_CTL1(ADC1) &= ~((uint32_t)ADC_CTL1_ETSIC);
-	ADC_CTL1(ADC1) |= (uint32_t)trigger;
-}
-
-static void __inline adc_disable_ext_trigger(void) {
-	ADC_CTL0(ADC0) &= ~(ADC_CTL0_SYNCM);
-   
+static void __inline adc_disable_ext_trigger(void) {   
 	ADC_CTL1(ADC0) &= ~ADC_CTL1_ETEIC;
-	ADC_CTL1(ADC1) &= ~ADC_CTL1_ETEIC;
-
-	ADC_CTL0(ADC0) |= ADC_DAUL_INSERTED_PARALLEL;
 }
 
-static void __inline adc_enable_ext_trigger(void) {
-	ADC_CTL0(ADC0) &= ~(ADC_CTL0_SYNCM);
-	
+static void __inline adc_enable_ext_trigger(void) {	
 	ADC_CTL1(ADC0) |= ADC_CTL1_ETEIC;
-	ADC_CTL1(ADC1) |= ADC_CTL1_ETEIC;
-
-	ADC_CTL0(ADC0) |= ADC_DAUL_INSERTED_PARALLEL;
 }
 
 static bool __inline adc_is_trigged_vbus(void) {
@@ -167,7 +143,7 @@ static __inline__ bool adc_eoic_interrupt(void)
 		return true;
 	}
 #else
-	if ((ADC_STAT(ADC0) & ADC_STAT_EOIC) && (ADC_STAT(ADC1) & ADC_STAT_EOIC)){
+	if (ADC_STAT(ADC0) & ADC_STAT_EOIC){
 		return true;
 	}
 #endif
@@ -178,13 +154,9 @@ static __inline__ bool adc_eoic_interrupt(void)
 
 static __inline__ void adc_clear_eoic_flags(void) {
 	ADC_STAT(ADC0) &= ~((u32) ADC_STAT_EOIC);
-	ADC_STAT(ADC1) &= ~((u32) ADC_STAT_EOIC);
 }
 
 
-static __inline__ void adc_insert_continue_mode(u32 adc_periph) {
-	ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_DISIC ));
-}
 void adc_init(void);
 s32 adc_sample_regular_channel(int chan, int times);
 void adc_start_insert_convert(void);

+ 10 - 37
Applications/foc/phase_current.c

@@ -10,7 +10,7 @@
 #define Gvbus (13.1f) //母线电流的运放 
 #define Rds_Defualt  0.00263f//欧
 #define Gmos  (1.7f)//mos 电流的运放
-
+#define Sample_R Rds_Defualt
 #define Lower_Pass_p 0.2f
 
 #define VBUS_VOL(adc) ((adc) * 3.3f / 4096.0f / Gvbus)
@@ -18,17 +18,11 @@
 
 #define current_i(v, r) ((v)/(r))
 
-/* Ids 通过母线采样电阻测量 */
-static __inline__ void _calc_mos_rds(u32 Vds, u32 Ids, float *dest) {
-	*dest = (*dest) * (1.0f - Lower_Pass_p) + Vds/Ids * Lower_Pass_p;
-}
-
 void phase_current_init(current_samp_t *cs) {
 	cs->offset_sample_count = NB_OFFSET_SAMPLES;
-	cs->vbus_i_invert = INVERT_NO;
-	cs->Rds_a = Rds_Defualt;
-	cs->Rds_b = Rds_Defualt;
-	cs->Rds_c = Rds_Defualt;
+	cs->adc_offset_a = 0;
+	cs->adc_offset_b = 0;
+	cs->adc_offset_c = 0;
 }
 
 
@@ -65,45 +59,24 @@ void phase_current_sample(current_samp_t *cs){
 	if (cs->sector == SECTOR_3 || cs->sector == SECTOR_6) {
 		/* Current on Phase C is not accessible */
 		/* Ia = PhaseAOffset - ADC converted value) */
-		cs->Ib = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_b), cs->Rds_b);
-		cs->Ia = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_a), cs->Rds_a);
+		cs->Ib = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_b), Sample_R);
+		cs->Ia = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_a), Sample_R);
 		cs->Ic = -(cs->Ia + cs->Ib);
 	}else if (cs->sector == SECTOR_2 || cs->sector == SECTOR_5) {
 		/* Current on Phase A is not accessible 	*/
 		/* Ib = PhaseBOffset - ADC converted value) */
-		cs->Ib = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_b), cs->Rds_b);
-		cs->Ic = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_c), cs->Rds_c);
+		cs->Ib = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_b), Sample_R);
+		cs->Ic = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_c), Sample_R);
 		cs->Ia = -(cs->Ib + cs->Ic);
 	}else if (cs->sector == SECTOR_1 || cs->sector == SECTOR_4) {
 		/* Current on Phase B is not accessible 	*/
 		/* Ia = PhaseAOffset - ADC converted value) */
-		cs->Ia = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_a), cs->Rds_a);
-		cs->Ic = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_c), cs->Rds_c);
+		cs->Ia = current_i(MOSds_VOL(phase_current1 - cs->adc_offset_a), Sample_R);
+		cs->Ic = current_i(MOSds_VOL(phase_current2 - cs->adc_offset_c), Sample_R);
 		cs->Ib = -(cs->Ia + cs->Ic);
 	}
 }
 
-/* 校准mos的 drain-source 内阻 */
-void phase_Rds_calibrate(current_samp_t *cs) {
-	adc_disable_ext_trigger();
-
-	if (cs->vbus_i_invert != INVERT_NO) {
-		s32 adcm;
-		s32 adcv;
-		adc_cali_current_read(&adcm, &adcv);
-		float vbus_i = VBUS_VOL(adcv)/Rvbus;
-		if (cs->vbus_i_invert == INVERT_A) {
-			_calc_mos_rds(adcm, vbus_i, &cs->Rds_a);
-		}else if (cs->vbus_i_invert == INVERT_B) {
-			_calc_mos_rds(adcm, vbus_i, &cs->Rds_b);
-		}else if (cs->vbus_i_invert == INVERT_C) {
-			_calc_mos_rds(adcm, vbus_i, &cs->Rds_c);
-		}
-		cs->vbus_i_invert = INVERT_NO;		
-	}
-	adc_config_trigger(ADC_TRIGGER_PHASE);
-	adc_phase_inserted_config(cs->sector);
-}
 
 u32 get_phase_sample_point(current_samp_t *cs, phase_time_t *time, u8 sector){
 	u32 low_side_low_duty = FOC_PWM_Half_Period - time->low;	

+ 0 - 2
Applications/foc/phase_current.h

@@ -4,9 +4,7 @@
 void phase_current_init(current_samp_t *cs);
 void phase_current_sample(current_samp_t *cs);
 void phase_current_offset(current_samp_t *cs);
-void phase_Rds_calibrate(current_samp_t *cs);
 u32 get_phase_sample_point(current_samp_t *cs, phase_time_t *time, u8 sector);
-u32 get_vbus_sample_point(current_samp_t *cs, phase_time_t *time);
 void phase_current_adc_triger(current_samp_t *cs);
 #endif /* _PHASE_CURRENT_H__ */