|
|
#include "ui_controler.hpp"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
#include "tjc/tjc_constant.hpp"
#include "tjc_event_processer_mgr.hpp"
#include "ui_state_mgr.hpp"
//
using namespace iflytop; #define TAG "UIScheduler"
#define MODULE_DEBUG 0
#define UART_RX_OVERTIME 5
#define CMD_OVERTIME 100
static ZThread uart_rx_thread; static ZThread rx_processed_thread; static ZThread ui_block_work_thread;
static ZQueue<tjc_rx_packet_t> ackQueue; static ZQueue<tjc_rx_packet_t> eventQueue; static ZThread usartRxThread; static ZThread eventProcessThread; static bool m_isWaitingForAck; static UART_HandleTypeDef* tjcUart; static UIEvent event_cache;
/***********************************************************************************************************************
* UTILS * ***********************************************************************************************************************/ 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; }
namespace iflytop { __weak void UIControlerHock_PageInit() {} } // namespace iflytop
/***********************************************************************************************************************
* FUNC * ***********************************************************************************************************************/ void UIControler::doBlockWork(const char* blockmask, function<void()> fn) { ui_block_work_thread.start([fn, blockmask]() { UIPublicState::setLoadingState(true, blockmask); osDelay(10); fn(); UIPublicState::setLoadingState(false, ""); }); }
void UIControler::postInitialize() { ackQueue.initialize(5, sizeof(tjc_rx_packet_t)); eventQueue.initialize(5, sizeof(tjc_rx_packet_t)); usartRxThread.init("UI_RX", 512); eventProcessThread.init("UI_RX_PROCESS", 1024); ui_block_work_thread.init("UI_WORK", 1024); tjcUart = AppHardware::ins()->tjcUart; UIPublicState::initialize(); m_cmdlock.init(); sendcmd("rest"); osDelay(1000); sendcmd("page %d", pg_pStart); }
void UIControler::initialize() { //
startSchedule(); }
void UIControler::pageInitialize() { UIControlerHock_PageInit(); }
void UIControler::callUsrEventCb(UIEvent* event) { static AppEvent appEvent; appEvent.type = KAE_UIEvent; appEvent.setUIEvent(event);
AppEventBus::ins()->pushEventBlock("UIEvent", &appEvent); }
void UIControler::startSchedule() { usartRxThread.start([this]() { static uint8_t rxbuf[256]; tjcUart->USR_UartITRxing = 1; tjcUart->USR_UartITRxBuf = rxbuf; tjcUart->USR_UartITRxBufSize = 256; tjcUart->USR_UartITRxOff = 0;
HAL_UART_Receive_IT(tjcUart, &tjcUart->USR_UartITRxBufCache, 1); while (1) { static uint8_t processbuf[256]; int32_t rxsize = 0; if (tjcUart->USR_UartITRxOff != 0 && zos_haspassedms(tjcUart->USR_UartITLastRxTicket) > UART_RX_OVERTIME) { vPortEnterCritical(); if (tjcUart->USR_UartITRxOff != 0 && zos_haspassedms(tjcUart->USR_UartITLastRxTicket) > UART_RX_OVERTIME) { memcpy(processbuf, tjcUart->USR_UartITRxBuf, tjcUart->USR_UartITRxOff); rxsize = tjcUart->USR_UartITRxOff; tjcUart->USR_UartITRxOff = 0; } vPortExitCritical(); }
if (rxsize != 0) { processScreenRxPacket(processbuf, rxsize); } osDelay(1); } });
eventProcessThread.start([this]() { while (1) { static tjc_rx_packet_t packet; bool suc = eventQueue.receive(&packet, 10); if (suc) { memset(&event_cache, 0, sizeof(event_cache));
tjc_packet_type_t packetType = (tjc_packet_type_t)packet.data[0]; auto* processer = TJCEventProcesserMgr::findProcesser((tjc_packet_type_t)packetType); // ZLOGI(TAG, "[eventprocess-thread]: rx_event:%s(%d)", tjc::pt2str(packetType), packetType);
if (processer != nullptr) { processer->process(packet.data, packet.datalen, &event_cache); } else { event_cache.eventId = packet.data[0]; } // ZLOGI(TAG, "push event %s(%d) ", tjc::pt2str(event_cache.eventId), event_cache.eventId);
callUsrEventCb(&event_cache); } osDelay(1); } }); }
void UIControler::processScreenRxPacket(uint8_t* data, size_t len) { // �жϰ��Ƿ��Ϸ�
#if MODULE_DEBUG
ZLOGI(TAG, "[rx-thread] : rx :%s(%d)", zhex2str(data, len), len); #endif
if (!(data[len - 1] == 0xff && data[len - 2] == 0xff && data[len - 3] == 0xff)) { ZLOGI(TAG, "rx invalid packet %s", zhex2str(data, len)); return; } if (TJC_MAX_PACKET_SIZE < len) { ZLOGI(TAG, "rx invalid packet(tool long) %s", zhex2str(data, len)); return; }
uint8_t packetType = data[0];
static tjc_rx_packet_t packet; packet.datalen = len; memcpy(packet.data, data, len); if (kpt_ack == packetType) { if (m_isWaitingForAck) { bool suc = ackQueue.send(&packet, 10); if (!suc) { ZLOGI(TAG, "ackQueue send failed"); } m_isWaitingForAck = false; }
} else { bool suc = eventQueue.send(&packet, 10); if (!suc) { ZLOGI(TAG, "eventQueue send failed"); } } }
bool UIControler::readTxt(uint8_t pid, uint8_t cId, char* txt, int32_t txtbuflen) { zlock_guard lg(m_cmdlock);
startReceiveAck(); // sendcmd("com_stop");
sendcmd("printh AA"); sendcmd("prints p[%d].b[%d].txt,0", pid, cId); sendcmd("printh 00"); sendcmd("printh FF FF FF"); sendcmd("com_start");
bool suc = ackQueue.receive(&ackcache, CMD_OVERTIME); if (!suc) { ZLOGI(TAG, "readTxt failed"); return false; } int32_t cpysize = ackcache.datalen - 3; if (cpysize > txtbuflen) { cpysize = txtbuflen - 1; }
memcpy(txt, &ackcache.data[1], cpysize); return true; }
bool UIControler::readFiledAsInt(uint8_t pid, uint8_t bid, const char* filedName, int32_t* val) { for (int i = 0; i < 5; i++) { if (_readFiledAsInt(pid, bid, filedName, val)) { return true; } ZLOGW(TAG, "readFiledAsInt pid:%d bid:%d %s failed retry %d", pid, bid, filedName, i); osDelay(1000); } ZLOGE(TAG, "readFiledAsInt %s failed", filedName); return false; } bool UIControler::_readFiledAsInt(uint8_t pid, uint8_t bid, const char* filedName, int32_t* val) { zlock_guard lg(m_cmdlock);
startReceiveAck(); // sendcmd("com_stop");
sendcmd("printh AA"); sendcmd("prints p[%d].b[%d].%s,4", pid, bid, filedName); sendcmd("printh FF FF FF"); // sendcmd("com_start");
bool suc = ackQueue.receive(&ackcache, CMD_OVERTIME); if (!suc) { return false; }
uint8_t int32val[4] = {0}; memcpy(int32val, &ackcache.data[1], 4); *val = *(int32_t*)int32val; return true; }
bool UIControler::readInt(uint8_t pid, uint8_t bid, int32_t* val) { return readFiledAsInt(pid, bid, "val", val); }
bool UIControler::echo(uint8_t tx, uint8_t* rx) { zlock_guard lg(m_cmdlock);
startReceiveAck(); // sendcmd("com_stop");
sendcmd("printh AA"); sendcmd("printh %02X", tx); sendcmd("printh FF FF FF"); sendcmd("com_start");
bool suc = ackQueue.receive(&ackcache, CMD_OVERTIME); if (!suc) { ZLOGI(TAG, "readTxt failed"); return false; }
uint8_t int32val = 0; memcpy(&int32val, &ackcache.data[1], 1); *rx = int32val;
if (tx != int32val) { return false; }
return true; }
bool UIControler::setTxt(uint8_t pid, uint8_t bid, const char* txt, ...) { zlock_guard lg(m_cmdlock); va_list args; va_start(args, txt); setTxt(pid, bid, txt, args); va_end(args); return true; } bool UIControler::setTxt(uint8_t pid, uint8_t bid, const char* txt, va_list args) { zlock_guard lg(m_cmdlock); static char buf[256]; memset(buf, 0, sizeof(buf));
vsprintf(buf, txt, args); sendcmd("p[%d].b[%d].txt=\"%s\"", pid, bid, buf); return true; }
void UIControler::setPicturePicNum(uint8_t pid, uint8_t bid, uint8_t fromBid) { zlock_guard lg(m_cmdlock); sendcmd("p[%d].b[%d].pic=p[%d].b[%d].pic", pid, bid, pid, fromBid); } void UIControler::setButtonPicNum(uint8_t pid, uint8_t bid, uint8_t fromBid) { zlock_guard lg(m_cmdlock); sendcmd("p[%d].b[%d].pic=p[%d].b[%d].pic", pid, bid, pid, fromBid); sendcmd("p[%d].b[%d].pic2=p[%d].b[%d].pic2", pid, bid, pid, fromBid); }
void UIControler::setPicturePicNumFromGlobal(uint8_t pid, uint8_t bid, uint8_t fromPid, uint8_t fromBid) { zlock_guard lg(m_cmdlock); sendcmd("p[%d].b[%d].pic=p[%d].b[%d].pic", pid, bid, fromPid, fromBid); } void UIControler::setButtonPicNumFromGlobal(uint8_t pid, uint8_t bid, uint8_t fromPid, uint8_t fromBid) { zlock_guard lg(m_cmdlock); sendcmd("p[%d].b[%d].pic=p[%d].b[%d].pic", pid, bid, fromPid, fromBid); sendcmd("p[%d].b[%d].pic2=p[%d].b[%d].pic2", pid, bid, fromPid, fromBid); }
bool UIControler::setVal(uint8_t pid, uint8_t cid, int32_t val) { zlock_guard lg(m_cmdlock); sendcmd("p[%d].b[%d].val=%d", pid, cid, val); return true; } bool UIControler::vis(uint16_t buuid, int32_t val) { zlock_guard lg(m_cmdlock); sendcmd("vis %d,%d", buuid & 0xff, val); return true; }
void UIControler::setrtc(zdate_t* date) { zlock_guard lg(m_cmdlock); sendcmd("rtc0=%d", date->year); sendcmd("rtc1=%d", date->month); sendcmd("rtc2=%d", date->day); sendcmd("rtc3=%d", date->hours); sendcmd("rtc4=%d", date->minutes); sendcmd("rtc5=%d", date->seconds); }
void UIControler::popWin(UIPopWinType_t type, const char* info, function<void(bool)> onConfirm) { zlock_guard lg(m_cmdlock); UIPublicState::pushUIPopInfo(type, info, onConfirm); }
void UIControler::chpage(uint8_t page, bool triggerEvent) { zlock_guard lg(m_cmdlock); UIStateMgr::ins()->changePage(page); if (triggerEvent) { AppEventBus::ins()->pushPageChangeEvent(page); osDelay(10); }
sendcmd("page %d", page); } void UIControler::sendcmd(const char* format, ...) { // static char buf[256];
va_list args; va_start(args, format); // vsprintf(buf, format, args);
sendcmd(format, args); va_end(args); }
void UIControler::sendcmd(const char* format, va_list args) { static char buf[1024]; memset(buf, 0, sizeof(buf));
vsprintf(buf, format, args); #if MODULE_DEBUG
ZLOGI(TAG, "tx:%s", buf); #endif
uint8_t len = strlen(buf); if (len > (1024 - 3)) { ZLOGI(TAG, "sendcmd too long"); return; }
buf[len] = 0xff; buf[len + 1] = 0xff; buf[len + 2] = 0xff;
// vPortEnterCritical();
// HAL_UART_Transmit_DMA(tjcUart, (uint8_t*)buf, len + 3);
HAL_UART_Transmit(tjcUart, (uint8_t*)buf, len + 3, 100); // vPortExitCritical();
// while (true) {
// osDelay(2);
// if (tjcUart->gState == HAL_UART_STATE_BUSY_RX || tjcUart->gState == HAL_UART_STATE_READY) {
// return;
// }
// }
}
void UIControler::startReceiveAck() { ackQueue.clear(); m_isWaitingForAck = true; }
void UIControler::virtualClick(uint8_t pid, uint8_t bid, uint8_t event) { zlock_guard lg(m_cmdlock); sendcmd("click b[%d],%d", bid, event); }
void UIControler::setTouchEnableState(uint8_t bid, uint8_t enable) { // tsw obj,state
zlock_guard lg(m_cmdlock); sendcmd("tsw b[%d],%d", bid, enable); }
void UIControler::setEnumComponentState(uint8_t pid, uint8_t bid, int32_t state) { // ö������ʹ�ö�������
sendcmd("p[%d].b[%d].tim=%d", pid, bid, state * 50); } void UIControler::setPic(uint8_t pid, uint8_t bid, int32_t picNum) { zlock_guard lg(m_cmdlock); sendcmd("p[%d].b[%d].pic=%d", pid, bid, picNum); }
void UIControler::setAph(uint8_t pid, uint8_t bid, int32_t state) { zlock_guard lg(m_cmdlock); sendcmd("p[%d].b[%d].aph=%d", pid, bid, state); }
bool UIControler::visEx(uint8_t pid, uint8_t bid, bool val) { zlock_guard lg(m_cmdlock);
component_info_t* component = UIStateMgr::ins()->forceFindComponent(pid, bid); if (component == NULL) { ZLOGW(TAG, "visEx failed,component alloc failed"); return false; }
bool suc = true;
do { if (!component->isPosInited) { suc = readFiledAsInt(pid, bid, "x", &component->oldPosX); if (!suc) { for (size_t i = 0; i < 3; i++) { ZLOGE(TAG, "fatal error, reboot"); osDelay(1000); } NVIC_SystemReset(); } suc = readFiledAsInt(pid, bid, "y", &component->oldPosY); if (!suc) { for (size_t i = 0; i < 3; i++) { ZLOGE(TAG, "fatal error, reboot"); osDelay(1000); } NVIC_SystemReset(); } }
if (val) { // ��ʾ
if (!component->isVis) { sendcmd("p[%d].b[%d].x=%d", pid, bid, component->oldPosX); sendcmd("p[%d].b[%d].y=%d", pid, bid, component->oldPosY); component->isVis = true; }
} else { if (component->isVis) { component->isPosInited = true; component->isVis = false; sendcmd("p[%d].b[%d].x=%d", pid, bid, -2000); sendcmd("p[%d].b[%d].y=%d", pid, bid, -2000); } } } while (false);
return suc; }
bool UIControler::movePicToXY(uint8_t pid, uint8_t bid, int32_t x, int32_t y) { sendcmd("p[%d].b[%d].x=%d", pid, bid, x); sendcmd("p[%d].b[%d].y=%d", pid, bid, y); return true; }
bool UIControler::movePicTo(uint8_t pid, uint8_t bid, uint8_t toBid) { sendcmd("p[%d].b[%d].x=p[%d].b[%d].x", pid, bid, pid, toBid); sendcmd("p[%d].b[%d].y=p[%d].b[%d].y", pid, bid, pid, toBid); return true; }
bool UIControler::movePicOutOfScreen(uint8_t pid, uint8_t bid) { sendcmd("p[%d].b[%d].x=%d", pid, bid, -2000); sendcmd("p[%d].b[%d].y=%d", pid, bid, -2000); return true; }
/***********************************************************************************************************************
* ���� * ***********************************************************************************************************************/
void UIControler::popFullKeyBoard(uint8_t fromPid, uint8_t fromBid, int limitLength, const char* initval) { zlock_guard lg(m_cmdlock);
UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
sendcmd("p[%d].b[%d].val=%d", pg_keybdAP, ob_keybdAP_loadpageid, fromPid); sendcmd("p[%d].b[%d].val=%d", pg_keybdAP, ob_keybdAP_loadcmpid, fromBid); sendcmd("p[%d].b[%d].txt=\"%s\"", pg_keybdAP, ob_keybdAP_show, initval); sendcmd("p[%d].b[%d].val=%d", pg_keybdAP, ob_keybdAP_inputlenth, limitLength); sendcmd("p[%d].b[%d].pw=0", pg_keybdAP, ob_keybdAP_show); chpage(pg_keybdAP, false); }
void UIControler::popPasswdKeyBoard(uint8_t fromPid, uint8_t fromBid, int limitLength) { zlock_guard lg(m_cmdlock); UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_loadpageid, fromPid); sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_loadcmpid, fromBid); sendcmd("p[%d].b[%d].txt=\"%s\"", pg_keybdB, ob_keybdB_show, ""); sendcmd("p[%d].b[%d].pw=1", pg_keybdB, ob_keybdB_show); sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_inputlenth, limitLength);
visEx(pg_keybdB, ob_keybdB_b11, false); // '-'
visEx(pg_keybdB, ob_keybdB_b10, false); // '.'
chpage(pg_keybdB, false); }
void UIControler::popNumKeyBoard(uint8_t fromPid, uint8_t fromBid, int limitLength, const char* initval, ...) { zlock_guard lg(m_cmdlock); UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
static char buf[60]; va_list args; va_start(args, initval); vsnprintf(buf, sizeof(buf), initval, args); va_end(args);
sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_loadpageid, fromPid); sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_loadcmpid, fromBid); sendcmd("p[%d].b[%d].txt=\"%s\"", pg_keybdB, ob_keybdB_show, buf); sendcmd("p[%d].b[%d].pw=0", pg_keybdB, ob_keybdB_show); sendcmd("p[%d].b[%d].val=%d", pg_keybdB, ob_keybdB_inputlenth, limitLength);
visEx(pg_keybdB, ob_keybdB_b11, true); // '-'
visEx(pg_keybdB, ob_keybdB_b10, true); // '.'
chpage(pg_keybdB, false); }
void UIControler::popKeyBMutSel(uint8_t fromPid, uint8_t fromBid, int selectvalindex, const char** selectvals) { zlock_guard lg(m_cmdlock);
static char contentbus[512]; memset(contentbus, 0, sizeof(contentbus)); for (int i = 0;; i++) { // \r\n ƴ���ַ�������
if (selectvals[i] == nullptr) break; if (i == 0) { sprintf(contentbus, "%s", selectvals[i]); continue; } sprintf(contentbus, "%s\r\n%s", contentbus, selectvals[i]); } popKeyBMutSel(fromPid, fromBid, selectvalindex, contentbus); }
void UIControler::popKeyBMutSel(uint8_t fromPid, uint8_t fromBid, int selectvalindex, const char* selectvals) { zlock_guard lg(m_cmdlock); UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
sendcmd("p[%d].b[%d].val=%d", pg_keybMutSel, ob_keybMutSel_loadpageid, fromPid); sendcmd("p[%d].b[%d].val=%d", pg_keybMutSel, ob_keybMutSel_loadcmpid, fromBid); sendcmd("p[%d].b[%d].val=%d", pg_keybMutSel, ob_keybMutSel_ctent, selectvalindex);
chpage(pg_keybMutSel, false); // ���л�ҳ�棬������ѡ��
sendcmd("p[%d].b[%d].path=\"%s\"", pg_keybMutSel, ob_keybMutSel_ctent, selectvals); }
void UIControler::popKeyBMutSelFix(uint8_t fromPid, uint8_t fromBid, int selectvalindex, const char* keyboardName, const char** selectvals) { int selectValsNum = 0; uint8_t pgNum = pg_keybMutSelFix; UIStateMgr::ins()->setKeyboardFrom(fromPid, fromBid);
static uint8_t selbid_table[] = { ob_keybMutSelFix_b0, //
ob_keybMutSelFix_b1, //
ob_keybMutSelFix_b2, //
ob_keybMutSelFix_b3, //
ob_keybMutSelFix_b4, //
ob_keybMutSelFix_b5, //
ob_keybMutSelFix_b6, //
ob_keybMutSelFix_b7, //
ob_keybMutSelFix_b8, //
ob_keybMutSelFix_b9, //
ob_keybMutSelFix_b10, //
ob_keybMutSelFix_b11, //
ob_keybMutSelFix_b12, //
ob_keybMutSelFix_b13, //
ob_keybMutSelFix_b14, //
};
static uint8_t selmaskbid_table[] = { ob_keybMutSelFix_t0, //
ob_keybMutSelFix_t1, //
ob_keybMutSelFix_t2, //
ob_keybMutSelFix_t3, //
ob_keybMutSelFix_t4, //
ob_keybMutSelFix_t5, //
ob_keybMutSelFix_t6, //
ob_keybMutSelFix_t7, //
ob_keybMutSelFix_t8, //
ob_keybMutSelFix_t9, //
ob_keybMutSelFix_t10, //
ob_keybMutSelFix_t11, //
ob_keybMutSelFix_t12, //
ob_keybMutSelFix_t13, //
ob_keybMutSelFix_t14, //
};
for (int i = 0;; i++) { if (selectvals[i] == nullptr) break; selectValsNum++; }
if (selectValsNum > sizeof(selbid_table) / sizeof(selbid_table[0])) { ZLOGE(TAG, "selectvals num is too large"); return; }
if (selectvalindex >= selectValsNum) { ZLOGE(TAG, "selectvalindex is too large"); return; }
zlock_guard lg(m_cmdlock);
sendcmd("p[%d].b[%d].val=%d", pgNum, ob_keybMutSelFix_loadpageid, fromPid); sendcmd("p[%d].b[%d].val=%d", pgNum, ob_keybMutSelFix_loadcmpid, fromBid);
sendcmd("p[%d].b[%d].val=%d", pgNum, ob_keybMutSelFix_val, selectvalindex); sendcmd("p[%d].b[%d].txt=%d", pgNum, ob_keybMutSelFix_txt, selectvals[selectvalindex]);
sendcmd("p[%d].b[%d].txt=\"%s\"", pgNum, ob_keybMutSelFix_keybtil, keyboardName);
chpage(pgNum, false); // ���л�ҳ�棬������ѡ��
// ����ѡ��
for (int i = 0; i < selectValsNum; i++) { // visEx(pgNum, selbid_table[i], true);
sendcmd("p[%d].b[%d].txt=\"%s\"", pgNum, selbid_table[i], selectvals[i]); } // ���ն�����ѡ��
for (int i = selectValsNum; i < sizeof(selbid_table) / sizeof(selbid_table[0]); i++) { sendcmd("p[%d].b[%d].txt=\"\"", pgNum, selbid_table[i], selectvals[i]); }
for (int i = 0; i < selectValsNum; i++) { movePicToXY(pgNum, selmaskbid_table[i], -100, -100); } for (int i = selectValsNum; i < sizeof(selbid_table) / sizeof(selbid_table[0]); i++) { movePicTo(pgNum, selmaskbid_table[i], selbid_table[i]); } }
|