Преглед изворни кода

update hall speed feedback

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui пре 5 година
родитељ
комит
8d1fcde91e

+ 2 - 1
Application/Bsp/bsp.c

@@ -6,9 +6,10 @@ void system_init(void){
 	SystemClock_Config();
 	SystemClock_Config();
 	HAL_GPIO_init();
 	HAL_GPIO_init();
 	HAL_NVIC_Init();
 	HAL_NVIC_Init();
-	HAL_EXIT_Init();
 	HAL_PWM_Init(FOC_FS);
 	HAL_PWM_Init(FOC_FS);
 	HAL_ADC1_Init();
 	HAL_ADC1_Init();
+	HAL_EXIT_Enable();
+	serial_init();
 }
 }
 
 
 void system_reboot(void){
 void system_reboot(void){

+ 1 - 0
Application/Bsp/bsp.h

@@ -4,6 +4,7 @@
 #include "hal/hal.h"
 #include "hal/hal.h"
 #include "hal/pwm.h"
 #include "hal/pwm.h"
 #include "hal/adc.h"
 #include "hal/adc.h"
+#include "bsp/serial.h"
 
 
 void system_init(void);
 void system_init(void);
 void system_reboot(void);
 void system_reboot(void);

+ 5 - 0
Application/Bsp/foc_irqs.c

@@ -8,6 +8,7 @@ __weak void foc_pwm_up_handler(void) {}
 __weak void system_tick_handler(void){}
 __weak void system_tick_handler(void){}
 __weak void current_sample_handler(void){}
 __weak void current_sample_handler(void){}
 __weak void hall_sensor_handler(void){}
 __weak void hall_sensor_handler(void){}
+__weak void uart2_irq_handler(void) {}
 
 
 void TIM1_BRK_TIM15_IRQHandler(void){
 void TIM1_BRK_TIM15_IRQHandler(void){
 	if (LL_TIM_IsActiveFlag_BRK2(TIM1))
 	if (LL_TIM_IsActiveFlag_BRK2(TIM1))
@@ -54,3 +55,7 @@ void EXTI15_10_IRQHandler(void) {
     	hall_sensor_handler();
     	hall_sensor_handler();
   	} 
   	} 
 }
 }
+
+void USART2_IRQHandler(void) {
+	uart2_irq_handler();
+}

+ 34 - 0
Application/Bsp/serial.c

@@ -0,0 +1,34 @@
+#include "hal/uart2.h"
+#include "libs/circle_buffer.h"
+#include "serial.h"
+
+static c_buffer_t c_buff;
+static u8 _tx_buf[256];
+
+void serial_init(void){
+	UART2_Init();
+	circle_buffer_init(&c_buff , _tx_buf, sizeof(_tx_buf));
+}
+
+void serial_write(u8 *data, int len){
+	circle_put_data(&c_buff, data, len);
+	UART2_EnableTx();
+}
+
+bool uart_tx_finished(void) {
+	u8 data;
+	if (circle_get_one_data(&c_buff, &data) <= 0){
+		return true;
+	}
+	UART2_TxData(data);
+	return false;
+}
+
+
+int fputc(int c, FILE *fp){
+	u8 data = c;
+	serial_write(&data, 1);
+	return 1;
+}
+
+

+ 8 - 0
Application/Bsp/serial.h

@@ -0,0 +1,8 @@
+#ifndef _SERIAL_H__
+#define _SERIAL_H__
+#include "libs/types.h"
+
+void serial_init(void);
+void serial_write(u8 *data, int len);
+#endif /* _SERIAL_H__ */
+

+ 71 - 31
Application/FOC/foc.c

@@ -7,27 +7,65 @@
 #include "foc/foc_task.h"
 #include "foc/foc_task.h"
 #include "foc/phase_current.h"
 #include "foc/phase_current.h"
 #include "foc/hall_sensor.h"
 #include "foc/hall_sensor.h"
+#include "foc/vbus_sensor.h"
+#include "foc/ntc_sensor.h"
 
 
-static void charge_cap_timer_handler(timer_t *t);
-static u32 foc_main_task_handler(void);
+static u32 foc_stm_task_handler(void);
+static u32 foc_measure_task_handler(void);
+static void foc_defulat_value(void);
 
 
-static timer_t charge_cap_timer = {.handler = charge_cap_timer_handler};
 static motor_foc_t m_foc;
 static motor_foc_t m_foc;
 
 
 void foc_init(void) {
 void foc_init(void) {
+	foc_defulat_value();
+	hall_sensor_init();
+	HAL_ADC1_Enable();
+	/* init pwm hardware timer */
+	PWM_TimerEnable();
+
+	task_start(foc_measure_task_handler, 0);
+	task_start(foc_stm_task_handler, 0);
+	printf("test\n");
+	foc_ramp_speed(400.0f, 10.0f);
+	
+	//foc_hall_detect(3.0f, m_foc.hall_table);
+}
+
+static void foc_defulat_value(void){
 	memset(&m_foc, 0, sizeof(m_foc));
 	memset(&m_foc, 0, sizeof(m_foc));
 	m_foc.state = IDLE;
 	m_foc.state = IDLE;
 	m_foc.gate_output = false;
 	m_foc.gate_output = false;
+	m_foc.vbus = 12.0f;
+	phase_current_init(&m_foc.current_samp);
+}
 
 
-	hall_sensor_init();
-	/* init pwm hardware timer */
-	PWM_TimerInit();
-
-	task_start(foc_main_task_handler, 0);
+void foc_ramp_speed(float rpm, u32 duration_ms) {
+	float current = 8.0f;
+	m_foc.dq_ref.q = 0;
+	m_foc.dq_ref.d = 0;
+	//m_foc.override_p.is_override_theta = true;
+	foc_pwm_start(true);
+	for (int i = 0;i < 100;i++) {
+		m_foc.dq_ref.d = (float)i * current / 1000.0f;
+		task_udelay(10);
+	}
+	m_foc.dq_ref.d = 0.0f;
+	m_foc.dq_ref.q = 4.0f;
+	
+	while(1) {
+		for (int i = 0; i < 360; i++) {
+			m_foc.override_p.theta = i;
+			task_udelay(100);
+			int theta = hall_sensor_get_theta();
+			if (i % 10 == 0) {
+				printf("$%d;", theta);
+			}
+		}
+	}
 }
 }
 
 
 int foc_hall_detect(float current, u16 *hall_table){
 int foc_hall_detect(float current, u16 *hall_table){
-	foc_start_pwm(true);
+	foc_pwm_start(true);
 	m_foc.override_p.is_override_theta = true;
 	m_foc.override_p.is_override_theta = true;
 	m_foc.override_p.theta = 0.0f;
 	m_foc.override_p.theta = 0.0f;
 	m_foc.override_p.is_override_v_dq = true;
 	m_foc.override_p.is_override_v_dq = true;
@@ -74,7 +112,7 @@ int foc_hall_detect(float current, u16 *hall_table){
 			hall_iterations[hall]++;
 			hall_iterations[hall]++;
 		}
 		}
 	}
 	}
-	foc_start_pwm(false);
+	foc_pwm_start(false);
 	m_foc.override_p.is_override_theta = false;
 	m_foc.override_p.is_override_theta = false;
 	m_foc.override_p.is_override_v_dq = false;
 	m_foc.override_p.is_override_v_dq = false;
 	int fails = 0;
 	int fails = 0;
@@ -91,17 +129,21 @@ int foc_hall_detect(float current, u16 *hall_table){
 	return fails == 2;	
 	return fails == 2;	
 }
 }
 
 
-static void charge_cap_timer_handler(timer_t *t) {
-	if (m_foc.state == CHARGER_BOOT_CAP) {
-		m_foc.state = READY_TO_RUN;
-	}
+void foc_clear(void) {
+	foc_defulat_value();
+	PWM_Stop();
+	m_foc.gate_output = false;
+}
+
+static u32 foc_measure_task_handler(void){
+	vbus_sample_voltage();
+	ntc_sensor_sample();
+	return 1;
 }
 }
-static u32 foc_main_task_handler(void) {
+
+static u32 foc_stm_task_handler(void) {
 	switch (m_foc.state) {
 	switch (m_foc.state) {
 		case START:
 		case START:
-			m_foc.state = CHARGER_BOOT_CAP;
-			timer_post(&charge_cap_timer, 10);
-			PWM_TurnOnLowSides();
 			break;
 			break;
 		case CHARGER_BOOT_CAP:
 		case CHARGER_BOOT_CAP:
 			break;
 			break;
@@ -110,14 +152,11 @@ static u32 foc_main_task_handler(void) {
 		default:
 		default:
 			break;
 			break;
 	}
 	}
-	return 1;
+	return 10;
 }
 }
 
 
 void foc_brake_handler(void) {
 void foc_brake_handler(void) {
-	if (m_foc.state == CHARGER_BOOT_CAP) {
-		timer_post(&charge_cap_timer, 10);
-		PWM_TurnOnLowSides();
-	}
+
 }
 }
 
 
 void foc_pwm_up_handler(void){
 void foc_pwm_up_handler(void){
@@ -129,14 +168,15 @@ void current_sample_handler(void) {
 	foc_task(&m_foc);
 	foc_task(&m_foc);
 }
 }
 
 
-void foc_start_pwm(bool start) {
-	if (start != m_foc.gate_output) {
-		if (start) {
-			PWM_Start();
-		}else {
-			PWM_Stop();
-		}
-		m_foc.gate_output = start;
+void foc_pwm_start(bool start) {
+	if (start == m_foc.gate_output) {
+		return;
+	}
+	if (start) {
+		PWM_Start();
+	}else {
+		PWM_Stop();
 	}
 	}
+	m_foc.gate_output = start;	
 }
 }
 
 

+ 2 - 1
Application/FOC/foc.h

@@ -5,8 +5,9 @@
 
 
 void foc_init(void);
 void foc_init(void);
 void set_dq_voltage(float d_v, float q_v);
 void set_dq_voltage(float d_v, float q_v);
-void foc_start_pwm(bool start);
+void foc_pwm_start(bool start);
 int foc_hall_detect(float current, u16 *hall_table);
 int foc_hall_detect(float current, u16 *hall_table);
+void foc_ramp_speed(float rpm, u32 duration_ms);
 
 
 #endif /* _FOC_H__ */
 #endif /* _FOC_H__ */
 
 

+ 39 - 21
Application/FOC/foc_task.c

@@ -6,36 +6,54 @@
 #include "hall_sensor.h"
 #include "hall_sensor.h"
 #include "svpwm.h"
 #include "svpwm.h"
 
 
-void foc_task(motor_foc_t *foc){
-	current_samp_t *c_sample = &foc->current_samp;
-	alpha_beta_t sample_ab, pwm_ab;
-	dq_t         sample_dq, v_dq;
-	phase_time_t         phase_time;
-	foc->motor_s.theta = hall_sensor_get_theta();
+static void __inline foc_update_theta(motor_foc_t *foc) {
+	float angle = 0.0f;
 	if (foc->override_p.is_override_theta) {
 	if (foc->override_p.is_override_theta) {
-		foc->motor_s.theta = foc->override_p.theta;
+		angle = foc->override_p.theta;
+	}else {
+		angle = hall_sensor_get_theta();
 	}
 	}
-	get_phase_current(c_sample);
-	Clark(c_sample->ia, c_sample->ib, c_sample->ic, &sample_ab);
-	Park(&sample_ab, foc->motor_s.theta, &sample_dq);
+	foc->motor_s.theta = degree_2_pi(angle);
+}
 
 
+static void __inline foc_update_PI_Contrl(motor_foc_t *foc, dq_t *sampled, dq_t *ref_out) {
 	if (foc->mode == FOC_MODE_PI_DQ || foc->mode == FOC_MODE_PI_FULL) {
 	if (foc->mode == FOC_MODE_PI_DQ || foc->mode == FOC_MODE_PI_FULL) {
-		v_dq.d = pi_control(&foc->PI_id, foc->dq_ref.d - sample_dq.d);
-		v_dq.q = pi_control(&foc->PI_iq, foc->dq_ref.q - sample_dq.q);
+		ref_out->d = pi_control(&foc->PI_id, foc->dq_ref.d - sampled->d);
+		ref_out->q = pi_control(&foc->PI_iq, foc->dq_ref.q - sampled->q);
 	}else {
 	}else {
-		v_dq.d = foc->dq_ref.d;
-		v_dq.q = foc->dq_ref.q;
+		ref_out->d = foc->dq_ref.d;
+		ref_out->q = foc->dq_ref.q;
 	}
 	}
 	if (foc->override_p.is_override_v_dq) {
 	if (foc->override_p.is_override_v_dq) {
-		v_dq.d = foc->override_p.v_dq.d;
-		v_dq.q = foc->override_p.v_dq.q;
+		ref_out->d = foc->override_p.v_dq.d;
+		ref_out->q = foc->override_p.v_dq.q;
 	}
 	}
-	Rev_Park(&v_dq, foc->motor_s.theta, &pwm_ab);
+}
 
 
+
+void foc_task(motor_foc_t *foc){
+	current_samp_t *c_sample = &foc->current_samp;
+	alpha_beta_t sample_ab, pwm_ab;
+	dq_t         sample_dq, v_dq;
+	phase_time_t         phase_time;
+	u32 sample_point;
+
+	/* 更新电角度 */
+	foc_update_theta(foc);
+	/* 采集3相电流 */
+	phase_current_sample(c_sample);
+	/* ABC坐标转alpha-beta坐标 */
+	Clark(c_sample->ia, c_sample->ib, c_sample->ic, &sample_ab);
+	/* alpha-beta坐标转旋转坐标系D-Q */
+	Park(&sample_ab, foc->motor_s.theta, &sample_dq);
+	/* 处理D,Q电流环,速度环低频运行,不在此处处理*/
+	foc_update_PI_Contrl(foc, &sample_dq, &v_dq);
+	/* d-q坐标转 alpha-beta坐标,输入给pwm */
+	Rev_Park(&v_dq, foc->motor_s.theta, &pwm_ab);
+	/* 生成 pwm,模拟正弦波,此处vbus需要动态采集 */
 	svpwm(&pwm_ab, foc->vbus, FOC_PWM_Half_Period, &phase_time, &foc->sector);
 	svpwm(&pwm_ab, foc->vbus, FOC_PWM_Half_Period, &phase_time, &foc->sector);
-	
-	u32 sample_point = get_phase_sample_point(c_sample, &phase_time, foc->sector);
-	
+	/* 通过扇区和pwm duty 选择合适的3相电流采样点 */
+	sample_point = get_phase_sample_point(c_sample, &phase_time, foc->sector);
+	/* 更新duty和采样点到硬件TIM1中 */
 	PWM_UpdateDuty(phase_time.A, phase_time.B, phase_time.C, sample_point);
 	PWM_UpdateDuty(phase_time.A, phase_time.B, phase_time.C, sample_point);
 }
 }
-

+ 6 - 2
Application/FOC/foc_type.h

@@ -40,14 +40,18 @@ typedef enum {
 	IDLE = 0,
 	IDLE = 0,
 	START = 1,
 	START = 1,
 	CHARGER_BOOT_CAP = 2,
 	CHARGER_BOOT_CAP = 2,
-	READY_TO_RUN = 3
+	READY_TO_RUN = 3,
+	OPEN_LOOP = 4,
+	RUNNING = 5,
+	ANY_STOP = 6
 }foc_state_t;
 }foc_state_t;
 
 
 typedef enum {
 typedef enum {
 	FOC_MODE_OPEN_LOOP, //开环
 	FOC_MODE_OPEN_LOOP, //开环
 	FOC_MODE_PI_DQ,      //只电流环
 	FOC_MODE_PI_DQ,      //只电流环
 	FOC_MODE_PI_SPEED,     //只速度环
 	FOC_MODE_PI_SPEED,     //只速度环
-	FOC_MODE_PI_FULL         //速度,电流环都有
+	FOC_MODE_PI_FULL,         //速度,电流环都有
+	FOC_MODE_CURRENT_CALI,    //校准电流读取
 }foc_mode_t;
 }foc_mode_t;
 
 
 typedef struct current_sample {
 typedef struct current_sample {

+ 88 - 23
Application/FOC/hall_sensor.c

@@ -5,8 +5,16 @@
 #include "hall_sensor.h"
 #include "hall_sensor.h"
 
 
 #define HALL_READ_TIMES 7
 #define HALL_READ_TIMES 7
-
-static u16 _hall_table[] = {0xFFFF, 292/*1*/, 47/*2*/, 1/*3*/, 180/*4*/, 227/*5*/, 113/*6*/, 0xFFFF};
+/* 
+100
+101
+001
+011
+010
+110
+4,5,1,3,2,6,4
+*/
+static u16 _hall_table[] = {0xFFFF, 292/*1*/, 54/*2*/, 1/*3*/, 180/*4*/, 229/*5*/, 115/*6*/, 0xFFFF};
 static hall_t _hall;
 static hall_t _hall;
 
 
 #define read_hall(h,t) {h = get_hall_stat(HALL_READ_TIMES); t = _hall_table[h];}
 #define read_hall(h,t) {h = get_hall_stat(HALL_READ_TIMES); t = _hall_table[h];}
@@ -17,7 +25,7 @@ static u32 __inline delta_ticks(u32 prev) {
 	if (now >= prev) {
 	if (now >= prev) {
 		return (now - prev);
 		return (now - prev);
 	}
 	}
-	return (0xFFFFFFFF - prev + now) + 1;
+	return (0xFFFFFFFFU - prev + now) + 1;
 }
 }
 
 
 void hall_sensor_init(void) {
 void hall_sensor_init(void) {
@@ -27,7 +35,8 @@ void hall_sensor_init(void) {
 
 
 float hall_sensor_get_theta(void){
 float hall_sensor_get_theta(void){
 	if (!_hall.working) {
 	if (!_hall.working) {
-		return THETA_NONE;
+		read_hall(_hall.state, _hall.theta);
+		return _hall.theta;
 	}
 	}
 	float est_theta = tick_2_s(delta_ticks(_hall.ticks)) * _hall.degree_per_s + _hall.theta;
 	float est_theta = tick_2_s(delta_ticks(_hall.ticks)) * _hall.degree_per_s + _hall.theta;
 	fast_norm_angle(&est_theta);
 	fast_norm_angle(&est_theta);
@@ -35,43 +44,99 @@ float hall_sensor_get_theta(void){
 }
 }
 
 
 float hall_sensor_get_speed(void) {
 float hall_sensor_get_speed(void) {
-	return 0.0f;
+	return _hall.e_rpm;
 }
 }
 
 
+
 void hall_sensor_handler(void) {
 void hall_sensor_handler(void) {
-	u8 hall = get_hall_stat(HALL_READ_TIMES);
-	float theta = _hall_table[hall];
+	u8 state_now = get_hall_stat(HALL_READ_TIMES);
+	float theta_now = _hall_table[state_now];
+	u8 state_prev = _hall.state;
+	float theta_prev = _hall.theta;
 	if (!_hall.working) {		
 	if (!_hall.working) {		
-		if(theta != 0xFFFF) {
+		if(theta_now != 0xFFFF) {
 			_hall.working = true;
 			_hall.working = true;
-			_hall.state = hall;
-			_hall.theta = theta;
+			_hall.state = state_now;
+			_hall.theta = theta_now;
 			_hall.ticks = task_ticks_abs();
 			_hall.ticks = task_ticks_abs();
 		}
 		}
 		return;
 		return;
 	}
 	}
+	//printf("hall %d, %d\n", state_now, state_prev);
 
 
-	if (theta == 0xFFFF || _hall.theta == theta) { //may be hall noise, drop it
-		return;
+	float delta_theta = 360.0f;
+	switch (state_now) {
+		case STATE_1:
+			if (state_prev == STATE_5) {
+				_hall.direction = POSITIVE;
+				delta_theta = theta_now - theta_prev;
+			}else if (state_prev == STATE_3) {
+				_hall.direction = NEGATIVE;
+				delta_theta = 360 - theta_now + theta_prev;
+			}
+			break;
+		case STATE_2:
+			if (state_prev == STATE_3) {
+				_hall.direction = POSITIVE;
+				delta_theta = theta_now - theta_prev;
+			}else if (state_prev == STATE_6) {
+				_hall.direction = NEGATIVE;
+				delta_theta = theta_prev - theta_now;
+			}
+			break;
+		case STATE_3:
+			if (state_prev == STATE_1) {
+				_hall.direction = POSITIVE;
+				delta_theta = 360 - theta_prev + theta_now;
+			}else if (state_prev == STATE_2) {
+				_hall.direction = NEGATIVE;
+				delta_theta = theta_prev - theta_now;
+			}
+			break;
+		case STATE_4:
+			if (state_prev == STATE_6) {
+				_hall.direction = POSITIVE;
+				delta_theta = theta_now - theta_prev;
+			}else if (state_prev == STATE_5) {
+				_hall.direction = NEGATIVE;
+				delta_theta = theta_prev - theta_now;
+			}
+			break;
+		case STATE_5:
+			if (state_prev == STATE_4) {
+				_hall.direction = POSITIVE;
+				delta_theta = theta_now - theta_prev;
+			}else if (state_prev == STATE_1) {
+				_hall.direction = NEGATIVE;
+				delta_theta = theta_prev - theta_now;
+			}
+			break;
+		case STATE_6:
+			if (state_prev == STATE_2) {
+				_hall.direction = POSITIVE;
+				delta_theta = theta_now - theta_prev;
+			}else if (state_prev == STATE_4) {
+				_hall.direction = NEGATIVE;
+				delta_theta = theta_prev - theta_now;
+			}
+			break;
+		default:
+			break;
 	}
 	}
-	float delta_theta = theta - _hall.theta;
-	float theta_abs = abs(delta_theta);
-	if (theta_abs > 70 || theta_abs < 40) { //may be hall noise, drop it
+	if (delta_theta == 360.0f) { //no vilid hall 
 		return;
 		return;
 	}
 	}
-	if (delta_theta < 0) {
-		_hall.direction = NEGATIVE;
-	}else {
-		_hall.direction = POSITIVE;
-	}
+
 	float delta_time = tick_2_s(delta_ticks(_hall.ticks));
 	float delta_time = tick_2_s(delta_ticks(_hall.ticks));
 	if (delta_time == 0.0f) { //may be errors ???
 	if (delta_time == 0.0f) { //may be errors ???
 		return;
 		return;
 	}
 	}
-	_hall.degree_per_s = theta_abs / delta_time;
-
+	_hall.degree_per_s = delta_theta / delta_time;
+	//printf("speed :%.4f - %.4f - %.4f - %d\n", _hall.degree_per_s, delta_theta, delta_time, state_now);
 	_hall.ticks = task_ticks_abs();
 	_hall.ticks = task_ticks_abs();
-	_hall.theta = theta;
+	_hall.theta = theta_now;
+	_hall.state = state_now;
+	_hall.e_rpm = _hall.degree_per_s / 360.0f * 60.0f;
 }
 }
 
 
 
 

+ 10 - 1
Application/FOC/hall_sensor.h

@@ -6,11 +6,20 @@
 #define NEGATIVE          (int8_t)-1
 #define NEGATIVE          (int8_t)-1
 #define POSITIVE          (int8_t)1
 #define POSITIVE          (int8_t)1
 
 
+#define STATE_0 (uint8_t)0
+#define STATE_1 (uint8_t)1
+#define STATE_2 (uint8_t)2
+#define STATE_3 (uint8_t)3
+#define STATE_4 (uint8_t)4
+#define STATE_5 (uint8_t)5
+#define STATE_6 (uint8_t)6
+#define STATE_7 (uint8_t)7
+
 #define THETA_NONE        (float)0xFFFF
 #define THETA_NONE        (float)0xFFFF
 typedef struct {
 typedef struct {
 	bool  alignmnet;
 	bool  alignmnet;
 	float theta;
 	float theta;
-	float rpm;        //每分钟转速
+	float e_rpm;        //每分钟转速,电转速,不是机械转速
 	u8    state;
 	u8    state;
 	u32   ticks;
 	u32   ticks;
 	bool  working;
 	bool  working;

+ 6 - 1
Application/FOC/ntc_sensor.c

@@ -6,9 +6,10 @@ void ntc_sensor_init(void) {
 	_ntc.temp_avg = 0;
 	_ntc.temp_avg = 0;
 	_ntc.low_pass_filter = 0.5f;
 	_ntc.low_pass_filter = 0.5f;
 	HAL_ADC1_ChanConfig(TEMP_SENSOR_ADC_CHANNEL);
 	HAL_ADC1_ChanConfig(TEMP_SENSOR_ADC_CHANNEL);
+	ntc_sensor_sample();
 }
 }
 
 
-int ntc_sensor_get_temperature(void){
+void ntc_sensor_sample(void){
 	u16 w_temp = HAL_ADC1_ReadValue(TEMP_SENSOR_ADC_CHANNEL);
 	u16 w_temp = HAL_ADC1_ReadValue(TEMP_SENSOR_ADC_CHANNEL);
     w_temp -= ( s32 )(V0_V *65536/ ADC_REFERENCE_VOLTAGE );
     w_temp -= ( s32 )(V0_V *65536/ ADC_REFERENCE_VOLTAGE );
     w_temp *= (ADC_REFERENCE_VOLTAGE/dV_dT);
     w_temp *= (ADC_REFERENCE_VOLTAGE/dV_dT);
@@ -16,6 +17,10 @@ int ntc_sensor_get_temperature(void){
 
 
 	_ntc.temp_avg = w_temp * _ntc.low_pass_filter + _ntc.temp_avg * (1.0f - _ntc.low_pass_filter);
 	_ntc.temp_avg = w_temp * _ntc.low_pass_filter + _ntc.temp_avg * (1.0f - _ntc.low_pass_filter);
 
 
+}
+
+
+int ntc_sensor_temperature(void){
 	return _ntc.temp_avg;
 	return _ntc.temp_avg;
 }
 }
 
 

+ 2 - 1
Application/FOC/ntc_sensor.h

@@ -15,6 +15,7 @@ typedef struct {
                                                        power stage working
                                                        power stage working
                                                        temperature, Celsius degrees */
                                                        temperature, Celsius degrees */
 void ntc_sensor_init(void);
 void ntc_sensor_init(void);
-int ntc_sensor_get_temperature(void);
+void ntc_sensor_sample(void);
+int ntc_sensor_temperature(void);
 #endif /* _NTC_H__ */
 #endif /* _NTC_H__ */
 
 

+ 2 - 2
Application/FOC/park_clark.h

@@ -6,7 +6,7 @@
 /* ·´Park ±ä»» */
 /* ·´Park ±ä»» */
 static __INLINE void Rev_Park(dq_t *dq, float angle, alpha_beta_t *alpha_bata) {
 static __INLINE void Rev_Park(dq_t *dq, float angle, alpha_beta_t *alpha_bata) {
 	float c,s;
 	float c,s;
-	fast_sincos(angle, &s, &c);
+	normal_sincosf(angle, &s, &c);
 
 
 	alpha_bata->alpha = dq->d * c - dq->q * s;
 	alpha_bata->alpha = dq->d * c - dq->q * s;
 	alpha_bata->beta = dq->d * s + dq->q * c;
 	alpha_bata->beta = dq->d * s + dq->q * c;
@@ -19,7 +19,7 @@ static __INLINE void Clark(float phaseU, float phaseV, float phaseW, alpha_beta_
 
 
 static __INLINE void Park(alpha_beta_t *alpha_beta, float angle, dq_t *dq) {
 static __INLINE void Park(alpha_beta_t *alpha_beta, float angle, dq_t *dq) {
 	float c,s;
 	float c,s;
-	fast_sincos(angle, &s, &c);
+	normal_sincosf(angle, &s, &c);
 
 
 	dq->d = alpha_beta->alpha * c + alpha_beta->beta * s;
 	dq->d = alpha_beta->alpha * c + alpha_beta->beta * s;
 	dq->q = -alpha_beta->alpha * s + alpha_beta->beta * c;
 	dq->q = -alpha_beta->alpha * s + alpha_beta->beta * c;

+ 5 - 1
Application/FOC/phase_current.c

@@ -11,7 +11,11 @@ static float __inline adc_to_current(u32 adc){
 	return (i_adc/4095.0f * 3.3f / 0.001f);
 	return (i_adc/4095.0f * 3.3f / 0.001f);
 }
 }
 
 
-void get_phase_current(current_samp_t *cs){
+void phase_current_init(current_samp_t *cs) {
+	cs->adc_inject_flags = LL_ADC_INJ_TRIG_EXT_RISING;
+}
+
+void phase_current_sample(current_samp_t *cs){
 	u32 phase_current1, phase_current2;
 	u32 phase_current1, phase_current2;
 	HAL_ADC1_Inject_Read(cs->sector, &phase_current1, &phase_current2);
 	HAL_ADC1_Inject_Read(cs->sector, &phase_current1, &phase_current2);
 	if (cs->sector == SECTOR_4 || cs->sector == SECTOR_5) {
 	if (cs->sector == SECTOR_4 || cs->sector == SECTOR_5) {

+ 2 - 2
Application/FOC/phase_current.h

@@ -1,8 +1,8 @@
 #ifndef _PHASE_CURRENT_H__
 #ifndef _PHASE_CURRENT_H__
 #define _PHASE_CURRENT_H__
 #define _PHASE_CURRENT_H__
 #include "foc_type.h"
 #include "foc_type.h"
-
-void get_phase_current(current_samp_t *cs);
+void phase_current_init(current_samp_t *cs);
+void phase_current_sample(current_samp_t *cs);
 u32 get_phase_sample_point(current_samp_t *cs, phase_time_t *time, u8 sector);
 u32 get_phase_sample_point(current_samp_t *cs, phase_time_t *time, u8 sector);
 void phase_current_adc_triger(current_samp_t *cs);
 void phase_current_adc_triger(current_samp_t *cs);
 #endif /* _PHASE_CURRENT_H__ */
 #endif /* _PHASE_CURRENT_H__ */

+ 39 - 0
Application/FOC/ramp_ctrl.c

@@ -0,0 +1,39 @@
+#include "ramp_ctrl.h"
+
+#define RAMP_INTVAL 5 //ms
+static void ramp_timer_handler(timer_t *timer);
+
+void ramp_ctrl_init(ramp_t *ramp, float start, float final, u32 duration_ms){
+	ramp->target = start;
+	ramp->final_point = final;
+	ramp->duration_ms = duration_ms;
+	ramp->steps = (final - start) / (duration_ms / RAMP_INTVAL);
+	if (ramp->timer.handler != NULL) {
+		timer_cancel(&ramp->timer);
+	}
+	ramp->timer.handler = NULL;
+}
+
+void ramp_exc(ramp_t *ramp){
+	if (ramp->timer.handler == NULL) {
+		ramp->timer.handler = ramp_timer_handler;
+		timer_post(&ramp->timer, RAMP_INTVAL);
+	}
+}
+
+float ramp_get_target(ramp_t *ramp){
+	return ramp->target;
+}
+
+static void ramp_timer_handler(timer_t *timer) {
+	ramp_t *ramp = (ramp_t *)timer;
+	float target = ramp->target + ramp->steps;
+	if (target > ramp->final_point) {
+		target = ramp->final_point;
+	}
+	ramp->target = target;
+	if (target != ramp->final_point) {
+		timer_post(&ramp->timer, RAMP_INTVAL);
+	}
+}
+

+ 17 - 0
Application/FOC/ramp_ctrl.h

@@ -0,0 +1,17 @@
+#ifndef _RAMP_CTRL_H__
+#define _RAMP_CTRL_H__
+#include "libs/types.h"
+#include "libs/task.h"
+typedef struct {
+	timer_t timer;
+	float final_point;
+	float target;
+	u32   duration_ms;
+	float steps;
+}ramp_t;
+
+void ramp_ctrl_init(ramp_t *ramp, float start, float final, u32 durations);
+void ramp_exc(ramp_t *ramp);
+float ramp_get_target(ramp_t *ramp);
+#endif /* _RAMP_CTRL_H__ */
+

+ 6 - 2
Application/FOC/vbus_sensor.c

@@ -6,10 +6,10 @@ void vbus_sensor_init(void){
 	_vbus.voltage_avg = 0;
 	_vbus.voltage_avg = 0;
 	_vbus.avg_count = 16;
 	_vbus.avg_count = 16;
 	HAL_ADC1_ChanConfig(VBUS_SENSOR_ADC_CHANNEL);
 	HAL_ADC1_ChanConfig(VBUS_SENSOR_ADC_CHANNEL);
-
+	vbus_sample_voltage();
 }
 }
 
 
-float vbus_get_voltage(void){
+void vbus_sample_voltage(void){
 	u32 vadc = 0;
 	u32 vadc = 0;
 	u32 max = 0, min = 0xFFFFFFF;
 	u32 max = 0, min = 0xFFFFFFF;
 	for (int i = 0; i < _vbus.avg_count; i++) {
 	for (int i = 0; i < _vbus.avg_count; i++) {
@@ -25,6 +25,10 @@ float vbus_get_voltage(void){
 	vadc -= (max + min);
 	vadc -= (max + min);
 	vadc = vadc / (_vbus.avg_count - 2);
 	vadc = vadc / (_vbus.avg_count - 2);
 	_vbus.voltage_avg = vadc/65536 * ADC_REFERENCE_VOLTAGE / VBUS_PARTITIONING_FACTOR;
 	_vbus.voltage_avg = vadc/65536 * ADC_REFERENCE_VOLTAGE / VBUS_PARTITIONING_FACTOR;
+}
+
+
+float vbus_get_voltage(void){
 
 
 	return _vbus.voltage_avg;
 	return _vbus.voltage_avg;
 }
 }

+ 2 - 0
Application/FOC/vbus_sensor.h

@@ -13,6 +13,8 @@ typedef struct {
 }vbus_t;
 }vbus_t;
 
 
 void vbus_sensor_init(void);
 void vbus_sensor_init(void);
+void vbus_sample_voltage(void);
 float vbus_get_voltage(void);
 float vbus_get_voltage(void);
+
 #endif /* _VBUS_SENSOR_H__ */
 #endif /* _VBUS_SENSOR_H__ */
 
 

+ 63 - 0
Application/Hal/adc.c

@@ -82,6 +82,69 @@ void HAL_ADC1_Init(void){
 }
 }
 
 
 
 
+void HAL_ADC1_Enable(void) {
+	ADC_TypeDef * ADCx = hadc1.Instance;
+    /* disable IT and flags in case of LL driver usage
+     * workaround for unwanted interrupt enabling done by LL driver */
+    LL_ADC_DisableIT_EOC( ADCx );
+    LL_ADC_ClearFlag_EOC( ADCx );
+    LL_ADC_DisableIT_JEOC( ADCx );
+    LL_ADC_ClearFlag_JEOC( ADCx );
+    if (LL_ADC_IsEnabled (ADCx) == 0)
+    {
+		if ( LL_ADC_IsInternalRegulatorEnabled(ADCx) == 0u)
+		{
+		  /* Enable ADC internal voltage regulator */
+		  LL_ADC_EnableInternalRegulator(ADCx);
+		
+		  /* Wait for Regulator Startup time */
+		  /* Note: Variable divided by 2 to compensate partially			  */
+		  /*	   CPU processing cycles, scaling in us split to not		  */
+		  /*	   exceed 32 bits register capacity and handle low frequency. */
+		  volatile uint32_t wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));	  
+		  while(wait_loop_index != 0UL)
+		  {
+			wait_loop_index--;
+		  }
+		}
+		
+		LL_ADC_StartCalibration( ADCx, LL_ADC_SINGLE_ENDED );
+		while ( LL_ADC_IsCalibrationOnGoing( ADCx) == 1u) 
+		{}
+		/* ADC Enable (must be done after calibration) */
+		/* ADC5-140924: Enabling the ADC by setting ADEN bit soon after polling ADCAL=0 
+		* following a calibration phase, could have no effect on ADC 
+		* within certain AHB/ADC clock ratio.
+		*/
+		while (  LL_ADC_IsActiveFlag_ADRDY( ADCx ) == 0u)  
+		{ 
+		  LL_ADC_Enable(  ADCx );
+		}
+		/* Clear JSQR from CubeMX setting to avoid not wanting conversion*/
+		LL_ADC_INJ_StartConversion( ADCx ); 
+		//LL_ADC_INJ_StopConversion(ADCx);
+		/* TODO: check if not already done by MX */
+		LL_ADC_INJ_SetQueueMode( ADCx, LL_ADC_INJ_QUEUE_2CONTEXTS_END_EMPTY );
+
+      	/* Only the Interrupt of the first ADC is enabled. 
+       	* As Both ADCs are fired by HW at the same moment 
+       	* It is safe to consider that both conversion are ready at the same time*/
+      	LL_ADC_ClearFlag_JEOS( ADCx );
+      	LL_ADC_EnableIT_JEOS( ADCx );
+    }	
+
+	HAL_NVIC_EnableIRQ(ADC1_IRQn);
+
+	//HAL_ADC1_InJ_StartConvert();
+}
+
+void HAL_ADC1_InJ_StartConvert(void) {
+	ADC_TypeDef * ADCx = hadc1.Instance;
+	while(LL_ADC_INJ_IsConversionOngoing( ADCx ) == 0) {
+		LL_ADC_INJ_StartConversion( ADCx );
+	}
+}
+
 void HAL_ADC1_ChanConfig(u32 channel) {
 void HAL_ADC1_ChanConfig(u32 channel) {
 	if (LL_ADC_IsEnabled(hadc1.Instance) == 0 )
 	if (LL_ADC_IsEnabled(hadc1.Instance) == 0 )
 	{
 	{

+ 2 - 0
Application/Hal/adc.h

@@ -45,6 +45,8 @@ static const R3_F30x_8_ADC_Config_t adc_config = {
 };
 };
 
 
 void HAL_ADC1_Init(void);
 void HAL_ADC1_Init(void);
+void HAL_ADC1_Enable(void);
+void HAL_ADC1_InJ_StartConvert(void);
 void HAL_ADC1_ChanConfig(u32 channel);
 void HAL_ADC1_ChanConfig(u32 channel);
 u16 HAL_ADC1_ReadValue(u32 channel);
 u16 HAL_ADC1_ReadValue(u32 channel);
 
 

+ 6 - 18
Application/Hal/hal.c

@@ -70,19 +70,19 @@ void HAL_GPIO_init(void){
   	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
   	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
 
   	GPIO_InitStruct.Pin = HALL_1_PIN;
   	GPIO_InitStruct.Pin = HALL_1_PIN;
-  	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
   	GPIO_InitStruct.Pull = GPIO_NOPULL;
   	GPIO_InitStruct.Pull = GPIO_NOPULL;
   	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   	HAL_GPIO_Init(HALL_1_GROUP, &GPIO_InitStruct);
   	HAL_GPIO_Init(HALL_1_GROUP, &GPIO_InitStruct);
 
 
   	GPIO_InitStruct.Pin = HALL_2_PIN;
   	GPIO_InitStruct.Pin = HALL_2_PIN;
-  	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
   	GPIO_InitStruct.Pull = GPIO_NOPULL;
   	GPIO_InitStruct.Pull = GPIO_NOPULL;
   	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   	HAL_GPIO_Init(HALL_2_GROUP, &GPIO_InitStruct);
   	HAL_GPIO_Init(HALL_2_GROUP, &GPIO_InitStruct);
 
 
   	GPIO_InitStruct.Pin = HALL_3_PIN;
   	GPIO_InitStruct.Pin = HALL_3_PIN;
-  	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
   	GPIO_InitStruct.Pull = GPIO_NOPULL;
   	GPIO_InitStruct.Pull = GPIO_NOPULL;
   	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   	HAL_GPIO_Init(HALL_3_GROUP, &GPIO_InitStruct);	
   	HAL_GPIO_Init(HALL_3_GROUP, &GPIO_InitStruct);	
@@ -166,23 +166,11 @@ void HAL_NVIC_Init(void){
 	HAL_NVIC_SetPriority(EXTI15_10_IRQn, 8, 0);
 	HAL_NVIC_SetPriority(EXTI15_10_IRQn, 8, 0);
 	/* USART2_IRQn interrupt configuration */
 	/* USART2_IRQn interrupt configuration */
 	HAL_NVIC_SetPriority(USART2_IRQn, 8, 0);
 	HAL_NVIC_SetPriority(USART2_IRQn, 8, 0);
-	/* EXTI15_10_IRQn interrupt configuration */
-	HAL_NVIC_SetPriority(EXTI15_10_IRQn, 8, 0);
 }
 }
 
 
-void HAL_EXIT_Init(void) {
-	LL_EXTI_InitTypeDef exti;
-	exti.Line_0_31 = LL_EXTI_LINE_3;
-	exti.LineCommand = ENABLE;
-	exti.Mode = LL_EXTI_MODE_IT;
-	exti.Trigger = LL_EXTI_TRIGGER_RISING_FALLING;
-	LL_EXTI_Init(&exti);
-
-	exti.Line_0_31 = LL_EXTI_LINE_10;
-	LL_EXTI_Init(&exti);
-
-	exti.Line_0_31 = LL_EXTI_LINE_15;
-	LL_EXTI_Init(&exti);
+void HAL_EXIT_Enable(void) {
+	HAL_NVIC_EnableIRQ(EXTI3_IRQn);
+	HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
 }
 }
 
 
 void Error_Handler(void)
 void Error_Handler(void)

+ 6 - 1
Application/Hal/hal.h

@@ -39,6 +39,11 @@
 #define HALL_3_PIN GPIO_PIN_10
 #define HALL_3_PIN GPIO_PIN_10
 #define HALL_3_GROUP GPIOB
 #define HALL_3_GROUP GPIOB
 
 
+#define UART_TX_Pin GPIO_PIN_2
+#define UART_TX_GPIO_Port GPIOA
+#define UART_RX_Pin GPIO_PIN_3
+#define UART_RX_GPIO_Port GPIOA
+
 #define CURRENT_U_ADC_CHANNAL 6
 #define CURRENT_U_ADC_CHANNAL 6
 #define CURRENT_V_ADC_CHANNAL 7
 #define CURRENT_V_ADC_CHANNAL 7
 #define CURRENT_W_ADC_CHANNAL 1
 #define CURRENT_W_ADC_CHANNAL 1
@@ -80,6 +85,6 @@ void Error_Handler(void);
 void SystemClock_Config(void);
 void SystemClock_Config(void);
 void HAL_GPIO_init(void);
 void HAL_GPIO_init(void);
 void HAL_NVIC_Init(void);
 void HAL_NVIC_Init(void);
-void HAL_EXIT_Init(void);
+void HAL_EXIT_Enable(void);
 
 
 #endif /* _HAL_H__ */
 #endif /* _HAL_H__ */

+ 17 - 2
Application/Hal/pwm.c

@@ -2,6 +2,7 @@
 #include "hal/pwm.h"
 #include "hal/pwm.h"
 #include "stm32f3xx_ll_tim.h"
 #include "stm32f3xx_ll_tim.h"
 #include "stm32f3xx_ll_gpio.h"
 #include "stm32f3xx_ll_gpio.h"
+#include "stm32f3xx_ll_system.h"
 
 
 #define TIMxCCER_MASK_CH123        ((uint16_t)  (LL_TIM_CHANNEL_CH1|LL_TIM_CHANNEL_CH1N|\
 #define TIMxCCER_MASK_CH123        ((uint16_t)  (LL_TIM_CHANNEL_CH1|LL_TIM_CHANNEL_CH1N|\
                                                  LL_TIM_CHANNEL_CH2|LL_TIM_CHANNEL_CH2N|\
                                                  LL_TIM_CHANNEL_CH2|LL_TIM_CHANNEL_CH2N|\
@@ -87,11 +88,12 @@ void HAL_PWM_Init(int fs) {
 	{
 	{
 	  Error_Handler();
 	  Error_Handler();
 	}
 	}
-
+	/* TIM1 Counter Clock stopped when the core is halted */
+	LL_DBGMCU_APB2_GRP1_FreezePeriph( LL_DBGMCU_APB2_GRP1_TIM1_STOP );
 	HAL_TIM1_Pin_Init();
 	HAL_TIM1_Pin_Init();
 }
 }
 
 
-void PWM_TimerInit(void){
+void PWM_TimerEnable(void){
 	TIM_TypeDef * TIMx = htim1.Instance;
 	TIM_TypeDef * TIMx = htim1.Instance;
 	uint32_t Brk2Timeout = 1000;
 	uint32_t Brk2Timeout = 1000;
 	
 	
@@ -103,6 +105,8 @@ void PWM_TimerInit(void){
 	LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH2 );
 	LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH2 );
 	/* Enables the TIMx Preload on CC3 Register */
 	/* Enables the TIMx Preload on CC3 Register */
 	LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH3 );
 	LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH3 );
+  	/* Enables the TIMx Preload on CC4 Register */
+  	LL_TIM_OC_EnablePreload( TIMx, LL_TIM_CHANNEL_CH4 );	
 	/* Prepare timer for synchronization */
 	/* Prepare timer for synchronization */
 	LL_TIM_GenerateEvent_UPDATE( TIMx );
 	LL_TIM_GenerateEvent_UPDATE( TIMx );
 
 
@@ -150,6 +154,17 @@ void PWM_UpdateDuty(u32 duty1, u32 duty2, u32 duty3, u32 sample_point ) {
 
 
 void PWM_Start(void) {
 void PWM_Start(void) {
 	TIM_TypeDef * TIMx = htim1.Instance;
 	TIM_TypeDef * TIMx = htim1.Instance;
+  	/* Set all duty to 50% */
+  	LL_TIM_OC_SetCompareCH1(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
+  	LL_TIM_OC_SetCompareCH2(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
+  	LL_TIM_OC_SetCompareCH3(TIMx, ((uint32_t) FOC_PWM_Half_Period / (uint32_t) 2));
+  	LL_TIM_OC_SetCompareCH4(TIMx, ((uint32_t) FOC_PWM_Half_Period - (uint32_t) 5));	
+  	/* wait for a new PWM period */
+  	LL_TIM_ClearFlag_UPDATE( TIMx );
+  	while ( LL_TIM_IsActiveFlag_UPDATE( TIMx ) == 0u )
+  	{}
+  	/* Clear Update Flag */
+  	LL_TIM_ClearFlag_UPDATE( TIMx );
 	/* Main PWM Output Enable */
 	/* Main PWM Output Enable */
 	TIMx->BDTR |= LL_TIM_OSSI_ENABLE;
 	TIMx->BDTR |= LL_TIM_OSSI_ENABLE;
 	LL_TIM_EnableAllOutputs ( TIMx );
 	LL_TIM_EnableAllOutputs ( TIMx );

+ 1 - 1
Application/Hal/pwm.h

@@ -6,7 +6,7 @@ void HAL_PWM_Init(int fs);
 void PWM_UpdateDuty(u32 duty1, u32 duty2, u32 duty3, u32 sample_point);
 void PWM_UpdateDuty(u32 duty1, u32 duty2, u32 duty3, u32 sample_point);
 void PWM_Start(void);
 void PWM_Start(void);
 void PWM_Stop(void);
 void PWM_Stop(void);
-void PWM_TimerInit(void);
+void PWM_TimerEnable(void);
 void PWM_TurnOnLowSides(void);
 void PWM_TurnOnLowSides(void);
 
 
 #endif /* _PWM_H__ */
 #endif /* _PWM_H__ */

+ 70 - 0
Application/Hal/uart2.c

@@ -0,0 +1,70 @@
+#include "hal/hal.h"
+#include "stm32f3xx_ll_usart.h"
+#include "uart2.h"
+
+static UART_HandleTypeDef huart2;
+
+static void UART2_Pin_Init(void){
+	GPIO_InitTypeDef GPIO_InitStruct = {0};
+	/* Peripheral clock enable */
+	__HAL_RCC_USART2_CLK_ENABLE();
+	
+	__HAL_RCC_GPIOA_CLK_ENABLE();
+	/**USART2 GPIO Configuration
+	PA2	  ------> USART2_TX
+	PA3	  ------> USART2_RX
+	*/
+	GPIO_InitStruct.Pin = UART_TX_Pin|UART_RX_Pin;
+	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+	GPIO_InitStruct.Pull = GPIO_NOPULL;
+	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+	GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
+	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+}
+
+void UART2_Init(void){
+	huart2.Instance = USART2;
+	huart2.Init.BaudRate = 115200;
+	huart2.Init.WordLength = UART_WORDLENGTH_8B;
+	huart2.Init.StopBits = UART_STOPBITS_1;
+	huart2.Init.Parity = UART_PARITY_NONE;
+	huart2.Init.Mode = UART_MODE_TX_RX;
+	huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+	huart2.Init.OverSampling = UART_OVERSAMPLING_16;
+	huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
+	huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
+	UART2_Pin_Init();
+	if (HAL_UART_Init(&huart2) != HAL_OK)
+	{
+	  Error_Handler();
+	}
+	LL_USART_DisableIT_TXE(huart2.Instance);
+	LL_USART_DisableDirectionRx(huart2.Instance);
+	LL_USART_EnableDirectionTx(huart2.Instance);
+	HAL_NVIC_EnableIRQ(USART2_IRQn);
+}
+
+void UART2_EnableTx(void) {
+	USART_TypeDef *USARTx = huart2.Instance;
+	if (!LL_USART_IsEnabledIT_TXE(USARTx)) {
+		LL_USART_EnableIT_TXE(huart2.Instance);
+	}
+}
+
+void UART2_TxData(u8 data) {
+	LL_USART_TransmitData8(huart2.Instance, data);
+}
+
+__weak bool uart_tx_finished(void) {return true;}
+void uart2_irq_handler(void) {
+	USART_TypeDef *USARTx = huart2.Instance;
+	if (LL_USART_IsActiveFlag_RXNE(USARTx)){
+
+	}
+	if (LL_USART_IsActiveFlag_TXE(USARTx)) {
+		if (uart_tx_finished()){
+			LL_USART_DisableIT_TXE(huart2.Instance);
+		}
+	}
+}
+

+ 10 - 0
Application/Hal/uart2.h

@@ -0,0 +1,10 @@
+#ifndef _UART2_H__
+#define _UART2_H__
+#include "libs/types.h"
+
+void UART2_Init(void);
+void UART2_EnableTx(void);
+void UART2_TxData(u8 data);
+
+#endif /* _UART2_H__ */
+

+ 116 - 0
Application/Libs/circle_buffer.c

@@ -0,0 +1,116 @@
+
+#include <string.h>
+#include "circle_buffer.h"
+
+static int circle_get_write_space(c_buffer_t *cbuff);
+static int circle_get_read_space(c_buffer_t *cbuff);
+
+void circle_buffer_init(c_buffer_t *cbuff, uint8_t *buffer, int16_t max_len){
+	cbuff->buffer = buffer;
+	cbuff->buffer_len = max_len;
+}
+
+void circle_reset(c_buffer_t *cbuff){
+	cbuff->r_pos = cbuff->w_pos = 0;
+}
+
+
+int circle_put_data(c_buffer_t *cbuff, uint8_t *data, int16_t len){
+	int16_t size = circle_get_write_space(cbuff);
+	int16_t w_len = len;
+	int16_t w1_len = len;
+	if (size < 0){
+		return size;
+	}
+	w_len = min(len, size);
+	while(w_len > 0){
+		//wrapper
+		if (cbuff->w_pos + w_len > cbuff->buffer_len){
+			w1_len = cbuff->buffer_len - cbuff->w_pos;
+		}else{
+			w1_len = w_len;
+		}
+		memcpy(cbuff->buffer + cbuff->w_pos, data, w1_len);
+		cbuff->w_pos = (cbuff->w_pos + w1_len);
+		if (cbuff->w_pos == cbuff->buffer_len){
+			cbuff->w_pos = 0;
+		}
+		w_len -= w1_len;
+		data += w1_len;
+	}
+	return min(len, size);
+}
+
+int circle_put_one_data(c_buffer_t *cbuff, uint8_t data){
+	int16_t size = circle_get_write_space(cbuff);
+	if (size < 0){
+		return size;
+	}
+	cbuff->buffer[cbuff->w_pos] = data;
+	cbuff->w_pos = cbuff->w_pos + 1;
+	if (cbuff->w_pos == cbuff->buffer_len){
+		cbuff->w_pos = 0;
+	}
+	return 1;
+}
+
+int circle_get_data(c_buffer_t *cbuff, uint8_t *data, int16_t len){
+	int16_t size = circle_get_read_space(cbuff);
+	int16_t r_len = len;
+	int16_t r1_len = 0;
+	if (size <= 0){
+		return size;
+	}
+
+	r_len = min(size, len);
+
+	while(r_len > 0){
+		if (cbuff->r_pos + r_len > cbuff->buffer_len){
+			r1_len = cbuff->buffer_len - cbuff->r_pos;
+		}else{
+			r1_len = r_len;
+		}
+		memcpy(data, cbuff->buffer + cbuff->r_pos, r1_len);
+		cbuff->r_pos = (cbuff->r_pos + r1_len);
+		if (cbuff->r_pos == cbuff->buffer_len){
+			cbuff->r_pos = 0;
+		}		
+		r_len -= r1_len;
+		data += r1_len;
+	}
+	return min(size, len);
+}
+
+
+int circle_get_one_data(c_buffer_t *cbuff, uint8_t *data){
+	int16_t size = circle_get_read_space(cbuff);
+	if (size <= 0){
+		return size;
+	}
+	*data = cbuff->buffer[cbuff->r_pos];
+	cbuff->r_pos = cbuff->r_pos + 1;
+	if (cbuff->r_pos == cbuff->buffer_len){
+		cbuff->r_pos = 0;
+	}
+	return 1;
+}
+
+#if 0
+static __inline__ int circle_get_write_space(c_buffer_t *cbuff){
+	int16_t size = (cbuff->w_pos >= cbuff->r_pos)?(cbuff->buffer_len - cbuff->w_pos + cbuff->r_pos):(cbuff->r_pos - cbuff->w_pos);
+	size -= 1;
+	if (size <= 0){
+		return CBUFF_FULL;
+	}
+	return size;
+}
+#endif
+static __inline__ int circle_get_read_space(c_buffer_t *cbuff){
+	int16_t size = (cbuff->r_pos > cbuff->w_pos) ? (cbuff->buffer_len - cbuff->r_pos + cbuff->w_pos) : (cbuff->w_pos - cbuff->r_pos);
+	if (size <= 0){
+		return CBUFF_EMPTY;
+	}
+	return size;
+}
+
+

+ 45 - 0
Application/Libs/circle_buffer.h

@@ -0,0 +1,45 @@
+#ifndef _Cirule_Buffer_h__
+#define _Cirule_Buffer_h__
+
+#include <stdint.h>
+#ifndef min
+#define min(x,y)(x<y)?x:y;
+#endif
+
+#define CBUFF_SUCCESS 0
+#define CBUFF_FULL -1
+#define CBUFF_EMPTY -2
+
+typedef struct {
+	uint8_t * buffer;
+	int16_t buffer_len;
+	int16_t w_pos;
+	int16_t r_pos;
+}c_buffer_t;
+
+//used by dma
+static __inline__ void circle_update_write_position(c_buffer_t *cbuff, int pos){
+	cbuff->w_pos = pos;
+}
+
+static __inline__ int circle_get_read_position(c_buffer_t *cbuff){
+	return cbuff->r_pos;
+}
+static __inline__ int circle_get_write_space(c_buffer_t *cbuff){
+	int16_t size = (cbuff->w_pos >= cbuff->r_pos)?(cbuff->buffer_len - cbuff->w_pos + cbuff->r_pos):(cbuff->r_pos - cbuff->w_pos);
+	size -= 1;
+	if (size <= 0){
+		return CBUFF_FULL;
+	}
+	return size;
+}
+
+void circle_buffer_init(c_buffer_t *cbuff, uint8_t *buffer, int16_t max_len);
+void circle_reset(c_buffer_t *cbuff);
+int circle_put_one_data(c_buffer_t *cbuff, uint8_t data);
+int circle_put_data(c_buffer_t *cbuff, uint8_t *data, int16_t len);
+int circle_get_one_data(c_buffer_t *cbuff, uint8_t *data);
+int circle_get_data(c_buffer_t *cbuffer, uint8_t *data, int16_t len);
+
+#endif /* _Cirule_Buffer_h__ */
+

+ 106 - 56
Project/Motor_PMSM.uvoptx

@@ -117,6 +117,11 @@
         <pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon>
         <pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon>
       </DebugOpt>
       </DebugOpt>
       <TargetDriverDllRegistry>
       <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>JL2CM3</Key>
+          <Name>-U776565619 -O78 -S8 -ZTIFSpeedSel50000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F3xx_256.FLM -FS08000000 -FL010000 -FP0($$Device:STM32F302R8Tx$CMSIS\Flash\STM32F3xx_256.FLM)</Name>
+        </SetRegEntry>
         <SetRegEntry>
         <SetRegEntry>
           <Number>0</Number>
           <Number>0</Number>
           <Key>ARMRTXEVENTFLAGS</Key>
           <Key>ARMRTXEVENTFLAGS</Key>
@@ -140,7 +145,7 @@
         <SetRegEntry>
         <SetRegEntry>
           <Number>0</Number>
           <Number>0</Number>
           <Key>ST-LINKIII-KEIL_SWO</Key>
           <Key>ST-LINKIII-KEIL_SWO</Key>
-          <Name>-U0671FF363730554157013636 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F3xx_256.FLM -FS08000000 -FL010000 -FP0($$Device:STM32F302R8Tx$CMSIS\Flash\STM32F3xx_256.FLM)</Name>
+          <Name>-U0671FF363730554157013636 -O206 -SF1800 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F3xx_256.FLM -FS08000000 -FL010000 -FP0($$Device:STM32F302R8Tx$CMSIS\Flash\STM32F3xx_256.FLM)</Name>
         </SetRegEntry>
         </SetRegEntry>
         <SetRegEntry>
         <SetRegEntry>
           <Number>0</Number>
           <Number>0</Number>
@@ -148,30 +153,23 @@
           <Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F3xx_256 -FS08000000 -FL010000 -FP0($$Device:STM32F302R8Tx$CMSIS\Flash\STM32F3xx_256.FLM))</Name>
           <Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F3xx_256 -FS08000000 -FL010000 -FP0($$Device:STM32F302R8Tx$CMSIS\Flash\STM32F3xx_256.FLM))</Name>
         </SetRegEntry>
         </SetRegEntry>
       </TargetDriverDllRegistry>
       </TargetDriverDllRegistry>
-      <Breakpoint>
-        <Bp>
-          <Number>0</Number>
-          <Type>0</Type>
-          <LineNumber>92</LineNumber>
-          <EnabledFlag>1</EnabledFlag>
-          <Address>0</Address>
-          <ByteObject>0</ByteObject>
-          <HtxType>0</HtxType>
-          <ManyObjects>0</ManyObjects>
-          <SizeOfObject>0</SizeOfObject>
-          <BreakByAccess>0</BreakByAccess>
-          <BreakIfRCount>0</BreakIfRCount>
-          <Filename>..\Application\FOC\foc.c</Filename>
-          <ExecCommand></ExecCommand>
-          <Expression></Expression>
-        </Bp>
-      </Breakpoint>
+      <Breakpoint/>
       <WatchWindow1>
       <WatchWindow1>
         <Ww>
         <Ww>
           <count>0</count>
           <count>0</count>
           <WinNumber>1</WinNumber>
           <WinNumber>1</WinNumber>
           <ItemText>hall_table,0x0A</ItemText>
           <ItemText>hall_table,0x0A</ItemText>
         </Ww>
         </Ww>
+        <Ww>
+          <count>1</count>
+          <WinNumber>1</WinNumber>
+          <ItemText>m_foc,0x0A</ItemText>
+        </Ww>
+        <Ww>
+          <count>2</count>
+          <WinNumber>1</WinNumber>
+          <ItemText>hall_iterations,0x0A</ItemText>
+        </Ww>
       </WatchWindow1>
       </WatchWindow1>
       <Tracepoint>
       <Tracepoint>
         <THDelay>0</THDelay>
         <THDelay>0</THDelay>
@@ -179,7 +177,7 @@
       <DebugFlag>
       <DebugFlag>
         <trace>0</trace>
         <trace>0</trace>
         <periodic>1</periodic>
         <periodic>1</periodic>
-        <aLwin>1</aLwin>
+        <aLwin>0</aLwin>
         <aCover>0</aCover>
         <aCover>0</aCover>
         <aSer1>0</aSer1>
         <aSer1>0</aSer1>
         <aSer2>0</aSer2>
         <aSer2>0</aSer2>
@@ -216,6 +214,10 @@
       <pSingCmdsp></pSingCmdsp>
       <pSingCmdsp></pSingCmdsp>
       <pMultCmdsp></pMultCmdsp>
       <pMultCmdsp></pMultCmdsp>
       <SystemViewers>
       <SystemViewers>
+        <Entry>
+          <Name>System Viewer\ADC1</Name>
+          <WinId>35904</WinId>
+        </Entry>
         <Entry>
         <Entry>
           <Name>System Viewer\TIM1</Name>
           <Name>System Viewer\TIM1</Name>
           <WinId>35905</WinId>
           <WinId>35905</WinId>
@@ -226,7 +228,7 @@
         <EnableFlashSeq>0</EnableFlashSeq>
         <EnableFlashSeq>0</EnableFlashSeq>
         <EnableLog>0</EnableLog>
         <EnableLog>0</EnableLog>
         <Protocol>2</Protocol>
         <Protocol>2</Protocol>
-        <DbgClock>10000000</DbgClock>
+        <DbgClock>1800000</DbgClock>
       </DebugDescription>
       </DebugDescription>
     </TargetOption>
     </TargetOption>
   </Target>
   </Target>
@@ -353,6 +355,18 @@
       <RteFlg>0</RteFlg>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
       <bShared>0</bShared>
     </File>
     </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>10</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Application\FOC\ramp_ctrl.c</PathWithFileName>
+      <FilenameWithoutPath>ramp_ctrl.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
   </Group>
 
 
   <Group>
   <Group>
@@ -363,7 +377,7 @@
     <RteFlg>0</RteFlg>
     <RteFlg>0</RteFlg>
     <File>
     <File>
       <GroupNumber>3</GroupNumber>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>10</FileNumber>
+      <FileNumber>11</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -375,7 +389,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>3</GroupNumber>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>11</FileNumber>
+      <FileNumber>12</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -385,6 +399,18 @@
       <RteFlg>0</RteFlg>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
       <bShared>0</bShared>
     </File>
     </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>13</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Application\Libs\circle_buffer.c</PathWithFileName>
+      <FilenameWithoutPath>circle_buffer.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
   </Group>
 
 
   <Group>
   <Group>
@@ -395,7 +421,7 @@
     <RteFlg>0</RteFlg>
     <RteFlg>0</RteFlg>
     <File>
     <File>
       <GroupNumber>4</GroupNumber>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>12</FileNumber>
+      <FileNumber>14</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -407,7 +433,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>4</GroupNumber>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>13</FileNumber>
+      <FileNumber>15</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -419,7 +445,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>4</GroupNumber>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>14</FileNumber>
+      <FileNumber>16</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -429,6 +455,18 @@
       <RteFlg>0</RteFlg>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
       <bShared>0</bShared>
     </File>
     </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>17</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Application\Bsp\serial.c</PathWithFileName>
+      <FilenameWithoutPath>serial.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
   </Group>
 
 
   <Group>
   <Group>
@@ -439,7 +477,7 @@
     <RteFlg>0</RteFlg>
     <RteFlg>0</RteFlg>
     <File>
     <File>
       <GroupNumber>5</GroupNumber>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>15</FileNumber>
+      <FileNumber>18</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -451,7 +489,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>5</GroupNumber>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>16</FileNumber>
+      <FileNumber>19</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -463,7 +501,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>5</GroupNumber>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>17</FileNumber>
+      <FileNumber>20</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -473,6 +511,18 @@
       <RteFlg>0</RteFlg>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
       <bShared>0</bShared>
     </File>
     </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>21</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Application\Hal\uart2.c</PathWithFileName>
+      <FilenameWithoutPath>uart2.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
   </Group>
 
 
   <Group>
   <Group>
@@ -483,7 +533,7 @@
     <RteFlg>0</RteFlg>
     <RteFlg>0</RteFlg>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>18</FileNumber>
+      <FileNumber>22</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -495,7 +545,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>19</FileNumber>
+      <FileNumber>23</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -507,7 +557,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>20</FileNumber>
+      <FileNumber>24</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -519,7 +569,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>21</FileNumber>
+      <FileNumber>25</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -531,7 +581,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>22</FileNumber>
+      <FileNumber>26</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -543,7 +593,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>23</FileNumber>
+      <FileNumber>27</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -555,7 +605,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>24</FileNumber>
+      <FileNumber>28</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -567,7 +617,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>25</FileNumber>
+      <FileNumber>29</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -579,7 +629,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>26</FileNumber>
+      <FileNumber>30</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -591,7 +641,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>27</FileNumber>
+      <FileNumber>31</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -603,7 +653,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>28</FileNumber>
+      <FileNumber>32</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -615,7 +665,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>29</FileNumber>
+      <FileNumber>33</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -627,7 +677,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>30</FileNumber>
+      <FileNumber>34</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -639,7 +689,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>31</FileNumber>
+      <FileNumber>35</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -651,7 +701,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>32</FileNumber>
+      <FileNumber>36</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -663,7 +713,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>33</FileNumber>
+      <FileNumber>37</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -675,7 +725,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>34</FileNumber>
+      <FileNumber>38</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -687,7 +737,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>35</FileNumber>
+      <FileNumber>39</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -699,7 +749,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>36</FileNumber>
+      <FileNumber>40</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -711,7 +761,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>37</FileNumber>
+      <FileNumber>41</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -723,7 +773,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>38</FileNumber>
+      <FileNumber>42</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -735,7 +785,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>39</FileNumber>
+      <FileNumber>43</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -747,7 +797,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>40</FileNumber>
+      <FileNumber>44</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -759,7 +809,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>41</FileNumber>
+      <FileNumber>45</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -771,7 +821,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>6</GroupNumber>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>42</FileNumber>
+      <FileNumber>46</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -791,7 +841,7 @@
     <RteFlg>0</RteFlg>
     <RteFlg>0</RteFlg>
     <File>
     <File>
       <GroupNumber>7</GroupNumber>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>43</FileNumber>
+      <FileNumber>47</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -803,7 +853,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>7</GroupNumber>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>44</FileNumber>
+      <FileNumber>48</FileNumber>
       <FileType>2</FileType>
       <FileType>2</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>

+ 20 - 0
Project/Motor_PMSM.uvprojx

@@ -433,6 +433,11 @@
               <FileType>1</FileType>
               <FileType>1</FileType>
               <FilePath>..\Application\FOC\hall_sensor.c</FilePath>
               <FilePath>..\Application\FOC\hall_sensor.c</FilePath>
             </File>
             </File>
+            <File>
+              <FileName>ramp_ctrl.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Application\FOC\ramp_ctrl.c</FilePath>
+            </File>
           </Files>
           </Files>
         </Group>
         </Group>
         <Group>
         <Group>
@@ -448,6 +453,11 @@
               <FileType>1</FileType>
               <FileType>1</FileType>
               <FilePath>..\Application\Math\fast_math.c</FilePath>
               <FilePath>..\Application\Math\fast_math.c</FilePath>
             </File>
             </File>
+            <File>
+              <FileName>circle_buffer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Application\Libs\circle_buffer.c</FilePath>
+            </File>
           </Files>
           </Files>
         </Group>
         </Group>
         <Group>
         <Group>
@@ -468,6 +478,11 @@
               <FileType>1</FileType>
               <FileType>1</FileType>
               <FilePath>..\Application\Bsp\foc_irqs.c</FilePath>
               <FilePath>..\Application\Bsp\foc_irqs.c</FilePath>
             </File>
             </File>
+            <File>
+              <FileName>serial.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Application\Bsp\serial.c</FilePath>
+            </File>
           </Files>
           </Files>
         </Group>
         </Group>
         <Group>
         <Group>
@@ -488,6 +503,11 @@
               <FileType>1</FileType>
               <FileType>1</FileType>
               <FilePath>..\Application\Hal\adc.c</FilePath>
               <FilePath>..\Application\Hal\adc.c</FilePath>
             </File>
             </File>
+            <File>
+              <FileName>uart2.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Application\Hal\uart2.c</FilePath>
+            </File>
           </Files>
           </Files>
         </Group>
         </Group>
         <Group>
         <Group>