|
|
@@ -12,8 +12,8 @@
|
|
|
|
|
|
//#define USE_DETECTED_ANGLE 1
|
|
|
|
|
|
-#define HALL_READ_TIMES 5
|
|
|
-#define SMOOTH_COUNT 50.0F
|
|
|
+#define HALL_READ_TIMES 9
|
|
|
+#define SMOOTH_COUNT 0
|
|
|
|
|
|
/*
|
|
|
1,5,4,6,2,3
|
|
|
@@ -30,11 +30,9 @@ static hall_t g_hall;
|
|
|
|
|
|
measure_time_t g_meas_hall = {.exec_max_time = 6,};
|
|
|
|
|
|
-//#define read_hall(h,t) {h = get_hall_stat(HALL_READ_TIMES); t = _hall_table[h];}
|
|
|
#define us_2_s(tick) ((float)tick / 1000000.0f) //s32q14
|
|
|
-#define HALL_TIMEOUT_US (1000000L/4)
|
|
|
-
|
|
|
|
|
|
+u32 stop_cnt = 0;
|
|
|
static u8 __INLINE hall_read_state(void) {
|
|
|
u8 hall_a = 0, hall_b = 0, hall_c = 0;
|
|
|
for (int i = 0; i < HALL_READ_TIMES; i++) {
|
|
|
@@ -70,6 +68,7 @@ static void hall_init_low_pos(void) {
|
|
|
|
|
|
static void __INLINE hall_put_sample(u32 ticks, float angle) {
|
|
|
hsample_t *s = &g_hall.samples;
|
|
|
+ g_hall.last_delta_ticks = ticks;
|
|
|
s->ticks_sum -= s->ticks[s->index];
|
|
|
s->angles_sum -= s->angles[s->index];
|
|
|
s->ticks[s->index] = ticks;
|
|
|
@@ -93,19 +92,9 @@ static float __INLINE hall_elec_angle_vel(void){
|
|
|
}
|
|
|
|
|
|
void hall_debug_log(void) {
|
|
|
- sys_debug("angle dir %d, stat %d, lowres %f, err %d,%d\n", g_hall.dir, g_hall.state, g_hall.low_res_pos, g_hall.sig_errors, g_hall.noise_errors);
|
|
|
+ sys_debug("angle dir %d, stat %d, lowres %f, err %d,%d, sp %d\n", g_hall.dir, g_hall.state, g_hall.low_res_pos, g_hall.sig_errors, g_hall.noise_errors, stop_cnt);
|
|
|
}
|
|
|
|
|
|
-static u32 hall_timeout_task(void *args) {
|
|
|
- hall_t *phall = (hall_t *)args;
|
|
|
- if (phall->velocity_raw != 0) {
|
|
|
- if (time_delta_us(phall->edge_ticks, NULL) >= HALL_TIMEOUT_US) {
|
|
|
- phall->elec_angle_vel = 0;
|
|
|
- phall->velocity_raw = phall->velocity_filted = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
|
|
|
void hall_init(void) {
|
|
|
g_hall.phase_offset = mc_conf()->m.encoder_offset;
|
|
|
@@ -126,11 +115,12 @@ void hall_init(void) {
|
|
|
if (!g_hall.inited) {
|
|
|
g_hall.inited = true;
|
|
|
gpio_hall_init();
|
|
|
- shark_task_create(hall_timeout_task, &g_hall);
|
|
|
}
|
|
|
hall_init_low_pos();
|
|
|
+ stop_cnt = 0;
|
|
|
}
|
|
|
|
|
|
+#if SMOOTH_COUNT > 0
|
|
|
static float get_angle_diff(float a1, float a2) {
|
|
|
float diff = a1 - a2;
|
|
|
float abs_diff = ABS(diff);
|
|
|
@@ -140,6 +130,7 @@ static float get_angle_diff(float a1, float a2) {
|
|
|
return diff;
|
|
|
}
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
static bool hall_update_low_pos(void) {
|
|
|
u8 state = hall_read_state();
|
|
|
@@ -148,20 +139,24 @@ static bool hall_update_low_pos(void) {
|
|
|
g_hall.sig_errors ++;
|
|
|
return false;
|
|
|
}
|
|
|
+ s16 pos_prev = hall_2_pos[g_hall.state];
|
|
|
g_hall.state = state;
|
|
|
- s16 delta_pos = pos - g_hall.low_res_pos;
|
|
|
+ s16 delta_pos = pos - pos_prev;
|
|
|
g_hall.low_res_pos = pos;
|
|
|
if (delta_pos != 0) {
|
|
|
s8 prev_dir = g_hall.dir;
|
|
|
- if (g_hall.samples.full || g_hall.samples.index != 0) {
|
|
|
- if (delta_pos == 1 || delta_pos == -5) {
|
|
|
- g_hall.dir = POSITIVE;
|
|
|
- }else{
|
|
|
- g_hall.dir = NEGATIVE;
|
|
|
- }
|
|
|
+ if (delta_pos == 1 || delta_pos == -5) {
|
|
|
+ g_hall.dir = POSITIVE;
|
|
|
+ g_hall.prev_dir = prev_dir;
|
|
|
+ }else if (delta_pos == -1 || delta_pos == 5){
|
|
|
+ g_hall.dir = NEGATIVE;
|
|
|
+ g_hall.prev_dir = prev_dir;
|
|
|
+ }else {
|
|
|
+ //keep prev dir value
|
|
|
}
|
|
|
g_hall.edge_ticks = task_ticks_abs();
|
|
|
- g_hall.prev_dir = prev_dir;
|
|
|
+ }else {
|
|
|
+ g_hall.sig_errors ++;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
@@ -187,8 +182,9 @@ float hall_update_elec_angle(void) {
|
|
|
}
|
|
|
float high_res_pos = delta_pos + low_res;
|
|
|
float elec_angle = high_res_pos * PHASE_60_DEGREE;
|
|
|
- float delta_angle = delta_pos * PHASE_60_DEGREE;
|
|
|
float elec_smooth_angle;
|
|
|
+#if SMOOTH_COUNT>0
|
|
|
+ float delta_angle = delta_pos * PHASE_60_DEGREE;
|
|
|
if (g_hall.angle_smooth_cnt < (SMOOTH_COUNT + 1)) {
|
|
|
elec_smooth_angle = g_hall.elec_angle_edge + g_hall.angle_smooth_step * g_hall.angle_smooth_cnt + delta_angle;
|
|
|
g_hall.angle_smooth_cnt++;
|
|
|
@@ -200,9 +196,22 @@ float hall_update_elec_angle(void) {
|
|
|
}else {
|
|
|
elec_smooth_angle = elec_angle;
|
|
|
}
|
|
|
+#else
|
|
|
+ elec_smooth_angle = elec_angle;
|
|
|
+#endif
|
|
|
norm_angle_deg(elec_smooth_angle);
|
|
|
g_hall.elec_angle = elec_smooth_angle;
|
|
|
g_hall.position += g_hall.elec_angle_vel * FOC_CTRL_US / g_hall.mot_poles;
|
|
|
+ if (g_hall.samples.full && (delta_ticks / g_hall.last_delta_ticks >= 1.3f)) {
|
|
|
+ stop_cnt ++;
|
|
|
+ g_hall.elec_angle_vel = g_hall.elec_angle_vel * 0.99f;
|
|
|
+ if (g_hall.elec_angle_vel < 10) {
|
|
|
+ g_hall.elec_angle_vel = 0;
|
|
|
+ }
|
|
|
+ float velocity_raw = g_hall.elec_angle_vel/PHASE_360_DEGREE/g_hall.mot_poles * 60.0f * g_hall.dir;
|
|
|
+ g_hall.velocity_raw = velocity_raw;
|
|
|
+ LowPass_Filter(g_hall.velocity_filted, velocity_raw, 1.0f);
|
|
|
+ }
|
|
|
return hall_get_elec_angle();
|
|
|
}
|
|
|
|
|
|
@@ -246,17 +255,18 @@ float hall_offset_detect(float *off) {
|
|
|
}
|
|
|
|
|
|
void HALL_IRQHandler(void) {
|
|
|
+ u32 mask = cpu_enter_critical();
|
|
|
u32 prev_ticks = g_hall.edge_ticks;
|
|
|
if (!hall_update_low_pos()) {
|
|
|
- return;
|
|
|
+ goto hall_end;
|
|
|
}
|
|
|
if (time_delta_us(prev_ticks, NULL) == 0) {
|
|
|
g_hall.noise_errors++;
|
|
|
- return;
|
|
|
+ goto hall_end;
|
|
|
}
|
|
|
g_hall.elec_angle_edge = g_hall.elec_angle;
|
|
|
- float low_res = g_hall.low_res_pos;
|
|
|
- g_hall.delta_angle_edge = get_angle_diff(low_res * PHASE_60_DEGREE, g_hall.elec_angle_edge);
|
|
|
+#if SMOOTH_COUNT>0
|
|
|
+ g_hall.delta_angle_edge = get_angle_diff(g_hall.low_res_pos * PHASE_60_DEGREE, g_hall.elec_angle_edge);
|
|
|
if (ABS(g_hall.delta_angle_edge) >= 2.0f) {
|
|
|
g_hall.angle_smooth_step = 0;//g_hall.delta_angle_edge/SMOOTH_COUNT;
|
|
|
g_hall.angle_smooth_cnt = SMOOTH_COUNT + 1;
|
|
|
@@ -264,7 +274,11 @@ void HALL_IRQHandler(void) {
|
|
|
g_hall.angle_smooth_step = 0;
|
|
|
g_hall.angle_smooth_cnt = SMOOTH_COUNT + 1;
|
|
|
}
|
|
|
+#endif
|
|
|
hall_calc_mot_velocity(prev_ticks);
|
|
|
+hall_end:
|
|
|
+ cpu_exit_critical(mask);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
|