AVS/GD32F103C8T6/App/User/Peripheral/Api/api.c

379 lines
9.6 KiB
C

#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;
}
}