#include "api.h" #define API_RX_MAXSIZE 615 uint8_t api_upgrade_mode = 0; static uint8_t version[24] = {SOFTWARE_VERSION}; static uint16_t api_rx_status = 0; static uint16_t api_rx_length = 0; static uint8_t api_rx_buffer[API_RX_MAXSIZE] = {0}; /* 升级包序号 */ static uint16_t upgrade_pack_index = 0; /* 升级包总数 */ static uint16_t upgrade_pack_count = 0; /* 升级包数据接收长度 */ static uint16_t upgrade_rx_length = 0; /* 升级包数据接收长度 */ static uint16_t upgrade_rx_index = 0; /* 升级包写入下标 */ static uint16_t upgrade_write_index = 0; /* 升级包数据接收长度 */ static uint8_t upgrade_rx_buffer[1024] = {0}; static void api_notify_upgrade(uint8_t *buffer, uint16_t length); static void api_notify_get_fhss_channel(void); static void api_package(uint8_t type, uint8_t command, uint8_t *data, uint8_t length); static void api_package_response(uint8_t command, uint8_t status, uint8_t *buffer, uint16_t length); static void api_unpacking(uint8_t *buffer, uint16_t length); /** * @brief 应用程序初始化 */ void api_init(void) { /* 加载设置信息 */ setting_load(); } /** * @brief 应用程序处理任务 */ void api_process(void) { if (api_rx_status & 0x8000) { #ifdef USE_LED gpio_bit_toggle(LED_RX_PERIPH, LED_RX_PIN); #endif uint8_t buffer[API_RX_MAXSIZE] = {0}; uint16_t length = api_rx_status & 0x7FFF; for (uint16_t i = 0; i < length; i++) buffer[i] = api_rx_buffer[i]; api_rx_length = 0; api_rx_status = 0; api_unpacking(buffer, length); } } /** * @brief 数据组包 */ void api_concat_byte(uint8_t data) { if (api_rx_status & 0x8000) return; if (api_rx_length > API_RX_MAXSIZE || api_rx_status > API_RX_MAXSIZE) { api_rx_status = 0; api_rx_length = 0; } api_rx_buffer[api_rx_status++] = data; if (api_rx_status == 1) { if (api_rx_buffer[0] != 0xA6) api_rx_status = 0; } else if (api_rx_status == 5) { api_rx_length = (api_rx_buffer[3] << 8 & 0xFF00) | (api_rx_buffer[4] & 0xFF); api_rx_length += 7; } else if (api_rx_status == api_rx_length) { if (api_rx_buffer[api_rx_status - 1] == 0x77) { api_rx_status |= 0x8000; } else { api_rx_status = 0; api_rx_length = 0; } } } /** * @brief 上传数据 */ __weak void api_notify_data_upload(uint8_t *buffer, uint16_t length) {} /** * @brief 返回成功执行指令 */ void api_response_success(uint8_t command) { api_package_response(command, API_SUCCESS, nullptr, 0); } /** * @brief 上传心跳数据 */ void api_upload_heart_beat(void) { uint8_t index = 0, buffer[40] = {0}; for (uint8_t i = 0; i < 12; i++) buffer[index++] = uuid[i]; for (uint8_t i = 0; i < 24; i++) buffer[index++] = version[i]; uint32_t runtime = timestamp / 1000; buffer[index++] = runtime >> 24 % 0xFF; buffer[index++] = runtime >> 16 % 0xFF; buffer[index++] = runtime >> 8 % 0xFF; buffer[index++] = runtime & 0xFF; api_package(API_FRAME_NOTIFICATION, API_COMMAND_HEART_BEAT, buffer, index); } void api_upload_vehicle_status(uint8_t type, uint8_t value) { uint8_t buffer[2] = { type, value}; api_package(API_FRAME_NOTIFICATION, API_COMMAND_VEHICLE_STATUS, buffer, 2); } __weak void api_notify_set_strobe_light_mode(uint8_t mode) {} void api_response_set_strobe_light_mode(uint8_t status) { api_package_response(API_COMMAND_SET_STROBE_LIGHT_MODE, status, nullptr, 0); } __weak void api_notify_get_strobe_light_mode(void) {} __weak void api_response_get_strobe_light_mode(uint8_t status, uint8_t mode) { api_package_response(API_COMMAND_GET_STROBE_LIGHT_MODE, status, &mode, 1); } __weak void api_notify_set_volume_level(uint8_t level) {} void api_response_set_volume_level(uint8_t status) { api_response_success(API_COMMAND_SET_VOLUME_LEVEL); } __weak void api_notify_get_volume_level(void){} void api_response_get_volume_level(uint8_t status, uint8_t level) { api_package_response(API_COMMAND_GET_VOLUME_LEVEL, status, &level, 1); } __weak void api_notify_set_can_type(uint8_t type){} void api_response_set_can_type(uint8_t status) { api_package_response(API_COMMAND_SET_CAN_TYPE, status, nullptr, 0); } __weak void api_notify_get_can_type(void){} void api_response_get_can_type(uint8_t status, uint8_t type) { api_package_response(API_COMMAND_GET_CAN_TYPE, status, &type, 1); } __weak void api_notify_send_audio_pulse(uint8_t pulse_count){} void api_response_send_audio_pulse(uint8_t status) { api_package_response(API_COMMAND_SEND_AUDIO_PULSE, status, nullptr, 0); } void api_upload_data_forwarding(uint8_t type, uint8_t value) { uint8_t buffer[2] = { type, value}; api_package(API_FRAME_NOTIFICATION, API_COMMAND_DATA_FORWARDING, buffer, 2); } __weak void api_notify_data_forwarding(uint8_t type, uint8_t value) { } /** * @brief 升级 */ static void api_notify_upgrade(uint8_t *buffer, uint16_t length) { /* 升级数据包大小, 包编号+包总数+包数据 */ uint16_t pack_length = (((buffer[3] << 8) & 0xFF00) | (buffer[4] & 0xFF)) - 4; /* 升级包总数 */ upgrade_pack_count = ((buffer[5] << 8) & 0xFF00) | (buffer[6] & 0xFF); /* 当前下发下来的包序号 */ uint16_t index = ((buffer[7] << 8) & 0xFF00) | (buffer[8] & 0xFF); if (pack_length > FMC_PAGE_SIZE) { api_package_response(API_COMMAND_UPGRADE, 0x02, nullptr, 0); return; } /* 启动升级 初始化 */ if (index == 0x0001) { api_upgrade_mode = 1; upgrade_rx_index = 0; upgrade_rx_length = 0; upgrade_pack_index = 0; } for (uint16_t i = 0; i < pack_length; i++) upgrade_rx_buffer[upgrade_rx_index++] = buffer[i + 9]; if (index == upgrade_pack_index + 1) { /* 更改ARM接收到的升级包序号 */ upgrade_pack_index = index; if (upgrade_rx_index >= 1024 || upgrade_pack_index == upgrade_pack_count) { /* 写入升级包数据 */ fmc_write_bytes(FMC_ADDRESS_UPGRADE_BUFFER + upgrade_write_index * FMC_PAGE_SIZE, upgrade_rx_buffer, upgrade_rx_index / 4 + (upgrade_rx_index % 4 ? 1 : 0)); upgrade_write_index++; upgrade_rx_length += upgrade_rx_index; upgrade_rx_index = 0; } /* 通知上位机当前升级包成功接收 */ api_response_success(API_COMMAND_UPGRADE); if (upgrade_pack_index == upgrade_pack_count) { uint8_t upgrade_info[8] = { 0x00, 0x00, 0x00, 0x01, upgrade_rx_length >> 24 & 0xFF, upgrade_rx_length >> 16 & 0xFF, upgrade_rx_length >> 8 & 0xFF, upgrade_rx_length & 0xFF}; /* 写入需要升级的状态 */ fmc_write_bytes(FMC_ADDRESS_UPGRADE_INFO, upgrade_info, 2); /* 延时以确保数据完整发送到上位机 */ delay_ms(1000); /* 重启以完成升级 */ NVIC_SystemReset(); } } else { api_upgrade_mode = 0; /* 通知上位机丢包 */ api_package_response(API_COMMAND_UPGRADE, 0x03, nullptr, 0); } } /** * @brief 按协议方式组包 * * @param type 帧类型 * @param command 指令代码 * @param data 指令参数 * @param length 指令参数长度 */ static void api_package(uint8_t type, uint8_t command, uint8_t *data, uint8_t length) { uint8_t index = 0; uint8_t buffer[128] = {0}; uint16_t check_sum = 0; buffer[index++] = 0xA6; buffer[index++] = type; buffer[index++] = command; buffer[index++] = length >> 8 & 0xFF; buffer[index++] = length & 0xFF; for (uint8_t i = 0; i < length; i++) buffer[index++] = data[i]; for (uint8_t i = 1; i < index; i++) check_sum += buffer[i]; buffer[index++] = check_sum & 0xFF; buffer[index++] = 0x77; api_notify_data_upload(buffer, index); } static void api_package_response(uint8_t command, uint8_t status, uint8_t *data, uint16_t length) { uint16_t index = 0; uint8_t buffer[128] = {0}; buffer[index++] = status; for (uint16_t i = 0; i < length; i++) buffer[index++] = data[i]; api_package(API_FRAME_RESPONSE, command, buffer, index); } /** * @brief 按协议方式拆包 */ void api_unpacking(uint8_t *buffer, uint16_t length) { /* 判断校验是否正确 */ uint16_t crc = 0x00; for (uint16_t i = 1; i < length - 2; i++) crc += buffer[i]; switch (buffer[2]) { /* 升级 */ case API_COMMAND_UPGRADE: api_notify_upgrade(buffer, length); break; /* 重启 */ case API_COMMAND_REBOOT: api_response_success(buffer[2]); delay_ms(1000); NVIC_SystemReset(); break; /* 设置频闪灯工作方式 */ case API_COMMAND_SET_STROBE_LIGHT_MODE: api_notify_set_strobe_light_mode(buffer[5]); break; case API_COMMAND_GET_STROBE_LIGHT_MODE: api_notify_get_strobe_light_mode(); break; case API_COMMAND_SET_VOLUME_LEVEL: api_notify_set_volume_level(buffer[5]); break; case API_COMMAND_GET_VOLUME_LEVEL: api_notify_get_volume_level(); break; case API_COMMAND_SET_CAN_TYPE: api_notify_set_can_type(buffer[5]); break; case API_COMMAND_GET_CAN_TYPE: api_notify_get_can_type(); break; case API_COMMAND_SEND_AUDIO_PULSE: api_notify_send_audio_pulse(buffer[5]); break; case API_COMMAND_DATA_FORWARDING: api_notify_data_forwarding(buffer[5], buffer[6]); break; } }