refactor(vd960Loop): 算法回退到 DLD154V4B,四通道适配
- 用 DLD154V4B vd1_task/per_channel 替换 vds_task 复杂算法
- 移除 FUNCTION_B/二次判断/快速变化/多重确认等增强特性
- 保留平坦性离开算法 (CN200910309382),每通道独立状态
- 灵敏度表改为 DLD154V4B 4级: {216,108,36,10} / {108,72,18,9}
- 清理废弃类型: FltHistoryManager, Loop_ACS_Info, StageRangeConfig 等
- 首次添加 vd960DBN 完整源码
This commit is contained in:
710
vd960Loop/utilities/at32f421_freertos_demo/src/TaskLoop.c
Normal file
710
vd960Loop/utilities/at32f421_freertos_demo/src/TaskLoop.c
Normal file
@@ -0,0 +1,710 @@
|
||||
|
||||
#include "TaskLoop.h"
|
||||
#include "at32f421_board.h"
|
||||
#include "cmcng.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*===========================================================================
|
||||
* 灵敏度表 — 对齐 DLD154V4B / M1H
|
||||
* 进入阈值 = Origin × SensTable[SENS] / 65536
|
||||
* 离开阈值 = Origin × SensTable_1[SENS] / 65536 (滞回 ~50%)
|
||||
* SENS: 0=低灵敏, 3=高灵敏
|
||||
*===========================================================================*/
|
||||
const uint16_t SensTable[4] = {216, 108, 36, 10};
|
||||
const uint16_t SensTable_1[4] = {108, 72, 18, 9};
|
||||
|
||||
/*===========================================================================
|
||||
* 全局状态
|
||||
*===========================================================================*/
|
||||
Loop154_States g_loop_states = {{0}, {{{0}}}};
|
||||
uint32_t g_sys_freq = 0;
|
||||
uint8_t g_input_div = 1;
|
||||
uint32_t g_safe_max_cnt = LC_HOLD_TIME;
|
||||
|
||||
/*===========================================================================
|
||||
* 调试
|
||||
*===========================================================================*/
|
||||
uint8_t g_flag_output = 0;
|
||||
uint8_t g_flag_output2 = 0;
|
||||
|
||||
/*===========================================================================
|
||||
* 一阶 IIR 低通滤波器(对齐 DLD154V4B)
|
||||
* CAPVD_new = α·new_value + (1-α)·CAPVD_old, α = Flt_Reg/256
|
||||
*===========================================================================*/
|
||||
uint32_t get_flt_value(uint32_t new_value, uint32_t last_Value)
|
||||
{
|
||||
uint32_t value_Flt;
|
||||
uint32_t delta = (new_value > last_Value)
|
||||
? (new_value - last_Value)
|
||||
: (last_Value - new_value);
|
||||
uint32_t scaled_delta = (delta * (uint32_t)Flt_Reg) >> 8;
|
||||
|
||||
if (new_value > last_Value) {
|
||||
value_Flt = last_Value + scaled_delta;
|
||||
} else {
|
||||
value_Flt = last_Value - scaled_delta;
|
||||
}
|
||||
return value_Flt;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* 滑动平均基线更新
|
||||
*===========================================================================*/
|
||||
uint8_t update_moving_average(uint32_t* p_sum, uint16_t* p_cnt,
|
||||
uint32_t* p_origin, uint32_t new_value,
|
||||
uint8_t window)
|
||||
{
|
||||
if (!p_sum || !p_cnt || !p_origin || window == 0) return 0;
|
||||
|
||||
*p_sum += new_value;
|
||||
(*p_cnt)++;
|
||||
|
||||
if (*p_cnt >= window) {
|
||||
*p_origin = *p_sum / window;
|
||||
*p_cnt = 0;
|
||||
*p_sum = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* 继电器控制
|
||||
*===========================================================================*/
|
||||
void set_loops_relay_on(uint8_t loop_num)
|
||||
{
|
||||
switch(loop_num) {
|
||||
case 0: RLY1_ON; break;
|
||||
case 1: RLY2_ON; break;
|
||||
case 2: RLY3_ON; break;
|
||||
case 3: RLY4_ON; break;
|
||||
}
|
||||
}
|
||||
|
||||
void set_loops_relay_off(uint8_t loop_num)
|
||||
{
|
||||
switch(loop_num) {
|
||||
case 0: RLY1_OFF; break;
|
||||
case 1: RLY2_OFF; break;
|
||||
case 2: RLY3_OFF; break;
|
||||
case 3: RLY4_OFF; break;
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* 单通道初始化
|
||||
*===========================================================================*/
|
||||
void init_vd_single(Loop154_Unit *unit)
|
||||
{
|
||||
unit->loop_INCNT = 0;
|
||||
unit->loop_OUTCNT = 0;
|
||||
unit->loop_CapCnt = 0;
|
||||
unit->loop_CapLast = 0;
|
||||
unit->loop_LPCNT = 0;
|
||||
unit->loop_INI_LOOP = 1;
|
||||
|
||||
unit->loop_VD_FLAG = 0;
|
||||
unit->loop_RF_FLAG = 0;
|
||||
unit->loop_LOOP_OK = 1;
|
||||
unit->loop_LOOP_OK0 = 0;
|
||||
unit->loop_CAP_OK = 0;
|
||||
unit->loop_CAPVD = 0;
|
||||
|
||||
unit->loop_SensLevel = 2; // 默认中灵敏度
|
||||
unit->Flt_Reg = ALFA_CAP1;
|
||||
|
||||
unit->loop_ORG_CNT = 0;
|
||||
unit->loop_ORG_SUM = 0;
|
||||
|
||||
unit->loop_FLAG_IN = 0;
|
||||
unit->loop_FLAG_OUT = 0;
|
||||
unit->loop_FLAG_PLUSE = 0;
|
||||
unit->loop_cnt_release = 0;
|
||||
unit->loop_stable = 0;
|
||||
|
||||
#if USE_FLATNESS_EXIT
|
||||
unit->exit_state = 0;
|
||||
unit->max_slope = 0;
|
||||
unit->max_slope_rate = 0;
|
||||
unit->delta2 = 0;
|
||||
unit->delta3 = 0;
|
||||
unit->prev_capvd = 0;
|
||||
unit->prev_first_deriv = 0;
|
||||
unit->slope_flat_cnt = 0;
|
||||
unit->flat_ok_cnt = 0;
|
||||
#endif
|
||||
|
||||
unit->LC_HOLD = 0;
|
||||
unit->LC_Reset = 0;
|
||||
unit->LC_Hold_CNT = 0;
|
||||
unit->Hold_CNT = 0;
|
||||
|
||||
unit->power_up_state = 0;
|
||||
unit->disconnect_count = 0;
|
||||
unit->disconnect_active = 0;
|
||||
unit->fault_phase = 0;
|
||||
unit->fault_tick = 0;
|
||||
|
||||
unit->SET_PLUS = 1; // 存在输出
|
||||
unit->SET_DLY = 0;
|
||||
unit->SET_SAFE = 1;
|
||||
|
||||
unit->stable_cnt = 0;
|
||||
unit->xn_counter = 0;
|
||||
}
|
||||
|
||||
void INIT_VDs(Loop154_States *loops)
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < LOOP_CAPTURE_MAX; i++) {
|
||||
loops->loop_unit[i].loop_num = i;
|
||||
init_vd_single(&loops->loop_unit[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* TMR3 输入捕获中断 — 四路线圈频率测量(对齐 DLD154V4B CAP0 ISR)
|
||||
*
|
||||
* 每个通道独立捕获,使用 MEASUREMENT_BASE 自适应测量窗口。
|
||||
* LPCNT = MEASUREMENT_BASE / Xn,使 Value ≈ 131072,无需后续 >> 移位。
|
||||
*===========================================================================*/
|
||||
void TMR3_GLOBAL_IRQHandler(void)
|
||||
{
|
||||
#define PROCESS_CHANNEL(ch_flag, ch_select, idx) \
|
||||
if (tmr_interrupt_flag_get(TMR3, ch_flag) != RESET) { \
|
||||
tmr_flag_clear(TMR3, ch_flag); \
|
||||
uint16_t cap_this = tmr_channel_value_get(TMR3, ch_select); \
|
||||
Loop154_Unit *unit = &g_loop_states.loop_unit[idx]; \
|
||||
if (!unit->loop_RF_FLAG) { \
|
||||
unit->loop_CapLast = cap_this; \
|
||||
unit->loop_RF_FLAG = 1; \
|
||||
} else { \
|
||||
uint16_t xn; \
|
||||
if (cap_this > unit->loop_CapLast) { \
|
||||
xn = cap_this - unit->loop_CapLast; \
|
||||
} else { \
|
||||
xn = (0x10000 - unit->loop_CapLast) + cap_this; \
|
||||
} \
|
||||
unit->loop_Xn = xn; \
|
||||
unit->xn_counter++; \
|
||||
unit->loop_CapLast = cap_this; \
|
||||
unit->loop_CapCnt++; \
|
||||
if (unit->loop_INI_LOOP) { \
|
||||
if (unit->loop_LPCNT == 0) { \
|
||||
if (unit->loop_CapCnt > 10) { \
|
||||
unit->loop_LPCNT = MEASUREMENT_BASE / xn; \
|
||||
PRINT("Loop%d LPCNT:%d Xn:%d\n", idx+1, unit->loop_LPCNT, xn); \
|
||||
if (unit->loop_LPCNT == 0) unit->loop_LPCNT = 100; \
|
||||
unit->loop_CAPVD = 0; \
|
||||
unit->loop_CapSum = 0; \
|
||||
unit->loop_CapCnt = 0; \
|
||||
} \
|
||||
} else { \
|
||||
unit->loop_CapSum += xn; \
|
||||
if (unit->loop_CapCnt >= unit->loop_LPCNT) { \
|
||||
unit->loop_CAPVD = unit->loop_CapSum; \
|
||||
unit->loop_Origin = unit->loop_CAPVD; \
|
||||
PRINT("Loop%d Origin:%d\n", idx+1, unit->loop_Origin); \
|
||||
unit->loop_INI_LOOP = 0; \
|
||||
unit->loop_CapSum = 0; \
|
||||
unit->loop_Value = 0; \
|
||||
unit->loop_CapCnt = 0; \
|
||||
} \
|
||||
} \
|
||||
} else { \
|
||||
unit->loop_CapSum += xn; \
|
||||
if (unit->loop_CapCnt >= unit->loop_LPCNT) { \
|
||||
unit->loop_Value = unit->loop_CapSum; \
|
||||
unit->loop_CAP_OK = 1; \
|
||||
unit->loop_CapSum = 0; \
|
||||
unit->loop_CapCnt = 0; \
|
||||
unit->loop_INI_LOOP = 0; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
PROCESS_CHANNEL(TMR_C1_FLAG, TMR_SELECT_CHANNEL_1, 0)
|
||||
PROCESS_CHANNEL(TMR_C2_FLAG, TMR_SELECT_CHANNEL_2, 1)
|
||||
PROCESS_CHANNEL(TMR_C3_FLAG, TMR_SELECT_CHANNEL_3, 2)
|
||||
PROCESS_CHANNEL(TMR_C4_FLAG, TMR_SELECT_CHANNEL_4, 3)
|
||||
|
||||
#undef PROCESS_CHANNEL
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* TMR15 定时器中断 — 5ms tick,主状态机(对齐 DLD154V4B Timer1 ISR)
|
||||
*
|
||||
* 职责:
|
||||
* 1. 50ms tick 分频
|
||||
* 2. 四通道 进入/离开/脉冲 时序状态机
|
||||
* 3. 有限存在超时 / 安全复位超时
|
||||
* 4. 线圈载波检测 (RF_FLAG) 及继电器输出刷新
|
||||
* 5. 呼吸灯、指示灯驱动
|
||||
*===========================================================================*/
|
||||
void TMR15_GLOBAL_IRQHandler(void)
|
||||
{
|
||||
static uint16_t _counter1_init = 0;
|
||||
static uint8_t TM1cnt = 0;
|
||||
uint8_t i;
|
||||
|
||||
if (tmr_interrupt_flag_get(TMR15, TMR_OVF_FLAG) != RESET) {
|
||||
|
||||
/*--- 上报计数器 ---*/
|
||||
g_loop_states.report_counter++;
|
||||
|
||||
/*--- 50ms tick 分频 ---*/
|
||||
TM1cnt++;
|
||||
if (TM1cnt >= 10) {
|
||||
TM1cnt = 0;
|
||||
|
||||
for (i = 0; i < LOOP_CAPTURE_MAX; i++) {
|
||||
Loop154_Unit *unit = &g_loop_states.loop_unit[i];
|
||||
|
||||
/* FLAG_IN: 进入延时 500ms */
|
||||
if (unit->loop_FLAG_IN) {
|
||||
unit->INCNT++;
|
||||
if (unit->INCNT > IN_DELAY) {
|
||||
unit->loop_FLAG_IN = 0;
|
||||
unit->INCNT = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* FLAG_OUT: 离开延时 → 脉冲 */
|
||||
if (unit->loop_FLAG_OUT) {
|
||||
if (!unit->SET_DLY) {
|
||||
unit->OUTCNT++;
|
||||
if (unit->OUTCNT > OUT_DELAY) {
|
||||
unit->loop_FLAG_OUT = 0;
|
||||
unit->loop_FLAG_PLUSE = 1;
|
||||
unit->OUTCNT = 0;
|
||||
}
|
||||
} else {
|
||||
unit->loop_FLAG_OUT = 0;
|
||||
unit->loop_FLAG_PLUSE = 1;
|
||||
unit->OUTCNT = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* FLAG_PLUSE: 脉冲宽度 500ms */
|
||||
if (unit->loop_FLAG_PLUSE) {
|
||||
unit->OUTCNT++;
|
||||
if (unit->OUTCNT > PULSE_DELAY) {
|
||||
unit->loop_FLAG_PLUSE = 0;
|
||||
unit->OUTCNT = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 有限存在超时 */
|
||||
if (unit->loop_VD_HOLD) {
|
||||
unit->Hold_CNT++;
|
||||
if (unit->Hold_CNT > HOLD_TIME) {
|
||||
unit->loop_VD_HOLD = 0;
|
||||
unit->Hold_CNT = 0;
|
||||
if (unit->loop_VD_FLAG) {
|
||||
set_loops_relay_off(unit->loop_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 安全复位超时 */
|
||||
if (unit->LC_HOLD) {
|
||||
unit->LC_Hold_CNT++;
|
||||
if (unit->LC_Hold_CNT > g_safe_max_cnt) {
|
||||
unit->LC_Reset = 1;
|
||||
unit->loop_INI_LOOP = 1;
|
||||
unit->loop_LOOP_OK0 = 0;
|
||||
unit->loop_stable = 0;
|
||||
#if USE_FLATNESS_EXIT
|
||||
unit->exit_state = 0;
|
||||
unit->max_slope = 0;
|
||||
unit->max_slope_rate = 0;
|
||||
#endif
|
||||
unit->LC_Hold_CNT = 0;
|
||||
unit->loop_ORG_CNT = 0;
|
||||
unit->loop_ORG_SUM = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*================================================================
|
||||
* 线圈载波检测 & 继电器输出刷新(每 5ms)
|
||||
*================================================================*/
|
||||
for (i = 0; i < LOOP_CAPTURE_MAX; i++) {
|
||||
Loop154_Unit *unit = &g_loop_states.loop_unit[i];
|
||||
|
||||
if (unit->loop_RF_FLAG) {
|
||||
unit->loop_LOOP_OK = 1;
|
||||
unit->loop_RF_FLAG = 0;
|
||||
|
||||
if (unit->LC_Reset == 0) {
|
||||
if (unit->SET_PLUS) {
|
||||
/* 存在输出模式:有车或离开延时中 */
|
||||
if (unit->loop_VD_FLAG || unit->loop_FLAG_OUT)
|
||||
set_loops_relay_on(unit->loop_num);
|
||||
else
|
||||
set_loops_relay_off(unit->loop_num);
|
||||
} else {
|
||||
/* 脉冲输出模式:脉冲期间吸合 */
|
||||
if (unit->loop_FLAG_PLUSE)
|
||||
set_loops_relay_on(unit->loop_num);
|
||||
else
|
||||
set_loops_relay_off(unit->loop_num);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unit->loop_LOOP_OK0 = unit->loop_LOOP_OK;
|
||||
unit->loop_LOOP_OK = 0;
|
||||
}
|
||||
|
||||
/*--- LED 指示 ---*/
|
||||
poll_green_led(unit);
|
||||
}
|
||||
|
||||
/*--- 呼吸灯 ---*/
|
||||
poll_red_pwm();
|
||||
|
||||
tmr_flag_clear(TMR15, TMR_OVF_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* 绿灯指示 — 每通道独立
|
||||
*
|
||||
* 模式:
|
||||
* 自检/稳定中 (loop_INI_LOOP || 未连 || !loop_stable):
|
||||
* → 慢闪 (200ms 亮/灭)
|
||||
* 正常工作:
|
||||
* → 有车亮, 无车灭
|
||||
*===========================================================================*/
|
||||
void poll_green_led(Loop154_Unit *unit)
|
||||
{
|
||||
#define GREEN_SLOW_HALF 40 // 200ms (40 × 5ms)
|
||||
|
||||
static uint16_t _slow_tick[LOOP_CAPTURE_MAX] = {0};
|
||||
uint8_t idx = unit->loop_num;
|
||||
|
||||
if (unit->disconnect_active) {
|
||||
at32_led_off(idx);
|
||||
_slow_tick[idx] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (unit->loop_INI_LOOP || !unit->power_up_state || !unit->loop_stable) {
|
||||
_slow_tick[idx]++;
|
||||
if (_slow_tick[idx] >= GREEN_SLOW_HALF) {
|
||||
_slow_tick[idx] = 0;
|
||||
at32_led_toggle(idx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_slow_tick[idx] = 0;
|
||||
if (unit->loop_VD_FLAG)
|
||||
at32_led_on(idx);
|
||||
else
|
||||
at32_led_off(idx);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* vd1_task_per_channel — 核心检测算法(移植自 DLD154V4B vd1_task)
|
||||
*
|
||||
* 每次 loop_CAP_OK 时调用。
|
||||
* 流程:
|
||||
* 1. IIR 滤波:CAPVD = α·Value + (1-α)·CAPVD
|
||||
* 2. 稳定期:只跟踪基线,不检测车辆 (STABLE_SAMPLES=128)
|
||||
* 3. 无车时:基线跟踪 + 进入检测(带基线污染保护)
|
||||
* 4. 有车时:平坦性离开 (USE_FLATNESS_EXIT=1) 或 cnt_release 防抖
|
||||
*===========================================================================*/
|
||||
void vd1_task_per_channel(Loop154_Unit *unit)
|
||||
{
|
||||
if (unit->loop_Origin == 0) return;
|
||||
|
||||
/*--- 1. IIR 一阶低通滤波 ---*/
|
||||
if (unit->loop_CAPVD == 0) {
|
||||
unit->loop_CAPVD = unit->loop_Value;
|
||||
} else {
|
||||
uint8_t saved_flt_reg = Flt_Reg;
|
||||
Flt_Reg = unit->Flt_Reg;
|
||||
unit->loop_CAPVD = get_flt_value(unit->loop_Value, unit->loop_CAPVD);
|
||||
Flt_Reg = saved_flt_reg;
|
||||
}
|
||||
|
||||
/*--- 2. 稳定期:只跟踪基线,不检测车辆 ---*/
|
||||
if (!unit->loop_stable) {
|
||||
update_moving_average(&unit->loop_ORG_SUM, &unit->loop_ORG_CNT,
|
||||
&unit->loop_Origin, unit->loop_CAPVD, WINDOW_ORIGIN);
|
||||
unit->stable_cnt++;
|
||||
if (unit->stable_cnt >= STABLE_SAMPLES) {
|
||||
unit->loop_stable = 1;
|
||||
PRINT("Loop%d stable, Origin:%d\n", unit->loop_num + 1, unit->loop_Origin);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!unit->loop_VD_FLAG) {
|
||||
/*================================================================
|
||||
* 无车状态
|
||||
*================================================================*/
|
||||
|
||||
/* 基线跟踪(有车时冻结)
|
||||
* 保护: CAPVD 异常上升时暂停跟踪,防止基线被污染 */
|
||||
unit->loop_dlt_ORG = ((uint32_t)unit->loop_Origin * SensTable[unit->loop_SensLevel]) >> 16;
|
||||
{
|
||||
int32_t dev = (int32_t)unit->loop_CAPVD - (int32_t)unit->loop_Origin;
|
||||
if (dev < (int32_t)(unit->loop_dlt_ORG * 4)) {
|
||||
update_moving_average(&unit->loop_ORG_SUM, &unit->loop_ORG_CNT,
|
||||
&unit->loop_Origin, unit->loop_CAPVD, WINDOW_ORIGIN);
|
||||
} else {
|
||||
unit->loop_ORG_CNT = 0;
|
||||
unit->loop_ORG_SUM = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 进入检测 */
|
||||
if (unit->loop_CAPVD < (unit->loop_Origin - unit->loop_dlt_ORG)) {
|
||||
PRINT("Loop%d Car_In, Value:%d CAPVD:%d Origin:%d dlt:%d\n",
|
||||
unit->loop_num + 1, unit->loop_Value, unit->loop_CAPVD,
|
||||
unit->loop_Origin, unit->loop_dlt_ORG);
|
||||
|
||||
unit->loop_VD_FLAG = 1;
|
||||
unit->loop_FLAG_IN = 1;
|
||||
at32_led_on(unit->loop_num);
|
||||
|
||||
if (!unit->SET_SAFE) {
|
||||
unit->LC_HOLD = 1;
|
||||
} else {
|
||||
unit->LC_HOLD = 0;
|
||||
}
|
||||
if (unit->LC_Reset)
|
||||
unit->LC_Reset = 0;
|
||||
|
||||
unit->loop_ORG_CNT = 0;
|
||||
unit->loop_ORG_SUM = 0;
|
||||
|
||||
#if USE_FLATNESS_EXIT
|
||||
unit->exit_state = 0;
|
||||
unit->max_slope = 0;
|
||||
unit->max_slope_rate = 0;
|
||||
unit->delta2 = 0;
|
||||
unit->delta3 = 0;
|
||||
unit->slope_flat_cnt = 0;
|
||||
unit->flat_ok_cnt = 0;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#if USE_FLATNESS_EXIT
|
||||
/*================================================================
|
||||
* 有车状态 — 平坦性判定离开 (CN200910309382)
|
||||
*================================================================*/
|
||||
int32_t first_deriv, abs_fd, abs_sd, second_deriv;
|
||||
|
||||
first_deriv = (int32_t)unit->loop_CAPVD - unit->prev_capvd;
|
||||
second_deriv = first_deriv - unit->prev_first_deriv;
|
||||
abs_fd = (first_deriv >= 0) ? first_deriv : -first_deriv;
|
||||
abs_sd = (second_deriv >= 0) ? second_deriv : -second_deriv;
|
||||
|
||||
if (unit->exit_state == 0) {
|
||||
/* 追踪第一上升坡面最大斜率 */
|
||||
if (abs_fd > unit->max_slope) unit->max_slope = abs_fd;
|
||||
if (abs_sd > unit->max_slope_rate) unit->max_slope_rate = abs_sd;
|
||||
if (abs_fd < SLOPE_FLAT_THRESH) {
|
||||
unit->slope_flat_cnt++;
|
||||
if (unit->slope_flat_cnt >= 3) {
|
||||
unit->delta2 = unit->max_slope / K1;
|
||||
unit->delta3 = unit->max_slope_rate / K2;
|
||||
if (unit->delta2 < MIN_DELTA2) unit->delta2 = MIN_DELTA2;
|
||||
if (unit->delta3 < MIN_DELTA3) unit->delta3 = MIN_DELTA3;
|
||||
unit->exit_state = 1;
|
||||
unit->flat_ok_cnt = 0;
|
||||
}
|
||||
} else {
|
||||
unit->slope_flat_cnt = 0;
|
||||
}
|
||||
} else {
|
||||
int32_t dev = (int32_t)unit->loop_CAPVD - (int32_t)unit->loop_Origin;
|
||||
int32_t cond1 = (dev >= 0) ? dev : -dev;
|
||||
unit->loop_dlt_ORG = ((uint32_t)unit->loop_Origin * SensTable_1[unit->loop_SensLevel]) >> 16;
|
||||
if (cond1 < (int32_t)unit->loop_dlt_ORG && abs_fd < (int32_t)unit->delta2
|
||||
&& abs_sd < (int32_t)unit->delta3) {
|
||||
unit->flat_ok_cnt++;
|
||||
if (unit->flat_ok_cnt >= FLAT_CONFIRM_CNT) {
|
||||
PRINT("Loop%d Car_OFF_FLAT, CAPVD:%d Origin:%d d1:%d d2:%d d3:%d f':%d f'':%d\n",
|
||||
unit->loop_num + 1, unit->loop_CAPVD, unit->loop_Origin,
|
||||
unit->loop_dlt_ORG, unit->delta2, unit->delta3,
|
||||
first_deriv, second_deriv);
|
||||
unit->loop_VD_FLAG = 0;
|
||||
unit->loop_FLAG_OUT = 1;
|
||||
unit->loop_VD_HOLD = 0;
|
||||
unit->LC_HOLD = 0;
|
||||
unit->loop_ORG_CNT = 0;
|
||||
unit->loop_ORG_SUM = 0;
|
||||
unit->Hold_CNT = 0;
|
||||
unit->flat_ok_cnt = 0;
|
||||
unit->exit_state = 0;
|
||||
}
|
||||
} else {
|
||||
unit->flat_ok_cnt = 0;
|
||||
}
|
||||
}
|
||||
unit->prev_capvd = unit->loop_CAPVD;
|
||||
unit->prev_first_deriv = first_deriv;
|
||||
#else
|
||||
/*================================================================
|
||||
* 有车状态 — cnt_release 防抖离开
|
||||
*================================================================*/
|
||||
unit->loop_dlt_ORG = ((uint32_t)unit->loop_Origin * SensTable_1[unit->loop_SensLevel]) >> 16;
|
||||
|
||||
if ((unit->loop_Origin - unit->loop_dlt_ORG) < unit->loop_CAPVD) {
|
||||
unit->loop_cnt_release++;
|
||||
if (unit->loop_cnt_release >= 3) {
|
||||
PRINT("Loop%d Car_OFF, Value:%d CAPVD:%d Origin:%d dlt:%d\n",
|
||||
unit->loop_num + 1, unit->loop_Value, unit->loop_CAPVD,
|
||||
unit->loop_Origin, unit->loop_dlt_ORG);
|
||||
unit->loop_VD_FLAG = 0;
|
||||
unit->loop_FLAG_OUT = 1;
|
||||
unit->loop_VD_HOLD = 0;
|
||||
unit->LC_HOLD = 0;
|
||||
unit->loop_ORG_CNT = 0;
|
||||
unit->loop_ORG_SUM = 0;
|
||||
unit->Hold_CNT = 0;
|
||||
unit->loop_cnt_release = 0;
|
||||
}
|
||||
} else {
|
||||
if (unit->loop_cnt_release > 0) unit->loop_cnt_release = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* loop_task_function — FreeRTOS 主任务(对齐 DLD154V4B main 循环)
|
||||
* 10ms 周期,独立处理每路线圈。
|
||||
*===========================================================================*/
|
||||
void loop_task_function(void *pvParameters)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
g_sys_freq = g_crm_clocks_freq_struct.sclk_freq;
|
||||
INIT_VDs(&g_loop_states);
|
||||
|
||||
while (1) {
|
||||
for (i = 0; i < LOOP_CAPTURE_MAX; i++) {
|
||||
Loop154_Unit *unit = &g_loop_states.loop_unit[i];
|
||||
|
||||
if (unit->loop_LOOP_OK) {
|
||||
/* 线圈重连 */
|
||||
if (!unit->loop_LOOP_OK0) {
|
||||
unit->loop_LOOP_OK0 = 1;
|
||||
unit->disconnect_active = 0;
|
||||
unit->loop_CAPVD = 0; // 强制 IIR 重新收敛
|
||||
}
|
||||
|
||||
if (unit->loop_CAP_OK) {
|
||||
taskENTER_CRITICAL();
|
||||
unit->loop_CAP_OK = 0;
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
if (!unit->power_up_state) {
|
||||
unit->power_up_state = 1;
|
||||
}
|
||||
|
||||
/* 核心检测算法 */
|
||||
vd1_task_per_channel(unit);
|
||||
}
|
||||
} else {
|
||||
/* 线圈断开 */
|
||||
set_loops_relay_off(unit->loop_num);
|
||||
|
||||
if (unit->power_up_state && !unit->disconnect_active) {
|
||||
unit->disconnect_active = 1;
|
||||
if (unit->disconnect_count < 3) {
|
||||
unit->disconnect_count++;
|
||||
}
|
||||
unit->fault_phase = 0;
|
||||
unit->fault_tick = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wdt_feed();
|
||||
vTaskDelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* LED 指示灯后台任务 — 线圈未连接时的闪烁指示
|
||||
*===========================================================================*/
|
||||
void led_indicator_task_function(void *pvParameters)
|
||||
{
|
||||
uint8_t i;
|
||||
static uint8_t led_step[LOOP_CAPTURE_MAX] = {0};
|
||||
|
||||
while (1) {
|
||||
for (i = 0; i < LOOP_CAPTURE_MAX; i++) {
|
||||
Loop154_Unit *unit = &g_loop_states.loop_unit[i];
|
||||
|
||||
if (unit->loop_LOOP_OK0 == 0) {
|
||||
if (led_step[i] % 2 == 0) {
|
||||
at32_led_toggle(i);
|
||||
}
|
||||
if (unit->loop_stable) {
|
||||
unit->loop_LOOP_OK0 = 1;
|
||||
continue;
|
||||
}
|
||||
led_step[i]++;
|
||||
if (led_step[i] > 16) {
|
||||
led_step[i] = 0;
|
||||
unit->loop_LOOP_OK0 = 1;
|
||||
at32_led_off(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
vTaskDelay(200);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* USART1 接收缓冲区 & 任务
|
||||
*===========================================================================*/
|
||||
char usart1_rx_buffer[USART1_RX_BUFFER_SIZE];
|
||||
volatile uint16_t usart1_rx_head = 0;
|
||||
volatile uint16_t usart1_rx_tail = 0;
|
||||
TaskHandle_t usart_task_handler = NULL;
|
||||
|
||||
void usart_task_function(void *pvParameters)
|
||||
{
|
||||
while (1) {
|
||||
if (g_pkg_uart_1.flag) {
|
||||
manage_dbn_ble_default(g_pkg_uart_1.pkg, g_pkg_uart_1.offset);
|
||||
InitPkgUart(&g_pkg_uart_1);
|
||||
}
|
||||
uart_report_packet_loop_acs(0);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (g_flag_output) {
|
||||
g_flag_output = 0;
|
||||
PRINT("xnC:%d,%d,%d,%d LPCNT:%d,%d,%d,%d CAPVD:%d,%d,%d,%d Origin:%d,%d,%d,%d VD:%d,%d,%d,%d\n",
|
||||
g_loop_states.loop_unit[0].xn_counter, g_loop_states.loop_unit[1].xn_counter,
|
||||
g_loop_states.loop_unit[2].xn_counter, g_loop_states.loop_unit[3].xn_counter,
|
||||
g_loop_states.loop_unit[0].loop_LPCNT, g_loop_states.loop_unit[1].loop_LPCNT,
|
||||
g_loop_states.loop_unit[2].loop_LPCNT, g_loop_states.loop_unit[3].loop_LPCNT,
|
||||
g_loop_states.loop_unit[0].loop_CAPVD, g_loop_states.loop_unit[1].loop_CAPVD,
|
||||
g_loop_states.loop_unit[2].loop_CAPVD, g_loop_states.loop_unit[3].loop_CAPVD,
|
||||
g_loop_states.loop_unit[0].loop_Origin, g_loop_states.loop_unit[1].loop_Origin,
|
||||
g_loop_states.loop_unit[2].loop_Origin, g_loop_states.loop_unit[3].loop_Origin,
|
||||
g_loop_states.loop_unit[0].loop_VD_FLAG, g_loop_states.loop_unit[1].loop_VD_FLAG,
|
||||
g_loop_states.loop_unit[2].loop_VD_FLAG, g_loop_states.loop_unit[3].loop_VD_FLAG);
|
||||
g_loop_states.loop_unit[0].xn_counter = 0;
|
||||
g_loop_states.loop_unit[1].xn_counter = 0;
|
||||
g_loop_states.loop_unit[2].xn_counter = 0;
|
||||
g_loop_states.loop_unit[3].xn_counter = 0;
|
||||
}
|
||||
#endif
|
||||
vTaskDelay(10);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file at32f421_clock.c
|
||||
* @brief system clock config program
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
/* includes ------------------------------------------------------------------*/
|
||||
#include "at32f421_clock.h"
|
||||
|
||||
/**
|
||||
* @brief system clock config program
|
||||
* @note the system clock is configured as follow:
|
||||
* system clock (sclk) = hext * pll_mult
|
||||
* system clock source = pll (hext)
|
||||
* - hext = HEXT_VALUE
|
||||
* - sclk = 120000000
|
||||
* - ahbdiv = 1
|
||||
* - ahbclk = 120000000
|
||||
* - apb2div = 1
|
||||
* - apb2clk = 120000000
|
||||
* - apb1div = 1
|
||||
* - apb1clk = 120000000
|
||||
* - pll_mult = 15
|
||||
* - flash_wtcyc = 3 cycle
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void system_clock_config(void)
|
||||
{
|
||||
/* reset crm */
|
||||
crm_reset();
|
||||
|
||||
/* config flash psr register */
|
||||
flash_psr_set(FLASH_WAIT_CYCLE_3);
|
||||
|
||||
crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
|
||||
|
||||
/* wait till hext is ready */
|
||||
while(crm_hext_stable_wait() == ERROR)
|
||||
{
|
||||
}
|
||||
|
||||
/* config pll clock resource */
|
||||
crm_pll_config(CRM_PLL_SOURCE_HEXT, CRM_PLL_MULT_10);
|
||||
|
||||
/* enable pll */
|
||||
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
|
||||
|
||||
/* wait till pll is ready */
|
||||
while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
|
||||
{
|
||||
}
|
||||
|
||||
/* config ahbclk */
|
||||
crm_ahb_div_set(CRM_AHB_DIV_1);
|
||||
|
||||
/* config apb2clk, the maximum frequency of APB1/APB2 clock is 120 MHz */
|
||||
crm_apb2_div_set(CRM_APB2_DIV_1);
|
||||
|
||||
/* config apb1clk, the maximum frequency of APB1/APB2 clock is 120 MHz */
|
||||
crm_apb1_div_set(CRM_APB1_DIV_1);
|
||||
|
||||
/* enable auto step mode */
|
||||
crm_auto_step_mode_enable(TRUE);
|
||||
|
||||
/* select pll as system clock source */
|
||||
crm_sysclk_switch(CRM_SCLK_PLL);
|
||||
|
||||
/* wait till pll is used as system clock source */
|
||||
while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
|
||||
{
|
||||
}
|
||||
|
||||
/* disable auto step mode */
|
||||
crm_auto_step_mode_enable(FALSE);
|
||||
|
||||
/* update system_core_clock global variable */
|
||||
system_core_clock_update();
|
||||
}
|
||||
142
vd960Loop/utilities/at32f421_freertos_demo/src/at32f421_int.c
Normal file
142
vd960Loop/utilities/at32f421_freertos_demo/src/at32f421_int.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file at32f421_int.c
|
||||
* @brief main interrupt service routines.
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
/* includes ------------------------------------------------------------------*/
|
||||
#include "at32f421_int.h"
|
||||
|
||||
|
||||
|
||||
/** @addtogroup FreeRTOS_demo
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function handles nmi exception.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function handles hard fault exception.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* go to infinite loop when hard fault exception occurs */
|
||||
while(1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function handles memory manage exception.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void MemManage_Handler(void)
|
||||
{
|
||||
/* go to infinite loop when memory manage exception occurs */
|
||||
while(1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function handles bus fault exception.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void BusFault_Handler(void)
|
||||
{
|
||||
/* go to infinite loop when bus fault exception occurs */
|
||||
while(1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function handles usage fault exception.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void UsageFault_Handler(void)
|
||||
{
|
||||
/* go to infinite loop when usage fault exception occurs */
|
||||
while(1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function handles svcall exception.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
//void SVC_Handler(void)
|
||||
//{
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief this function handles debug monitor exception.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void DebugMon_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function handles pendsv_handler exception.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
//void PendSV_Handler(void)
|
||||
//{
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief this function handles systick handler.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
//void SysTick_Handler(void)
|
||||
//{
|
||||
//}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
195
vd960Loop/utilities/at32f421_freertos_demo/src/flash.c
Normal file
195
vd960Loop/utilities/at32f421_freertos_demo/src/flash.c
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file flash.c
|
||||
* @brief flash program
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include "at32f421_board.h"
|
||||
#include "flash.h"
|
||||
|
||||
/** @addtogroup AT32F421_periph_examples
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup 421_FLASH_write_read
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define SECTOR_SIZE 512 //1024 /* this parameter depends on the specific model of the chip */
|
||||
|
||||
uint16_t flash_buf[SECTOR_SIZE / 2];
|
||||
|
||||
/**
|
||||
* @brief read data using halfword mode
|
||||
* @param read_addr: the address of reading
|
||||
* @param p_buffer: the buffer of reading data
|
||||
* @param num_read: the number of reading data
|
||||
* @retval none
|
||||
*/
|
||||
void flash_read(uint32_t read_addr, uint16_t *p_buffer, uint16_t num_read)
|
||||
{
|
||||
uint16_t i;
|
||||
for(i = 0; i < num_read; i++)
|
||||
{
|
||||
p_buffer[i] = *(uint16_t*)(read_addr);
|
||||
read_addr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief write data using halfword mode without checking
|
||||
* @param write_addr: the address of writing
|
||||
* @param p_buffer: the buffer of writing data
|
||||
* @param num_write: the number of writing data
|
||||
* @retval result
|
||||
*/
|
||||
error_status flash_write_nocheck(uint32_t write_addr, uint16_t *p_buffer, uint16_t num_write)
|
||||
{
|
||||
uint16_t i;
|
||||
flash_status_type status = FLASH_OPERATE_DONE;
|
||||
for(i = 0; i < num_write; i++)
|
||||
{
|
||||
status = flash_halfword_program(write_addr, p_buffer[i]);
|
||||
if(status != FLASH_OPERATE_DONE)
|
||||
return ERROR;
|
||||
write_addr += 2;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief write data using halfword mode with checking
|
||||
* @param write_addr: the address of writing
|
||||
* @param p_buffer: the buffer of writing data
|
||||
* @param num_write: the number of writing data
|
||||
* @retval result
|
||||
*/
|
||||
error_status flash_write(uint32_t write_addr, uint16_t *p_buffer, uint16_t num_write)
|
||||
{
|
||||
uint32_t offset_addr = write_addr + DLD_FLASH_ADDRESS_START;
|
||||
uint16_t i;
|
||||
flash_status_type status = FLASH_OPERATE_DONE;
|
||||
if(offset_addr < FLASH_BASE || (offset_addr + num_write) >= DLD_FLASH_MAX_SIZE){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
flash_unlock();
|
||||
flash_read(DLD_FLASH_ADDRESS_START, flash_buf, DLD_BUFEER_SIZE);
|
||||
|
||||
/* wait for operation to be completed */
|
||||
status = flash_operation_wait_for(ERASE_TIMEOUT);
|
||||
|
||||
if((status == FLASH_PROGRAM_ERROR) || (status == FLASH_EPP_ERROR))
|
||||
flash_flag_clear(FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
|
||||
else if(status == FLASH_OPERATE_TIMEOUT)
|
||||
return ERROR;
|
||||
status = flash_sector_erase(DLD_FLASH_ADDRESS_START);
|
||||
if(status != FLASH_OPERATE_DONE)
|
||||
return ERROR;
|
||||
for(i = 0; i < num_write; i++)
|
||||
{
|
||||
flash_buf[write_addr + i] = p_buffer[i];
|
||||
}
|
||||
if(flash_write_nocheck(DLD_FLASH_ADDRESS_START, flash_buf, SECTOR_SIZE / 2) != SUCCESS)
|
||||
return ERROR;
|
||||
|
||||
flash_lock();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
error_status flash_write_old(uint32_t write_addr, uint16_t *p_buffer, uint16_t num_write)
|
||||
{
|
||||
uint32_t offset_addr;
|
||||
uint32_t sector_position;
|
||||
uint16_t sector_offset;
|
||||
uint16_t sector_remain;
|
||||
uint16_t i;
|
||||
flash_status_type status = FLASH_OPERATE_DONE;
|
||||
|
||||
flash_unlock();
|
||||
offset_addr = write_addr - FLASH_BASE;
|
||||
sector_position = offset_addr / SECTOR_SIZE;
|
||||
sector_offset = (offset_addr % SECTOR_SIZE) / 2;
|
||||
sector_remain = SECTOR_SIZE / 2 - sector_offset;
|
||||
if(num_write <= sector_remain)
|
||||
sector_remain = num_write;
|
||||
while(1)
|
||||
{
|
||||
flash_read(sector_position * SECTOR_SIZE + FLASH_BASE, flash_buf, SECTOR_SIZE / 2);
|
||||
for(i = 0; i < sector_remain; i++)
|
||||
{
|
||||
if(flash_buf[sector_offset + i] != 0xFFFF)
|
||||
break;
|
||||
}
|
||||
if(i < sector_remain)
|
||||
{
|
||||
/* wait for operation to be completed */
|
||||
status = flash_operation_wait_for(ERASE_TIMEOUT);
|
||||
|
||||
if((status == FLASH_PROGRAM_ERROR) || (status == FLASH_EPP_ERROR))
|
||||
flash_flag_clear(FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
|
||||
else if(status == FLASH_OPERATE_TIMEOUT)
|
||||
return ERROR;
|
||||
status = flash_sector_erase(sector_position * SECTOR_SIZE + FLASH_BASE);
|
||||
if(status != FLASH_OPERATE_DONE)
|
||||
return ERROR;
|
||||
for(i = 0; i < sector_remain; i++)
|
||||
{
|
||||
flash_buf[i + sector_offset] = p_buffer[i];
|
||||
}
|
||||
if(flash_write_nocheck(sector_position * SECTOR_SIZE + FLASH_BASE, flash_buf, SECTOR_SIZE / 2) != SUCCESS)
|
||||
return ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(flash_write_nocheck(write_addr, p_buffer, sector_remain) != SUCCESS)
|
||||
return ERROR;
|
||||
}
|
||||
if(num_write == sector_remain)
|
||||
break;
|
||||
else
|
||||
{
|
||||
sector_position++;
|
||||
sector_offset = 0;
|
||||
p_buffer += sector_remain;
|
||||
write_addr += (sector_remain * 2);
|
||||
num_write -= sector_remain;
|
||||
if(num_write > (SECTOR_SIZE / 2))
|
||||
sector_remain = SECTOR_SIZE / 2;
|
||||
else
|
||||
sector_remain = num_write;
|
||||
}
|
||||
}
|
||||
flash_lock();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file include_port.c
|
||||
* @brief include_port program
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup UTILITIES_examples
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup FreeRTOS_demo
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* support ac5 and ac6 compiler */
|
||||
#if (__ARMCC_VERSION > 6000000)
|
||||
|
||||
#include "..\..\..\middlewares\freertos\source\portable\GCC\ARM_CM3\port.c"
|
||||
|
||||
#else
|
||||
|
||||
#include "..\..\..\middlewares\freertos\source\portable\rvds\ARM_CM3\port.c"
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
1044
vd960Loop/utilities/at32f421_freertos_demo/src/main.c
Normal file
1044
vd960Loop/utilities/at32f421_freertos_demo/src/main.c
Normal file
File diff suppressed because it is too large
Load Diff
233
vd960Loop/utilities/at32f421_freertos_demo/src/storage.c
Normal file
233
vd960Loop/utilities/at32f421_freertos_demo/src/storage.c
Normal file
@@ -0,0 +1,233 @@
|
||||
|
||||
#include "storage.h"
|
||||
#include "flash.h"
|
||||
#include <stdlib.h>
|
||||
#include "TaskLoop.h"
|
||||
|
||||
|
||||
Loop_Balance_PlanB g_loop_balance_planB;
|
||||
Loop_Cng_Info g_loop_cng_info = {0, {0}};
|
||||
Loop_Sens_List g_loop_sens_list;
|
||||
|
||||
|
||||
uint8_t loop_cng_default[8] = {2,1,0,0,4,0,0,0};
|
||||
uint8_t loops_cng_default[LOOP_CAPTURE_MAX][8] = {
|
||||
{2, 1, 0, 0, Freq_Low, 0, 0, 0 },
|
||||
{2, 1, 0, 0, Freq_Middle_High, 0, 0, 0},
|
||||
{2, 1, 0, 0, Freq_Middle_Low, 0, 0, 0 },
|
||||
{2, 1, 0, 0, Freq_Low, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
void set_factory_param(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
g_loop_cng_info.smart_mode = Smart_Mode_Disable;
|
||||
Loop_Cng_Unit *unit = g_loop_cng_info.loop_cng;
|
||||
for(i = 0; i < LOOP_CAPTURE_MAX; i++)
|
||||
{
|
||||
memcpy(unit, loops_cng_default[i], 8);
|
||||
unit++;
|
||||
}
|
||||
|
||||
|
||||
g_loop_sens_list.total = SENS_Default_Amount;
|
||||
for(i = 0; i < g_loop_sens_list.total && i < 4; i++)
|
||||
{
|
||||
g_loop_sens_list.sens[i].sens_in = SensTable[i];
|
||||
g_loop_sens_list.sens[i].sens_out = SensTable_1[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void storage_dev(void)
|
||||
{
|
||||
uint8_t i = 0, k = 0;
|
||||
|
||||
uint8_t *rBuf = (uint8_t *)malloc(MAX_Store_Size);
|
||||
if(rBuf == NULL){
|
||||
// PRINT("Not enough memory!!");
|
||||
nvic_system_reset();
|
||||
}
|
||||
for(i = 0; i < MAX_Store_Size; i++){
|
||||
rBuf[i] = 0;
|
||||
}
|
||||
|
||||
PRINT("Will_storage_dev\r\n");
|
||||
|
||||
rBuf[0] = 0x33;
|
||||
rBuf[1] = 0xBB;
|
||||
rBuf[2] = 0xC3;
|
||||
rBuf[3] = 0x3C;
|
||||
|
||||
// g_freq_sens = 1;
|
||||
rBuf[Addr_Sens_Amount_Offset] = g_loop_sens_list.total;
|
||||
rBuf[Addr_Smart_Mode_Offset] = g_loop_cng_info.smart_mode;
|
||||
i = Addr_Loop_Cng_Offset;
|
||||
memcpy(&rBuf[i], (uint8_t *)g_loop_cng_info.loop_cng, sizeof(Loop_Cng_Unit) * LOOP_CAPTURE_MAX );
|
||||
i += sizeof(Loop_Cng_Unit) * LOOP_CAPTURE_MAX;
|
||||
|
||||
// i = Addr_Loop_PlanB_Cng_Offset;
|
||||
// rBuf[i++] = g_loop_balance_planB.sample_cng.flag;
|
||||
// rBuf[i++] = g_loop_balance_planB.sample_cng.max_amplitude;
|
||||
// rBuf[i++] = g_loop_balance_planB.sample_cng.max_amplitude >> 8;
|
||||
// rBuf[i++] = g_loop_balance_planB.balance_ori_cng.flag;
|
||||
// rBuf[i++] = g_loop_balance_planB.balance_ori_cng.max_cnt;
|
||||
// rBuf[i++] = g_loop_balance_planB.balance_ori_cng.max_cnt >> 8;
|
||||
// rBuf[i++] = g_loop_balance_planB.release_ori_planB.flag_weight;
|
||||
// rBuf[i++] = g_loop_balance_planB.release_ori_planB.max_amplitude;
|
||||
// rBuf[i++] = g_loop_balance_planB.release_ori_planB.max_amplitude >> 8;
|
||||
// rBuf[i++] = g_loop_balance_planB.release_ori_planB.timeout;
|
||||
//
|
||||
// rBuf[i++] = g_loop_balance_planB.release_change_rate.flag_weight;
|
||||
// rBuf[i++] = g_loop_balance_planB.release_change_rate.rate_first;
|
||||
// rBuf[i++] = g_loop_balance_planB.release_change_rate.rate_second;
|
||||
// rBuf[i++] = g_loop_balance_planB.release_change_rate.mode;
|
||||
|
||||
i = Addr_Loop_Sens_List_Offset;
|
||||
if(g_loop_sens_list.total > MAX_LOOP_SENS_AMOUNT)
|
||||
{
|
||||
g_loop_sens_list.total = MAX_LOOP_SENS_AMOUNT;
|
||||
}
|
||||
|
||||
for(k = 0; k < MAX_LOOP_SENS_AMOUNT; k++)
|
||||
{
|
||||
rBuf[i++] = g_loop_sens_list.sens[k].sens_in;
|
||||
rBuf[i++] = g_loop_sens_list.sens[k].sens_in >> 8;
|
||||
rBuf[i++] = g_loop_sens_list.sens[k].sens_out;
|
||||
rBuf[i++] = g_loop_sens_list.sens[k].sens_out >> 8;
|
||||
}
|
||||
|
||||
// PRINT("Will_write: \n");
|
||||
// for(i = 0; i < MAX_Store_Size; i++)
|
||||
// {
|
||||
// PRINT(" %02X", rBuf[i]);
|
||||
// }
|
||||
|
||||
flash_write(Addr_Dev_Flag_Offset, (uint16_t *)rBuf, DLD_BUFEER_SIZE/2);
|
||||
|
||||
free(rBuf);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// set frequent level
|
||||
void set_flp_level(uint8_t loop_num, uint8_t freq_level)
|
||||
{
|
||||
switch( freq_level)
|
||||
{
|
||||
case Freq_High: // 33nF
|
||||
{
|
||||
if(loop_num == 0) { FLPA1_HIGH; FLPA2_HIGH; }
|
||||
else if(loop_num == 1){ FLPB1_HIGH; FLPB2_HIGH; }
|
||||
else if(loop_num == 2){ FLPC1_HIGH; FLPC2_HIGH; }
|
||||
else if(loop_num == 3){ FLPD1_HIGH; FLPD2_HIGH; }
|
||||
} break;
|
||||
case Freq_Middle_High: // 43nF
|
||||
{
|
||||
if(loop_num == 0) { FLPA1_HIGH; FLPA2_LOW; }
|
||||
else if(loop_num == 1){ FLPB1_HIGH; FLPB2_LOW; }
|
||||
else if(loop_num == 2){ FLPC1_HIGH; FLPC2_LOW; }
|
||||
else if(loop_num == 3){ FLPD1_HIGH; FLPD2_LOW; }
|
||||
} break;
|
||||
case Freq_Middle_Low: // 66nF
|
||||
{
|
||||
if(loop_num == 0) { FLPA1_LOW; FLPA2_HIGH; }
|
||||
else if(loop_num == 1){ FLPB1_LOW; FLPB2_HIGH; }
|
||||
else if(loop_num == 2){ FLPC1_LOW; FLPC2_HIGH; }
|
||||
else if(loop_num == 3){ FLPD1_LOW; FLPD2_HIGH; }
|
||||
} break;
|
||||
case Freq_Low: //76nF
|
||||
{
|
||||
if(loop_num == 0) { FLPA1_LOW; FLPA2_LOW; }
|
||||
else if(loop_num == 1){ FLPB1_LOW; FLPB2_LOW; }
|
||||
else if(loop_num == 2){ FLPC1_LOW; FLPC2_LOW; }
|
||||
else if(loop_num == 3){ FLPD1_LOW; FLPD2_LOW; }
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void para_store_init(void)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t *rBuf = (uint8_t *)malloc(MAX_Store_Size);
|
||||
|
||||
if(rBuf == NULL){
|
||||
// PRINT("Not enough memory!!");
|
||||
nvic_system_reset();
|
||||
}
|
||||
memset(rBuf, 0, MAX_Store_Size);
|
||||
|
||||
flash_read(DLD_FLASH_ADDRESS_START, (uint16_t *)rBuf, MAX_Store_Size/2);
|
||||
PRINT("Read_Cng_Store:\n");
|
||||
for(i = 0; i < MAX_Store_Size; i++){
|
||||
PRINT("%02X ", rBuf[i]);
|
||||
}
|
||||
PRINT("\n");
|
||||
|
||||
if(rBuf[0] == 0x33 && rBuf[1] == 0xBB && rBuf[2] == 0xC3 && rBuf[3] == 0x3C){
|
||||
g_loop_sens_list.total = rBuf[Addr_Sens_Amount_Offset];
|
||||
g_loop_cng_info.smart_mode = rBuf[Addr_Smart_Mode_Offset];
|
||||
memcpy(g_loop_cng_info.loop_cng, &rBuf[Addr_Loop_Cng_Offset], sizeof(Loop_Cng_Unit) * LOOP_CAPTURE_MAX);
|
||||
memcpy(&g_loop_sens_list.sens, &rBuf[Addr_Loop_Sens_List_Offset], sizeof(g_loop_sens_list) - 1);
|
||||
|
||||
Loop_Cng_Unit *unitout = g_loop_cng_info.loop_cng;
|
||||
for(i = 0; i < LOOP_CAPTURE_MAX; i++)
|
||||
{
|
||||
PRINT("loop_%d, sens:%d,delay:%d, exit_mode:%d, out_put:%d\n", i, unitout->sensitvity, unitout->delay_time, unitout->exist_mode, unitout->output_mode);
|
||||
set_flp_level(i, unitout->loopFreq_Level);
|
||||
|
||||
// 同步灵敏度到检测单元
|
||||
g_loop_states.loop_unit[i].loop_SensLevel = unitout->sensitvity & 0x03;
|
||||
g_loop_states.loop_unit[i].SET_PLUS = unitout->output_mode & 0x01;
|
||||
g_loop_states.loop_unit[i].SET_DLY = (unitout->output_mode >> 1) & 0x01;
|
||||
|
||||
unitout++;
|
||||
}
|
||||
|
||||
// g_loop_out_delay = g_loop_cng_unit.delay_time * 2; // 定时器以 50ms 为单位, 延时以100ms为单位
|
||||
|
||||
// g_hold_time = g_loop_cng_unit.exist_mode * 30 * 20; //50ms/per, 30s
|
||||
|
||||
|
||||
// g_safe_max_cnt = g_loop_cng_unit.loopSafe_Timeout * 10 * (1000 / 50);
|
||||
// g_freq_level = g_loop_cng_unit.loopFreq_Level - 1;
|
||||
|
||||
// flt_mgr.max_cnt_flat_release = g_loop_cng_unit.delay_time * 20 /2;
|
||||
// if(flt_mgr.max_cnt_flat_release < 40){ // 至少检查400毫秒
|
||||
// flt_mgr.max_cnt_flat_release = 40;
|
||||
// }
|
||||
|
||||
|
||||
free(rBuf);
|
||||
}
|
||||
else{
|
||||
free(rBuf);
|
||||
//TODO: need to be normal
|
||||
set_factory_param();
|
||||
|
||||
storage_dev();
|
||||
//
|
||||
delay_ms(10);
|
||||
nvic_system_reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void test_factory(void)
|
||||
{
|
||||
set_factory_param();
|
||||
|
||||
storage_dev();
|
||||
|
||||
// delay_ms(10);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user