Files
vd_960/vd960Loop/utilities/at32f421_freertos_demo/src/main.c
wangfq 58774a2038 fix: 上报频率字段从raw CAPVD改为实际线圈频率
uart_report_packet_loop_acs 和 CMD_DBN_GET_MCJQ_PARAM 两处,
loop_CAPVD 需经公式转换为实际频率后再上报:
  freq = sclk_freq * input_div * LPCNT / CAPVD
使用 uint64_t 先乘后除避免整数截断
2026-06-26 09:46:58 +08:00

1055 lines
34 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
**************************************************************************
* @file main.c
* @brief main 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 "at32f421_clock.h"
#include "FreeRTOS.h"
#include "task.h"
#include "cmcng.h"
#include "TaskLoop.h"
#include <string.h>
#include "storage.h"
#include <stdlib.h>
#include "at32f421_wdt.h"
#include "iap.h"
/** @addtogroup UTILITIES_examples
* @{
*/
volatile uint8_t usart1_rx_dma_status = 0;
Pkg_Uart g_pkg_uart_1 = { 0, 0, 0, "", 0};
Pkg_Uart g_pkg_uart_report = { 0, 0, 0, "", 0};
static uint8_t tmp_ble_buf[BUFF_STACK_SIZE];
char usart1_rx_buffer[USART1_RX_BUFFER_SIZE];
TaskHandle_t usart_task_handler = NULL;
/** @addtogroup FreeRTOS_demo
* @{
*/
crm_clocks_freq_type g_crm_clocks_freq_struct = {0};
tmr_input_config_type g_tmr_input_config_struct;
__IO uint32_t sys_counter = 0;
__IO uint64_t TimingDelayInc;
__IO uint32_t TimingDelayDec;
TaskHandle_t loop_task_handler;
// 看门狗相关
#define WDT_TIMEOUT_MS 3000 // 看门狗超时时间 3秒
void wdt_init(void);
void wdt_feed(void);
tmr_output_config_type tmr_oc_init_structure;
/*
pb1 output pwm waveform, use Tmr14.
tmr3 channel1 duty cycle = (tmr3_c1dt/ tmr3_pr)* 100 = 50%
tmr3 channel2 duty cycle = (tmr3_c2dt/ tmr3_pr)* 100 = 37.5%
tmr3 channel3 duty cycle = (tmr3_c3dt/ tmr3_pr)* 100 = 25%
tmr3 channel4 duty cycle = (tmr3_c4dt/ tmr3_pr)* 100 = 12.5%
*/
uint16_t c1dt_val = 333;
//uint16_t c2dt_val = 249;
//uint16_t c3dt_val = 166;
//uint16_t c4dt_val = 83;
uint16_t prescaler_value = 0;
__IO uint16_t pulse=0;//55; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint8_t g_pulse_counter = 0;
uint8_t g_flag_pulse = 1;
uint64_t mstick(void){
return TimingDelayInc;
}
void InitPkgUart(Pkg_Uart * pkg){
memset(pkg->pkg, 0, BUFF_STACK_SIZE);
pkg->flag = 0;
pkg->tick = 0;
pkg->len = 0;
pkg->offset = 0;
}
/**
* @brief 初始化独立看门狗
* @param none
* @retval none
* @note 超时时间 = (预分频系数 × 重载值) / LSI频率
* LSI频率约 40kHz预分频64重载值=4687超时≈ 3秒
*/
void wdt_init(void)
{
// 使能看门狗寄存器写访问
wdt_register_write_enable(TRUE);
// 设置预分频系数为 64
wdt_divider_set(WDT_CLK_DIV_64);
// 设置重载值
// 超时时间 = (64 × 4687) / 40000 ≈ 7.5秒
// 如果需要 3秒: (64 × 1875) / 40000 = 3秒
wdt_reload_value_set(1875);
// 重载计数器
wdt_counter_reload();
// 使能看门狗
wdt_enable();
PRINT("Watchdog initialized, timeout: %d ms\n", WDT_TIMEOUT_MS);
}
/**
* @brief 喂狗(重载看门狗计数器)
* @param none
* @retval none
*/
void wdt_feed(void)
{
wdt_counter_reload();
}
uint16_t timer_period = 0;
uint16_t channel1_pulse = 0;
void Timr_msic_Init_Pwm(void)
{
gpio_init_type gpio_init_struct = {0};
tmr_output_config_type tmr_output_struct;
/* enable tmr1/gpioa/gpiob clock */
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
/* timer1 output pin Configuration */
gpio_init_struct.gpio_pins = GPIO_PINS_8 ;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(GPIOA, &gpio_init_struct);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE8, GPIO_MUX_2);
/* tmr1 configuration generate 7 pwm signals with 4 different duty cycles:
prescaler = 0, tmr1 counter clock = system_core_clock
the objective is to generate 7 pwm signal at 17.57 khz:
- tim1_period = (system_core_clock / 17570) - 1
the channel 1 and channel 1c duty cycle is set to 50%
the channel 2 and channel 2c duty cycle is set to 37.5%
the channel 3 and channel 3c duty cycle is set to 25%
the channel 4 duty cycle is set to 12.5%
the timer pulse is calculated as follows:
- channelxpulse = duty_cycle * (tim1_period - 1) / 100 */
/* compute the value to be set in arr regiter to generate signal frequency at 17.57 khz */
timer_period = (g_crm_clocks_freq_struct.sclk_freq / 17570 ) - 1;
/* compute c1dt value to generate a duty cycle at 50% for channel 1 and 1c */
// channel1_pulse = (uint16_t)(((uint32_t) 5 * (timer_period - 1)) / 10);
/* compute c2dt value to generate a duty cycle at 37.5% for channel 2 and 2c */
channel1_pulse = (uint16_t)(((uint32_t) 375 * (timer_period - 1)) / 1000);
/* compute c3dt value to generate a duty cycle at 25% for channel 3 and 3c */
// channel1_pulse = (uint16_t)(((uint32_t) 25 * (timer_period - 1)) / 100);
/* compute c4dt value to generate a duty cycle at 12.5% for channel 4 */
// channel1_pulse = (uint16_t)(((uint32_t) 125 * (timer_period- 1)) / 1000);
channel1_pulse = (uint16_t)(((uint32_t) 999 * (timer_period - 1)) / 1000);
tmr_base_init(TMR1, timer_period, 0);
tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
/* channel 1, 2, 3 and 4 configuration in output mode */
tmr_output_default_para_init(&tmr_output_struct);
tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
tmr_output_struct.oc_output_state = TRUE;
tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
tmr_output_struct.oc_idle_state = TRUE;
tmr_output_struct.occ_output_state = TRUE;
tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
tmr_output_struct.occ_idle_state = FALSE;
/* channel 1 */
tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, channel1_pulse);
/* output enable */
tmr_output_enable(TMR1, TRUE);
/* enable tmr1 */
tmr_counter_enable(TMR1, TRUE);
}
/* Basic timr msic, other timer init */
void Timr_msic_Init(void)
{
crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, TRUE);
//TODO: <20><>ʱ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><E3B7BD>
// tmr_base_init(TMR6, 9999, (g_crm_clocks_freq_struct.ahb_freq / 10000) - 1); // 1s
tmr_base_init(TMR6, 999, (g_crm_clocks_freq_struct.ahb_freq / 1000000) - 1); // 1ms
tmr_cnt_dir_set(TMR6, TMR_COUNT_UP);
tmr_interrupt_enable(TMR6, TMR_OVF_INT, TRUE);
nvic_irq_enable(TMR6_GLOBAL_IRQn, 2, 0); // 较低:系统节拍,上报计时、一般计数器
tmr_counter_enable(TMR6, TRUE);
crm_periph_clock_enable(CRM_TMR15_PERIPH_CLOCK, TRUE);
//TODO: <20><>ʱ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><E3B7BD>
// tmr_base_init(TMR6, 9999, (g_crm_clocks_freq_struct.ahb_freq / 10000) - 1); // 1s
tmr_base_init(TMR15, (5000-1), (g_crm_clocks_freq_struct.ahb_freq / 1000000) - 1); // 5ms
// tmr_base_init(TMR14, 9999, (g_crm_clocks_freq_struct.ahb_freq / 1000000) - 1); // 10ms
tmr_cnt_dir_set(TMR15, TMR_COUNT_UP);
tmr_interrupt_enable(TMR15, TMR_OVF_INT, TRUE);
nvic_irq_enable(TMR15_GLOBAL_IRQn, 2, 0); // 较低定时任务线圈任务定时器5ms
tmr_counter_enable(TMR15, TRUE);
Timr_msic_Init_Pwm();
}
uint8_t g_cnt_pwm_red_low_timeout = 0;
void poll_red_pwm(void)
{
g_pulse_counter++;
if(g_pulse_counter >= 12){
g_pulse_counter = 0;
if(g_flag_pulse){
if(pulse < 6000){
pulse += 400;
}
else{
pulse += 100;
}
if(pulse >= 6800)
{
if(g_cnt_pwm_red_low_timeout < 3){
pulse = 6800;
g_cnt_pwm_red_low_timeout++;
}
else{
g_flag_pulse = 0;
g_cnt_pwm_red_low_timeout = 0;
pulse = 6800;
}
}
}
else{
if(pulse <= 6800)
{
pulse -= 400;
}
// else{
// pulse -= 20;
// }
if(pulse < 500){
g_flag_pulse = 1;
}
}
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, pulse);
}
}
void usart1_sendstring(uint8_t *buf, uint16_t len)
{
uint16_t _len = len;
while(_len){
while(usart_flag_get(USART1, USART_TDBE_FLAG) == RESET);
usart_data_transmit(USART1, *buf++);
_len--;
}
}
/**
* @brief main function.
* @param none
* @retval none
*/
int main(void)
{
nvic_vector_table_set(NVIC_VECTTAB_FLASH, APP_START_ADDR - FLASH_BASE);
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
system_clock_config();
/* get system clock */
crm_clocks_freq_get(&g_crm_clocks_freq_struct);
at32_board_init();
/* init usart1 */
//2250000
// 115200
#ifdef DEBUG
// uart_print_init(230400); //115200
// uart_print_init(115200); //115200
usart_configuration();
PRINT("sys_clock:%d, ahb_freq:%d, sclk_freq:%d\n", system_core_clock, g_crm_clocks_freq_struct.ahb_freq, g_crm_clocks_freq_struct.sclk_freq);
#else
usart_configuration();
#endif
para_store_init();
loop_timer_io_init();
Timr_msic_Init();
// 初始化看门狗
wdt_init();
/* enter critical */
taskENTER_CRITICAL();
/* create loop task */
if(xTaskCreate((TaskFunction_t )loop_task_function,
(const char* )"Loop_task",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )2,
(TaskHandle_t* )&loop_task_handler) != pdPASS)
{
PRINT("loop task could not be created as there was insufficient heap memory remaining.\r\n");
}
else
{
PRINT("loop task was created successfully.\r\n");
}
/* create usart task */
if(xTaskCreate((TaskFunction_t )usart_task_function,
(const char* )"Usart_task",
(uint16_t )256,
(void* )NULL,
(UBaseType_t )3,
(TaskHandle_t* )&usart_task_handler) != pdPASS)
{
PRINT("usart task could not be created as there was insufficient heap memory remaining.\r\n");
}
else
{
PRINT("usart task was created successfully.\r\n");
}
/* create led indicator task */
if(xTaskCreate((TaskFunction_t )led_indicator_task_function,
(const char* )"LED_Task",
(uint16_t )256,
(void* )NULL,
(UBaseType_t )1,
(TaskHandle_t* )NULL) != pdPASS)
{
PRINT("led task could not be created as there was insufficient heap memory remaining.\r\n");
}
else
{
PRINT("led task was created successfully.\r\n");
}
/* exit critical */
taskEXIT_CRITICAL();
/* start scheduler */
vTaskStartScheduler();
}
void uart_report_packet_loop_acs(uint8_t flag)
{
uint8_t i,j, _flag_event = 0, _len = 0, _ckb = 0, _sum = 0;
uint8_t _misc = 0;
for(i = 0; i < LOOP_CAPTURE_MAX; i++)
{
Loop154_Unit *unit = &g_loop_states.loop_unit[i];
if(unit->loop_FLAG_IN || unit->loop_FLAG_OUT) _flag_event = 1;
}
if(_flag_event == 0)
{
if(g_loop_states.report_counter < 200) return;
}
else
{
if(g_loop_states.report_counter < 30) return;
}
InitPkgUart(&g_pkg_uart_report);
i = 0;
g_pkg_uart_report.pkg[i++] = 0x7F;
g_pkg_uart_report.pkg[i++] = 0;
g_pkg_uart_report.pkg[i++] = _len;
g_pkg_uart_report.pkg[i++] = CMD_SUB_SENS_REPORT;
g_pkg_uart_report.pkg[i++] = SENS_MULTI_LOOP_DYNAMIC;
g_pkg_uart_report.pkg[i++] = 0x00;
for(j = 0; j < LOOP_CAPTURE_MAX; j++)
{
Loop154_Unit *unit = &g_loop_states.loop_unit[j];
g_pkg_uart_report.pkg[i++] = (g_loop_cng_info.loop_cng[j].loopFreq_Level << 6) | (1 << 4) | (unit->loop_SensLevel & 0x03);
g_pkg_uart_report.pkg[i++] = 0 | ((!unit->loop_LOOP_OK) << 3) | (unit->loop_VD_FLAG << 2) | (_misc);
// 上报频率 = sclk_freq * input_div * LPCNT / CAPVD (先乘后除避免精度损失)
uint32_t _frequent = 0;
if (unit->loop_LPCNT > 0 && unit->loop_CAPVD > 0) {
_frequent = (uint32_t)((uint64_t)g_crm_clocks_freq_struct.sclk_freq * g_input_div * unit->loop_LPCNT / unit->loop_CAPVD);
}
g_pkg_uart_report.pkg[i++] = (uint8_t)(_frequent & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_frequent >> 8) & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_frequent >> 16) & 0xFF);
uint32_t variation = (unit->loop_Origin > unit->loop_CAPVD) ?
(unit->loop_Origin - unit->loop_CAPVD) : (unit->loop_CAPVD - unit->loop_Origin);
g_pkg_uart_report.pkg[i++] = (uint8_t)(variation & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((variation >> 8) & 0xFF);
// time val: pass_time (placeholder, not tracked in DLD154V4B algo)
uint32_t _tmp = 0;
g_pkg_uart_report.pkg[i++] = (uint8_t)(_tmp & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_tmp >> 8) & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_tmp >> 16) & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_tmp >> 24) & 0xFF);
}
g_pkg_uart_report.pkg[2] = i - 3;
for(j = 1; j < i; j++){
_ckb ^= g_pkg_uart_report.pkg[j];
_sum += g_pkg_uart_report.pkg[j];
}
g_pkg_uart_report.pkg[i++] = _ckb;
g_pkg_uart_report.pkg[i++] = _sum & 0xFF;
usart1_sendstring(g_pkg_uart_report.pkg, i);
g_loop_states.report_counter = 0;
}
// 7F
void response_uart_pkg(uint8_t cmd, uint8_t *dat, uint8_t dat_len)
{
uint8_t i,j, _ckb = 0, _sum = 0;
uint8_t *sBuf = (uint8_t *)malloc(BUFF_STACK_SIZE);
if(sBuf == NULL){
PRINT("Not enough memory!!");
}
memset(sBuf, 0, BUFF_STACK_SIZE);
i = 0;
sBuf[i++] = 0x7F;
sBuf[i++] = 0x80;
sBuf[i++] = 1 + dat_len;
sBuf[i++] = cmd;
memcpy(&sBuf[i], dat, dat_len);
i += dat_len;
for(j = 1; j < i; j++)
{
_ckb ^= sBuf[j];
_sum += sBuf[j];
}
sBuf[i++] = _ckb;
sBuf[i++] = _sum & 0xFF;
usart1_sendstring(sBuf, i);
free(sBuf);
}
// multip loop cjq param
static void unpack_pkg_set_mcjq_param(uint8_t *pkg, uint8_t len)
{
uint8_t i = 4, j, k = 0;
uint8_t _amount = 0;
g_loop_cng_info.smart_mode = pkg[i++];
_amount = pkg[i++];
Loop_Cng_Unit *unit = g_loop_cng_info.loop_cng;
for(j = 0; j < _amount; j++)
{
k = pkg[i++];
unit->sensitvity = k & 0x0F;
unit->loopFreq_Level = k >> 4;
unit->delay_time = pkg[i++];
k = pkg[i++];
unit->output_mode = k & 0x03;
unit->loopSafe_Timeout = k >> 3;
unit->exist_mode = pkg[i++];
unit->direction_mode = pkg[i++];
unit++;
}
storage_dev();
}
/**
* @brief USART1 串口数据包校验函数
* @param pkg: 接收到的数据包指针
* @param len: 数据包实际长度
* @retval 0: 校验成功;其他:校验失败
*/
uint8_t usart_packet_validate(uint8_t *pkg, uint8_t len)
{
uint8_t _len = pkg[2];
uint8_t _cmd = pkg[3];
uint8_t _addr = pkg[1];
uint8_t j;
// ===== 数据包校验 =====
// 1. 检查起始字节 STX (0x7F)
// if(pkg[0] != 0x7F && pkg[0] != 0x8F)
// {
// PRINT("Error: Invalid STX 0x%02X\n", pkg[0]);
// return 1; // 校验失败
// }
// 2. 检查长度字段
// LEN = CMD(1) + Data(LEN-1), 总长度应该是 LEN+3(STX+ADDR+LEN+XOR+SUM)
if(_len < 1) // 至少要有 CMD
{
PRINT("Error: Invalid length %d\n", _len);
return 2; // 校验失败
}
// 3. 检查接收到的数据长度是否匹配
if(len < (_len + 3)) // STX(1) + ADDR(1) + LEN(1) + LEN bytes + XOR(1) + SUM(1) = LEN+4但 pkg 从 0 开始,所以是 len >= _len + 3
{
PRINT("Error: Received length %d doesn't match declared length %d\n", len, _len);
return 3; // 校验失败
}
// 4. 提取并验证 XOR 校验
uint8_t received_xor = pkg[3 + _len]; // XOR 位置STX+ADDR+LEN+CMD+Data
uint8_t calculated_xor = _addr; // ADDR
calculated_xor ^= _len; // LEN
calculated_xor ^= _cmd; // CMD
for(j = 0; j < (_len - 1); j++) // Data (LEN-1 bytes)
{
calculated_xor ^= pkg[4 + j];
}
if(received_xor != calculated_xor)
{
PRINT("Error: XOR check failed! Received: 0x%02X, Calculated: 0x%02X\n", received_xor, calculated_xor);
return 4; // 校验失败
}
// 5. 提取并验证 SUM 校验
uint8_t received_sum = pkg[3 + _len + 1]; // SUM 位置XOR 后一个字节
uint8_t calculated_sum = _addr; // ADDR
calculated_sum += _len; // LEN
calculated_sum += _cmd; // CMD
for(j = 0; j < (_len - 1); j++) // Data (LEN-1 bytes)
{
calculated_sum += pkg[4 + j];
}
if(received_sum != calculated_sum)
{
PRINT("Error: SUM check failed! Received: 0x%02X, Calculated: 0x%02X\n", received_sum, calculated_sum);
return 5; // 校验失败
}
// ===== 所有校验通过 =====
return 0; // 校验成功
}
uint8_t usart_packet_9F_validate(uint8_t *pkg, uint8_t len)
{
uint8_t _sub1 = pkg[1];
uint8_t _sub2 = pkg[2];
uint8_t _len = pkg[3];
uint8_t _cmd = pkg[4];
uint8_t j;
// ===== 数据包校验 =====
// 1. 检查起始字节 STX (0x7F)
if(pkg[0] != 0x9F)
{
PRINT("Error: Invalid STX 0x%02X\n", pkg[0]);
return 1; // 校验失败
}
// // 2. 检查长度字段
// // LEN = CMD(1) + Data(LEN-1), 总长度应该是 LEN+3(STX+ADDR+LEN+XOR+SUM)
// if(_len < 1) // 至少要有 CMD
// {
// PRINT("Error: Invalid length %d\n", _len);
// return 2; // 校验失败
// }
//
// // 3. 检查接收到的数据长度是否匹配
// if(len < (_len + 2)) // STX(1) + ADDR(1) + LEN(1) + LEN bytes + SUM(1) = LEN+3但 pkg 从 0 开始,所以是 len >= _len + 2
// {
// PRINT("Error: Received length %d doesn't match declared length %d\n", len, _len);
// return 3; // 校验失败
// }
//
// // 5. 提取并验证 SUM 校验
// uint8_t received_sum = pkg[4 + _len]; // SUM 位置XOR 后一个字节
// uint8_t calculated_sum = _sub1 + _sub2; // ADDR
// calculated_sum += _len; // LEN
// calculated_sum += _cmd; // CMD
// for(j = 0; j < (_len - 1); j++) // Data (LEN-1 bytes)
// {
// calculated_sum += pkg[4 + j];
// }
//
// if(received_sum != calculated_sum)
// {
// PRINT("Error: SUM check failed! Received: 0x%02X, Calculated: 0x%02X\n", received_sum, calculated_sum);
// return 5; // 校验失败
// }
// ===== 所有校验通过 =====
return 0; // 校验成功
}
void iap_command_handle(void)
{
// IAP_REV_FLAG_DONE
flash_unlock();
flash_sector_erase(IAP_UPGRADE_FLAG_ADDR);
flash_word_program(IAP_UPGRADE_FLAG_ADDR, IAP_UPGRADE_FLAG_9F);
flash_lock();
nvic_system_reset();
}
void manage_dbn_ble_default(uint8_t *pkg, uint8_t len)
{
uint8_t _header_0 = pkg[1];
uint8_t _header_0_high = 0;
uint8_t _header_0_low = _header_0 % 0x10;
uint8_t _len = pkg[2];
uint8_t _cmd = pkg[3];
uint8_t _tmp = 0;
uint8_t i = 0, j,k = 0;
uint8_t _ota_pre_flag = 0;
if(pkg[0] == 0x7F || pkg[0] == 0x8F)
{
// ===== 调用校验函数进行数据包校验 =====
if(usart_packet_validate(pkg, len) != 0)
{
// 校验失败,直接返回
return;
}
}
else if(pkg[0] == 0x9F)
{
// ===== 调用校验函数进行数据包校验 =====
if(usart_packet_9F_validate(pkg, len) != 0)
{
// 校验失败,直接返回
return;
}
_ota_pre_flag = 1;
}
else{
PRINT("Error: Invalid STX 0x%02X\n", pkg[0]);
return;
}
if(_ota_pre_flag){
PRINT("OTA Pre Flag: %d\n", _ota_pre_flag);
if(pkg[1] == 0x01 && pkg[2] == 0x00 && pkg[3] == 0x01 && pkg[4] == 0xA5 && pkg[5] == 0xA7){
PRINT("OTA Pre Flag: %d\n", _ota_pre_flag);
iap_command_handle();
}
return;
}
switch(_cmd)
{
case CMD_DBN_DEV_RESET:
{
//Restart Dev
nvic_system_reset();
} break;
case CMD_DEV_Ver:
{
i = 0;
tmp_ble_buf[i++] = 0x00;
tmp_ble_buf[i++] = HARDWARE_VER_MAIN;
tmp_ble_buf[i++] = HARDWARE_VER_SUB;
tmp_ble_buf[i++] = HARDWARE_VER_SSUB;
tmp_ble_buf[i++] = FIRMWARE_VER_MAIN;
tmp_ble_buf[i++] = FIRMWARE_VER_SUB;
tmp_ble_buf[i++] = FIRMWARE_VER_SSUB;
response_uart_pkg(_cmd, tmp_ble_buf, i);
} break;
case CMD_DBN_SET_MCJQ_PARAM:
{
unpack_pkg_set_mcjq_param(pkg, len);
tmp_ble_buf[0] = 0;
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
response_uart_pkg(_cmd, tmp_ble_buf, 1);
delay_ms(30);
NVIC_SystemReset(); // 自动复位
// para_store_init();
} break;
case CMD_DBN_GET_MCJQ_PARAM:
{
i = 0;
tmp_ble_buf[i++] = g_loop_cng_info.smart_mode;
tmp_ble_buf[i++] = LOOP_CAPTURE_MAX;
Loop_Cng_Unit *_cng = g_loop_cng_info.loop_cng;
for(j = 0; j < LOOP_CAPTURE_MAX; j++)
{
tmp_ble_buf[i++] = (_cng->sensitvity) | (_cng->loopFreq_Level << 4);
tmp_ble_buf[i++] = _cng->delay_time;
tmp_ble_buf[i++] = (_cng->output_mode) | (_cng->loopSafe_Timeout << 3);
tmp_ble_buf[i++] = _cng->exist_mode;
tmp_ble_buf[i++] = _cng->direction_mode;
// 上报频率 = sclk_freq * input_div * LPCNT / CAPVD (先乘后除避免精度损失)
uint32_t _freq = 0;
if (g_loop_states.loop_unit[j].loop_LPCNT > 0 && g_loop_states.loop_unit[j].loop_CAPVD > 0) {
_freq = (uint32_t)((uint64_t)g_crm_clocks_freq_struct.sclk_freq * g_input_div
* g_loop_states.loop_unit[j].loop_LPCNT / g_loop_states.loop_unit[j].loop_CAPVD);
}
tmp_ble_buf[i++] = (uint8_t)(_freq & 0xFF);
tmp_ble_buf[i++] = (uint8_t)((_freq >> 8) & 0xFF);
tmp_ble_buf[i++] = (uint8_t)((_freq >> 16) & 0xFF);
_cng++;
}
response_uart_pkg(_cmd, tmp_ble_buf, i);
} break;
// case CMD_DBN_LOOP_SAMPLE_PARAM:{
// // 获取/设置 地感采样参数
//// PRINT("SAMPLE_CNG: %02X\n", pkg[4]);
// if(pkg[4] == 0){
// // get param
// i = 0;
// tmp_ble_buf[i++] = 0x10;
// tmp_ble_buf[i++] = g_loop_balance_planB.sample_cng.flag;
// tmp_ble_buf[i++] = g_loop_balance_planB.sample_cng.max_amplitude;
// tmp_ble_buf[i++] = (g_loop_balance_planB.sample_cng.max_amplitude >> 8) & 0xFF;
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
// }
// else {
// // set param
// i = 0;
// k = 4;
// tmp_ble_buf[i++] = 0x11;
// tmp_ble_buf[i++] = pkg[k++];
// tmp_ble_buf[i++] = pkg[k++];
// tmp_ble_buf[i++] = pkg[k++];
//
// g_loop_balance_planB.sample_cng.flag = tmp_ble_buf[1];
// g_loop_balance_planB.sample_cng.max_amplitude = tmp_ble_buf[2] | ((tmp_ble_buf[3] << 8 ) & 0xFF00);
//
// write_cfg_to_store(Addr_Loop_PlanB_Cng_Offset, &tmp_ble_buf[1], sizeof(Loop_Sample_Cng));
//
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
//
// //TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
// para_store_init();
// }
//
// } break;
// case CMD_DBN_LOOP_BALANCE_PARAM: {
// // 获取/设置 漂移补偿参数
//// PRINT("Balance_CNG: %02X\n", pkg[4]);
// if(pkg[4] == 0){
// // get param
// i = 0;
// tmp_ble_buf[i++] = 0x10;
// tmp_ble_buf[i++] = g_loop_balance_planB.balance_ori_cng.flag;
// tmp_ble_buf[i++] = g_loop_balance_planB.balance_ori_cng.max_cnt;
// tmp_ble_buf[i++] = (g_loop_balance_planB.balance_ori_cng.max_cnt >> 8) & 0xFF;
//
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
// }
// else{
// // set param
// i = 0;
// k = 4;
// tmp_ble_buf[i++] = 0x11;
// tmp_ble_buf[i++] = pkg[k++];
// tmp_ble_buf[i++] = pkg[k++];
// tmp_ble_buf[i++] = pkg[k++];
//
// g_loop_balance_planB.balance_ori_cng.flag = tmp_ble_buf[1];
// g_loop_balance_planB.balance_ori_cng.max_cnt = tmp_ble_buf[2] | ((tmp_ble_buf[3] << 8 ) & 0xFF00);
//
// write_cfg_to_store(Addr_Loop_PlanB_Cng_Offset + sizeof(Loop_Sample_Cng), &tmp_ble_buf[1], sizeof(Loop_Balance_Ori_Cng));
//
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
//
// //TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
// para_store_init();
//
// }
//
// } break;
// case CMD_DBN_LOOP_RELEASE_PLANB: {
// // 获取/设置 释放去抖动算法参数
//// PRINT("Release2_CNG: %02X\n", pkg[4]);
// if(pkg[4] == 0){
// // get param
// i = 0;
// tmp_ble_buf[i++] = 0x10;
// tmp_ble_buf[i++] = g_loop_balance_planB.release_ori_planB.flag_weight;
// tmp_ble_buf[i++] = g_loop_balance_planB.release_ori_planB.max_amplitude;
// tmp_ble_buf[i++] = (g_loop_balance_planB.release_ori_planB.max_amplitude >> 8) & 0xFF;
// tmp_ble_buf[i++] = g_loop_balance_planB.release_ori_planB.timeout;
// tmp_ble_buf[i++] = g_loop_balance_planB.release_change_rate.flag_weight;
// tmp_ble_buf[i++] = g_loop_balance_planB.release_change_rate.rate_first;
// tmp_ble_buf[i++] = g_loop_balance_planB.release_change_rate.rate_second;
// tmp_ble_buf[i++] = g_loop_balance_planB.release_change_rate.mode;
//
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
// }
// else{
// // set param
// i = 0; k = 0;
// tmp_ble_buf[i++] = 0x11;
// memcpy(&tmp_ble_buf[1], &pkg[4], 8);
// i += 8;
//
// write_cfg_to_store(Addr_Loop_PlanB_Cng_Offset + sizeof(Loop_Sample_Cng) + sizeof(Loop_Balance_Ori_Cng), &tmp_ble_buf[1], 8);
//
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
//
// //TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
// para_store_init();
// }
// } break;
case CMD_DBN_LOOP_SENS_LIST: {
PRINT("SENS_CNG: %02X\n", pkg[4]);
if(pkg[4] == 0x00){
// get param
i = 0;
tmp_ble_buf[i++] = 0x10;
tmp_ble_buf[i++] = g_loop_sens_list.total;
for(k = 0; k < g_loop_sens_list.total; k++){
tmp_ble_buf[i++] = g_loop_sens_list.sens[k].sens_in;
tmp_ble_buf[i++] = g_loop_sens_list.sens[k].sens_in >> 8;
tmp_ble_buf[i++] = g_loop_sens_list.sens[k].sens_out;
tmp_ble_buf[i++] = g_loop_sens_list.sens[k].sens_out >> 8;
}
response_uart_pkg(_cmd, tmp_ble_buf, i);
}
else {
// set param
i = 0; k = 5;
tmp_ble_buf[i++] = 0x11;
g_loop_sens_list.total = pkg[k];
if(g_loop_sens_list.total > MAX_LOOP_SENS_AMOUNT){
g_loop_sens_list.total = MAX_LOOP_SENS_AMOUNT;
}
k = 1+ g_loop_sens_list.total * 4;
memcpy(&tmp_ble_buf[i], &pkg[5], k);
memcpy(&g_loop_sens_list.sens, &pkg[6], k - 1);
i += ( k );
storage_dev();
response_uart_pkg(_cmd, tmp_ble_buf, i);
//TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
para_store_init();
}
} break;
case CMD_DBN_SET_CJQ_FACTORY: {
// 出厂初始化
tmp_ble_buf[0] = 0;
set_factory_param();
storage_dev();
response_uart_pkg(_cmd, tmp_ble_buf, 1);
//TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
para_store_init();
} break;
case CMD_SENS_ACS_ENABLE: {
// 线圈动态上报使能(简化版:仅处理 enable flag
// g_dbn_ble_state_acs_enable.enable = pkg[5];
} break;
default:
{
} break;
}
}
/**
* @brief USART1串口接收任务
* @param pvParameters: 任务参数
* @retval None
*/
void usart_task_function(void *pvParameters)
{
uint8_t received_data;
while(1)
{
if(g_pkg_uart_1.flag){
// PRINT("Rcv_uart:%s\n", g_pkg_uart_1.pkg);
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("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].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);
}
#endif
// 短暂延迟避免过度占用CPU
vTaskDelay(10);
}
}
uint8_t g_flag_output = 0;
uint8_t g_flag_output2 = 0;
// 1ms interval
void TMR6_GLOBAL_IRQHandler(void)
{
static uint16_t _cnt_5ms = 0;
static uint32_t _cnt = 0;
if(tmr_interrupt_flag_get(TMR6, TMR_OVF_FLAG) != RESET)
{
#ifdef DEBUG
_cnt++;
if(_cnt >= 2000){
g_flag_output = 1;
_cnt = 0;
}
#endif
TimingDelayInc++;
if(g_pkg_uart_1.offset){
if(g_pkg_uart_1.flag == 0){
g_pkg_uart_1.tick++;
if(g_pkg_uart_1.tick > 8){
g_pkg_uart_1.flag = 1;
}
}
g_loop_states.report_counter = 0;
}
tmr_flag_clear(TMR6, TMR_OVF_FLAG);
}
}
/**
* @brief this function handles usart1 handler.
* @param none
* @retval none
*/
void USART1_IRQHandler(void)
{
if(usart_interrupt_flag_get(USART1, USART_RDBF_FLAG) != RESET)
{
/* read one byte from the receive data register */
g_pkg_uart_1.pkg[g_pkg_uart_1.offset++] = usart_data_receive(USART1);
g_pkg_uart_1.tick = 0;
// if(usart1_rx_counter == usart2_tx_buffer_size)
// {
// /* disable the usart1 receive interrupt */
// usart_interrupt_enable(USART1, USART_RDBF_INT, FALSE);
// }
}
}
/**
* @}
*/
/**
* @}
*/