|
|
#include "remote_controler.hpp"
#include "app_protocols/ble_through/ble_proto_utils.h"
using namespace iflytop;
#define TAG "RemoteControler"
#define MODULE_DEBUG 0
#define UART_RX_OVERTIME 200
#define CMD_OVERTIME 500
static ZQueue<RemoteControlerReportPacket_t> ackQueue; static ZQueue<RemoteControlerReportPacket_t> eventQueue; static ZThread usartRxThread; static ZThread eventProcessThread; static bool m_isWaitingForAck; static UART_HandleTypeDef* m_uart;
static const char* zhex2str(uint8_t* data, size_t len) { static char buf[256]; memset(buf, 0, sizeof(buf)); for (size_t i = 0; i < len; i++) { sprintf(buf + i * 2, "%02X", data[i]); } return buf; }
void RemoteControlerUpper::initialize() { ackQueue.initialize(1, sizeof(RemoteControlerReportPacket_t)); eventQueue.initialize(3, sizeof(RemoteControlerReportPacket_t)); usartRxThread.init("usartRxThread", 1024); eventProcessThread.init("eventProcessThread", 1024); ZASSERT(AppHardware::ins()->remoteContolerUart);
m_uart = AppHardware::ins()->remoteContolerUart; m_cmdlock.init(); zble_proto_utils_init(kzble_master);
// m_cmdlock
} void RemoteControlerUpper::regOnReport(on_report_cb_t on_report) { m_cb[m_ncb] = on_report; m_ncb++; }
bool RemoteControlerUpper::isConnected() { return AppHardware::ins()->BLE_CONNECTED_STATE.getState(); } void RemoteControlerUpper::callOnReport(uint8_t* rx, int32_t len) { for (int32_t i = 0; i < m_ncb; i++) { m_cb[i](rx, len); } }
void RemoteControlerUpper::startSchedule() { usartRxThread.start([this]() { static uint8_t rxbuf[128]; m_uart->USR_UartITRxing = 1; m_uart->USR_UartITRxBuf = rxbuf; m_uart->USR_UartITRxBufSize = 128; m_uart->USR_UartITRxOff = 0; HAL_UART_Receive_IT(m_uart, &m_uart->USR_UartITRxBufCache, 1); while (1) { // static uint8_t processbuf[128];
static RemoteControlerReportPacket_t rxpacket; rxpacket.datalen = 0; zble_proto_packet_t* rxblepacket = (zble_proto_packet_t*)m_uart->USR_UartITRxBuf; uint8_t* rxblepacketu8 = (uint8_t*)m_uart->USR_UartITRxBuf; int curPacketlen = rxblepacket->packetlen;
if (m_uart->USR_UartITRxOff != 0) { if ((m_uart->USR_UartITRxOff >= curPacketlen) && //
rxblepacket->h1 == 0xAA && //
rxblepacket->h2 == 0xBB && //
rxblepacketu8[curPacketlen - 1] == 0xCC) { //ZLOGI(TAG, "uuuuuuuuuuuuuuuuuuuuuuuuuu");
vPortEnterCritical(); // copy data
memcpy(rxpacket.data, rxblepacketu8, curPacketlen); rxpacket.datalen = curPacketlen; // move data
memmove(m_uart->USR_UartITRxBuf, m_uart->USR_UartITRxBuf + curPacketlen, curPacketlen); m_uart->USR_UartITRxOff = m_uart->USR_UartITRxOff - curPacketlen; vPortExitCritical(); } else { if (zos_haspassedms(m_uart->USR_UartITLastRxTicket) > UART_RX_OVERTIME) { // drop data
ZLOGI(TAG, "drop data %d %s", m_uart->USR_UartITRxOff, zhex2str(m_uart->USR_UartITRxBuf, m_uart->USR_UartITRxOff));
vPortEnterCritical(); m_uart->USR_UartITRxOff = 0; memset(rxbuf, 0, 128); vPortExitCritical(); } } } if (rxpacket.datalen != 0) { preProcessrxpacket(&rxpacket); } // ZLOGI(TAG,".");
osDelay(2); } });
/**
* @brief �����ϱ���Ϣ */ eventProcessThread.start([this]() { while (1) { static RemoteControlerReportPacket_t packet; bool suc = eventQueue.receive(&packet, 10); if (suc) { processRxEventPacket(&packet); } osDelay(1); } }); }
void RemoteControlerUpper::preProcessrxpacket(RemoteControlerReportPacket_t* packet) { #if MODULE_DEBUG
ZLOGI(TAG, "[rx-thread] : rx :%s(%d)", zhex2str(packet->data, packet->datalen), packet->datalen); #endif
zble_proto_packet_t* p_packet = (zble_proto_packet_t*)packet->data; if (!ble_through_proto_check_packet(p_packet)) { ZLOGI(TAG, "rx invalid packet %s", zhex2str(packet->data, packet->datalen)); return; }
bool suc = true; if (p_packet->frameType == kzble_proto_cmd) { // suc = ackQueue.send(packet, 10);
} else if (p_packet->frameType == kzble_proto_report) { suc = eventQueue.send(packet, 10); } else if (p_packet->frameType == kzble_proto_error_receipt || p_packet->frameType == kzble_proto_cmd_receipt) { if (m_isWaitingForAck) { suc = ackQueue.send(packet, 10); m_isWaitingForAck = false; } } if (!suc) { ZLOGI(TAG, "eventQueue send failed"); } }
void RemoteControlerUpper::processRxEventPacket(RemoteControlerReportPacket_t* packet) { #if MODULE_DEBUG
ZLOGI(TAG, "[process-thread] rx event : %s", zhex2str(packet->data, packet->datalen)); #endif
// if (m_on_report) {
// m_on_report(packet->data, packet->datalen);
// }
callOnReport(packet->data, packet->datalen); } bool RemoteControlerUpper::txcmd(uint8_t* data, uint32_t len) { /**
* @brief */ zlock_guard lg(m_cmdlock); ackQueue.clear(); m_isWaitingForAck = true; #if MODULE_DEBUG
ZLOGI(TAG, "txcmd : %s(%d)", zhex2str(data, len), len); #endif
// vPortEnterCritical();
HAL_UART_Transmit(m_uart, data, len, 100); // vPortExitCritical();
// HAL_UART_Transmit_DMA(m_uart, data, len);
bool suc = ackQueue.receive(&ackcache, CMD_OVERTIME); if (!suc) { ZLOGI(TAG, "txcmd : %s(%d) fail", zhex2str(data, len), len); // HAL_UART_DMAStop(m_uart);
return false; } #if MODULE_DEBUG
ZLOGI(TAG, "ack : %s", zhex2str(ackcache.data, ackcache.datalen)); #endif
// HAL_UART_DMAStop(m_uart);
return true; }
/***********************************************************************************************************************
* CMD * ***********************************************************************************************************************/
bool RemoteControlerUpper::resetMasterBoard() { zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_reset, m_index++, NULL, 0); zble_proto_utils_set_packet_to(txpacket, kzble_master); bool suc = txcmd(txbuf, txpacket->packetlen); return suc; } bool RemoteControlerUpper::resetClientBoard() { zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_reset, m_index++, NULL, 0); zble_proto_utils_set_packet_to(txpacket, kzble_slave); bool suc = txcmd(txbuf, txpacket->packetlen); return suc; }
bool RemoteControlerUpper::readMasterBoardVersion(zble_read_version_t* version) { zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_read_version, m_index++, NULL, 0); zble_proto_utils_set_packet_to(txpacket, kzble_master); bool suc = txcmd(txbuf, txpacket->packetlen); if (suc) *version = *(zble_read_version_t*)(rxpacket->data); return suc; } bool RemoteControlerUpper::readClientBoardVersion(zble_read_version_t* version) { zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_read_version, m_index++, NULL, 0); zble_proto_utils_set_packet_to(txpacket, kzble_slave); bool suc = txcmd(txbuf, txpacket->packetlen); if (suc) *version = *(zble_read_version_t*)(rxpacket->data); return suc; }
bool RemoteControlerUpper::clearMasterResetFlag() { zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_clear_reset_flag, m_index++, NULL, 0); zble_proto_utils_set_packet_to(txpacket, kzble_master); bool suc = txcmd(txbuf, txpacket->packetlen); return suc; } bool RemoteControlerUpper::clearSlaveResetFlag() { zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_clear_reset_flag, m_index++, NULL, 0); zble_proto_utils_set_packet_to(txpacket, kzble_slave); bool suc = txcmd(txbuf, txpacket->packetlen); return suc; }
bool RemoteControlerUpper::setMasterInDfuMode() { zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_set_in_dfu_mode, m_index++, NULL, 0); zble_proto_utils_set_packet_to(txpacket, kzble_master); bool suc = txcmd(txbuf, txpacket->packetlen); return suc; } bool RemoteControlerUpper::setSlaveInDfuMode() { zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_set_in_dfu_mode, m_index++, NULL, 0); zble_proto_utils_set_packet_to(txpacket, kzble_slave); bool suc = txcmd(txbuf, txpacket->packetlen); return suc; }
bool RemoteControlerUpper::startScan(const char* slaveName, bool autoConnect) { // typedef struct {
// uint8_t slaveName[20];
// uint8_t autoConnect;
// } zble_start_scan_t;
zble_start_scan_t scanparam = {0}; if (slaveName) strncpy((char*)scanparam.slaveName, slaveName, 20); scanparam.autoConnect = autoConnect;
zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_start_scan, m_index++, (uint8_t*)&scanparam, sizeof(scanparam)); zble_proto_utils_set_packet_to(txpacket, kzble_master); bool suc = txcmd(txbuf, txpacket->packetlen); return suc; } bool RemoteControlerUpper::stopScan() { zble_proto_utils_create_cmd_packet(txpacket, kzble_cmd_stop_scan, m_index++, NULL, 0); zble_proto_utils_set_packet_to(txpacket, kzble_master); bool suc = txcmd(txbuf, txpacket->packetlen); return suc; } /***********************************************************************************************************************
* APP * ***********************************************************************************************************************/ bool RemoteControlerUpper::setRemoterState(hand_acid_mode_t mode, bool state) { zble_proto_packet_t* packet = (zble_proto_packet_t*)txbuf; int32_t param[2] = {mode, state}; zble_proto_utils_create_cmd_packet_int32(packet, kzble_app_cmd_set_state, m_index++, param, 2); bool suc = txcmd(txbuf, packet->packetlen); return suc; }
|