Ver Fonte

hall按Simulink仿真的逻辑重写

Signed-off-by: kevin <huhui@sharkgulf.com>
kevin há 2 anos atrás
pai
commit
f42d435954

+ 5 - 3
Applications/app/app.c

@@ -31,6 +31,7 @@ extern void encoder_log(void);
 extern void sample_log(void);
 extern void throttle_log(void);
 extern bool can_is_connect_pc(void);
+extern void hall_debug_log(void);
 extern measure_time_t g_meas_hall;
 extern measure_time_t g_meas_foc;
 extern measure_time_t g_meas_MCTask;
@@ -97,18 +98,19 @@ static void app_print_log(void) {
 	//sys_debug("Slow: %d - %d, err:%d, %d\n", g_meas_MCTask.intval_time, g_meas_MCTask.exec_time, g_meas_MCTask.exec_max_error_time, g_meas_MCTask.exec_time_error);
 	sys_debug("Fast: %d - %d, err: %d-%d-%d\n", g_meas_foc.intval_time, g_meas_foc.exec_time, g_meas_foc.intval_hi_err, g_meas_foc.intval_low_err, g_meas_foc.exec_max_error_time);
 	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("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("ADC Vref %f, %f\n", get_adc_vref(), adc_5vref_compesion());
 	//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);
 	//encoder_log();
+	hall_debug_log();
 	//motor_debug();
 	//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\n", mot_contrl_is_start(mot_contrl())?"start":"stop", motor.foc_start_cnt, motor.foc_stop_cnt);
 	//F_debug();
 	//eCtrl_debug_log();
 	//sys_debug("enc err %d, %d\n", foc_observer_enc_errcount(), foc_observer_sensorless_stable());

+ 35 - 1
Applications/bsp/gd32/board_mc105_v3.h

@@ -322,6 +322,38 @@
 #define CAN_RX0_IRQHandler  USBD_LP_CAN0_RX0_IRQHandler
 #endif
 /* 是否用编码器 */
+#ifdef CONFIG_USE_ENCODER_HALL
+#define HALL_A_GROUP GPIOB
+#define HALL_A_PIN GPIO_PIN_4
+#define HALL_A_RCU RCU_GPIOB
+#define HALL_A_MODE GPIO_MODE_IN_FLOATING
+
+#define HALL_B_GROUP GPIOB
+#define HALL_B_PIN GPIO_PIN_5
+#define HALL_B_RCU RCU_GPIOB
+#define HALL_B_MODE GPIO_MODE_IN_FLOATING
+
+#define HALL_C_GROUP GPIOB
+#define HALL_C_PIN GPIO_PIN_6
+#define HALL_C_RCU RCU_GPIOB
+#define HALL_C_MODE GPIO_MODE_IN_FLOATING
+
+#define HALL_A_IRQ  				EXTI4_IRQn
+#define HALL_A_EXTI 				EXTI_4
+#define HALL_A_EXIT_SRC_GROUP 		GPIO_PORT_SOURCE_GPIOB
+#define HALL_A_EXIT_SRC_PIN 		GPIO_PIN_SOURCE_4
+
+#define HALL_B_IRQ  				EXTI5_9_IRQn
+#define HALL_B_EXTI 				EXTI_5
+#define HALL_B_EXIT_SRC_GROUP 		GPIO_PORT_SOURCE_GPIOB
+#define HALL_B_EXIT_SRC_PIN 		GPIO_PIN_SOURCE_5
+
+#define HALL_C_IRQ  				EXTI5_9_IRQn
+#define HALL_C_EXTI 				EXTI_6
+#define HALL_C_EXIT_SRC_GROUP 		GPIO_PORT_SOURCE_GPIOB
+#define HALL_C_EXIT_SRC_PIN 		GPIO_PIN_SOURCE_6
+
+#else
 #define USE_ENCODER_ABI
 #define ENCODER_TYPE ENCODER_MT
 
@@ -375,13 +407,14 @@
 #define ENC_PWM_TIMER_IRQ_CH TIMER_INT_CH0
 #define ENC_PWM_TIMER_INT_FLG TIMER_INT_FLAG_CH0
 #define ENC_PWM_IRQHandler TIMER1_IRQHandler
-
+#endif
 /* board id, 0x01=>v3, 0x02=>v4 */
 #define BOOT_PIN_0_GROUP GPIOC 
 #define BOOT_PIN_0_PIN   GPIO_PIN_6
 #define BOOT_PIN_1_GROUP GPIOC 
 #define BOOT_PIN_1_PIN   GPIO_PIN_7
 
+#ifdef 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采集到信号没有变才认为是有效值*/
@@ -413,6 +446,7 @@
 #else
 #error "Postion sensor ERROR"
 #endif
+#endif
 
 #define DEBUG_PORT_UART2
 //#define CONFIG_MOTOR_TORQUE_CONF "foc/motor/A1_motor_config.c"

+ 36 - 1
Applications/bsp/gd32/gpio.c

@@ -241,11 +241,16 @@ u16 gpio_get_pin_values(void) {
 #ifdef BOOT_PIN_1_GROUP
 	value |= (gpio_input_bit_get(BOOT_PIN_1_GROUP, BOOT_PIN_1_PIN) == SET?:0) << 4;
 #endif
+#ifdef CONFIG_USE_ENCODER_HALL
+	value |= (gpio_input_bit_get(HALL_A_GROUP, HALL_A_PIN) == SET?:0) << 5;
+	value |= (gpio_input_bit_get(HALL_B_GROUP, HALL_B_PIN) == SET?:0) << 6;
+	value |= (gpio_input_bit_get(HALL_C_GROUP, HALL_C_PIN) == SET?:0) << 7;
+#else
 	value |= (gpio_input_bit_get(ENC_A_GROUP, ENC_A_PIN) == SET?:0) << 5;
 	value |= (gpio_input_bit_get(ENC_B_GROUP, ENC_B_PIN) == SET?:0) << 6;
 	value |= (gpio_input_bit_get(ENC_I_GROUP, ENC_I_PIN) == SET?:0) << 7;
 	value |= (gpio_input_bit_get(ENC_PWM_GROUP, ENC_PWM_PIN) == SET?:0) << 8;
-
+#endif
 	return value;
 }
 
@@ -293,4 +298,34 @@ int gpio_funckey_value(void) {
 	return 0;
 }
 
+#ifdef CONFIG_USE_ENCODER_HALL
+void gpio_hall_init(void) {
+	rcu_periph_clock_enable(HALL_A_RCU);
+	gpio_init(HALL_A_GROUP, HALL_A_MODE, GPIO_OSPEED_50MHZ, HALL_A_PIN);
+
+	rcu_periph_clock_enable(HALL_B_RCU);
+	gpio_init(HALL_B_GROUP, HALL_B_MODE, GPIO_OSPEED_50MHZ, HALL_B_PIN);
+
+	rcu_periph_clock_enable(HALL_C_RCU);
+	gpio_init(HALL_C_GROUP, HALL_C_MODE, GPIO_OSPEED_50MHZ, HALL_C_PIN);
+
+	gpio_exti_source_select(HALL_A_EXIT_SRC_GROUP, HALL_A_EXIT_SRC_PIN);
+	exti_init(HALL_A_EXTI, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	exti_interrupt_flag_clear(HALL_A_EXTI);
+	exti_interrupt_enable(HALL_A_EXTI);
+	nvic_irq_enable(HALL_A_IRQ, HALL_IRQ_PRIORITY, 0U);
+
+	gpio_exti_source_select(HALL_B_EXIT_SRC_GROUP, HALL_B_EXIT_SRC_PIN);
+	exti_init(HALL_B_EXTI, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	exti_interrupt_flag_clear(HALL_B_EXTI);
+	exti_interrupt_enable(HALL_B_EXTI);
+	nvic_irq_enable(HALL_B_IRQ, HALL_IRQ_PRIORITY, 0U);
+
+	gpio_exti_source_select(HALL_C_EXIT_SRC_GROUP, HALL_C_EXIT_SRC_PIN);
+	exti_init(HALL_C_EXTI, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	exti_interrupt_flag_clear(HALL_C_EXTI);
+	exti_interrupt_enable(HALL_C_EXTI);
+	nvic_irq_enable(HALL_C_IRQ, HALL_IRQ_PRIORITY, 0U);
+}
+#endif
 

+ 6 - 1
Applications/bsp/gd32/gpio.h

@@ -40,5 +40,10 @@ void gpio_brk_light_enable(bool enable);
 u8  gpio_board_id(void);
 bool gpio_is_repear_mode(void);
 u16 gpio_get_pin_values(void);
-
+#ifdef CONFIG_USE_ENCODER_HALL
+void gpio_hall_init(void);
+#define gpio_hall_a_value() (gpio_input_bit_get(HALL_A_GROUP, HALL_A_PIN)==SET?1:0)
+#define gpio_hall_b_value() (gpio_input_bit_get(HALL_B_GROUP, HALL_B_PIN)==SET?1:0)
+#define gpio_hall_c_value() (gpio_input_bit_get(HALL_C_GROUP, HALL_C_PIN)==SET?1:0)
+#endif
 #endif /* _GPIO_PIN_H__ */

+ 1 - 1
Applications/bsp/gd32/mc_irqs.c

@@ -124,7 +124,7 @@ void EXTI0_IRQHandler(void)
 		exti_interrupt_flag_clear(EXTI_0);
 #if (ENC_I_EXTI == EXTI_0)
 		ABI_I_IRQHandler();
-#elif defined (USE_ENCODER_HALL)
+#elif defined (CONFIG_USE_ENCODER_HALL)
 		HALL_IRQHandler();
 #else
 	#error "Postion sensor ERROR"

+ 4 - 0
Applications/foc/commands.c

@@ -312,10 +312,14 @@ static void process_foc_command(foc_cmd_body_t *command) {
 		}
 		case Foc_Enc_Zero_Cali_Result:
 		{
+		#ifndef CONFIG_USE_ENCODER_HALL
 			response[2] = encoder_get_cali_error()?1:0;
 			u32 off = encoder_get_cnt_offset();
 			encode_u32(response + 3, off);
 			len += 4;
+		#else
+			erroCode = FOC_Param_Err;
+		#endif
 			break;
 		}
 		case Foc_Force_Open_Run:

+ 257 - 488
Applications/foc/motor/hall.c

@@ -1,488 +1,257 @@
-#include <string.h>
-#include "bsp/bsp_driver.h"
-#include "os/os_task.h"
-#include "libs/utils.h"
-#include "libs/logger.h"
-#include "math/fast_math.h"
-#include "foc/motor/hall.h"
-#include "app/nv_storage.h"
-#include "libs/time_measure.h"
-#include "app/nv_storage.h"
-#include "libs/logger.h"
-
-//#define USE_DETECTED_ANGLE 1
-
-#define HALL_READ_TIMES 9
-
-static u32 _hall_detect_task(void *args);
-static void _hall_init_el_angle(void);
-
-
-//#define HALL_PLACE_OFFSET (360-25)//(230) //(345) //315
-#define HALL_PLACE_OFFSET (230)
-
-/* 
-4,5,1,3,2,6,4
-*/
-
-hall_t _sensor_hander;
-
-measure_time_t g_meas_hall = {.exec_max_time = 6,};
-
-//#define read_hall(h,t) {h = get_hall_stat(HALL_READ_TIMES); t = _hall_table[h];}
-#define us_2_s(tick) ((float)tick / 1000000.0f) //s32q14
-
-static void __inline _hall_put_sample(u32 ticks, float angle) {
-	hall_sample_t *s = &_sensor_hander.samples;
-	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->index >= SAMPLE_MAX_COUNT) {
-		s->full = true;
-		s->index = 0;
-	}
-}
-
-static u32 __inline__ _hall_get_angle_ticks(void) {
-	hall_sample_t *s = &_sensor_hander.samples;
-	if (!s->full) {
-		return s->ticks[s->index-1];
-	}else {
-		return s->ticks_sum/SAMPLE_MAX_COUNT;
-	}
-}
-
-static float __inline _hall_angle_speed(void){
-	hall_sample_t *s = &_sensor_hander.samples;
-	if (s->ticks_sum == 0) {
-		return 0.0f;
-	}
-	
-	if (!s->full) {
-		return s->angles[s->index - 1] / us_2_s(s->ticks[s->index-1]);
-	}else {
-		return s->angles_sum / us_2_s(s->ticks_sum);
-	}
-}
-
-void hall_debug_log(void) {
-	sys_debug("angle dir %d\n", _sensor_hander.direction);
-}
-
-/*
-static bool __inline _hall_data_empty(void) {
-	hall_sample_t *s = &_sensor_hander.samples;
-	if ((!s->full) && (s->index == 0)){
-		return true;
-	}
-	return false;
-}
-*/
-
-static void hall_sensor_default(s8 direction) {
-	memset(&_sensor_hander, 0, sizeof(_sensor_hander));
-	_sensor_hander.phase_offset = HALL_PLACE_OFFSET;//mc_config_get()->hall_offset;
-	for (int i = 0; i < 8; i++) {
-		_sensor_hander.angle_table[i] = (nv_get_motor_params()->hall_table[i]);
-	}
-	_sensor_hander.manual_angle = 0x3FF;
-	_sensor_hander.direction = direction;
-	_sensor_hander.running_dir = _sensor_hander.direction;
-	_hall_init_el_angle();
-}
-
-void hall_sensor_init(void) {
-	hall_sensor_default(POSITIVE);
-	mc_hall_init();
-	shark_task_create(_hall_detect_task, NULL);
-}
-
-void hall_set_direction(s8 direction) {
-	hall_sensor_default(direction);
-}
-
-void hall_sensor_clear(void) {
-	hall_set_direction(POSITIVE);
-}
-
-static u32 _hall_detect_task(void *args) {
-	if (_sensor_hander.el_speed != 0) {
-		u32 ticks_now = task_ticks_abs();
-		if (ticks_now > _sensor_hander.hall_ticks) {
-			if (task_delta_ticks(ticks_now) > 2000*1000) {
-				hall_sensor_clear();
-			}
-		}
-	}
-	return 0;
-}
-
-#if 1
-int hall_e_count = 0;
-float hall_sensor_get_theta(bool detect_err){
-	hall_e_count++;
-	float angle_add = _sensor_hander.delta_angle_ts;
-	if (_sensor_hander.comp_count > 0) {
-		_sensor_hander.comp_count--;
-		angle_add += _sensor_hander.angle_comp_ts;
-	}
-	_sensor_hander.estimate_delta_angle += angle_add;
-
-	float el_angle = _sensor_hander.estimate_delta_angle;
-	if (el_angle > _sensor_hander.next_delta_angle) {
-		el_angle = _sensor_hander.next_delta_angle;
-	}
-	if (_sensor_hander.direction == POSITIVE) {
-		el_angle = _sensor_hander.estimate_el_angle + el_angle;
-	}else {
-		el_angle = _sensor_hander.estimate_el_angle - el_angle;
-	}
-	norm_angle_deg(el_angle);
-	if (hall_e_count%5 == 0) {
-		plot_2data16((s16)el_angle, _sensor_hander.hall_stat*10);
-	}
-	return (el_angle);
-}
-#else
-static int test_loop = 0;
-float hall_sensor_get_theta(void){
-	float angle_add = _sensor_hander.delta_angle_ts;
-	float comp_angle = 0;
-	if (_sensor_hander.comp_count > 0) {
-		_sensor_hander.comp_count--;
-		comp_angle = _sensor_hander.angle_comp_ts;
-	}
-
-	if (_sensor_hander.direction == POSITIVE) {
-		_sensor_hander.estimate_delta_angle += angle_add;
-		_sensor_hander.estimate_el_angle += (angle_add + comp_angle);
-	}else {
-		_sensor_hander.estimate_delta_angle -= angle_add;
-		_sensor_hander.estimate_el_angle -= (angle_add + comp_angle);
-	}
-	norm_angle_deg(_sensor_hander.estimate_el_angle);
-	test_loop ++;
-	if (test_loop % 20 == 0) {
-		//plot_3data16(_sensor_hander.estimate_el_angle, _sensor_hander.angle_comp_ts * 1000, _sensor_hander.comp_count);
-	}
-	return ( _sensor_hander.estimate_el_angle);
-}
-
-#endif
-
-float hall_sensor_get_speed(void) {
-	return (_sensor_hander.rpm) * _sensor_hander.running_dir;
-}
-
-int hall_offset_increase(int inc) {
-	inc = inc << 19;
-	if (_sensor_hander.phase_offset + inc >= PHASE_360_DEGREE) {
-		_sensor_hander.phase_offset = _sensor_hander.phase_offset + inc - PHASE_360_DEGREE;
-	}else {
-		_sensor_hander.phase_offset += inc;
-	}
-	return _sensor_hander.phase_offset;
-}
-
-s32 *hall_get_table(void) {
-	return _sensor_hander.angle_table;
-}
-
-static float sin_hall[8];
-static float cos_hall[8];
-static int hall_iterations[8];
-void hall_detect_angle(s16 angle) {
-	_sensor_hander.manual_angle = (angle);
-	int hall = get_hall_stat(HALL_READ_TIMES);
-	float s, c;
-	normal_sincosf(degree_2_pi(angle), &s, &c);
-	sin_hall[hall] += s;
-	cos_hall[hall] += c;
-	hall_iterations[hall]++;
-}
-
-bool hall_detect_angle_finish(void) {
-	int fails = 0;
-	for(int i = 0;i < 8;i++) {
-		if (hall_iterations[i] > 30) {
-			float ang = pi_2_degree(atan2f(sin_hall[i], cos_hall[i]));
-			fast_norm_angle(&ang);
-			_sensor_hander.angle_table[i] = (ang);
-		} else {
-			_sensor_hander.angle_table[i] = (0x3FF);
-			fails++;
-		}
-	}
-	if (fails == 2) {
-		nv_save_hall_table(_sensor_hander.angle_table);
-	}
-	memset(sin_hall, 0, sizeof(sin_hall));
-	memset(cos_hall, 0, sizeof(cos_hall));
-	memset(hall_iterations, 0, sizeof(hall_iterations));	
-	return fails == 2;
-}
-
-void hall_detect_offset(s16 angle) {
-	_sensor_hander.manual_angle = (angle);
-}
-
-bool hall_detect_offset_finish(void) {
-	int fails = 0;
-	for(int i = 0;i < 8;i++) {
-		if (hall_iterations[i] > 20) {
-			_sensor_hander.angle_table[i] = _sensor_hander.angle_table[i] / hall_iterations[i];
-		}
-	}
-	return (fails == 2);
-}
-static void _hall_init_el_angle(void) {
-	_sensor_hander.hall_stat = get_hall_stat(HALL_READ_TIMES);
-#ifdef USE_DETECTED_ANGLE
-	if (_sensor_hander.hall_stat == 0 || _sensor_hander.hall_stat == 7) {
-		_sensor_hander.sensor_error ++;
-		return;
-	}
-	_sensor_hander.measured_el_angle = _sensor_hander.phase_offset + _sensor_hander.angle_table[_sensor_hander.hall_stat];
-#else
-	s32 sector_center = PHASE_60_DEGREE/2;
-  	switch ( _sensor_hander.hall_stat )
-  	{
-    case STATE_5:
-      	_sensor_hander.measured_el_angle = _sensor_hander.phase_offset + sector_center;
-      	break;
-    case STATE_1:
-		_sensor_hander.measured_el_angle = _sensor_hander.phase_offset + PHASE_60_DEGREE + sector_center;
-      	break;
-    case STATE_3:
-		_sensor_hander.measured_el_angle = _sensor_hander.phase_offset + PHASE_120_DEGREE + sector_center;
-      	break;
-    case STATE_2:
-		_sensor_hander.measured_el_angle = _sensor_hander.phase_offset + PHASE_180_DEGREE + sector_center;
-      	break;
-    case STATE_6:
-		_sensor_hander.measured_el_angle = _sensor_hander.phase_offset + PHASE_240_DEGREE + sector_center;
-      	break;
-    case STATE_4:
-		_sensor_hander.measured_el_angle = _sensor_hander.phase_offset + PHASE_300_DEGREE + sector_center;
-      	break;
-    default:
-      	/* Bad hall sensor configutarion so update the speed reliability */
-      	_sensor_hander.sensor_error ++;
-      	return;
- 	}
-#endif
-	_sensor_hander.sensor_error = 0;
-  	/* Initialize the measured angle */
-	_sensor_hander.measured_el_angle += PHASE_60_DEGREE;
-	norm_angle_deg(_sensor_hander.measured_el_angle);
-  	_sensor_hander.estimate_el_angle = _sensor_hander.measured_el_angle;
-	_sensor_hander.hall_ticks = task_ticks_abs();
-}
-
-static __inline__ float _get_angle(u8 state, float added) {
-#ifdef USE_DETECTED_ANGLE
-	return _sensor_hander.phase_offset + _sensor_hander.angle_table[state];
-#else
-	return _sensor_hander.phase_offset + added;
-#endif
-}
-/* 4,5,1,3,2,6,4 */
-static float _hall_position(u8 state_now, u8 state_prev) {
-	float theta_now =  0xFFFFFFFF;
-	switch (state_now) {
-		case STATE_1:
-			if (state_prev == STATE_5) {
-				_sensor_hander.running_dir = POSITIVE;
-				theta_now = _get_angle(state_now, PHASE_60_DEGREE);//_sensor_hander.phase_offset + PHASE_60_DEGREE;
-			}else if (state_prev == STATE_3) {
-				_sensor_hander.running_dir = NEGATIVE;
-				theta_now = _get_angle(state_now, PHASE_120_DEGREE);//_sensor_hander.phase_offset + PHASE_120_DEGREE;
-			}
-			break;
-		case STATE_2:
-			if (state_prev == STATE_3) {
-				_sensor_hander.running_dir = POSITIVE;
-				theta_now = _get_angle(state_now, PHASE_180_DEGREE);//_sensor_hander.phase_offset + PHASE_180_DEGREE;
-			}else if (state_prev == STATE_6) {
-				_sensor_hander.running_dir = NEGATIVE;
-				theta_now = _get_angle(state_now, PHASE_240_DEGREE);//_sensor_hander.phase_offset + PHASE_240_DEGREE;
-			}
-			break;
-		case STATE_3:
-			if (state_prev == STATE_1) {
-				_sensor_hander.running_dir = POSITIVE;
-				theta_now = _get_angle(state_now, PHASE_120_DEGREE);//_sensor_hander.phase_offset + PHASE_120_DEGREE;
-			}else if (state_prev == STATE_2) {
-				_sensor_hander.running_dir = NEGATIVE;
-				theta_now = _get_angle(state_now, PHASE_180_DEGREE);//_sensor_hander.phase_offset + PHASE_180_DEGREE;
-			}
-			break;
-		case STATE_4:
-			if (state_prev == STATE_6) {
-				_sensor_hander.running_dir = POSITIVE;
-				theta_now = _get_angle(state_now, PHASE_300_DEGREE);//_sensor_hander.phase_offset + PHASE_300_DEGREE;
-			}else if (state_prev == STATE_5) {
-				_sensor_hander.running_dir = NEGATIVE;
-				theta_now = _get_angle(state_now, PHASE_0_DEGREE);//_sensor_hander.phase_offset + PHASE_0_DEGREE;
-			}
-			break;
-		case STATE_5:
-			if (state_prev == STATE_4) {
-				_sensor_hander.running_dir = POSITIVE;
-				theta_now = _get_angle(state_now, PHASE_0_DEGREE);//_sensor_hander.phase_offset + PHASE_0_DEGREE;
-			}else if (state_prev == STATE_1) {
-				_sensor_hander.running_dir = NEGATIVE;
-				theta_now = _get_angle(state_now, PHASE_60_DEGREE);//_sensor_hander.phase_offset + PHASE_60_DEGREE;
-			}
-			break;
-		case STATE_6:
-			if (state_prev == STATE_2) {
-				_sensor_hander.running_dir = POSITIVE;
-				theta_now = _get_angle(state_now, PHASE_240_DEGREE);//_sensor_hander.phase_offset + PHASE_240_DEGREE;
-			}else if (state_prev == STATE_4) {
-				_sensor_hander.running_dir = NEGATIVE;
-				theta_now = _get_angle(state_now, PHASE_300_DEGREE);//_sensor_hander.phase_offset + PHASE_300_DEGREE;
-			}
-			break;
-		default:
-			_sensor_hander.sensor_error ++;
-			return 0xFFFFFFFF;
-	}
-	if (theta_now != 0xFFFFFFFF) {
-		norm_angle_deg(theta_now);
-	}
-	return theta_now;
-}
-
-#ifdef USE_DETECTED_ANGLE
-static __inline u8 _next_hall(u8 hall_now) {
-	switch (hall_now) {
-		case STATE_1:
-			if (_sensor_hander.direction == POSITIVE) {
-				return STATE_3;
-			}else {
-				return STATE_5;
-			}
-		case STATE_2:
-			if (_sensor_hander.direction == POSITIVE) {
-				return STATE_6;
-			}else {
-				return STATE_3;
-			}
-		case STATE_3:
-			if (_sensor_hander.direction == POSITIVE) {
-				return STATE_2;
-			}else {
-				return STATE_1;
-			}
-		case STATE_4:
-			if (_sensor_hander.direction == POSITIVE) {
-				return STATE_5;
-			}else {
-				return STATE_6;
-			}
-		case STATE_5:
-			if (_sensor_hander.direction == POSITIVE) {
-				return STATE_1;
-			}else {
-				return STATE_4;
-			}
-		case STATE_6:
-			if (_sensor_hander.direction == POSITIVE) {
-				return STATE_4;
-			}else {
-				return STATE_2;
-			}
-		default: //not reached here
-			return STATE_1;
-	}
-} 
-
-
-static __inline__ s32 _get_delta_angle(u8 now, u8 next) {
-	s32 delta_angle = _sensor_hander.angle_table[next] - _sensor_hander.angle_table[now];
-	if (_sensor_hander.direction == POSITIVE) {
-		if (delta_angle < 0) { //process cross 360 degree
-			delta_angle += PHASE_360_DEGREE;
-		}
-	}else if (_sensor_hander.direction == NEGATIVE) {
-		if (delta_angle > 0) { //process cross 360 degree
-			delta_angle -= PHASE_360_DEGREE;
-		}
-		delta_angle = -delta_angle;
-	}
-	return delta_angle;
-}
-#endif
-
-void HALL_IRQHandler(void) {
-	time_measure_start(&g_meas_hall);
-	u8 hall_stat_now = get_hall_stat(HALL_READ_TIMES);
-	u8 hall_stat_prev = _sensor_hander.hall_stat;
-	u32 hall_ticks_now = task_ticks_abs();	
-
-	/*获取当前转子角度*/
-	float theta_now = _hall_position(hall_stat_now, hall_stat_prev);
-	if (theta_now == 0xFFFFFFFF) {
-		return;
-	}
-	//plot_2data16(hall_stat_now*60, _sensor_hander.manual_angle);
-	//获取两次中断的时间间隔,估计速度
-	u32 delta_us = task_delta_ticks(hall_ticks_now);
-	if (delta_us == 0) {
-		return;
-	}
-	_sensor_hander.hall_ticks = hall_ticks_now;
-	//获取两次中断之间转子转过的角度,获取预期的下次hall状态变换转过的角度
-#ifdef USE_DETECTED_ANGLE
-	float delta_angle = _get_delta_angle(hall_stat_prev, hall_stat_now);
-	float next_delta_angle = _get_delta_angle(hall_stat_now, _next_hall(hall_stat_now));
-#else
-	float delta_angle = PHASE_60_DEGREE;
-	float next_delta_angle = delta_angle;
-#endif
-	float delta_time = us_2_s(delta_us);
-	float prev_imme_el_speed = _sensor_hander.immediately_el_speed + 1;
-	_sensor_hander.immediately_el_speed = delta_angle/delta_time; //s32q5
-	float delta_el_speed = abs(_sensor_hander.immediately_el_speed - prev_imme_el_speed);
-	if (delta_el_speed*100/prev_imme_el_speed >= 40) { //即时速度增加40%,认为不稳定,需要使用即时速度估计转子位置
-		_sensor_hander.trns_detect = true;
-	}else {
-		_sensor_hander.trns_detect = false;
-	}
-	_hall_put_sample(delta_us, delta_angle);
-	u32 mask = cpu_enter_critical();
-	if (_sensor_hander.samples.full) {
-		//float estimate_delta_angle =  _sensor_hander.next_delta_angle - _sensor_hander.estimate_delta_angle;
-		//plot_2data16(estimate_delta_angle>>19, (estimate_delta_angle/((s32)(delta_us/FOC_CTRL_US)))>>10);//, _sensor_hander.estimate_delta_angle>>19);
-		/*通过上次预估的转子位置,对当前的预估速度进行补偿*/
-		delta_us = _hall_get_angle_ticks();
-		//_sensor_hander.comp_count = 50;
-		//_sensor_hander.angle_comp_ts = estimate_delta_angle/(float)_sensor_hander.comp_count;
-		_sensor_hander.estimate_el_angle = theta_now;
-	}else {
-		_sensor_hander.comp_count = 0;
-		_sensor_hander.angle_comp_ts = 0;
-		_sensor_hander.estimate_el_angle = theta_now;
-	}
-	_sensor_hander.estimate_delta_angle = 0;
-	_sensor_hander.delta_angle_ts = (next_delta_angle/(us_2_s(delta_us)/FOC_CTRL_US));
-	_sensor_hander.next_delta_angle = next_delta_angle;
-	_sensor_hander.measured_el_angle = theta_now;
-
-	cpu_exit_critical(mask);
-	_sensor_hander.hall_stat = hall_stat_now;
-	_sensor_hander.hall_ticks = hall_ticks_now;
-	_sensor_hander.el_speed = _hall_angle_speed();	//s32q5
-	_sensor_hander.rpm = (_sensor_hander.el_speed / 360 * 60) * nv_get_motor_params()->poles; //s32q5
-	//plot_3data16(_sensor_hander.rpm >> 5, _sensor_hander.el_speed>>5, delta_us);
-	time_measure_end(&g_meas_hall);
-
-	//plot_3data16(delta_us/10, hall_stat_prev * 10, _sensor_hander.hall_stat * 10);
-}
-
-
+#include <string.h>
+#include "bsp/bsp_driver.h"
+#include "os/os_task.h"
+#include "libs/utils.h"
+#include "libs/logger.h"
+#include "math/fast_math.h"
+#include "foc/motor/hall.h"
+#include "foc/mc_config.h"
+#include "libs/time_measure.h"
+#include "app/nv_storage.h"
+#include "libs/logger.h"
+
+//#define USE_DETECTED_ANGLE 1
+
+#define HALL_READ_TIMES 9
+#define SMOOTH_COUNT 10.0F
+
+/* 
+4,5,1,3,2,6,4
+*/
+static s8 hall_2_pos[] = {7,5,1,0,3,4,2,7};
+static hall_t g_hall;
+
+measure_time_t g_meas_hall = {.exec_max_time = 6,};
+
+//#define read_hall(h,t) {h = get_hall_stat(HALL_READ_TIMES); t = _hall_table[h];}
+#define us_2_s(tick) ((float)tick / 1000000.0f) //s32q14
+#define HALL_TIMEOUT_US (1*1000000L)
+
+
+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++) {
+		if (gpio_hall_a_value()) {
+			hall_a++;
+		}
+		if (gpio_hall_b_value()) {
+			hall_b++;
+		}
+		if (gpio_hall_c_value()) {
+			hall_c++;
+		}
+	}
+	u8 state = 0;
+	if (hall_a > (HALL_READ_TIMES/2 + 1)) {
+		state = 1<<2;
+	}
+	if (hall_b > (HALL_READ_TIMES/2 + 1)) {
+		state = state | (1<<1);
+	}
+	if (hall_c > (HALL_READ_TIMES/2 + 1)) {
+		state = state | 1;
+	}
+	return state;
+}
+
+static void hall_init_low_pos(void) {
+	u8 state = hall_read_state();
+	s16 pos = hall_2_pos[state];
+	if (pos == 7) {
+		g_hall.errors ++;
+		return;
+	}
+	g_hall.state = state;
+	g_hall.prev_dir = g_hall.dir = POSITIVE;
+	g_hall.low_res_pos = pos;
+}
+
+
+static void __INLINE hall_put_sample(u32 ticks, float angle) {
+	hsample_t *s = &g_hall.samples;
+	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->index >= SAMPLE_MAX_COUNT) {
+		s->full = true;
+		s->index = 0;
+	}
+}
+
+
+static float __INLINE hall_elec_angle_vel(void){
+	hsample_t *s = &g_hall.samples;
+	if (s->ticks_sum == 0) {
+		return 0.0f;
+	}
+	return s->angles_sum / us_2_s(s->ticks_sum);
+}
+
+void hall_debug_log(void) {
+	sys_debug("angle dir %d, stat %d, lowres %d, err %d\n", g_hall.dir, g_hall.state, g_hall.low_res_pos, g_hall.errors);
+}
+
+static u32 hall_timeout_task(void *args) {
+	hall_t *phall = (hall_t *)args;
+	if (phall->velocity_raw != 0) {
+		if (time_delta_us(phall->edge_ticks, NULL) >= HALL_TIMEOUT_US) {
+			phall->velocity_raw = phall->velocity_filted = 0;
+		}
+	}
+	return 0;
+}
+
+void hall_init(void) {
+	g_hall.phase_offset = mc_conf()->m.encoder_offset;
+	g_hall.mot_poles = mc_conf()->m.poles;
+	g_hall.b_trns_det = false;
+	g_hall.angle_smooth_cnt = SMOOTH_COUNT + 1;
+	g_hall.samples.ticks_sum = 0;
+	g_hall.position = 0;
+	for (int i = 0; i < SAMPLE_MAX_COUNT; i++) {
+		g_hall.samples.ticks[i] = 120*1000000*1;
+		g_hall.samples.angles[i] = 0;
+		g_hall.samples.ticks_sum += g_hall.samples.ticks[i];
+	}
+	if (!g_hall.inited) {
+		g_hall.inited = true;
+		gpio_hall_init();
+		shark_task_create(hall_timeout_task, &g_hall);
+	}
+	hall_init_low_pos();
+}
+
+static float get_angle_diff(float a1, float a2) {
+	float diff = a1 - a2;
+	float abs_diff = ABS(diff);
+	if (abs_diff >= PHASE_180_DEGREE) {
+		return (PHASE_360_DEGREE - abs_diff);
+	}else {
+		return diff;
+	}
+}
+
+static bool hall_update_low_pos(void) {
+	u8 state = hall_read_state();
+	s16 pos = hall_2_pos[state];
+	if (pos == 7) {
+		g_hall.errors ++;
+		return false;
+	}
+	g_hall.state = state;
+	s16 delta_pos = pos - g_hall.low_res_pos;
+	g_hall.low_res_pos = pos;
+	s8  prev_dir = g_hall.dir;
+	if (delta_pos == 1 || delta_pos == -5) {
+		g_hall.dir = POSITIVE;
+	}else{
+		g_hall.dir = NEGATIVE;
+	}
+	if (delta_pos != 0) {
+		g_hall.edge_ticks = task_ticks_abs();
+		g_hall.prev_dir = prev_dir;
+	}
+	return true;
+}
+
+hall_t *hall_get(void) {
+	return &g_hall;
+}
+
+float hall_get_elec_angle(void) {
+	float angle = g_hall.elec_angle + g_hall.phase_offset;
+	norm_angle_deg(angle);
+	return angle;
+}
+
+float hall_update_elec_angle(void) {
+	float delta_ticks = (float)time_delta_us(g_hall.edge_ticks, NULL);//上次hall变换到目前的时间
+	float low_res = g_hall.low_res_pos;
+	if (g_hall.dir == NEGATIVE) {
+		low_res += 1.0f;
+	}
+	float delta_pos = g_hall.elec_angle_vel / PHASE_60_DEGREE * us_2_s(delta_ticks) * g_hall.dir;//上次hall变换到目前走过的角度(对60度的比值,小于1),通过速度插值
+	float high_res_pos = delta_pos  + low_res;
+	if (high_res_pos < 0) {
+		high_res_pos = 0;
+	}
+	float elec_angle = high_res_pos * PHASE_60_DEGREE;
+	float delta_angle = delta_pos * PHASE_60_DEGREE;
+	float elec_smooth_angle;
+	if (g_hall.angle_smooth_cnt < (SMOOTH_COUNT + 1)) {
+		elec_smooth_angle = g_hall.delta_angle_edge + g_hall.angle_smooth_step * g_hall.angle_smooth_cnt + delta_angle;
+		g_hall.angle_smooth_cnt++;
+		if (g_hall.angle_smooth_step >= 0) {
+			elec_smooth_angle = min(elec_smooth_angle, elec_angle);
+		}else {
+			elec_smooth_angle = MAX(elec_smooth_angle, elec_angle);
+		}
+	}else {
+		elec_smooth_angle = elec_angle;
+	}
+	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;
+	return hall_get_elec_angle();
+}
+
+float hall_get_velocity(void) {
+	return g_hall.velocity_filted;
+}
+
+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);
+	hall_put_sample(PHASE_60_DEGREE, delta_cnt);
+	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.8f);
+	}else {
+		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, 0.5f);
+}
+
+
+float hall_offset_detect(float *off) {
+	return 0.0f;
+}
+
+void HALL_IRQHandler(void) {
+	u32 prev_ticks = g_hall.edge_ticks;
+	if (!hall_update_low_pos()) {
+		return;
+	}
+	g_hall.elec_angle_edge = g_hall.elec_angle;
+	float low_res = g_hall.low_res_pos;
+	if (g_hall.dir == NEGATIVE) {
+		low_res += 1.0f;
+	}
+	g_hall.delta_angle_edge = get_angle_diff(low_res * PHASE_60_DEGREE, g_hall.elec_angle_edge);
+	if (ABS(g_hall.delta_angle_edge) >= 2.0f) {
+		g_hall.angle_smooth_step = g_hall.delta_angle_edge/SMOOTH_COUNT;
+		g_hall.angle_smooth_cnt = 1;
+	}else {
+		g_hall.angle_smooth_step = 0;
+		g_hall.angle_smooth_cnt = SMOOTH_COUNT + 1;
+	}
+	hall_calc_mot_velocity(prev_ticks);
+}
+
+

+ 28 - 32
Applications/foc/motor/hall.h

@@ -15,7 +15,7 @@
 #define STATE_7 (uint8_t)7
 
 #define THETA_NONE        (float)0xFFFF
-#define SAMPLE_MAX_COUNT 16
+#define SAMPLE_MAX_COUNT 6
 
 typedef struct {
 	u32       	ticks[SAMPLE_MAX_COUNT];
@@ -24,42 +24,38 @@ typedef struct {
 	float   	angles_sum;
 	u32   		index;
 	bool  		full;
-}hall_sample_t;
+}hsample_t;
 
 typedef struct {
-	float 		estimate_el_angle; //60度区间内的估计电角度
-	float 		estimate_delta_angle;		
-	float   		measured_el_angle; //hall测量到的电角度
-	float 		next_delta_angle;
-	float        delta_angle_ts;    //每个控制周期角度的增加量,通过上次的速度计算得到
-	float        angle_comp_ts;     //每个控制周期角度增加的补偿量,主要用在加减速,hall角度和60度有偏差的情况
-	int             comp_count;
-	float 		immediately_el_speed; //当前的即时速度,主要用来判断电机转动是否达到稳定
-	float 		el_speed; 		//当前的平均效果的电角速度, 单位:rad/s
-	float  		rpm;        		//当前的电速度, 单位:RPM
-	bool  			trns_detect;     //速度变化超过阈值
-	u8    			hall_stat;
-	u32   			hall_ticks;	
-	s8    			direction;
-	s8              running_dir;
+	bool			inited;
 	float   		phase_offset;
-	hall_sample_t 	samples;
-	u32  			sensor_error;
-	float         manual_angle;
-	s32  		angle_table[8];
+	float			mot_poles;
+	u8				state; // state = A <<2+ B <<1 + C
+	s8				low_res_pos; //每个霍尔中断更新一次,60度
+	s8				dir;
+	s8				prev_dir;
+	u32				edge_ticks;
+	float			elec_angle; //经过插值的高分辨率角度
+	float			elec_angle_vel;
+	float			elec_angle_edge; //霍尔中断的时候,上面插值高分辨率的角度所存
+	float			delta_angle_edge;
+	float			angle_smooth_step;
+	float			angle_smooth_cnt;
+	float 			velocity_raw;
+	float			velocity_filted;
+	float			position;
+	hsample_t		samples;
+	bool			b_trns_det; //速度突变
+	u32				errors;
 }hall_t;
 
-void hall_sensor_init(void);
-void hall_sensor_clear(void);
-float hall_sensor_get_theta(bool detect_err); //return degree
-float hall_sensor_get_speed(void); //return rpm;
-int hall_offset_increase(int inc);
-s32 *hall_get_table(void);
-bool hall_detect_angle_finish(void);
-void hall_detect_angle(s16 angle);
-bool hall_detect_offset_finish(void);
-void hall_detect_offset(s16 angle);
-void hall_set_direction(s8 direction);
+void hall_init(void);
+float hall_update_elec_angle(void);
+float hall_get_elec_angle(void);
+float hall_get_velocity(void);
+float hall_get_position(void);
+float hall_offset_detect(float *off);
+hall_t *hall_get(void);
 
 #endif /* _HALL_SENSOR_H__ */
 

+ 4 - 3
Applications/foc/motor/motor.c

@@ -146,12 +146,13 @@ static u32 _self_check_task(void *p) {
 			hw_brk_no_err_cnt = 0;
 		}
 	}
-
+#ifndef CONFIG_USE_ENCODER_HALL
 	if (ENC_Check_error()) {
 		if (mc_set_critical_error(FOC_CRIT_Encoder_Err)) {
 			mc_crit_err_add_s16(FOC_CRIT_Encoder_Err, -1);
 		}
 	}
+#endif
 	if (get_tick_ms() < 5000) { //启动后5s内检测锁电机线
 		if (mc_is_gpio_mlock()) {
 			mc_lock_motor(true);
@@ -924,7 +925,7 @@ static void _encoder_zero_off_timer_handler(shark_timer_t *t){
 bool mc_encoder_zero_calibrate(s16 vd) {
 	if (motor.b_calibrate) {
 		if (vd == 0) {
-			encoder_clear_cnt_offset();
+			motor_encoder_clear_detect();
 			shark_timer_cancel(&_encoder_zero_off_timer);
 			mot_contrl_set_vdq(&motor.controller, 0, 0);
 			delay_ms(500);
@@ -937,7 +938,7 @@ bool mc_encoder_zero_calibrate(s16 vd) {
 		}
 		return true;
 	}
-	encoder_clear_cnt_offset();
+	motor_encoder_clear_detect();
 	motor.b_ignor_throttle = true;
 	MC_Check_MosVbusThrottle();
 	if (mc_unsafe_critical_error()) {

+ 25 - 24
Applications/foc/motor/motor.h

@@ -147,8 +147,8 @@ static __INLINE foc_t *foc(void) {
 }
 
 static __INLINE float motor_encoder_get_angle(void) {
-#ifdef USE_ENCODER_HALL
-	return hall_sensor_get_theta(true);
+#ifdef CONFIG_USE_ENCODER_HALL
+	return hall_update_elec_angle();
 #elif defined (USE_ENCODER_ABI)
 	return encoder_get_theta(true);
 #else
@@ -157,7 +157,7 @@ static __INLINE float motor_encoder_get_angle(void) {
 }
 
 static __INLINE u8 motor_encoder_may_error(void) {
-#ifdef USE_ENCODER_HALL
+#ifdef CONFIG_USE_ENCODER_HALL
 	return false;
 #elif defined (USE_ENCODER_ABI)
 	return encoder_may_error();
@@ -167,8 +167,8 @@ static __INLINE u8 motor_encoder_may_error(void) {
 }
 
 static __INLINE void motor_encoder_update(bool detect_err) {
-#ifdef USE_ENCODER_HALL
-	hall_sensor_get_theta(detect_err);
+#ifdef CONFIG_USE_ENCODER_HALL
+	hall_update_elec_angle();
 #elif defined (USE_ENCODER_ABI)
 	encoder_get_theta(detect_err);
 #else
@@ -177,8 +177,8 @@ static __INLINE void motor_encoder_update(bool detect_err) {
 }
 
 static __INLINE float motor_encoder_get_speed(void) {
-#ifdef USE_ENCODER_HALL
-	return hall_sensor_get_speed();
+#ifdef CONFIG_USE_ENCODER_HALL
+	return hall_get_velocity();
 #elif defined (USE_ENCODER_ABI)
 	return encoder_get_speed();
 #else
@@ -187,8 +187,8 @@ static __INLINE float motor_encoder_get_speed(void) {
 }
 
 static __INLINE float motor_encoder_get_vel_count(void) {
-#ifdef USE_ENCODER_HALL
-	return 0;
+#ifdef CONFIG_USE_ENCODER_HALL
+	return hall_get_velocity();
 #elif defined (USE_ENCODER_ABI)
 	return encoder_get_vel_count();
 #else
@@ -197,8 +197,8 @@ static __INLINE float motor_encoder_get_vel_count(void) {
 }
 
 static __INLINE float motor_encoder_get_position(void) {
-#ifdef USE_ENCODER_HALL
-	return 0;
+#ifdef CONFIG_USE_ENCODER_HALL
+	return hall_get_position();
 #elif defined (USE_ENCODER_ABI)
 	return encoder_get_position();
 #else
@@ -208,8 +208,8 @@ static __INLINE float motor_encoder_get_position(void) {
 
 
 static __INLINE void motor_encoder_init(void) {
-#ifdef USE_ENCODER_HALL
-	hall_sensor_init();
+#ifdef CONFIG_USE_ENCODER_HALL
+	hall_init();
 #elif defined (USE_ENCODER_ABI)
 	encoder_init();
 #else
@@ -218,8 +218,8 @@ static __INLINE void motor_encoder_init(void) {
 }
 
 static __INLINE void motor_encoder_start(bool start) {
-#ifdef USE_ENCODER_HALL
-	hall_sensor_clear(direction);
+#ifdef CONFIG_USE_ENCODER_HALL
+	hall_init();
 #elif defined (USE_ENCODER_ABI)
 	encoder_init_clear();
 #else
@@ -228,8 +228,8 @@ static __INLINE void motor_encoder_start(bool start) {
 }
 
 static __INLINE float motor_encoder_zero_phase_detect(float *enc_off){
-#ifdef USE_ENCODER_HALL
-	return 0.0f;
+#ifdef CONFIG_USE_ENCODER_HALL
+	return hall_offset_detect(enc_off);
 #elif defined (USE_ENCODER_ABI)
 	return encoder_zero_phase_detect(enc_off);
 #else
@@ -237,18 +237,19 @@ static __INLINE float motor_encoder_zero_phase_detect(float *enc_off){
 #endif
 }
 
-static __INLINE void motor_encoder_set_direction(s8 dir) {
-#ifdef USE_ENCODER_HALL
-	hall_set_direction(dir);
+static __INLINE void motor_encoder_clear_detect(void) {
+#ifdef CONFIG_USE_ENCODER_HALL
+	
 #elif defined (USE_ENCODER_ABI)
-	encoder_set_direction(dir);
+	encoder_clear_cnt_offset();
 #else
 	#error "Postion sensor ERROR"
 #endif
 }
 
+
 static __INLINE void motor_encoder_lock_pos(bool lock) {
-#ifdef USE_ENCODER_HALL
+#ifdef CONFIG_USE_ENCODER_HALL
 		
 #elif defined (USE_ENCODER_ABI)
 	encoder_lock_position(lock);
@@ -258,7 +259,7 @@ static __INLINE void motor_encoder_lock_pos(bool lock) {
 }
 
 static __INLINE void motor_encoder_band_epm(bool epm) {
-#ifdef USE_ENCODER_HALL
+#ifdef CONFIG_USE_ENCODER_HALL
 		
 #elif defined (USE_ENCODER_ABI)
 	encoder_epm_pll_band(epm);
@@ -268,7 +269,7 @@ static __INLINE void motor_encoder_band_epm(bool epm) {
 }
 
 static __INLINE void motor_encoder_produce_error(bool error) {
-#ifdef USE_ENCODER_HALL
+#ifdef CONFIG_USE_ENCODER_HALL
 
 #elif defined (USE_ENCODER_ABI)
 	encoder_produce_error(error);

+ 1 - 0
Applications/libs/time_measure.h

@@ -21,6 +21,7 @@ typedef struct {
 
 void time_measure_start(measure_time_t *m);
 void time_measure_end(measure_time_t *m);
+u32 time_delta_us(u32 count, u32 *p_update);
 
 
 #endif	/* _TIME_MEASURE_H__ */

+ 851 - 0
Project/MC124_Hall.uvprojx

@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
+  <SchemaVersion>2.1</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Targets>
+    <Target>
+      <TargetName>GD32F305RC</TargetName>
+      <ToolsetNumber>0x4</ToolsetNumber>
+      <ToolsetName>ARM-ADS</ToolsetName>
+      <pCCUsed>5060750::V5.06 update 6 (build 750)::.\ARMCC</pCCUsed>
+      <uAC6>0</uAC6>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>GD32F305RC</Device>
+          <Vendor>GigaDevice</Vendor>
+          <PackID>GigaDevice.GD32F30x_DFP.2.2.3</PackID>
+          <PackURL>https://gd32mcu.com/data/documents/pack/</PackURL>
+          <Cpu>IRAM(0x20000000,0x018000) IROM(0x08000000,0x040000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_CL -FS08000000 -FL040000 -FP0($$Device:GD32F305RC$Flash\GD32F30x_CL.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:GD32F305RC$Device\Include\gd32f30x.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:GD32F305RC$SVD\GD32F30x_CL.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\Objects\</OutputDirectory>
+          <OutputName>MC124Hall</OutputName>
+          <CreateExecutable>1</CreateExecutable>
+          <CreateLib>0</CreateLib>
+          <CreateHexFile>1</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>1</BrowseInformation>
+          <ListingPath>.\Listings\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>0</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>SharkFwVersion gen ..\Applications\version.h  .\version_mc124_Hall.cfg</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>1</RunUserProg2>
+            <UserProg1Name>fromelf --bin --output ./Output/MC124Hall.bin ./Objects/MC124Hall.axf</UserProg1Name>
+            <UserProg2Name>SharkFwVersion copy  ./Output/MC124Hall.bin</UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments> -REMAP -MPU</SimDllArguments>
+          <SimDlgDll>DCM.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM4</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments> -MPU</TargetDllArguments>
+          <TargetDlgDll>TCM.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>1</Capability>
+            <DriverSelection>4096</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3></Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArmAds>
+          <ArmAdsMisc>
+            <GenerateListings>0</GenerateListings>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <AdsALst>1</AdsALst>
+            <AdsACrf>1</AdsACrf>
+            <AdsANop>0</AdsANop>
+            <AdsANot>0</AdsANot>
+            <AdsLLst>1</AdsLLst>
+            <AdsLmap>1</AdsLmap>
+            <AdsLcgr>1</AdsLcgr>
+            <AdsLsym>1</AdsLsym>
+            <AdsLszi>1</AdsLszi>
+            <AdsLtoi>1</AdsLtoi>
+            <AdsLsun>1</AdsLsun>
+            <AdsLven>1</AdsLven>
+            <AdsLsxf>1</AdsLsxf>
+            <RvctClst>0</RvctClst>
+            <GenPPlst>0</GenPPlst>
+            <AdsCpuType>"Cortex-M4"</AdsCpuType>
+            <RvctDeviceName></RvctDeviceName>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>2</RvdsVP>
+            <RvdsMve>0</RvdsMve>
+            <RvdsCdeCp>0</RvdsCdeCp>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <StupSel>8</StupSel>
+            <useUlib>1</useUlib>
+            <EndSel>0</EndSel>
+            <uLtcg>0</uLtcg>
+            <nSecure>0</nSecure>
+            <RoSelD>3</RoSelD>
+            <RwSelD>3</RwSelD>
+            <CodeSel>0</CodeSel>
+            <OptFeed>0</OptFeed>
+            <NoZi1>0</NoZi1>
+            <NoZi2>0</NoZi2>
+            <NoZi3>0</NoZi3>
+            <NoZi4>0</NoZi4>
+            <NoZi5>0</NoZi5>
+            <Ro1Chk>0</Ro1Chk>
+            <Ro2Chk>0</Ro2Chk>
+            <Ro3Chk>0</Ro3Chk>
+            <Ir1Chk>1</Ir1Chk>
+            <Ir2Chk>0</Ir2Chk>
+            <Ra1Chk>0</Ra1Chk>
+            <Ra2Chk>0</Ra2Chk>
+            <Ra3Chk>0</Ra3Chk>
+            <Im1Chk>1</Im1Chk>
+            <Im2Chk>0</Im2Chk>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x18000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x8000000</StartAddress>
+                <Size>0x40000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <OCR_RVCT1>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT1>
+              <OCR_RVCT2>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT2>
+              <OCR_RVCT3>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT3>
+              <OCR_RVCT4>
+                <Type>1</Type>
+                <StartAddress>0x8002000</StartAddress>
+                <Size>0x40000</Size>
+              </OCR_RVCT4>
+              <OCR_RVCT5>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT5>
+              <OCR_RVCT6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT6>
+              <OCR_RVCT7>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT7>
+              <OCR_RVCT8>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT8>
+              <OCR_RVCT9>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x18000</Size>
+              </OCR_RVCT9>
+              <OCR_RVCT10>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT10>
+            </OnChipMemories>
+            <RvctStartVector></RvctStartVector>
+          </ArmAdsMisc>
+          <Cads>
+            <interw>1</interw>
+            <Optim>4</Optim>
+            <oTime>1</oTime>
+            <SplitLS>0</SplitLS>
+            <OneElfS>1</OneElfS>
+            <Strict>0</Strict>
+            <EnumInt>0</EnumInt>
+            <PlainCh>0</PlainCh>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <wLevel>2</wLevel>
+            <uThumb>0</uThumb>
+            <uSurpInc>0</uSurpInc>
+            <uC99>1</uC99>
+            <uGnu>1</uGnu>
+            <useXO>0</useXO>
+            <v6Lang>3</v6Lang>
+            <v6LangP>3</v6LangP>
+            <vShortEn>1</vShortEn>
+            <vShortWch>1</vShortWch>
+            <v6Lto>0</v6Lto>
+            <v6WtE>0</v6WtE>
+            <v6Rtti>0</v6Rtti>
+            <VariousControls>
+              <MiscControls>--gnu</MiscControls>
+              <Define>USE_STDPERIPH_DRIVER,GD32F30X_CL,CONFIG_BOARD_MC124,CONFIG_CAN_IAP,CONFIG_USE_ENCODER_HALL</Define>
+              <Undefine></Undefine>
+              <IncludePath>..\Librarys\CMSIS\Include,..\Librarys\CMSIS\GD\GD32F30x\Include,..\Librarys\GD32F30x_Drivers\include,..\Applications;..\Simulink\PMSM_Controller_ert_rtw</IncludePath>
+            </VariousControls>
+          </Cads>
+          <Aads>
+            <interw>1</interw>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <thumb>0</thumb>
+            <SplitLS>0</SplitLS>
+            <SwStkChk>0</SwStkChk>
+            <NoWarn>0</NoWarn>
+            <uSurpInc>0</uSurpInc>
+            <useXO>0</useXO>
+            <ClangAsOpt>1</ClangAsOpt>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aads>
+          <LDads>
+            <umfTarg>1</umfTarg>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <noStLib>0</noStLib>
+            <RepFail>1</RepFail>
+            <useFile>0</useFile>
+            <TextAddressRange>0x08000000</TextAddressRange>
+            <DataAddressRange>0x20000000</DataAddressRange>
+            <pXoBase></pXoBase>
+            <ScatterFile></ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc></Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
+          </LDads>
+        </TargetArmAds>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>Application</GroupName>
+          <Files>
+            <File>
+              <FileName>main.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\main.c</FilePath>
+            </File>
+            <File>
+              <FileName>app.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\app\app.c</FilePath>
+            </File>
+            <File>
+              <FileName>nv_storage.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\app\nv_storage.c</FilePath>
+            </File>
+            <File>
+              <FileName>factory.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\app\factory.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Foc</GroupName>
+          <Files>
+            <File>
+              <FileName>commands.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\commands.c</FilePath>
+            </File>
+            <File>
+              <FileName>samples.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\samples.c</FilePath>
+            </File>
+            <File>
+              <FileName>svpwm.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\core\svpwm.c</FilePath>
+            </File>
+            <File>
+              <FileName>mc_error.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\mc_error.c</FilePath>
+            </File>
+            <File>
+              <FileName>limit.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\limit.c</FilePath>
+            </File>
+            <File>
+              <FileName>smo_observer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\core\smo_observer.c</FilePath>
+            </File>
+            <File>
+              <FileName>foc_observer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\core\foc_observer.c</FilePath>
+            </File>
+            <File>
+              <FileName>adrc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\core\adrc.c</FilePath>
+            </File>
+            <File>
+              <FileName>ladrc_observer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\core\ladrc_observer.c</FilePath>
+            </File>
+            <File>
+              <FileName>F_Calc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\core\F_Calc.c</FilePath>
+            </File>
+            <File>
+              <FileName>etcs.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\core\etcs.c</FilePath>
+            </File>
+            <File>
+              <FileName>controller.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\core\controller.c</FilePath>
+            </File>
+            <File>
+              <FileName>foc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\core\foc.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Motor</GroupName>
+          <Files>
+            <File>
+              <FileName>motor.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\motor\motor.c</FilePath>
+            </File>
+            <File>
+              <FileName>ntc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\ntc.c</FilePath>
+            </File>
+            <File>
+              <FileName>current_ics.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\motor\current_ics.c</FilePath>
+            </File>
+            <File>
+              <FileName>motor_param.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\motor\motor_param.c</FilePath>
+            </File>
+            <File>
+              <FileName>mot_params_ind.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\motor\mot_params_ind.c</FilePath>
+            </File>
+            <File>
+              <FileName>mc_config.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\mc_config.c</FilePath>
+            </File>
+            <File>
+              <FileName>throttle.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\motor\throttle.c</FilePath>
+            </File>
+            <File>
+              <FileName>hall.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\motor\hall.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Proto</GroupName>
+          <Files>
+            <File>
+              <FileName>can_message.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\prot\can_message.c</FilePath>
+            </File>
+            <File>
+              <FileName>can_pc_message.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\prot\can_pc_message.c</FilePath>
+            </File>
+            <File>
+              <FileName>can_foc_msg.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\prot\can_foc_msg.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Math</GroupName>
+          <Files>
+            <File>
+              <FileName>fast_math.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\math\fast_math.c</FilePath>
+            </File>
+            <File>
+              <FileName>sin_table.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\math\sin_table.c</FilePath>
+            </File>
+            <File>
+              <FileName>arm_cortexM4lf_math.lib</FileName>
+              <FileType>4</FileType>
+              <FilePath>..\Applications\math\arm_cortexM4lf_math.lib</FilePath>
+            </File>
+            <File>
+              <FileName>Fir.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\math\Fir.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>BSP</GroupName>
+          <Files>
+            <File>
+              <FileName>adc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\adc.c</FilePath>
+            </File>
+            <File>
+              <FileName>bsp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\bsp.c</FilePath>
+            </File>
+            <File>
+              <FileName>can.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\can.c</FilePath>
+            </File>
+            <File>
+              <FileName>fan_pwm.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\fan_pwm.c</FilePath>
+            </File>
+            <File>
+              <FileName>fmc_flash.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\fmc_flash.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32_bkp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\gd32_bkp.c</FilePath>
+            </File>
+            <File>
+              <FileName>gpio.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\gpio.c</FilePath>
+            </File>
+            <File>
+              <FileName>mc_irqs.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\mc_irqs.c</FilePath>
+            </File>
+            <File>
+              <FileName>pwm.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\pwm.c</FilePath>
+            </File>
+            <File>
+              <FileName>sched_timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\sched_timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>uart.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\gd32\uart.c</FilePath>
+            </File>
+            <File>
+              <FileName>delay.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\bsp\delay.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Libs</GroupName>
+          <Files>
+            <File>
+              <FileName>circle_buffer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\libs\circle_buffer.c</FilePath>
+            </File>
+            <File>
+              <FileName>logger.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\libs\logger.c</FilePath>
+            </File>
+            <File>
+              <FileName>crc16.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\libs\crc16.c</FilePath>
+            </File>
+            <File>
+              <FileName>byte_queue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\libs\byte_queue.c</FilePath>
+            </File>
+            <File>
+              <FileName>time_measure.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\libs\time_measure.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>OS</GroupName>
+          <Files>
+            <File>
+              <FileName>heap_4.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\os\heap_4.c</FilePath>
+            </File>
+            <File>
+              <FileName>queue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\os\queue.c</FilePath>
+            </File>
+            <File>
+              <FileName>os_task.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\os\os_task.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>GD32F30x_Drivers</GroupName>
+          <Files>
+            <File>
+              <FileName>gd32f30x_adc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_adc.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_bkp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_bkp.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_can.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_can.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_dma.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_dma.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_exti.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_exti.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_fmc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_fmc.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_fwdgt.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_fwdgt.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_gpio.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_gpio.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_i2c.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_i2c.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_misc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_misc.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_rcu.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_rcu.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_rtc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_rtc.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_usart.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_usart.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_pmu.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_pmu.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32f30x_dbg.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\GD32F30x_Drivers\source\gd32f30x_dbg.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>StartUp</GroupName>
+          <Files>
+            <File>
+              <FileName>system_gd32f30x.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Librarys\CMSIS\GD\GD32F30x\Source\system_gd32f30x.c</FilePath>
+            </File>
+            <File>
+              <FileName>startup_gd32f30x_hd.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\Librarys\CMSIS\GD\GD32F30x\Source\ARM\startup_gd32f30x_hd.s</FilePath>
+              <FileOption>
+                <CommonProperty>
+                  <UseCPPCompiler>2</UseCPPCompiler>
+                  <RVCTCodeConst>0</RVCTCodeConst>
+                  <RVCTZI>0</RVCTZI>
+                  <RVCTOtherData>0</RVCTOtherData>
+                  <ModuleSelection>0</ModuleSelection>
+                  <IncludeInBuild>0</IncludeInBuild>
+                  <AlwaysBuild>2</AlwaysBuild>
+                  <GenerateAssemblyFile>2</GenerateAssemblyFile>
+                  <AssembleAssemblyFile>2</AssembleAssemblyFile>
+                  <PublicsOnly>2</PublicsOnly>
+                  <StopOnExitCode>11</StopOnExitCode>
+                  <CustomArgument></CustomArgument>
+                  <IncludeLibraryModules></IncludeLibraryModules>
+                  <ComprImg>1</ComprImg>
+                </CommonProperty>
+                <FileArmAds>
+                  <Aads>
+                    <interw>2</interw>
+                    <Ropi>2</Ropi>
+                    <Rwpi>2</Rwpi>
+                    <thumb>2</thumb>
+                    <SplitLS>2</SplitLS>
+                    <SwStkChk>2</SwStkChk>
+                    <NoWarn>2</NoWarn>
+                    <uSurpInc>2</uSurpInc>
+                    <useXO>2</useXO>
+                    <ClangAsOpt>0</ClangAsOpt>
+                    <VariousControls>
+                      <MiscControls></MiscControls>
+                      <Define></Define>
+                      <Undefine></Undefine>
+                      <IncludePath></IncludePath>
+                    </VariousControls>
+                  </Aads>
+                </FileArmAds>
+              </FileOption>
+            </File>
+            <File>
+              <FileName>startup_gd32f30x_cl.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\Librarys\CMSIS\GD\GD32F30x\Source\ARM\startup_gd32f30x_cl.s</FilePath>
+            </File>
+          </Files>
+        </Group>
+      </Groups>
+    </Target>
+  </Targets>
+
+  <RTE>
+    <apis/>
+    <components/>
+    <files/>
+  </RTE>
+
+  <LayerInfo>
+    <Layers>
+      <Layer>
+        <LayName>&lt;Project Info&gt;</LayName>
+        <LayDesc></LayDesc>
+        <LayUrl></LayUrl>
+        <LayKeys></LayKeys>
+        <LayCat></LayCat>
+        <LayLic></LayLic>
+        <LayTarg>0</LayTarg>
+        <LayPrjMark>1</LayPrjMark>
+      </Layer>
+    </Layers>
+  </LayerInfo>
+
+</Project>

+ 3 - 0
Project/version_mc124_Hall.cfg

@@ -0,0 +1,3 @@
+project: MC124Hall
+version: 01
+debug: 0