#include "soft_gs.h" #include "common.h" #include "drv_usart.h" #include "gcs_vklink_v30.h" #include "params.h" #include "rkfifo.h" #include "soft_time.h" #include "vklink.h" struct GCS_Link gcs_link = { .link_protocal_type = GCS_LINK_PROTOCAL_TYPE_VKLINK, /* 默认使用 VKLINK 协议 */ .vklink_protocal_version = 300, /* 默认 vklink v300 版本 */ .link_status = COMP_NOEXIST, /* 默认状态是未连接地面站 */ }; /** * @brief 设置地面站 vklink 的协议版本 * * @param version */ void gs_set_vklink_protocal_version(struct GCS_Link *gcs, uint16_t version) { switch (version) { case 300: case 400: gcs->vklink_protocal_version = version; break; default: break; } } /** * @brief 电台串口初始化 * * @param gs_bps 串口波特率 */ int gcs_init(struct GCS_Link *gcs, unsigned int gs_bps) { int ret = 0; gcs_link.uart = uart_find("uart1"); if (gcs_link.uart) { gcs_link.uart->ops->init(gs_bps); } else { ret = -1; } return ret; } /** * @brief 地面站失联检测 * */ void _gs_uart_link_status_check(struct GCS_Link *pgcs) { /* 检测间隔 0.5 */ const uint32_t check_dt_us = 500000; /* 失联时间 */ const uint16_t linklost_time_s = (uint16_t)conf_par.lostlink_time; if (micros() - pgcs->last_check_time_us > check_dt_us) { pgcs->last_check_time_us = micros(); if (pgcs->link_status == COMP_NORMAL) { pgcs->link_lost_time_us += check_dt_us; if (pgcs->link_lost_time_us > linklost_time_s * 1000000 && linklost_time_s > 0) { pgcs->link_status = COMP_LOST; } } } } /** * @brief 获取地面站连接状态 * * @return comp_status */ comp_status gs_get_link_status(struct GCS_Link *pgcs) { return pgcs->link_status; } /** * @brief 地面站解析数据循环 * */ void gs_receive_msg_poll(struct GCS_Link *pgcs) { uint8_t c; /* 如果 rx fifo 中有数据,则读出数据进行解析 */ while (pgcs->uart->ops->read(&c, 1) == 1) { switch (pgcs->link_protocal_type) { case GCS_LINK_PROTOCAL_TYPE_VKLINK: default: if (VKlink_ParseChar(&pgcs->vklink_rx_msg, c) == 1) { /* 对接收消息进行解析 */ switch (pgcs->vklink_protocal_version) { /* vklink v30 协议 */ case 300: gcs_vklink_v300_rx_decode(pgcs); break; /* vklink v40 协议 */ case 400: // gcs_vklink_v400_rx_decode(&pgcs->vklink_rx_msg); break; default: break; } } break; } } } /** * @brief 发送数据到地面站,轮询调用 * */ void gs_send_msg_poll(struct GCS_Link *pgcs) { /* 检测地面站失联 */ _gs_uart_link_status_check(pgcs); /* 发消息给地面站 */ if (pgcs->link_protocal_type == GCS_LINK_PROTOCAL_TYPE_VKLINK) { switch (pgcs->vklink_protocal_version) { case 300: gcs_vklink_v300_tx_poll(pgcs); break; case 400: break; default: break; } } } void gs_tx_vklink_msg(struct GCS_Link *pgcs, const VKlink_Msg_Type *msg) { uint8_t *tx_buff = pgcs->msg_pack_buffer; uint32_t tx_len = VKlink_MsgTxFormat(msg, tx_buff); pgcs->uart->ops->write(tx_buff, tx_len); } void gs_send_pos_msg(struct GCS_Link *pgcs, uint32_t pos_num) { if (gcs_link.link_protocal_type == GCS_LINK_PROTOCAL_TYPE_VKLINK) { switch (gcs_link.vklink_protocal_version) { case 300: gcs_vklink_v300_set_tx_msg(pgcs, GCS_VKLINK_V300_POS_ID, (void *)pos_num); break; case 400: // gcs_vklink_v400_set_tx_msg(GCS_VKLINK_V400_POS_ID, 0); break; default: break; } } } void gs_send_ack_msg(struct GCS_Link *pgcs, void *arg) { if (gcs_link.link_protocal_type == GCS_LINK_PROTOCAL_TYPE_VKLINK) { switch (gcs_link.vklink_protocal_version) { case 300: gcs_vklink_v300_set_tx_msg(pgcs, GCS_VKLINK_V300_ACK_ID, arg); break; case 400: // gcs_vklink_v400_set_tx_msg(GCS_VKLINK_V400_ACK_ID, arg); break; default: break; } } } void gs_send_payload_msg(struct GCS_Link *pgcs, const void *data, uint32_t len) { if (gcs_link.link_protocal_type == GCS_LINK_PROTOCAL_TYPE_VKLINK) { switch (gcs_link.vklink_protocal_version) { case 300: { struct gcs_transparent_transmission_arg tt_arg; tt_arg.data = data; tt_arg.data_len = len; gcs_vklink_v300_set_tx_msg(pgcs, GCS_VKLINK_V300_PORT_UART4_DATA, &tt_arg); } break; case 400: // gcs_vklink_v400_set_tx_msg(GCS_VKLINK_V400_PAYLOAD_DATA_ID, 0); break; default: break; } } }