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

add can message for calibrate hall offset/phase, ready/unready, set open vq

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 4 лет назад
Родитель
Сommit
ecf14a2832

+ 5 - 14
Applications/app/app.c

@@ -6,30 +6,21 @@
 #include "prot/can_message.h"
 #include "foc/foc_api.h"
 
-
-static void _test_timer_handler(timer_t *t);
-static void _log_test(void *args);
-
-static timer_t test_timer = TIMER_INIT(test_timer, _test_timer_handler);
+static void _app_low_task(void *args);
 
 void app_start(void){
 	set_log_level(MOD_SYSTEM, L_debug);
 	can_message_init();
 	foc_init();
-	co_task_create(_log_test, NULL, 512);
-	timer_post(&test_timer, 200);
+	co_task_create(_app_low_task, NULL, 512);
 	co_task_schedule();
 }
 
-static void _test_timer_handler(timer_t *t){
-	//foc_start_motor();
-}
-
 
-static void _log_test(void *args) {
-	int count = 0;
+static void _app_low_task(void *args) {
 	while(1) {
-		sys_debug("log test count %d\n", count++);
+		wdog_reload();
+		sys_debug("speed %d RPM\n", foc_get_speed());
 		co_task_delay(500);
 	}
 }

+ 2 - 2
Applications/bsp/bsp.h

@@ -41,11 +41,11 @@
 #define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
 #define TADC   ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
 
-#define START_RAMP_DURATION (100)//ms
+#define START_RAMP_DURATION (1000)//ms
 #define SPEED_SAMPLE_INVAL (100) //ת�Ѳɼ��ļ��,ms
 #define SPEED_RAMP_DURATION SPEED_SAMPLE_INVAL //�����ٶȵ�б��ʱ�䣬�ٶ�ƽ���������½�
 
-#define MAX_VBUS_VOLTAGE 12.0f
+#define MAX_VBUS_VOLTAGE 48.0f
 #define MAX_CURRENT      50.0F
 
 #define pwm_timer TIMER0

+ 0 - 2
Applications/bsp/can.c

@@ -35,8 +35,6 @@ static void _can_rx_task(void *args){
 	}
 }
 
-
-
 static __inline__ void can_fifo_recv(int fifo){
 	can_receive_message_struct message;
 

+ 1 - 1
Applications/bsp/uart.c

@@ -50,7 +50,7 @@ static uart_enum_t _uart_index(uint32_t com){
 }
 static bool shark_uart_on_rx_frame(shark_uart_t *uart)
 {
-	u16 crc0 = DECODE_U16(uart->rx_frame + uart->rx_length);
+	u16 crc0 = decode_u16(uart->rx_frame + uart->rx_length);
 	u16 crc1 = crc16_get(uart->rx_frame, uart->rx_length);
 
 	if (crc0 != crc1) {

+ 5 - 0
Applications/foc/foc_api.c

@@ -1,6 +1,7 @@
 #include <string.h>
 #include "os/os_type.h"
 #include "libs/utils.h"
+#include "libs/logger.h"
 #include "bsp/bsp.h"
 #include "bsp/adc.h"
 #include "bsp/pwm.h"
@@ -12,6 +13,8 @@
 #include "foc/phase_current.h"
 #include "foc/hall_sensor.h"
 #include "foc/gas_sensor.h"
+#include "foc/foc_cmd.h"
+
 extern motor_foc_t g_foc;
 static void foc_defulat_value(void);
 
@@ -21,6 +24,7 @@ void foc_init(void) {
 	pwm_3phase_init();
 	hall_sensor_init();
 	foc_core_init();
+	foc_command_init();
 }
 
 static void foc_defulat_value(void){
@@ -76,6 +80,7 @@ void foc_set_dq_command(float d, float q) {
 }
 
 void foc_set_voltage_ramp(float final){
+	sys_debug("voltage %f -> %f\n", g_foc.dq_last.Vq, final);
 	ramp_set_target(&g_foc.voltage_ramp, g_foc.dq_last.Vq, final, START_RAMP_DURATION);
 	ramp_exc(&g_foc.voltage_ramp);
 }

+ 101 - 0
Applications/foc/foc_cmd.c

@@ -0,0 +1,101 @@
+#include "os/co_task.h"
+#include "os/queue.h"
+#include "libs/logger.h"
+#include "libs/utils.h"
+#include "prot/can_message.h"
+#include "bsp/bsp.h"
+#include "bsp/pwm.h"
+#include "bsp/adc.h"
+#include "foc/foc_api.h"
+#include "foc/foc_core.h"
+#include "foc/hall_sensor.h"
+#include "foc/foc_cmd.h"
+
+extern motor_foc_t g_foc;
+
+static void foc_cmd_task(void *args);
+static void process_foc_command(foc_cmd_body_t *command);
+
+static co_queue_t _cmd_queue;
+
+void foc_command_init(void) {
+	_cmd_queue = queue_create(16, sizeof(foc_cmd_body_t));
+	co_task_create(foc_cmd_task, NULL, 512);
+}
+
+bool foc_send_command(foc_cmd_body_t *command) {
+	return queue_put(_cmd_queue, command);
+}
+
+static void foc_cmd_task(void *args) {
+	foc_cmd_body_t command;
+	while(1) {
+		if (queue_get(_cmd_queue, &command)) {
+			process_foc_command(&command);
+			if (command.data) {
+				co_free(command.data);
+			}
+		}
+		co_task_yield();
+	}
+}
+
+static void do_hall_calibrate(u8 can_addr, float vq) {
+	sys_debug("cali hall phase, %d\n", g_foc.state);
+	if (g_foc.state == IDLE) {
+		can_send_ack(can_addr, CMD_2_CAN_KEY(Foc_Cali_Hall_Phase), 1);
+		pwm_turn_on_low_side();
+		delay_ms(10);
+		foc_pwm_start(true);
+		pwm_enable_channel();
+		adc_start_insert_convert();
+		int result = hall_sensor_calibrate(vq, NULL);
+		sys_debug("hall phase cali %d\n", result);
+		can_send_ack(can_addr, CMD_2_CAN_KEY(Foc_Hall_Phase_Cali_Result), result);
+	}else {
+		can_send_ack(can_addr, CMD_2_CAN_KEY(Foc_Cali_Hall_Phase), 0);
+	}
+}
+
+static void process_foc_command(foc_cmd_body_t *command) {
+	sys_debug("command %d\n", command->cmd);
+	switch (command->cmd) {
+		case Foc_Start_Motor:
+		{
+			foc_fault_t f;
+			foc_start_stop_t start = (foc_start_stop_t)decode_u8((u8 *)command->data);
+			if (start == Foc_Start) {
+				f = foc_start_motor();
+			}else if (start == Foc_Stop) {
+				f = foc_stop_motor();
+			}
+			can_send_ack(command->can_src, CMD_2_CAN_KEY(Foc_Start_Motor), (u8)f);
+			break;
+		}
+		case Foc_Cali_Hall_Phase:
+			do_hall_calibrate(command->can_src, decode_u32((u8 *)command->data));
+			break;
+		case Foc_Cali_Hall_Offset:
+		{
+			int offset = 0;
+			u8 inc = decode_u8((u8 *)command->data);
+			if (inc) {
+				hall_offset_increase(1);
+			}else {
+				hall_offset_increase(-1);
+			}
+			sys_debug("cali hall offset %d\n", offset);
+			can_send_ack(command->can_src, CMD_2_CAN_KEY(Foc_Cali_Hall_Offset), 1);
+			break;
+		}
+		case Foc_Set_Open_Dq_Vol:
+		{
+			u32 v_q = decode_u32(((u8 *)command->data) + 4);
+			sys_debug("set v_q %d\n", v_q);
+			foc_set_voltage_ramp(v_q);
+			break;
+		}
+		default:
+			break;
+	}
+}

+ 59 - 0
Applications/foc/foc_cmd.h

@@ -0,0 +1,59 @@
+#ifndef _FOC_CMD_H__
+#define _FOC_CMD_H__
+#include "os/os_type.h"
+#include "config.h"
+
+typedef enum {
+	Foc_Start_Motor = 1, //foc_start_stop_t, ready, unread, 0x014d01
+	Foc_Cali_Hall_Phase, //calibrate hall phase, get the angle when motor running 0-360
+	Foc_Cali_Hall_Offset,//calibrate hall offset from A phase 0x034d00
+	Foc_Current_Limit,   //u32, set the limited current//mA
+	Foc_Set_Speed_Limit,     //u32, set the limited speed//rpm
+	Foc_Set_Speed_Target,    //u32, set the target speed, just for test
+	Foc_Set_Cruise_Speed,    //u32, set the speed for curise riding
+	Foc_Hall_Phase_Cali_Result,
+	Foc_Hall_Offset_Cali_Result,
+	Foc_Report_Speed,
+	Foc_Report_Vbus_Current, 	//u32
+	Foc_Report_Phase_Current, 	//s32,s32,s32
+	Foc_Report_Dq_Current, 		//s32,s32
+	Foc_Report_Vbus_Vol,		//u32
+	Foc_Report_Phase_Vol,		//u32,u32,u32
+	Foc_Report_Dq_Vol,			//u32, u32
+	Foc_Set_Open_Dq_Vol,  		//u32, u32, 0x114d000000000a000000
+	Foc_Cmd_Max
+}foc_cmd_t;
+
+#define CMD_2_CAN_KEY(cmd) ((u16)(((u16)cmd) | (CAN_MY_ADDRESS<<8)))
+typedef enum {
+	Foc_Start = 1,
+	Foc_Stop,
+}foc_start_stop_t;
+
+typedef struct {
+	foc_cmd_t cmd;
+	u8        can_src;
+	void      *data;
+}foc_cmd_body_t;
+
+#pragma  pack (push,1)
+typedef struct {
+	foc_start_stop_t start_stop; //1: start, 2: stop
+}foc_start_cmd_t;
+
+typedef struct {
+	u32 vq_mvol; //mV
+}hall_phase_cali_cmd_t;
+
+typedef struct {
+	u32 vq_mvol;  //mV
+	u32 step_inc; //degree
+	u32 step_time;//second
+}hall_offset_cali_cmd_t;
+#pragma pack(pop)
+
+void foc_command_init(void);
+bool foc_send_command(foc_cmd_body_t *command);
+
+#endif /*_FOC_CMD_H__ */
+

+ 2 - 1
Applications/foc/foc_core.c

@@ -16,7 +16,7 @@
 
 motor_foc_t g_foc = {
 	.motor_param = {
-		.poles = 2,
+		.poles = 5,
 		.ld = 0.578477f,
 		.lq = 5.78477f,
 		.rs = 1.088f,
@@ -257,6 +257,7 @@ static void foc_measure_task(void *args){
 	while(1) {
 		vbus_sample_voltage();
 		ntc_sensor_sample();
+		g_foc.vbus = vbus_get_filted_voltage();
 		wdog_reload();
 		co_task_yield();
 	}

+ 0 - 3
Applications/foc/foc_stm.c

@@ -63,10 +63,7 @@ void FOC_Normal_Task(motor_foc_t *foc) {
 			break;
 		case READY_TO_RUN:
 			foc_pwm_start(true);
-			//hall_sensor_calibrate(1.0f, NULL);
 			foc_stm_nextstate(RAMPING_START);
-			//ramp_exc(&foc->voltage_ramp);
-			foc_set_voltage_ramp(1.0f);
 			break;
 		case RAMPING_START:
 			foc_set_dq_command(0.0f, ramp_get_target(&foc->voltage_ramp));

+ 27 - 16
Applications/foc/hall_sensor.c

@@ -2,6 +2,7 @@
 #include "bsp/bsp.h"
 #include "bsp/mc_hall_gpio.h"
 #include "os/co_task.h"
+#include "os/timer.h"
 #include "libs/utils.h"
 #include "math/fast_math.h"
 #include "hall_sensor.h"
@@ -10,6 +11,8 @@
 #include "bsp/timer_count32.h"
 
 #define HALL_READ_TIMES 3
+static void _hall_timeout_handler(timer_t *timer);
+
 /* 
 * 测量HALL_PLACE_OFFSET通用方式就是ST推荐的通过外力带动电机,
 * 测量电机U相反电动势和hall 1的上升沿之间的差值
@@ -18,7 +21,7 @@
 * 从0开始增加,每增加1度观察电机电流(看直流电源),
 * 找到一个电机平稳转动并且电流最小的角度作为HALL_PLACE_OFFSET
 */
-#define HALL_PLACE_OFFSET 213.0f
+#define HALL_PLACE_OFFSET 210.0f
 /* 
 100
 101
@@ -32,6 +35,7 @@
 static u16 _hall_table[] = {0xFFFF, 121/*1*/, 240/*2*/, 190/*3*/, 13/*4*/, 58/*5*/, 306/*6*/, 0xFFFF};
 static hall_t _hall;
 static hall_sample_t h_samples;
+static timer_t _hall_detect_timer = TIMER_INIT(_hall_detect_timer, _hall_timeout_handler);
 
 #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)
@@ -73,18 +77,18 @@ void hall_sensor_init(void) {
 	mc_hall_init();
 	memset(&_hall, 0, sizeof(_hall));
 	read_hall(_hall.state, _hall.theta);
-	_hall.phase_offset = 180.0f;//mc_config_get()->hall_offset;
+	_hall.phase_offset = HALL_PLACE_OFFSET;//mc_config_get()->hall_offset;
 }
 
+void _hall_timeout_handler(timer_t *timer){
 
-static void _detect_timeout(void){
-	u32 now = get_seconds();
-	if (now > _hall.second + 4) {//4s内没有霍尔中断,速度清零
-		if (_hall.degree_per_s > 0) {
-			_hall.degree_per_s = 0;
-			_hall.e_rpm = _hall.e_filted_rpm = 0;
-		}
-	}
+	_hall.degree_per_s = 0;
+	_hall.e_rpm = _hall.e_filted_rpm = 0;
+	h_samples.index = 0;
+}
+
+u16 *hall_phase_angle(void) {
+	return _hall_table;
 }
 
 float hall_sensor_get_theta(void){
@@ -117,15 +121,21 @@ void hall_sensor_set_theta(bool override, float theta){
 }
 
 float hall_sensor_get_speed(void) {
-	_detect_timeout();
 	return _hall.e_rpm;
 }
 
 float hall_sensor_avg_speed(void) {
-	_detect_timeout();
 	return _hall.e_filted_rpm;
 }
 
+int hall_offset_increase(int inc) {
+	if (_hall.phase_offset + inc >= 360.0f) {
+		_hall.phase_offset = _hall.phase_offset + inc - 360.0f;
+	}else {
+		_hall.phase_offset += inc;
+	}
+	return _hall.phase_offset;
+}
 
 int hall_sensor_calibrate(float voltage, u16 *hall_table){
 	if (hall_table == NULL) {
@@ -145,9 +155,9 @@ int hall_sensor_calibrate(float voltage, u16 *hall_table){
 	memset(sin_hall, 0, sizeof(sin_hall));
 	memset(cos_hall, 0, sizeof(cos_hall));
 	memset(hall_iterations, 0, sizeof(hall_iterations));
-	delay_ms(5 * 1000);
+	delay_ms(2 * 1000);
 	// Forwards
-	for (int i = 0;i < 3;i++) {
+	for (int i = 0;i < 5;i++) {
 		for (int j = 0;j < 360;j++) {
 			hall_sensor_set_theta(true, j);
 			delay_ms(5);
@@ -160,9 +170,9 @@ int hall_sensor_calibrate(float voltage, u16 *hall_table){
 			hall_iterations[hall]++;
 		}
 	}
-
+	delay_ms(2 * 1000);
 	// Reverse
-	for (int i = 0;i < 3;i++) {
+	for (int i = 0;i < 5;i++) {
 		for (int j = 360;j >= 0;j--) {
 			hall_sensor_set_theta(true, j);
 			delay_ms(5);
@@ -285,6 +295,7 @@ void hall_sensor_handler(void) {
 	_hall.theta = theta_now;
 	_hall.state = state_now;
 	_hall.e_rpm = _hall.degree_per_s / 360.0f * 60.0f;
+	timer_post(&_hall_detect_timer, 2000);
 	//printf("speed :%.4f - %.4f - %.4f - %d\n", _hall.degree_per_s, delta_theta, delta_time, (int)_hall.e_rpm);
 }
 

+ 3 - 0
Applications/foc/hall_sensor.h

@@ -55,5 +55,8 @@ float hall_sensor_get_speed(void); //return rpm
 float hall_sensor_avg_speed(void);
 int hall_sensor_calibrate(float voltage, u16 *hall_table);
 void hall_sensor_set_theta(bool override, float theta);
+u16 *hall_phase_angle(void);
+int hall_offset_increase(int inc);
+
 #endif /* _HALL_SENSOR_H__ */
 

+ 9 - 3
Applications/foc/ramp_ctrl.c

@@ -1,6 +1,6 @@
 #include "ramp_ctrl.h"
 
-#define RAMP_INTVAL 5 //ms
+#define RAMP_INTVAL 50 //ms
 void ramp_timer_handler(timer_t *timer);
 
 void ramp_ctrl_init(ramp_t *ramp){
@@ -40,8 +40,14 @@ bool ramp_complete(ramp_t *ramp) {
 void ramp_timer_handler(timer_t *timer) {
 	ramp_t *ramp = (ramp_t *)timer;
 	float target = ramp->target + ramp->steps;
-	if (abs(target) > abs(ramp->final_point)) {
-		target = ramp->final_point;
+	if (ramp->steps < 0) {
+		if (abs(target) < abs(ramp->final_point)) {
+			target = ramp->final_point;
+		}
+	}else {
+		if (abs(target) > abs(ramp->final_point)) {
+			target = ramp->final_point;
+		}
 	}
 	ramp->target = target;
 	if (target != ramp->final_point) {

+ 7 - 9
Applications/foc/vbus_sensor.c

@@ -5,7 +5,8 @@
 
 static vbus_t _vbus;
 void vbus_sensor_init(void){
-	_vbus.voltage_avg = 0;
+	_vbus.voltage = 0;
+	_vbus.voltage_filted = MAX_VBUS_VOLTAGE;
 	_vbus.avg_count = 5;
 	vbus_sample_voltage();
 }
@@ -13,17 +14,14 @@ void vbus_sensor_init(void){
 void vbus_sample_voltage(void){
 	u32 vadc = adc_sample_regular_channel(VBUS_V_CHAN, 16);
 
-	_vbus.voltage_avg = ((float)vadc)/(4096.0f) * ADC_REFERENCE_VOLTAGE / VBUS_PARTITIONING_FACTOR;
-	if (_vbus.voltage_filted == 0.0f) {
-		_vbus.voltage_filted = _vbus.voltage_avg;
-	}else {
-		LowPass_Filter(_vbus.voltage_filted, _vbus.voltage_avg, 0.1f);
-	}
+	_vbus.voltage = ((float)vadc)/(4096.0f) * ADC_REFERENCE_VOLTAGE * 45 / 1000; //1:44
+
+	LowPass_Filter(_vbus.voltage_filted, _vbus.voltage, 0.1f);
 }
 
 
-float vbus_get_voltage(void){
+float vbus_get_filted_voltage(void){
 
-	return _vbus.voltage_avg;
+	return _vbus.voltage_filted;
 }
 

+ 2 - 7
Applications/foc/vbus_sensor.h

@@ -2,20 +2,15 @@
 #define _VBUS_SENSOR_H__
 
 
-#define VBUS_PARTITIONING_FACTOR      0.0522f /*!< It expresses how
-                                                       much the Vbus is attenuated
-                                                       before being converted into
-                                                       digital value */
-
 typedef struct {
-	float voltage_avg;
+	float voltage;
 	float voltage_filted;
 	int avg_count;
 }vbus_t;
 
 void vbus_sensor_init(void);
 void vbus_sample_voltage(void);
-float vbus_get_voltage(void);
+float vbus_get_filted_voltage(void);
 
 #endif /* _VBUS_SENSOR_H__ */
 

+ 73 - 5
Applications/libs/utils.h

@@ -10,18 +10,86 @@ static __inline__ void delay_ms(u32 ms) {
 	cpu_udelay(ms*1000);
 }
 
-static __inline__ u16 DECODE_U16(u8 *buff) {
+static __inline__ u8 decode_u8(u8 *buff) {
+	return buff[0];
+}
+
+static __inline__ u16 decode_u16(u8 *buff) {
 	return (((u16)(buff[1]) << 8) | buff[0]);
 }
 
-static __inline__ u32 DECODE_U24(u8 *buff) {
-	return ((u32)(buff[2]) << 16 | DECODE_U16(buff));
+static __inline__ u32 decode_u24(u8 *buff) {
+	return ((u32)(buff[2]) << 16 | decode_u16(buff));
+}
+
+static __inline__ u16 decode_u32(u8 *buff) {
+	return ((u32)(buff[3]) << 24 | decode_u24(buff));
+}
+
+static __inline__ void encode_u16(u8 *buff, u16 value)
+{
+	buff[0] = value;
+	buff[1] = value >> 8;
+}
+
+static __inline__ void encode_u24(u8 *buff, u32 value)
+{
+	encode_u16(buff, value);
+	buff[2] = value >> 16;
+}
+
+static __inline__ void encode_u32(u8 *buff, u32 value)
+{
+	encode_u24(buff, value);
+	buff[3] = value >> 24;
 }
 
-static __inline__ u16 DECODE_U32(u8 *buff) {
-	return ((u32)(buff[3]) << 24 | DECODE_U24(buff));
+
+static __inline__ s8 decode_s08(const u8 *buff)
+{
+	return ((s8) buff[0]);
 }
 
+static __inline__ s16 decode_s16(const u8 *buff)
+{
+	return ((s16) buff[1]) << 8 | buff[0];
+}
+
+static __inline__ s32 decode_s24(const u8 *buff)
+{
+	return ((s32) buff[2]) << 16 | decode_s16(buff);
+}
+
+static __inline__ s32 decode_s32(const u8 *buff)
+{
+	return ((s32) buff[3]) << 24 | decode_s24(buff);
+}
+
+static __inline__ void encode_s08(u8 *buff, s8 value)
+{
+	buff[0] = value;
+}
+
+static __inline__ void encode_s16(u8 *buff, s16 value)
+{
+	encode_s08(buff,value);
+	encode_s08(buff+1,value >> 8);
+
+}
+
+static __inline__ void encode_s24(u8 *buff, s32 value)
+{
+	encode_s16(buff, value);
+	encode_s08(buff+2,value >> 16);
+}
+
+static __inline__ void encode_s32(u8 *buff, s32 value)
+{
+	encode_s24(buff, value);
+	encode_s08(buff+3,value >> 24);
+}
+
+
 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
 #define min(a,b) (a>b?b:a)
 #define MAX(x, y) ((x)>(y)?(x):(y))

+ 3 - 3
Applications/os/timer.c

@@ -57,12 +57,12 @@ static void timer_task_handler(void *args)
 {
 	while (1) {
 		timer_t *timer = timer_head.next;
-
+#if 0
 		if (timer->time > g_task_ticks64) {
 			co_task_delay((u32)(timer->time - g_task_ticks64));
 		}
-
-		if (timer != &timer_head) {
+#endif
+		if ((timer->time <= g_task_ticks64) && (timer != &timer_head)) {
 			timer_cancel(timer);
 			timer->handler(timer);
 		}

+ 24 - 7
Applications/prot/can_message.c

@@ -4,7 +4,8 @@
 #include "libs/utils.h"
 #include "can_message.h"
 #include "wait_queue.h"
-
+#include "can_pc_message.h"
+#include "foc/foc_cmd.h"
 static void can_process_message(can_message_t *message);
 static void free_can_message(can_message_t *message);
 
@@ -112,10 +113,19 @@ void handle_can_frame(can_id_t id, uint8_t *data, int len){
 
 static void can_process_message(can_message_t *message){
 	sys_debug("can %x [%x -> %x], len = %d\n", message->key, message->src, message->dest, message->len);
-	if (message->key & 0xFF >= 0xF0) {
-		//do iap update
-	}else if (message->src == 0x42){ //只处理后控的指令
-
+	if ((message->key & 0xFF) >= 0xF0) {
+		can_process_iap_message(message);
+	}else{ //只处理后控的指令
+		if ((message->key & 0xFF) < Foc_Cmd_Max){
+			foc_cmd_body_t command;
+			command.cmd = (foc_cmd_t)(message->key & 0xFF);
+			command.can_src = message->src;
+			command.data = co_malloc(message->len);
+			if (command.data) {
+				memcpy(command.data, message->data, message->len);
+				foc_send_command(&command);
+			}
+		}
 	}
 	free_can_message(message);
 }
@@ -131,8 +141,15 @@ static void free_can_message(can_message_t *message){
 	message->total_frame = 0xFF;
 }
 
-void can_send_response(uint8_t can_add, uint8_t *data, int len){
-	can_send_message(get_reponse_can_id(can_add), data, len, 50);
+void can_send_response(uint8_t can_addr, uint8_t *data, int len){
+	can_send_message(get_reponse_can_id(can_addr), data, len, 50);
+}
+
+void can_send_ack(uint8_t can_addr, uint16_t key, uint8_t data){
+	can_message_t message;
+	message.src = can_addr;
+	message.key = key;
+	can_send_message_ack(&message, data);
 }
 
 void can_send_message_ack(can_message_t *msg, uint8_t success){

+ 1 - 0
Applications/prot/can_message.h

@@ -53,6 +53,7 @@ static __inline__ uint32 get_reponse_can_id(u8 dest){
 
 //EXPORT FUNCTIONS
 extern void can_send_message_ack(can_message_t *msg, uint8_t success);
+extern void can_send_ack(uint8_t can_addr, uint16_t key, uint8_t data);
 extern void can_send_response(uint8_t can_add, uint8_t *data, int len);
 extern void can_send_indicator(uint8_t can_add, uint8_t *data, int len);
 extern void can_send_request(uint8_t can_add, uint8_t *data, int len);

+ 138 - 0
Applications/prot/can_pc_message.c

@@ -0,0 +1,138 @@
+#include "bsp/bsp.h"
+#include "can_pc_message.h"
+#include "bsp/fmc_flash.h"
+#include "bsp/gd32_bkp.h"
+#include "libs/logger.h"
+#include "os/co_task.h"
+
+static void can_send_backtrace(void){
+	set_log_level(MOD_SYSTEM, L_error);
+	
+	sys_error("src %x \n",gd32_get_reset_source());	
+	if (gd32_bkp_btrace_valid()){
+		uint32_t bt[16];
+		uint32_t bt_over;
+		uint32_t bt_dep;
+		uint16_t line;
+		gd32_bkp_get_backtrace(bt, &bt_over, &bt_dep, &line);
+		sys_error("system backtrace:\n");
+		sys_error("stack overflow %d, stack dep = %d, line = %d\n", bt_over, bt_dep, line);
+		for(bt_over = 0; bt_over < bt_dep; bt_over++){
+			sys_error("0x%x ", bt[bt_over]);
+		}
+		sys_error("system backtrace end!\n");
+	}else{
+		sys_error("no backtrace\n");
+	}
+
+}
+
+bool can_process_iap_message(can_message_t *can_message) {
+	uint8_t response[8];
+	uint8_t rsplen;
+	encoder_can_key(response, can_message->key);
+	response[2] = 0;
+	rsplen = 3;
+	switch(can_message->key) {
+		case BUILD_CMD_KEY(0xF0):
+			fmc_write_magic(0xFFFFFFFF);
+			iap_send_data(can_message->src, response, rsplen);
+			co_task_delay(100);
+			system_reboot();
+			break;
+		case BUILD_CMD_KEY(0xF5):
+			memcpy(response + rsplen, can_message->data, can_message->len);
+			rsplen += can_message->len;
+			break;
+		case BUILD_CMD_KEY(0xF9):
+			fmc_write_magic(IAP_MAGIC_SUCCESS);
+			break;
+		case BUILD_CMD_KEY(0xF6):
+			break;
+		case BUILD_CMD_KEY(0xF8):
+			iap_read_string(can_message->src, can_message->data);
+			rsplen = 0;
+			break;
+		default:
+			return false;
+	}
+	if (rsplen > 0) {
+		iap_send_data(can_message->src, response, rsplen);
+	}
+	return true;
+}
+extern void iap_test_download(void);
+extern void cellular_stat_log(void);
+void can_process_pc_message(can_message_t *can_message){
+	uint8_t response[8];
+	uint8_t rsplen;
+	encoder_can_key(response, can_message->key);
+	response[2] = 0;
+	rsplen = 3;
+	switch(can_message->key) {
+		case BUILD_CMD_KEY(0xD0):
+			if (can_message->len != 2){
+				response[2] = 1;
+				break;
+			}
+			set_log_level(can_message->data[0], can_message->data[1]);
+			break;
+		case 0x5030:
+			can_send_backtrace();
+			break;
+		case 0x5031:
+			set_log_level(MOD_SYSTEM, L_error);
+			sys_error("cls rst info\n");
+
+			break;
+		default:
+			rsplen = 0;
+			break;
+	}
+	if (rsplen > 0) {
+		iap_send_data(can_message->src, response, rsplen);
+	}
+}
+
+uint32_t iap_read_magic(void){
+	return fmc_read_magic();
+}
+
+
+void iap_read_string(uint8_t can, const uint8_t *args)
+{
+	#define buff_len 256
+	uint8_t buff[buff_len];
+	const char *text;
+	uint32_t addr;
+	uint32_t len;
+
+	addr = ((uint32_t) args[2]) << 16 | ((uint32_t) args[1]) << 8 | args[0];
+	text = (const char *) (0x08000000 + addr);
+
+	len = strlen(text);
+	if (len > buff_len) {
+		len = buff_len;
+	}
+
+	buff[0] = 0xF8;
+	buff[1] = CAN_MY_ADDRESS;
+	buff[2] = 0x00;
+	memcpy(buff + 3, args, 3);
+	memcpy(buff + 6, text, len);
+
+	iap_send_data(can, buff, len + 6);
+}
+
+
+void iap_send_data(uint8_t can, uint8_t *data, int len){
+	can_id_t frame_id;
+
+	frame_id.id=0;
+	frame_id.src 	= CAN_MY_ADDRESS;
+	frame_id.dest = can;
+	frame_id.type 		= ptype_response;
+	
+	shark_can0_send_message(frame_id.id, data, len);
+}
+

+ 9 - 0
Applications/prot/can_pc_message.h

@@ -0,0 +1,9 @@
+#pragma once
+#include "can_message.h"
+
+void can_process_pc_message(can_message_t *can_message);
+bool can_process_iap_message(can_message_t *can_message);
+void iap_read_string(uint8_t can, const uint8_t *args);
+void iap_send_data(uint8_t can, uint8_t *data, int len);
+uint32_t iap_read_magic(void);
+

+ 72 - 48
Project/MC100_OS.uvoptx

@@ -453,6 +453,18 @@
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>16</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Applications\foc\foc_cmd.c</PathWithFileName>
+      <FilenameWithoutPath>foc_cmd.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
 
   <Group>
@@ -463,7 +475,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>16</FileNumber>
+      <FileNumber>17</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -475,7 +487,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>17</FileNumber>
+      <FileNumber>18</FileNumber>
       <FileType>4</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -489,13 +501,13 @@
 
   <Group>
     <GroupName>Proto</GroupName>
-    <tvExp>0</tvExp>
+    <tvExp>1</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>18</FileNumber>
+      <FileNumber>19</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -507,7 +519,7 @@
     </File>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>19</FileNumber>
+      <FileNumber>20</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -517,6 +529,18 @@
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>21</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Applications\prot\can_pc_message.c</PathWithFileName>
+      <FilenameWithoutPath>can_pc_message.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
 
   <Group>
@@ -527,7 +551,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>20</FileNumber>
+      <FileNumber>22</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -539,7 +563,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>21</FileNumber>
+      <FileNumber>23</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -551,7 +575,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>22</FileNumber>
+      <FileNumber>24</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -563,7 +587,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>23</FileNumber>
+      <FileNumber>25</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -575,7 +599,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>24</FileNumber>
+      <FileNumber>26</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -587,7 +611,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>25</FileNumber>
+      <FileNumber>27</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -607,7 +631,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>26</FileNumber>
+      <FileNumber>28</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -619,7 +643,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>27</FileNumber>
+      <FileNumber>29</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -631,7 +655,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>28</FileNumber>
+      <FileNumber>30</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -643,7 +667,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>29</FileNumber>
+      <FileNumber>31</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -655,7 +679,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>30</FileNumber>
+      <FileNumber>32</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -667,7 +691,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>31</FileNumber>
+      <FileNumber>33</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -687,7 +711,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>32</FileNumber>
+      <FileNumber>34</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -699,7 +723,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>33</FileNumber>
+      <FileNumber>35</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -711,7 +735,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>34</FileNumber>
+      <FileNumber>36</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -723,7 +747,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>35</FileNumber>
+      <FileNumber>37</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -735,7 +759,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>36</FileNumber>
+      <FileNumber>38</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -747,7 +771,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>37</FileNumber>
+      <FileNumber>39</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -759,7 +783,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>38</FileNumber>
+      <FileNumber>40</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -771,7 +795,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>39</FileNumber>
+      <FileNumber>41</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -783,7 +807,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>40</FileNumber>
+      <FileNumber>42</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -795,7 +819,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>41</FileNumber>
+      <FileNumber>43</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -807,7 +831,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>42</FileNumber>
+      <FileNumber>44</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -819,7 +843,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>43</FileNumber>
+      <FileNumber>45</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -831,7 +855,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>44</FileNumber>
+      <FileNumber>46</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -851,7 +875,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>45</FileNumber>
+      <FileNumber>47</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -863,7 +887,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>46</FileNumber>
+      <FileNumber>48</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -875,7 +899,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>47</FileNumber>
+      <FileNumber>49</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -887,7 +911,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>48</FileNumber>
+      <FileNumber>50</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -899,7 +923,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>49</FileNumber>
+      <FileNumber>51</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -911,7 +935,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>50</FileNumber>
+      <FileNumber>52</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -923,7 +947,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>51</FileNumber>
+      <FileNumber>53</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -935,7 +959,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>52</FileNumber>
+      <FileNumber>54</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -947,7 +971,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>53</FileNumber>
+      <FileNumber>55</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -959,7 +983,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>54</FileNumber>
+      <FileNumber>56</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -971,7 +995,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>55</FileNumber>
+      <FileNumber>57</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -983,7 +1007,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>56</FileNumber>
+      <FileNumber>58</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -995,7 +1019,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>57</FileNumber>
+      <FileNumber>59</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1007,7 +1031,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>58</FileNumber>
+      <FileNumber>60</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1019,7 +1043,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>59</FileNumber>
+      <FileNumber>61</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1031,7 +1055,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>60</FileNumber>
+      <FileNumber>62</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1051,7 +1075,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>61</FileNumber>
+      <FileNumber>63</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1063,7 +1087,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>62</FileNumber>
+      <FileNumber>64</FileNumber>
       <FileType>2</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>

+ 10 - 0
Project/MC100_OS.uvprojx

@@ -463,6 +463,11 @@
               <FileType>1</FileType>
               <FilePath>..\Applications\foc\vbus_sensor.c</FilePath>
             </File>
+            <File>
+              <FileName>foc_cmd.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\foc\foc_cmd.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>
@@ -493,6 +498,11 @@
               <FileType>1</FileType>
               <FilePath>..\Applications\prot\wait_queue.c</FilePath>
             </File>
+            <File>
+              <FileName>can_pc_message.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\prot\can_pc_message.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>