You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
7.3 KiB
197 lines
7.3 KiB
#include "project_configs.h"
|
|
#include "project_dep.h"
|
|
//
|
|
#include "base_service/config_service.h"
|
|
#include "cmsis_os.h"
|
|
#include "reg_manager.h"
|
|
|
|
#define TAG "extern_if_service"
|
|
|
|
typedef struct {
|
|
zaf_packet_header_t *rxpacket;
|
|
zaf_buf_t receipt;
|
|
bool resetBoard;
|
|
} extern_if_service_context_t;
|
|
|
|
static udp_t m_udp_cmd_server; //
|
|
osThreadId m_cmd_uart_receiver_thread; //
|
|
|
|
extern DMA_HandleTypeDef COMMAND_UART_DMA_HANDLER;
|
|
extern UART_HandleTypeDef COMMAND_UART;
|
|
|
|
// static udp_broadcast_handler_t m_udp_camera_sync_sender; //
|
|
|
|
static struct sockaddr_in m_last_rxpacket_client;
|
|
static bool m_last_rxpacket_client_valid = false;
|
|
static uint8_t txbuf[2048];
|
|
|
|
/*******************************************************************************
|
|
* 包构造 *
|
|
*******************************************************************************/
|
|
|
|
static void create_receipt(extern_if_service_context_t *context, uint32_t ecode, uint32_t *data, size_t ndata) {
|
|
zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txbuf;
|
|
uint32_t txpacklen = sizeof(zaf_packet_header_t) + (ndata + 1) * sizeof(uint32_t) + 1 /*checksum*/ + 2 /*tail*/;
|
|
|
|
txpacket->packet_header = PACKET_HEADER;
|
|
txpacket->packet_type = kzaf_packet_type_receipt;
|
|
txpacket->index = context->rxpacket->index;
|
|
txpacket->cmd = context->rxpacket->cmd;
|
|
txpacket->ndata = ndata + 1;
|
|
txpacket->data[0] = ecode;
|
|
memcpy(&txpacket->data[1], data, ndata * sizeof(uint32_t));
|
|
|
|
uint8_t checksum = 0;
|
|
for (int i = 2; i < txpacklen - 3; i++) {
|
|
checksum += txbuf[i];
|
|
}
|
|
txbuf[txpacklen - 3] = checksum;
|
|
txbuf[txpacklen - 2] = PACKET_TAIL & 0xFF;
|
|
txbuf[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF;
|
|
|
|
zaf_buf_t buf;
|
|
buf.data = txbuf;
|
|
buf.len = txpacklen;
|
|
|
|
context->receipt = buf;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 接收消息处理 *
|
|
*******************************************************************************/
|
|
|
|
static bool process_rx_packet(extern_if_service_context_t *cx, uint8_t *data, uint16_t len) {
|
|
// ZLOGI(TAG, "process_rx_packet %d:", len);
|
|
// for (int i = 0; i < len; i++) {
|
|
// printf("%02x ", data[i]);
|
|
// }
|
|
// printf("\n");
|
|
zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)data;
|
|
cx->rxpacket = rxpacket;
|
|
|
|
if (rxpacket->packet_type != kzaf_packet_type_cmd) return false;
|
|
|
|
/*******************************************************************************
|
|
* 寄存器读 *
|
|
*******************************************************************************/
|
|
if (rxpacket->cmd == kzaf_cmd_reg_read) {
|
|
uint32_t readbak_regval = reg_manager_read_reg(rxpacket->data[0]); // regdata
|
|
create_receipt(cx, 0, &readbak_regval, 1);
|
|
}
|
|
/*******************************************************************************
|
|
* 寄存器写 *
|
|
*******************************************************************************/
|
|
else if (rxpacket->cmd == kzaf_cmd_reg_write) {
|
|
uint32_t readbak_regval = reg_manager_write_reg(rxpacket->data[0], rxpacket->data[1]);
|
|
create_receipt(cx, 0, &readbak_regval, 1);
|
|
}
|
|
/*******************************************************************************
|
|
* 多寄存器读 *
|
|
*******************************************************************************/
|
|
else if (rxpacket->cmd == kzaf_cmd_reg_read_regs) {
|
|
static uint32_t regcache[MAX_REG_NUM + 1];
|
|
uint32_t len = MAX_REG_NUM;
|
|
|
|
reg_manager_read_regs(rxpacket->data[0], rxpacket->data[1], ®cache[0], &len);
|
|
create_receipt(cx, 0, regcache, len);
|
|
}
|
|
|
|
else if (rxpacket->cmd == kzaf_cmd_reg_read_regs) {
|
|
static uint32_t regcache[MAX_REG_NUM + 1];
|
|
uint32_t len = MAX_REG_NUM;
|
|
|
|
reg_manager_read_regs(rxpacket->data[0], rxpacket->data[1], ®cache[0], &len);
|
|
create_receipt(cx, 0, regcache, len);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 产生新的MAC *
|
|
*******************************************************************************/
|
|
else if (rxpacket->cmd == kzaf_cmd_generator_new_mac) {
|
|
config_generate_random_mac();
|
|
config_flush();
|
|
create_receipt(cx, 0, NULL, 0);
|
|
} else if (rxpacket->cmd == kzaf_cmd_factory_reset) {
|
|
config_factory_reset();
|
|
cx->resetBoard = true;
|
|
create_receipt(cx, 0, NULL, 0);
|
|
} else if (rxpacket->cmd == kzaf_cmd_reboot) {
|
|
cx->resetBoard = true;
|
|
create_receipt(cx, 0, NULL, 0);
|
|
} else if (rxpacket->cmd == kzaf_cmd_storage_cfg) {
|
|
config_flush();
|
|
create_receipt(cx, 0, NULL, 0);
|
|
} else if (rxpacket->cmd == kzaf_cmd_ping) {
|
|
create_receipt(cx, 0, NULL, 0);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 框架 *
|
|
*******************************************************************************/
|
|
/**
|
|
* @brief UDP消息接收消息处理
|
|
*
|
|
* @param server
|
|
* @param client
|
|
* @param data
|
|
* @param len
|
|
*/
|
|
static void udp_on_packet(udp_t *server, struct sockaddr_in *client, uint8_t *data, uint16_t len) {
|
|
extern_if_service_context_t cx = {0};
|
|
bool ret = process_rx_packet(&cx, data, len);
|
|
if (ret) {
|
|
zaf_udp_send_message2(server, client, (const char *)cx.receipt.data, cx.receipt.len);
|
|
|
|
m_last_rxpacket_client_valid = true;
|
|
memcpy(&m_last_rxpacket_client, client, sizeof(struct sockaddr_in));
|
|
|
|
osDelay(5);
|
|
if (cx.resetBoard) NVIC_SystemReset();
|
|
}
|
|
}
|
|
|
|
static void uart_on_packet(uint8_t *packet, uint32_t len) {
|
|
extern_if_service_context_t cx = {0};
|
|
bool ret = process_rx_packet(&cx, packet, len);
|
|
if (ret) {
|
|
HAL_UART_Transmit(&COMMAND_UART, (uint8_t *)cx.receipt.data, cx.receipt.len, 1000);
|
|
osDelay(2);
|
|
if (cx.resetBoard) NVIC_SystemReset();
|
|
}
|
|
}
|
|
|
|
static uint8_t g_uart_rx_buf[128];
|
|
static uint32_t g_uart_rx_buf_index = 0;
|
|
bool uart_is_rxing(UART_HandleTypeDef *huart) { //
|
|
uint32_t uartstate = HAL_UART_GetState(huart);
|
|
if (uartstate & 0x02) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { g_uart_rx_buf_index = Size; }
|
|
|
|
static void uart_receiver_thread(const void *) {
|
|
while (1) {
|
|
if (!uart_is_rxing(&COMMAND_UART)) {
|
|
if (g_uart_rx_buf_index != 0) {
|
|
uart_on_packet(g_uart_rx_buf, g_uart_rx_buf_index);
|
|
}
|
|
g_uart_rx_buf_index = 0;
|
|
memset(g_uart_rx_buf, 0, sizeof(g_uart_rx_buf));
|
|
HAL_UARTEx_ReceiveToIdle_DMA(&COMMAND_UART, g_uart_rx_buf, sizeof(g_uart_rx_buf) - 1);
|
|
}
|
|
osDelay(1);
|
|
}
|
|
}
|
|
|
|
void extern_if_service_init() { //
|
|
ZASSERT(zaf_udp_init(&m_udp_cmd_server, "extern_if_udp", ZAF_SERVICE_DEVICE_PORT, udp_on_packet, 1024, NULL));
|
|
|
|
osThreadDef(cmdUartReceiverThread, uart_receiver_thread, osPriorityNormal, 0, 512);
|
|
m_cmd_uart_receiver_thread = osThreadCreate(osThread(cmdUartReceiverThread), NULL);
|
|
ZASSERT(m_cmd_uart_receiver_thread != NULL);
|
|
}
|