Explorar el Código

update hall, hall works

Signed-off-by: kevin <huhui@sharkgulf.com>
kevin hace 2 años
padre
commit
deff9f1e7d

+ 16 - 11
Applications/app/app.c

@@ -100,8 +100,8 @@ static void app_print_log(void) {
 	sys_debug("FOC time err %d %d %d %d\n", g_meas_foc.intval_time_h_error, g_meas_foc.intval_time_l_error, g_meas_foc.exec_max_error_time, g_meas_foc.exec_time_error);
 	//sys_debug("acc vol %d, bid %d\n", get_acc_vol(), gpio_board_id());
 	//sys_debug("throttle %f\n", get_throttle_float());
-	sys_debug("ADC Vref %f, %f\n", get_adc_vref(), adc_5vref_compesion());
-	sys_debug("curr A:%f,B:%f,C:%f\n", foc()->in.curr_abc[0], foc()->in.curr_abc[1], foc()->in.curr_abc[2]);
+	//sys_debug("ADC Vref %f, %f\n", get_adc_vref(), adc_5vref_compesion());
+	//sys_debug("curr A:%f,B:%f,C:%f\n", foc()->in.curr_abc[0], foc()->in.curr_abc[1], foc()->in.curr_abc[2]);
 	//sys_debug("dead time 0x%x\n", get_deadtime());
 	//thro_torque_log();
 	//sys_debug("_>%f, %f, %f\n", ladrc_observer_get()->ld, ladrc_observer_get()->lq, ladrc_observer_get()->poles);
@@ -111,7 +111,8 @@ static void app_print_log(void) {
 	//sample_log();
 	//throttle_log();
 	//sys_debug("Trq: %f-%f-%f\n", motor.controller.ramp_input_torque.target, motor.controller.ramp_input_torque.interpolation, motor.controller.ramp_input_torque.step);
-	sys_debug("FOC is %s, %d,%d\n", mot_contrl_is_start(mot_contrl())?"start":"stop", motor.foc_start_cnt, motor.foc_stop_cnt);
+	sys_debug("FOC is %s, %d,%d, pwm:%s\n", mot_contrl_is_start(mot_contrl())?"start":"stop", motor.foc_start_cnt, motor.foc_stop_cnt, pwm_channel_is_enabled()?"start":"stop");
+	sys_debug("duty: %d-%d-%d\n", foc()->out.duty[0], foc()->out.duty[1], foc()->out.duty[2]);
 	//F_debug();
 	//eCtrl_debug_log();
 	//sys_debug("enc err %d, %d\n", foc_observer_enc_errcount(), foc_observer_sensorless_stable());
@@ -161,7 +162,7 @@ int plot_type = 0;
 static void plot_smo_angle(void) {
 	u32 mask = cpu_enter_critical();
 	float smo_angle = foc_observer_sensorless_angle();
-	float mot_angle = hall_get_elec_angle();
+	float mot_angle = foc()->in.mot_angle;
 	cpu_exit_critical(mask);
 	float delta = smo_angle - mot_angle;
 	float s, c;
@@ -170,17 +171,23 @@ static void plot_smo_angle(void) {
 	can_plot3(mot_angle, smo_angle, delta);
 }
 
+#if 0
 static void plot_hall_angle(void) {
 	u32 mask = cpu_enter_critical();
-	float smo_angle = hall_get_elec_angle();
+	float hall_angle = hall_get_elec_angle();
 	float mot_angle = foc()->in.mot_angle;
+	if (mot_contrl()->if_ctl.b_ena) {
+		mot_angle += 90;
+	}
+	norm_angle_deg(mot_angle);
 	cpu_exit_critical(mask);
-	float delta = smo_angle - mot_angle;
+	float delta = hall_angle - mot_angle;
 	float s, c;
 	arm_sin_cos(delta, &s, &c);
 	delta = fast_atan2(s, c)/PI*180.0f;
-	can_plot3(mot_angle, smo_angle, delta);
+	can_plot3(mot_angle, hall_angle, delta);
 }
+#endif
 
 static u32 app_plot_task(void * args) {
 	if (plot_type == 1) {
@@ -195,13 +202,11 @@ static u32 app_plot_task(void * args) {
 		}
 		can_plot2(plot_arg1, plot_arg2);
 	}else if (plot_type == 2) {
-		//can_plot2(mot_contrl_get_final_torque(&motor.controller), mot_contrl()->target_torque);
-		can_plot2(hall_get()->state, hall_get()->low_res_pos);
+		can_plot2(mot_contrl_get_final_torque(&motor.controller), mot_contrl()->target_torque);
 	}else if (plot_type == 3) {
 		plot_smo_angle();
 	}else if (plot_type == 4) {
-		//can_plot2((s16)foc()->out.curr_dq.d, (s16)foc()->out.curr_dq.q);
-		plot_hall_angle();
+		can_plot2((s16)foc()->out.curr_dq.d, (s16)foc()->out.curr_dq.q);
 	}else if (plot_type == 5) {
 		can_plot2((s16)foc()->in.target_id.interpolation , (s16)foc()->in.target_iq.interpolation);
 	}else if (plot_type == 6) {

+ 1 - 1
Applications/bsp/at32/board_at_mc100_v1.h

@@ -266,7 +266,7 @@
 
 
 /* 是否用编码器 */
-#define USE_ENCODER_ABI
+#define CONFIG_USE_ENCODER_ABI
 #define ENCODER_TYPE ENCODER_MT
 
 /* 编码器 */

+ 1 - 1
Applications/bsp/at32/board_at_mc105_v3.h

@@ -296,7 +296,7 @@
 #define CAN_PIN_RCU  CRM_GPIOB_PERIPH_CLOCK
 #define CAN_REMAP    CAN_MUX_10
 /* 是否用编码器 */
-#define USE_ENCODER_ABI
+#define CONFIG_USE_ENCODER_ABI
 #define ENCODER_TYPE ENCODER_MT
 
 /* 编码器 */

+ 1 - 1
Applications/bsp/gd32/adc.h

@@ -16,7 +16,7 @@ inserted ADC 由timer0 ch3触发,
 #define ISQ3_OFFSET 15
 #define IL_OFFSET   20
 
-#define ADC_INSERT_SAMPLE_TIME ADC_SAMPLETIME_13POINT5
+#define ADC_INSERT_SAMPLE_TIME ADC_SAMPLETIME_41POINT5
 #ifdef CONFIG_SENSORLESS_TOW_SAMPLES
 #define ADC_TRIGGER_PHASE ADC0_1_EXTTRIG_INSERTED_T0_TRGO
 #else

+ 1 - 1
Applications/bsp/gd32/board_gd32demo.h

@@ -108,7 +108,7 @@
 #define THROTTLE_VOL_CEOF (ADC_REFERENCE_VOLTAGE/4096.0f * 2.0f)
 
 /* 是否用编码器 */
-#define USE_ENCODER_ABI
+#define CONFIG_USE_ENCODER_ABI
 #define ENCODER_CC_INVERT //编码器方向和电机反向
 
 /* 编码器 */

+ 2 - 2
Applications/bsp/gd32/board_mc100_v1.h

@@ -117,7 +117,7 @@
 #define W_PHASE_ADC_MODE 	GPIO_MODE_AIN
 
 #define ADC_TO_CURR_ceof1  (CONFIG_CURRENT_SENSOR_CEOF)
-#define ADC_TO_CURR_ceof2  (CONFIG_CURRENT_SENSOR_CEOF*1.16f)
+#define ADC_TO_CURR_ceof2  (CONFIG_CURRENT_SENSOR_CEOF)
 
 #define CONFIG_PWM_UV_SWAP 1
 
@@ -318,7 +318,7 @@
 #define HALL_C_EXIT_SRC_PIN 		GPIO_PIN_SOURCE_8
 #else
 /* 编码器 */
-#define USE_ENCODER_ABI
+#define CONFIG_USE_ENCODER_ABI
 #define ENCODER_TYPE ENCODER_MT
 
 #define ENC_A_GROUP GPIOB

+ 2 - 2
Applications/bsp/gd32/board_mc105_v3.h

@@ -354,7 +354,7 @@
 #define HALL_C_EXIT_SRC_PIN 		GPIO_PIN_SOURCE_6
 
 #else
-#define USE_ENCODER_ABI
+#define CONFIG_USE_ENCODER_ABI
 #define ENCODER_TYPE ENCODER_MT
 
 /* 编码器 */
@@ -414,7 +414,7 @@
 #define BOOT_PIN_1_GROUP GPIOC 
 #define BOOT_PIN_1_PIN   GPIO_PIN_7
 
-#ifdef USE_ENCODER_ABI
+#ifdef CONFIG_USE_ENCODER_ABI
 #define ENC_MAX_interpolation 1.0F
 
 /* 200hz机械转速,200K(12000RPM),AB信号高低电平宽度5us/2=2.5us, 按照timer滤波系数12算,1/7.5*8=1.06us采集到信号没有变才认为是有效值*/

+ 1 - 1
Applications/bsp/gd32/board_yuanqu.h

@@ -189,7 +189,7 @@
 #define GPIO_UDEC_OUT_REMAP_ENABLE  GPIO_SWJ_SWDPENABLE_REMAP
 
 /* 是否用编码器 */
-#define USE_ENCODER_ABI
+#define CONFIG_USE_ENCODER_ABI
 #define ENCODER_TYPE ENCODER_MPS
 
 /* 编码器 */

+ 1 - 1
Applications/bsp/gd32/pwm.h

@@ -9,7 +9,7 @@
 
 #define pwm_enable_channel() {TIMER_CHCTL2(MOS_PWM_TIMER) |= TIMxCCER_MASK_CH012;}
 #define pwm_disable_channel() {TIMER_CHCTL2(MOS_PWM_TIMER) &= ~TIMxCCER_MASK_CH012;}
-
+#define pwm_channel_is_enabled() ((TIMER_CHCTL2(MOS_PWM_TIMER)&TIMxCCER_MASK_CH012) != 0)
 
 #define ch0_update_duty(duty) 	TIMER_CH0CV(MOS_PWM_TIMER) = (uint32_t)duty
 #define ch1_update_duty(duty) 	TIMER_CH1CV(MOS_PWM_TIMER) = (uint32_t)duty

+ 1 - 1
Applications/bsp/n32/board_n32_mc105_v3.h

@@ -298,7 +298,7 @@
 #define CAN_RX1_IRQHandler  CAN1_RX1_IRQHandler
 
 /* 是否用编码器 */
-#define USE_ENCODER_ABI
+#define CONFIG_USE_ENCODER_ABI
 #define ENCODER_TYPE ENCODER_MT
 
 /* 编码器 */

+ 1 - 1
Applications/foc/commands.c

@@ -140,7 +140,7 @@ static u8 ignore_with_speed[] = {Foc_Set_Adrc_Params, Foc_Set_Gear_Limit, Foc_Co
 
 static bool _can_process_with_speed(u8 cmd) {
 	int size = ARRAY_SIZE(ignore_with_speed);
-	if (!mc_is_start() || mot_contrl_get_speed(&motor.controller) < 0.1f) {
+	if (!mc_is_start() || mot_contrl_get_speed_abs(&motor.controller) < CONFIG_ZERO_SPEED_RPM) {
 		return true;
 	}
 	for (int i = 0; i < size; i++) {

+ 9 - 6
Applications/foc/core/controller.c

@@ -8,6 +8,7 @@
 #include "foc/core/f_calc.h"
 #include "foc/motor/current.h"
 #include "foc/mc_error.h"
+#include "libs/logger.h"
 
 static void mot_contrl_pid(mot_contrl_t *ctrl);
 static void mot_contrl_ulimit(mot_contrl_t *ctrl);
@@ -92,10 +93,12 @@ void mot_contrl_IF_start(mot_contrl_t *ctrl, bool start, float accl, float max_v
 		memset(&ctrl->if_ctl, 0, sizeof(IF_t));
 		ctrl->if_ctl.elec_w_acc = accl * (1.0/30.0*M_PI*mc_conf()->m.poles);
 		ctrl->if_ctl.max_vel = max_vel * (1.0/30.0*M_PI*mc_conf()->m.poles);
-		ctrl->if_ctl.curr_angle = -M_PI/2.0f;
+		ctrl->if_ctl.curr_angle = 0;
 		ctrl->if_ctl.angle_deg = pi_2_degree(ctrl->if_ctl.curr_angle);
+		sys_debug("acc %f, %f\n", ctrl->if_ctl.elec_w_acc, ctrl->if_ctl.max_vel);
 	}
 	if (start) {
+		line_ramp_init(&ctrl->ramp_target_current, 20);
 		ctrl->if_ctl.iq_set = iq_set;
 	}else {
 		ctrl->if_ctl.iq_set = 0;
@@ -299,12 +302,12 @@ bool mot_contrl_update(mot_contrl_t *ctrl) {
 		enc_angle = foc_observer_sensorless_angle();
 		enc_vel = foc_observer_sensorless_speed();
 	}
-	
-	if (!ctrl->b_mtpa_calibrate && (ctrl->force_angle != INVALID_ANGLE)) {
-		foc->in.mot_angle = ctrl->force_angle;
-	}else if (ctrl->if_ctl.b_ena) {
-		enc_angle = mot_contrl_IF_update(ctrl);
+
+	if (ctrl->if_ctl.b_ena) {
+		foc->in.mot_angle = mot_contrl_IF_update(ctrl);
 		mot_contrl_set_current(ctrl, ctrl->if_ctl.iq_set);
+	}else if (!ctrl->b_mtpa_calibrate && (ctrl->force_angle != INVALID_ANGLE)) {
+		foc->in.mot_angle = ctrl->force_angle;
 	}else {
 		foc->in.mot_angle = enc_angle;
 	}

+ 99 - 50
Applications/foc/motor/hall.c

@@ -31,8 +31,14 @@ static hall_t g_hall;
 measure_time_t g_meas_hall = {.exec_max_time = 6,};
 
 #define us_2_s(tick) ((float)tick / 1000000.0f) //s32q14
+#define HALL_MAX_TIME 1000000UL
 
-u32 stop_cnt = 0;
+static u32 stop_cnt = 0;
+static u32 g_delta_cnt = 0;
+static u32 g_trns_cnt = 0;
+static u32 g_min_delta;
+//static float g_low_off[6];
+//static u32 g_low_off_cnt[6];
 static u8 __INLINE hall_read_state(void) {
 	u8 hall_a = 0, hall_b = 0, hall_c = 0;
 	for (int i = 0; i < HALL_READ_TIMES; i++) {
@@ -61,23 +67,25 @@ static void hall_init_low_pos(void) {
 		return;
 	}
 	g_hall.state = state;
-	g_hall.prev_dir = g_hall.dir = POSITIVE;
-	g_hall.low_res_pos = pos + 0.5f;
+	if (g_hall.dir == POSITIVE) {
+		g_hall.low_res_pos = pos + 0.5f;
+	}else {
+		g_hall.low_res_pos = pos - 0.5f;
+	}
 }
 
 
-static void __INLINE hall_put_sample(u32 ticks, float angle) {
+static void __INLINE hall_put_sample(u32 ticks) {
 	hsample_t *s = &g_hall.samples;
 	g_hall.last_delta_ticks = ticks;
 	s->ticks_sum -= s->ticks[s->index];
-	s->angles_sum -= s->angles[s->index];
 	s->ticks[s->index] = ticks;
-	s->angles[s->index] = angle;
 	s->ticks_sum += s->ticks[s->index];
-	s->angles_sum += s->angles[s->index];
 	s->index += 1;
+	if (s->filled < SAMPLE_MAX_COUNT) {
+		s->filled++;
+	}
 	if (s->index >= SAMPLE_MAX_COUNT) {
-		s->full = true;
 		s->index = 0;
 	}
 }
@@ -85,17 +93,35 @@ static void __INLINE hall_put_sample(u32 ticks, float angle) {
 
 static float __INLINE hall_elec_angle_vel(void){
 	hsample_t *s = &g_hall.samples;
+	if (s->filled < SAMPLE_MAX_COUNT) {
+		return (PHASE_60_DEGREE) / us_2_s(g_hall.last_delta_ticks);
+	}
 	if (s->ticks_sum == 0) {
 		return 0.0f;
 	}
-	return s->angles_sum / us_2_s(s->ticks_sum);
+	return (PHASE_60_DEGREE * SAMPLE_MAX_COUNT) / us_2_s(s->ticks_sum);
 }
 
 void hall_debug_log(void) {
-	sys_debug("angle dir %d, stat %d, lowres %f, err %d,%d, sp %d\n", g_hall.dir, g_hall.state, g_hall.low_res_pos, g_hall.sig_errors, g_hall.noise_errors, stop_cnt);
+	sys_debug("angle dir %d, stat %d, lowres %f, err %d,%d\n", g_hall.dir, g_hall.state, g_hall.low_res_pos, g_hall.sig_errors, g_hall.noise_errors);
+	sys_debug("D: %d,%d,%d,%d\n", stop_cnt, g_delta_cnt, g_trns_cnt, g_min_delta);
+	sys_debug("RPM: %f\n", hall_get_velocity());
+#if 0
+	if (g_low_off_cnt[0] < 10) {
+		return;
+	}
+	int value[6];
+	u32 mask = cpu_enter_critical();
+	for (int i = 0; i < 6; i++) {
+		value[i] = (int)(g_low_off[i]/(float)g_low_off_cnt[i]);
+		g_low_off[i] = 0;
+		g_low_off_cnt[i] = 0;
+	}
+	cpu_exit_critical(mask);
+	sys_debug("off:%d,%d,%d,%d,%d,%d\n", value[0], value[1], value[2], value[3], value[4], value[5]);
+#endif
 }
 
-
 void hall_init(void) {
 	g_hall.phase_offset = mc_conf()->m.encoder_offset;
 	g_hall.mot_poles = mc_conf()->m.poles;
@@ -103,15 +129,21 @@ void hall_init(void) {
 	g_hall.angle_smooth_cnt = SMOOTH_COUNT + 1;
 	g_hall.angle_smooth_step = 0;
 	g_hall.samples.ticks_sum = 0;
-	g_hall.samples.angles_sum = 0;
 	g_hall.position = 0;
-	g_hall.samples.full = false;
 	g_hall.samples.index = 0;
+	g_hall.samples.filled = 0;
 	g_hall.elec_angle_vel = 0;
+	g_hall.prev_dir = g_hall.dir = POSITIVE;
+	g_min_delta = 1000000 * 100;
 	for (int i = 0; i < SAMPLE_MAX_COUNT; i++) {
-		g_hall.samples.ticks[i] = 0;
-		g_hall.samples.angles[i] = 0;
+		g_hall.samples.ticks[i] = HALL_MAX_TIME;
 	}
+	for (int i = 0; i < 6; i++) {
+		//g_low_off[i] = 0;
+		//g_low_off_cnt[i] = 0;
+	}
+	g_hall.samples.ticks_sum = HALL_MAX_TIME * SAMPLE_MAX_COUNT;
+
 	if (!g_hall.inited) {
 		g_hall.inited = true;
 		gpio_hall_init();
@@ -120,6 +152,14 @@ void hall_init(void) {
 	stop_cnt = 0;
 }
 
+void  hall_set_direction(s8 dir) {
+	if (dir == g_hall.dir) {
+		return;
+	}
+	g_hall.dir = g_hall.prev_dir = dir;
+	hall_init_low_pos();
+}
+
 #if SMOOTH_COUNT > 0
 static float get_angle_diff(float a1, float a2) {
 	float diff = a1 - a2;
@@ -132,7 +172,7 @@ static float get_angle_diff(float a1, float a2) {
 }
 #endif
 
-static bool hall_update_low_pos(void) {
+static __INLINE bool hall_update_low_pos(void) {
 	u8 state = hall_read_state();
 	s16 pos = hall_2_pos[state];
 	if (pos == 7) {
@@ -140,9 +180,7 @@ static bool hall_update_low_pos(void) {
 		return false;
 	}
 	s16 pos_prev = hall_2_pos[g_hall.state];
-	g_hall.state = state;
 	s16 delta_pos = pos - pos_prev;
-	g_hall.low_res_pos = pos;
 	if (delta_pos != 0) {
 		s8  prev_dir = g_hall.dir;
 		if (delta_pos == 1 || delta_pos == -5) {
@@ -152,12 +190,20 @@ static bool hall_update_low_pos(void) {
 			g_hall.dir = NEGATIVE;
 			g_hall.prev_dir = prev_dir;
 		}else {
-			//keep prev dir value
+			if (g_hall.samples.filled > 0) {
+				g_hall.sig_errors ++;
+				return false;
+			}
 		}
 		g_hall.edge_ticks = task_ticks_abs();
 	}else {
 		g_hall.sig_errors ++;
-	}
+		return false;
+	}	
+	g_hall.state = state;
+	
+	g_hall.low_res_pos = pos;
+
 	return true;
 }
 
@@ -166,7 +212,11 @@ hall_t *hall_get(void) {
 }
 
 float hall_get_elec_angle(void) {
-	float angle = g_hall.elec_angle + g_hall.phase_offset;
+	float phase_offset = g_hall.phase_offset;
+	if (g_hall.dir == NEGATIVE) {
+		phase_offset = PHASE_60_DEGREE + phase_offset;
+	}
+	float angle = g_hall.elec_angle + phase_offset;
 	norm_angle_deg(angle);
 	return angle;
 }
@@ -202,10 +252,10 @@ float hall_update_elec_angle(void) {
 	norm_angle_deg(elec_smooth_angle);
 	g_hall.elec_angle = elec_smooth_angle;
 	g_hall.position += g_hall.elec_angle_vel * FOC_CTRL_US / g_hall.mot_poles;
-	if (g_hall.samples.full && (delta_ticks / g_hall.last_delta_ticks >= 1.3f)) {
+	if ((g_hall.samples.filled > 1) && (delta_ticks / g_hall.last_delta_ticks >= 1.4f)) {
 		stop_cnt ++;
-		g_hall.elec_angle_vel = g_hall.elec_angle_vel * 0.99f;
-		if (g_hall.elec_angle_vel < 10) {
+		g_hall.elec_angle_vel = g_hall.elec_angle_vel * 0.95f;
+		if (g_hall.elec_angle_vel < 30) {
 			g_hall.elec_angle_vel = 0;
 		}
 		float velocity_raw = g_hall.elec_angle_vel/PHASE_360_DEGREE/g_hall.mot_poles * 60.0f * g_hall.dir;
@@ -223,47 +273,46 @@ float hall_get_position(void) {
 	return g_hall.position;
 }
 
-static void hall_calc_mot_velocity(u32 prev_ticks) {
-	u32 delta_cnt = time_delta_us(prev_ticks, NULL);
-	if (!g_hall.samples.full && g_hall.samples.index == 0) {
-		if (delta_cnt <= 1000) {
-			delta_cnt = 1000;
-		}
+static __INLINE void hall_calc_mot_velocity(u32 delta_cnt) {
+	if (g_hall.samples.filled == 0) {
+		hall_put_sample(HALL_MAX_TIME/10);
+		return;
 	}
-	hall_put_sample(delta_cnt, PHASE_60_DEGREE);
-	float elec_vel;
-	if (g_hall.b_trns_det) {
-		elec_vel = PHASE_60_DEGREE/(us_2_s(delta_cnt));
-		LowPass_Filter(g_hall.elec_angle_vel, elec_vel, 0.5f);
-	}else {
-		g_hall.elec_angle_vel = hall_elec_angle_vel();
+	if (delta_cnt < g_min_delta) {
+		g_min_delta = delta_cnt;
 	}
+	hall_put_sample(delta_cnt);
+	g_hall.elec_angle_vel = hall_elec_angle_vel();
 	float velocity_raw = g_hall.elec_angle_vel/PHASE_360_DEGREE/g_hall.mot_poles * 60.0f * g_hall.dir;
-	float del_abs = ABS(velocity_raw - g_hall.velocity_raw);
-	if (del_abs > 140) {
-		g_hall.b_trns_det = true;
-	}else if (del_abs < 100) {
-		g_hall.b_trns_det = false;
-	}
 	g_hall.velocity_raw = velocity_raw;
-	LowPass_Filter(g_hall.velocity_filted, velocity_raw, 1.0f);
+	LowPass_Filter(g_hall.velocity_filted, velocity_raw, 0.9F);
 }
 
 
 float hall_offset_detect(float *off) {
 	return 0.0f;
 }
-
+extern float foc_observer_sensorless_angle(void);
 void HALL_IRQHandler(void) {
+	g_delta_cnt++;
+	//int pos_int;
+	//float delta;
 	u32 mask = cpu_enter_critical();
-	u32 prev_ticks = g_hall.edge_ticks;
-	if (!hall_update_low_pos()) {
+	u32 delta_cnt = time_delta_us(g_hall.edge_ticks, NULL);
+	if (delta_cnt < 300) {
+		g_hall.noise_errors++;
 		goto hall_end;
 	}
-	if (time_delta_us(prev_ticks, NULL) == 0) {
-		g_hall.noise_errors++;
+	if (!hall_update_low_pos()) {
 		goto hall_end;
 	}
+#if 0
+	pos_int = g_hall.low_res_pos;
+	delta = g_hall.low_res_pos * 60.0f - foc_observer_sensorless_angle();
+	norm_angle_deg(delta);
+	g_low_off_cnt[pos_int]++;
+	g_low_off[pos_int] += delta;
+#endif
 	g_hall.elec_angle_edge = g_hall.elec_angle;
 #if SMOOTH_COUNT>0
 	g_hall.delta_angle_edge = get_angle_diff(g_hall.low_res_pos * PHASE_60_DEGREE, g_hall.elec_angle_edge);
@@ -275,7 +324,7 @@ void HALL_IRQHandler(void) {
 		g_hall.angle_smooth_cnt = SMOOTH_COUNT + 1;
 	}
 #endif
-	hall_calc_mot_velocity(prev_ticks);
+	hall_calc_mot_velocity(delta_cnt);
 hall_end:
 	cpu_exit_critical(mask);
 	return;

+ 2 - 3
Applications/foc/motor/hall.h

@@ -20,11 +20,9 @@
 
 typedef struct {
 	u32       	ticks[SAMPLE_MAX_COUNT];
-	float   	angles[SAMPLE_MAX_COUNT];
 	u32   		ticks_sum;
-	float   	angles_sum;
 	u32   		index;
-	bool  		full;
+	u32			filled;
 }hsample_t;
 
 typedef struct {
@@ -58,6 +56,7 @@ float hall_get_elec_angle(void);
 float hall_get_velocity(void);
 float hall_get_position(void);
 float hall_offset_detect(float *off);
+void  hall_set_direction(s8 dir);
 hall_t *hall_get(void);
 
 #endif /* _HALL_SENSOR_H__ */

+ 20 - 1
Applications/foc/motor/motor.c

@@ -737,6 +737,14 @@ bool mc_start_epm_move(epm_dir_t dir, bool is_command) {
 		if (!mot_contrl_is_start(&motor.controller)) {
 			mot_contrl_start(&motor.controller, motor.mode);
 			mc_gear_mode_set();
+			#ifdef CONFIG_USE_ENCODER_HALL
+			motor_encoder_start(true);
+			#endif
+			if (dir == EPM_Dir_Back) {
+				motor_encoder_set_direction(NEGATIVE);
+			}else {
+				motor_encoder_set_direction(POSITIVE);
+			}
 			pwm_enable_channel();
 		}else if (mot_contrl_is_auto_holdding(&motor.controller)) {
 			mc_auto_hold(false);
@@ -752,6 +760,7 @@ bool mc_start_epm_move(epm_dir_t dir, bool is_command) {
 		mot_contrl_set_target_vel(&motor.controller, 0);
 	}
 	cpu_exit_critical(mask);
+	sys_debug("epm mov\n");
 	return true;
 }
 
@@ -824,7 +833,9 @@ static s16 if_acc, if_max_vel, if_iq_set;
 static void _if_start_timer_handler(shark_timer_t *t) {
 	mot_contrl_set_vdq_immediate(&motor.controller, 0, 0);
 	task_udelay(200);
+	sys_debug("start IF\n");
 	u32 mask = cpu_enter_critical();
+	mc_internal_init(CTRL_MODE_OPEN, true);
 	mc_set_ctrl_mode(CTRL_MODE_CURRENT);
 	mot_contrl_set_angle(&motor.controller, INVALID_ANGLE);
 	mot_contrl_IF_start(&motor.controller, true, if_acc, if_max_vel, if_iq_set);
@@ -869,6 +880,7 @@ bool mc_start_IF_mode(bool start, s16 accl, s16 max_vel, s16 align_vd, s16 iq_se
 		mc_internal_init(CTRL_MODE_OPEN, false);
 		mot_contrl_IF_start(&motor.controller, false, 0, 0, 0);
 		cpu_exit_critical(mask);
+		pwm_up_enable(true);
 	}
 	return true;
 }
@@ -1339,7 +1351,7 @@ void ADC_IRQHandler(void) {
 
 #if (CONFIG_ENABLE_IAB_REC==1)
 	if (b_iab_rec && (iab_w_count < CONFIG_IAB_REC_COUNT)) {
-		ia[iab_w_count] = (s16)motor.controller.foc.in.curr_abc[0];
+		ia[iab_w_count] = (s16)motor.controller.foc.in.curr_abc[2];
 		ib[iab_w_count] = (s16)motor.controller.foc.in.curr_abc[1];
 		iab_w_count ++;
 	}else if (b_vab_rec && (iab_w_count < CONFIG_IAB_REC_COUNT)) {
@@ -1650,6 +1662,13 @@ static void mc_motor_runstop(void) {
 #ifdef CONFIG_USE_ENCODER_HALL
 		motor_encoder_start(true);
 #endif
+		if (motor.b_epm) {
+			if (motor.epm_dir == EPM_Dir_Back) {
+				motor_encoder_set_direction(NEGATIVE);
+			}else {
+				motor_encoder_set_direction(POSITIVE);
+			}
+		}
 		g_meas_foc.first = true;
 		motor.foc_start_cnt ++;
 		cpu_exit_critical(mask);

+ 23 - 13
Applications/foc/motor/motor.h

@@ -150,7 +150,7 @@ static __INLINE foc_t *foc(void) {
 static __INLINE float motor_encoder_get_angle(void) {
 #ifdef CONFIG_USE_ENCODER_HALL
 	return hall_update_elec_angle();
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	return encoder_update_elec_angle(true);
 #else
 	#error "Postion sensor ERROR"
@@ -160,7 +160,7 @@ static __INLINE float motor_encoder_get_angle(void) {
 static __INLINE u8 motor_encoder_may_error(void) {
 #ifdef CONFIG_USE_ENCODER_HALL
 	return false;
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	return encoder_may_error();
 #else
 	#error "Postion sensor ERROR"
@@ -170,7 +170,7 @@ static __INLINE u8 motor_encoder_may_error(void) {
 static __INLINE void motor_encoder_update(bool detect_err) {
 #ifdef CONFIG_USE_ENCODER_HALL
 	hall_update_elec_angle();
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	encoder_update_elec_angle(detect_err);
 #else
 	#error "Postion sensor ERROR"
@@ -180,7 +180,7 @@ static __INLINE void motor_encoder_update(bool detect_err) {
 static __INLINE float motor_encoder_get_speed(void) {
 #ifdef CONFIG_USE_ENCODER_HALL
 	return hall_get_velocity();
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	return encoder_get_speed();
 #else
 	#error "Postion sensor ERROR"
@@ -190,7 +190,7 @@ static __INLINE float motor_encoder_get_speed(void) {
 static __INLINE float motor_encoder_get_vel_count(void) {
 #ifdef CONFIG_USE_ENCODER_HALL
 	return hall_get_velocity();
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	return encoder_get_vel_count();
 #else
 	#error "Postion sensor ERROR"
@@ -200,7 +200,7 @@ static __INLINE float motor_encoder_get_vel_count(void) {
 static __INLINE float motor_encoder_get_position(void) {
 #ifdef CONFIG_USE_ENCODER_HALL
 	return hall_get_position();
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	return encoder_get_position();
 #else
 	#error "Postion sensor ERROR"
@@ -211,7 +211,7 @@ static __INLINE float motor_encoder_get_position(void) {
 static __INLINE void motor_encoder_init(void) {
 #ifdef CONFIG_USE_ENCODER_HALL
 	hall_init();
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	encoder_init();
 #else
 	#error "Postion sensor ERROR"
@@ -221,7 +221,7 @@ static __INLINE void motor_encoder_init(void) {
 static __INLINE void motor_encoder_start(bool start) {
 #ifdef CONFIG_USE_ENCODER_HALL
 	hall_init();
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	encoder_init_clear();
 #else
 	#error "Postion sensor ERROR"
@@ -231,7 +231,7 @@ static __INLINE void motor_encoder_start(bool start) {
 static __INLINE float motor_encoder_zero_phase_detect(float *enc_off){
 #ifdef CONFIG_USE_ENCODER_HALL
 	return hall_offset_detect(enc_off);
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	return encoder_zero_phase_detect(enc_off);
 #else
 	#error "Postion sensor ERROR"
@@ -241,7 +241,7 @@ static __INLINE float motor_encoder_zero_phase_detect(float *enc_off){
 static __INLINE void motor_encoder_clear_detect(void) {
 #ifdef CONFIG_USE_ENCODER_HALL
 	
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	encoder_clear_cnt_offset();
 #else
 	#error "Postion sensor ERROR"
@@ -252,7 +252,7 @@ static __INLINE void motor_encoder_clear_detect(void) {
 static __INLINE void motor_encoder_lock_pos(bool lock) {
 #ifdef CONFIG_USE_ENCODER_HALL
 		
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	encoder_lock_position(lock);
 #else
 	#error "Postion sensor ERROR"
@@ -262,7 +262,7 @@ static __INLINE void motor_encoder_lock_pos(bool lock) {
 static __INLINE void motor_encoder_band_epm(bool epm) {
 #ifdef CONFIG_USE_ENCODER_HALL
 		
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	encoder_epm_pll_band(epm);
 #else
 	#error "Postion sensor ERROR"
@@ -272,12 +272,22 @@ static __INLINE void motor_encoder_band_epm(bool epm) {
 static __INLINE void motor_encoder_produce_error(bool error) {
 #ifdef CONFIG_USE_ENCODER_HALL
 
-#elif defined (USE_ENCODER_ABI)
+#elif defined (CONFIG_USE_ENCODER_ABI)
 	encoder_produce_error(error);
 #else
 	#error "Postion sensor ERROR"
 #endif
 }
 
+static __INLINE void motor_encoder_set_direction(s8 dir) {
+#ifdef CONFIG_USE_ENCODER_HALL
+	hall_set_direction(dir);
+#elif defined (CONFIG_USE_ENCODER_ABI)
+#else
+	#error "Postion sensor ERROR"
+#endif
+}
+
+
 #endif /* _MOTOR_H__ */