/** ************************************************************************** * @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 #include "storage.h" #include #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; //������� 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: ��ʱ�ļ��㷽�� // 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: ��ʱ�ļ��㷽�� // 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; uint32_t _misc_val[LOOP_CAPTURE_MAX] = {0}; uint16_t _interval; /*--- 0. 上电抑制: 3秒内不上报, 等线圈稳定 ---*/ if (g_loop_states.misc_counter < 60) { // 60 × 50ms = 3s g_loop_states.report_counter = 0; // 抑制期清零, 防止出抑制后立即上报 return; } /*--- 1. 检查是否有进场/离开事件 ---*/ 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; } /*--- 2. 确定上报间隔 ---*/ if (_flag_event) { _interval = REPORT_EVENT_TICKS; // 3×50ms = 150ms } else { _interval = REPORT_IDLE_TICKS; // 12×50ms = 600ms } if (g_loop_states.report_counter < _interval) return; /*--- 3. 确定本轮杂项类型 ---*/ if (_flag_event) { _misc = MISC_TYPE_TIME; // 事件优先级最高 } else { _misc = g_loop_states.report_misc_round; g_loop_states.report_misc_round++; if (g_loop_states.report_misc_round >= MISC_TYPE_COUNT) g_loop_states.report_misc_round = 0; } /*--- 4. 准备各通道杂项值 ---*/ for (i = 0; i < LOOP_CAPTURE_MAX; i++) { Loop154_Unit *unit = &g_loop_states.loop_unit[i]; switch (_misc) { case MISC_TYPE_TIME: if (_flag_event) { _misc_val[i] = unit->misc_value; // 已在上层计算 } else { _misc_val[i] = 0; // 空闲时为0 } break; case MISC_TYPE_CUT: _misc_val[i] = unit->disconnect_count; break; case MISC_TYPE_FLOW: _misc_val[i] = unit->flow_count; break; case MISC_TYPE_RELAY: _misc_val[i] = unit->relay_count; break; } } /*--- 5. 组包 ---*/ 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; // placeholder 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; // SubPkgFlag: 无分包 for (j = 0; j < LOOP_CAPTURE_MAX; j++) { Loop154_Unit *unit = &g_loop_states.loop_unit[j]; // 配置1: freq_level(2) | direction(1) | freq_type(1=实时) | sens(4) g_pkg_uart_report.pkg[i++] = (g_loop_cng_info.loop_cng[j].loopFreq_Level << 6) | (1 << 4) // freq_type=实时 | (unit->loop_SensLevel & 0x03); // 评估条件: condition(4) | loop_state(1) | car_state(1) | misc_type(2) g_pkg_uart_report.pkg[i++] = ((!unit->loop_LOOP_OK) << 3) // loop_state | (unit->loop_VD_FLAG << 2) // car_state | (_misc & 0x03); // misc_type // 频率 (3B, LE) 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); // 变化量 (3B, LE, 有符号补码) — V1.05 // 定义: variation = Origin - CAPVD // 正值 = 当前值低于基线(车辆/金属进入, 检测裕量方向) // 负值 = 当前值高于基线(反向漂移/异常抬升) int32_t variation = (int32_t)unit->loop_Origin - (int32_t)unit->loop_CAPVD; if (variation > 8388607) variation = 8388607; // +2^23-1 饱和, 防回绕 if (variation < -8388608) variation = -8388608; // -2^23 饱和 g_pkg_uart_report.pkg[i++] = (uint8_t)(variation & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((variation >> 8) & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((variation >> 16) & 0xFF); // 杂项值 (4B, LE) g_pkg_uart_report.pkg[i++] = (uint8_t)(_misc_val[j] & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((_misc_val[j] >> 8) & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((_misc_val[j] >> 16) & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((_misc_val[j] >> 24) & 0xFF); } /*--- 6. 回填 LEN + 校验 ---*/ 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; // 低4位: 灵敏度序号 (4级制 0~3) unit->loopFreq_Level = k >> 4; // 高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++]; // 同步灵敏度到检测单元 (修复: 运行中配置必须立即生效, 不依赖重启) g_loop_states.loop_unit[j].loop_SensLevel = sens_level_from_config(unit->sensitvity); 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++; } // LOOP_MEASURE_BASE: variation 归一化基数 (3B LE, 与 TaskLoop.h MEASUREMENT_BASE 同步) tmp_ble_buf[i++] = (uint8_t)(LOOP_MEASURE_BASE & 0xFF); tmp_ble_buf[i++] = (uint8_t)((LOOP_MEASURE_BASE >> 8) & 0xFF); tmp_ble_buf[i++] = (uint8_t)((LOOP_MEASURE_BASE >> 16) & 0xFF); 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); // } } } /** * @} */ /** * @} */