Files
ESPC3-wireless/app/drivers/sertrf/sertrf.c
2025-10-28 16:29:00 +08:00

676 lines
24 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.

#include "sertrf.h"
//设置日志打印类型
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_DBG
#define SYS_LOG_DOMAIN "Seryrf"
sertrf_t sertrf;
void sertrf_init(void)
{
uint8_t res = 0;
res = device_init(&sertrf.device);
if(res)
{
SYS_LOG_WRN("device init error");
}
// 打开SYS_LOG打印
app_cfg_set_sys_log(true);
// 协议初始化
Protocol_init(PORT_LINUX_SBDATA, sertrf.device.embedded_device);
//RGB灯
work_rgb_led_start();
//按键初始化
button_work_init();
// 协议初始化
sertrf.resend_read_mutex = xSemaphoreCreateMutex();
resend_init(&sertrf.resend_device, resend_send, resend_recv, resend_get_length,resend_user_parse);
// stmisp协议初始化
stmisp_init(&sertrf.stmisp_device,stmisp_send,stmisp_recv,stmisp_get_length);
//OAT信息获取
get_partition_status(&sertrf.otau);
//获取飞控代码地址
sertrf.fc_address = parse_hex_or_dec(FC_ADDRESS);
//获取加密后的efuse MAC 地址
if(!esp_efuse_mac_get_default_id(sertrf.efuse_mac))
{
sertrf_aes_ctr_encrypt(sertrf.efuse_mac, 6, sertrf.efuse_mac_encrypt);
}
//初始化环形buff
rb_init(&sertrf.data_handle_buffer, DATA_HANDLE_BUFFER_SIZE, sizeof(uint8_t));
// 判断飞控是否进入 飞控固件强刷模式
sertrf.force_update = key_get_status();
//线程启动
sertrf_start();
SYS_LOG_INF("sertrf init ok");
}
void sertrf_start(void)
{
os_thread_create(&sertrf.embedded_thread,
"embedded_thread",
embedded_thread,
NULL,
4096,
20);
os_thread_create(&sertrf.pc_thread,
"pc_thread",
pc_thread,
NULL,
4096,
20);
os_thread_create(&sertrf.app_thread,
"app_thread",
app_thread,
NULL,
4096,
15);
os_thread_create(&sertrf.task_thread,
"task_thread",
task_thread,
NULL,
2048,
10);
os_thread_create(&sertrf.data_handle_thread,
"data_handle_thread",
data_handle_thread,
NULL,
4096,
10);
}
void sertrf_rf_switch(uint8_t on)
{
switch(on)
{
case 1:
rf_start(&sertrf.device);
break;
case 0:
rf_stop(&sertrf.device);
break;
}
}
//因为 串口
void embedded_thread(void* arg)
{
while(true)
{
uint32_t embedded_size = embedded_device_get_rx_length(&sertrf.device);
if(embedded_size > 0)
{
uint8_t data[embedded_size ];
// data[embedded_size] = '\0';
if(!sertrf.stmisp_device.flag && !sertrf.force_update)
embedded_device_read(&sertrf.device, data, embedded_size,0);
Protocol_buf_decode(data, embedded_size);
// SYS_LOG_INF("data : %s", data);
pc_device_write(&sertrf.device, data, embedded_size);
}
// printf_chill_time(10,1000);
//需要添加一些延时,否则会卡死,导致看门狗复位
// vTaskDelay(( TickType_t ) 1000 / configTICK_RATE_HZ);
os_thread_sleep(1);
}
}
void pc_thread(void* arg)
{
static bool app_pc_discard = true;
while(true)
{
uint32_t pc_size = pc_device_get_rx_length(&sertrf.device);
if(pc_size > 0)
{
uint8_t data[pc_size];
pc_device_read(&sertrf.device, data, pc_size);
// SYS_LOG_INF("data : %s", data);
// 由于APP连接上后会发送一串我用不到的数据需要丢弃掉不然会影响我异常飞控固件升级
if(sertrf.device.ble_one_connect_flag == 1)
{
sertrf.device.ble_one_connect_flag = 0;
continue;
}
if(!sertrf.stmisp_device.flag && !sertrf.force_update)
embedded_device_write(&sertrf.device, data, pc_size);
}
// printf_chill_time(10,1000);
//需要添加一些延时,否则会卡死,导致看门狗复位
// vTaskDelay(( TickType_t ) 1000 / configTICK_RATE_HZ);
os_thread_sleep(1);
}
}
void app_thread(void* arg)
{
while (true)
{
switch(sertrf.resend_device.handle_flag)
{
case RESEND_CMD_GET_PARAM:
sertrf_stauct_t sertrf_stauct;
strcpy(sertrf_stauct.ble_name, g_cfg_app->device_name_ble);
strcpy(sertrf_stauct.wifi_ap_ssid, g_cfg_app->app_config_wifi_para.wifi_ap_ssid);
strcpy(sertrf_stauct.wifi_ap_password, g_cfg_app->app_config_wifi_para.wifi_ap_password);
strcpy(sertrf_stauct.wifi_sta_ssid, g_cfg_app->app_config_wifi_para.wifi_sta_ssid);
strcpy(sertrf_stauct.wifi_sta_password, g_cfg_app->app_config_wifi_para.wifi_sta_password);
memcpy(sertrf_stauct.efuse_mac_encrypt, sertrf.efuse_mac_encrypt, 6);
resend_send_data(&sertrf.resend_device, RESEND_CMD_GET_PARAM, &sertrf_stauct, sizeof(sertrf_stauct_t), 1000);
sertrf.resend_device.handle_flag = 0;//标志位清零
break;
case RESEND_CMD_OTA_GET_PARAM:
SYS_LOG_DBG("RESEND_CMD_OTA_GET_PARAM\r\n");
ota_parm_t ota_parm;
resend_send_data(&sertrf.resend_device, RESEND_CMD_OTA_GET_PARAM, &ota_parm, sizeof(ota_parm_t), 1000);
sertrf.resend_device.handle_flag = 0;//标志位清零
break;
case RESEND_CMD_FC_ISP_GET_PARAM:
SYS_LOG_DBG("RESEND_CMD_FC_ISP_GET_PARAM\r\n");
stmisp_parm_t stmisp_parm;
resend_send_data(&sertrf.resend_device, RESEND_CMD_FC_ISP_GET_PARAM, &stmisp_parm, sizeof(stmisp_parm), 1000);
sertrf.resend_device.handle_flag = 0;//标志位清零
break;
default:
break;
}
resend_recv_data(&sertrf.resend_device, 0);
os_thread_sleep(1);
}
}
void task_thread(void* arg)
{
while(true)
{
size_t start_time = os_get_sys_time();
pc_link_rgb_color(&sertrf.device);
if(sertrf.device.connect_pc > DISCONNECT)
{
static size_t end_time = 0;
if(start_time - end_time > 2000)
{
sertrf.fc_protocol_status = get_protocol_status();
switch(sertrf.fc_protocol_status)
{
case PROTOCOL_STATUS_OK:
// rgb_color_change(1, sertrf.device.last_color);
rgb_color_change(1, RGB_COLOR_ORANGE);
break;
case PROTOCOL_STATUS_NO_DATA:
rgb_color_change(1, RGB_COLOR_RAD);
break;
case PROTOCOL_STATUS_TYPE_IDLE:
rgb_color_change(1, RGB_COLOR_RAD);
break;
case PROTOCOL_STATUS_ANALYSIS_ERROR:
rgb_color_change(1, RGB_COLOR_RAD);
break;
case PROTOCOL_STATUS_IN_OTA:
rgb_color_change(1, RGB_COLOR_BLUE);
default:
break;
}
end_time = os_get_sys_time();
}
}
os_thread_sleep(100);
}
}
void data_handle_thread(void* arg)
{
while(true)
{
switch(sertrf.mode_status.task_state)
{
case DATA_HANDLE_OTA_DATA:
{
size_t data_size = rb_size(&sertrf.data_handle_buffer);
if(data_size > 1024)
{
uint8_t data[data_size];
rb_get_bulk(&sertrf.data_handle_buffer, data, data_size);
if(otau_write(&sertrf.otau, data, data_size))
{
SYS_LOG_DBG("stmisp write error");
}
else
{
SYS_LOG_DBG("stmisp write ok");
}
}
}
break;
case DATA_HANDLE_OTA_DATA_END:
{
size_t data_size = rb_size(&sertrf.data_handle_buffer);
if(data_size > 0)
{
uint8_t data[data_size];
rb_get_bulk(&sertrf.data_handle_buffer, data, data_size);
if(otau_write(&sertrf.otau, data, data_size))
{
SYS_LOG_DBG("stmisp write error");
}
else
{
SYS_LOG_DBG("stmisp write ok");
sertrf.mode_status.task_state = DATA_HANDLE_IDLE;
}
}
}
break;
case DATA_HANDLE_ISP_DATA:
{
size_t data_size = rb_size(&sertrf.data_handle_buffer);
if(data_size > 0)
{
uint8_t data[data_size];
rb_get_bulk(&sertrf.data_handle_buffer, data, data_size);
uint32_t addr = sertrf.fc_address + sertrf.stmisp_device.adder_offset;
if(cmd_write_memory(&sertrf.stmisp_device, addr, data, data_size, false))
{
resend_send_cmd(&sertrf.resend_device, RESEND_CMD_ACK, 0);
sertrf.stmisp_device.adder_offset += data_size;
SYS_LOG_INF("stmisp write ok %d %d\n",data_size, sertrf.stmisp_device.adder_offset);
}
else
{
sertrf.stmisp_device.adder_offset = 0;
sertrf.mode_status.task_state = DATA_HANDLE_IDLE;
SYS_LOG_DBG("stmisp write error");
}
}
}
break;
case DATA_HANDLE_ISP_DATA_END:
{
size_t data_size = rb_size(&sertrf.data_handle_buffer);
if(data_size > 0)
{
uint8_t data[data_size];
rb_get_bulk(&sertrf.data_handle_buffer, data, data_size);
uint32_t addr = sertrf.fc_address + sertrf.stmisp_device.adder_offset;
if(cmd_write_memory(&sertrf.stmisp_device, addr, data, data_size, true))
{
sertrf.stmisp_device.adder_offset = 0;
sertrf.mode_status.task_state = DATA_HANDLE_IDLE;
}
else
{
SYS_LOG_DBG("stmisp write end error");
}
}
else
{
sertrf.stmisp_device.adder_offset = 0;
sertrf.mode_status.task_state = DATA_HANDLE_IDLE;
}
}
break;
default:
break;
}
os_thread_sleep(1);
}
}
void pc_link_rgb_color(device_t* device)
{
static uint8_t last_connect = 255, last_wifi_mode = 0;
uint8_t new_color = 0;
if(device->connect_pc != last_connect || last_wifi_mode != device->init_device.wifi_mode)
{
switch (device->connect_pc)
{
case DISCONNECT:
{
if(device->init_device.wifi_mode == WIFI_NETIF_MODE_AP)
new_color = NO_CONNECT_COLOR_BLE_AP;
else if(device->init_device.wifi_mode == WIFI_NETIF_MODE_STA)
new_color = NO_CONNECT_COLOR_BLE_STA;
else if(device->init_device.wifi_mode == RC_OFF_NONE)
new_color = RF_OFF_COLOR;
break;
}
case CONNECT_WIFI_TCP:
{
if(device->init_device.wifi_mode == WIFI_NETIF_MODE_AP)
new_color = WIFI_AP_COLOR;
else if(device->init_device.wifi_mode == WIFI_NETIF_MODE_STA)
new_color = WIFI_STA_COLOR;
else if(device->init_device.wifi_mode == RC_OFF_NONE)
new_color = RF_OFF_COLOR;
break;
}
case CONNECT_WIFI_UDP:
{
if(device->init_device.wifi_mode == WIFI_NETIF_MODE_AP)
new_color = WIFI_AP_COLOR;
else
new_color = WIFI_STA_COLOR;
break;
}
case CONNECT_BLE:
{
new_color = BLE_COLOR;
}
break;
case CONNECT_RF_OFF:
{
new_color = RF_OFF_COLOR;
}
break;
}
if(device->last_color != new_color)
rgb_color_change(0,new_color);
device->last_color = new_color;
last_connect = device->connect_pc;
last_wifi_mode = device->init_device.wifi_mode;
if(device->connect_pc == DISCONNECT)
{
rgb_update_cyle(0,50);
}
else if(device->connect_pc){
rgb_update_cyle(0,888);
}else{
rgb_update_cyle(0,500);
}
}
}
int resend_send(void* data, uint16_t len, int timeout)
{
return app_device_write(&sertrf.device, data, len);
}
int resend_recv(void* data, uint16_t len, int timeout)
{
int ret = 0;
if (xSemaphoreTake(sertrf.resend_read_mutex, portMAX_DELAY) == pdTRUE)
{
ret = app_device_read(&sertrf.device, data, len,timeout);
xSemaphoreGive(sertrf.resend_read_mutex);
}
return ret;
}
int resend_get_length(void)
{
return app_device_get_rx_length(&sertrf.device);
}
void resend_user_parse(void *resend_device)
{
resend_device_t* resend_parse = (resend_device_t*)resend_device;
switch(resend_parse->rx_frame.cmd)
{
case RESEND_CMD_SET_PARAM:
// 减6的目的是因为华哥没对MAC进行处理所以也不返回
if(sizeof(sertrf_stauct_t) - 6 != resend_parse->rx_frame.len)
{
SYS_LOG_DBG("RESEND_CMD_SET_PARAM len error\r\n");
}
sertrf_stauct_t* sertrf_stauct = (sertrf_stauct_t*)resend_parse->rx_frame.payload;
app_cfg_set_device_name_ble(sertrf_stauct->ble_name, strlen(sertrf_stauct->ble_name));
app_cfg_set_wifi_ap_ssid(sertrf_stauct->wifi_ap_ssid);
app_cfg_set_wifi_ap_password(sertrf_stauct->wifi_ap_password);
app_cfg_set_wifi_sta_ssid(sertrf_stauct->wifi_sta_ssid);
app_cfg_set_wifi_sta_password(sertrf_stauct->wifi_sta_password);
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
os_thread_sleep(1000);
esp_restart();
break;
case RESEND_CMD_OTA_GET_PARAM:
{
if(sizeof(ota_parm_t) != resend_parse->rx_frame.len)
{
SYS_LOG_DBG("RESEND_CMD_OTA_GET_PARAM len error\r\n");
}
ota_parm_t* ota_parm = (ota_parm_t*)resend_parse->rx_frame.payload;
SYS_LOG_DBG("RESEND_CMD_OTA_GET_PARAM %d\n", ota_parm->ota_file_size);
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
}
break;
case RESEND_CMD_OTA_START:
{
//设置协议状态,为了后续灯颜色变化
protocol_set_message_status(MESSAGE_OTA);
// if(!sertrf.resend_device.status.resend_flag)
//初始化ota会占用大量系统资源需要先把飞控获取数据关闭不然会导致栈溢出
sb_data_port_stop(sertrf.device.embedded_device);
otau_init(&sertrf.otau);
sertrf.mode_status.task_state = DATA_HANDLE_OTA_DATA;
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
}
break;
case RESEND_CMD_OTA_DATA:
{
protocol_set_message_status(MESSAGE_OTA);
// 使用环形buff
if(rb_size(&sertrf.data_handle_buffer) + sertrf.resend_device.rx_frame.len <= DATA_HANDLE_BUFFER_SIZE)
{
rb_put_bulk(&sertrf.data_handle_buffer, sertrf.resend_device.rx_frame.payload, sertrf.resend_device.rx_frame.len);
}
else
{
SYS_LOG_DBG("RESEND_CMD_OTA_DATA buffer full");
}
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
}
break;
case RESEND_CMD_OTA_END:
{
sertrf.mode_status.task_state = DATA_HANDLE_OTA_DATA_END;
while (sertrf.mode_status.task_state != DATA_HANDLE_IDLE){
os_thread_sleep(10);}
otau_end(&sertrf.otau);
protocol_set_message_status(MESSAGE_IDLE);
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
os_thread_sleep(2);
esp_restart();
}
break;
case RESEND_CMD_FC_ISP_GET_PARAM:
if(sizeof(stmisp_parm_t) != resend_parse->rx_frame.len)
{
SYS_LOG_DBG("RESEND_CMD_FC_ISP_GET_PARAM len error\r\n");
}
stmisp_parm_t* stmisp_parm = (stmisp_parm_t*)resend_parse->rx_frame.payload;
SYS_LOG_DBG("RESEND_CMD_FC_ISP_GET_PARAM %d\n", stmisp_parm->stmisp_file_size);
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
break;
case RESEND_CMD_FC_ISP_START:
/*关闭其他线程中相同串口的使用并复位飞控使其进入isp烧录模式串口切换为偶校验模式
使用sync与isp确定通讯波特率并建立联系 解除其写保护 并重新sync建立连接后擦除全部区域内存*/
//关闭其他线程中相同串口的使用
sertrf.stmisp_device.flag = 1;
// 修改灯珠颜色
protocol_set_message_status(MESSAGE_FC_ISP);
// 重启飞控并使其进入isp烧录模式 需要在能够识别飞控的情况下才需要重启
// if(sertrf.fc_protocol_status != PROTOCOL_STATUS_TYPE_IDLE && sertrf.fc_protocol_status != PROTOCOL_STATUS_NO_DATA)
fc_reboot();
boot_set_2(0);
os_thread_sleep(1000);
//串口切换为偶校验模式,并清除缓存
uart_set_parity_switch(sertrf.device.embedded_device, 0x02);
os_thread_sleep(100);
// 与isp确定通讯波特率并建立联系
if(!send_sync(&sertrf.stmisp_device, 5))
{
SYS_LOG_DBG("stmisp: sync error\n");
// app_send_error_code(SERTRF_ERROR_FC_ISP_SYNC);
break;
}
else
SYS_LOG_DBG("stmisp: sync ok\n");
os_thread_sleep(100);
// 解除写保护
if(!cmd_write_unprotect(&sertrf.stmisp_device))
SYS_LOG_DBG("stmisp: write unprotect error\n");
else
SYS_LOG_DBG("stmisp: write unprotect ok\n");
os_thread_sleep(100);
if(!send_sync(&sertrf.stmisp_device, 5))
SYS_LOG_DBG("stmisp: sync error\n");
else
SYS_LOG_DBG("stmisp: sync ok\n");
os_thread_sleep(100);
boot_set_high_z_2();
// 全盘擦除
if(!cmd_extended_erase_mass(&sertrf.stmisp_device))
SYS_LOG_DBG("stmisp: erase mass error\n");
else
SYS_LOG_DBG("stmisp: erase mass ok\n");
os_thread_sleep(10);
SYS_LOG_DBG("stmisp: isp start\n");
sertrf.mode_status.task_state = DATA_HANDLE_ISP_DATA;
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
break;
case RESEND_CMD_FC_ISP_DATA:
protocol_set_message_status(MESSAGE_FC_ISP);
// 使用环形buff
if(rb_size(&sertrf.data_handle_buffer) + sertrf.resend_device.rx_frame.len <= DATA_HANDLE_BUFFER_SIZE)
{
rb_put_bulk(&sertrf.data_handle_buffer, sertrf.resend_device.rx_frame.payload, sertrf.resend_device.rx_frame.len);
}
else
{
SYS_LOG_DBG("RESEND_CMD_FC_ISP_DATA buffer full");
}
// resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
break;
case RESEND_CMD_FC_ISP_END:
// 告诉数据处理线程ISP烧录数据传输完成
sertrf.mode_status.task_state = DATA_HANDLE_ISP_DATA_END;
// 等待数据处理线程写入完成
SYS_LOG_INF("RESEND_CMD_FC_ISP_END1");
while(sertrf.mode_status.task_state != DATA_HANDLE_IDLE){
os_thread_sleep(10);}
// ISP下跳转到应用层运行地址
if(cmd_go(&sertrf.stmisp_device, sertrf.fc_address))
{
SYS_LOG_DBG("stmisp: go ok\n");
}
else
{
SYS_LOG_DBG("stmisp: go error\n");
}
//开启其他线程中相同串口的使用
sertrf.stmisp_device.flag = 0;
// 将串口切换为无校验模式
uart_set_parity_switch(sertrf.device.embedded_device, 0x00);
SYS_LOG_INF("RESEND_CMD_FC_ISP_END2");
protocol_set_message_status(MESSAGE_IDLE);
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
esp_restart();
break;
default:
break;
}
}
void Examples_run(void)
{
// // //关闭其他线程中相同串口的使用
sertrf.stmisp_device.flag = 1;
// // // 重启飞控并使其进入isp烧录模式
fc_reboot();
boot_set(0);
os_thread_sleep(500);
uart_set_parity_switch(sertrf.device.embedded_device, 0x02);
os_thread_sleep(500);
// 与isp确定通讯波特率并建立联系
if(!send_sync(&sertrf.stmisp_device, 5))
SYS_LOG_DBG("stmisp: sync error\n");
else
SYS_LOG_DBG("stmisp: sync ok\n");
os_thread_sleep(100);
// 解除写保护
if(!cmd_write_unprotect(&sertrf.stmisp_device))
SYS_LOG_DBG("stmisp: write unprotect error\n");
else
SYS_LOG_DBG("stmisp: write unprotect ok\n");
os_thread_sleep(100);
if(!send_sync(&sertrf.stmisp_device, 5))
SYS_LOG_DBG("stmisp: sync error\n");
else
SYS_LOG_DBG("stmisp: sync ok\n");
os_thread_sleep(100);
boot_set_high_z();
// 全盘擦除
if(!cmd_extended_erase_mass(&sertrf.stmisp_device))
SYS_LOG_DBG("stmisp: erase mass error\n");
else
SYS_LOG_DBG("stmisp: erase mass ok\n");
os_thread_sleep(10);
SYS_LOG_DBG("stmisp: isp start\n");
}
int stmisp_send(void* data, uint16_t len, int timeout)
{
return embedded_device_write(&sertrf.device, data, len);
}
int stmisp_recv(void* data, uint16_t len, int timeout)
{
uint32_t time_start = os_get_sys_time();
int size = 0;
while(os_get_sys_time() - time_start < timeout)
{
size = embedded_device_read(&sertrf.device, data, len, 0);
if(size > 0)
return size;
os_thread_sleep(1);
}
return size;
}
int stmisp_get_length(void)
{
return embedded_device_get_rx_length(&sertrf.device);
}
int app_send_error_code(uint8_t error_code)
{
sertrf.mode_status.sertrf_error_code = error_code;
return resend_send_data(&sertrf.resend_device, RESEND_CMD_ERROR_CODE, &sertrf.mode_status.sertrf_error_code, sizeof(sertrf_mode_status_t), 1000);
}