diff --git a/components/dwin/dwin_screen.cpp b/components/dwin/dwin_screen.cpp new file mode 100644 index 0000000..c081e80 --- /dev/null +++ b/components/dwin/dwin_screen.cpp @@ -0,0 +1,296 @@ +#include "dwin_screen.hpp" + +#include +using namespace iflytop; + +#define TAG "dwin" + +void DwinScreen::init(UART_HandleTypeDef* huart, int __) { + m_huart = huart; + ZUART::cfg_t cfg; + cfg.huart = m_huart; + cfg.name = "DwinScreenUart"; + cfg.rxbuffersize = RX_CACHE_SIZE; + cfg.rxovertime_ms = 2; + m_uarthandler.initialize(&cfg); + + m_uarthandler.startRxIt(); + + m_uarthandler.setrxcb([this](uint8_t* data, size_t len) { + if (txcontext.receipt_ready_flag) { + return; + } + memcpy(txcontext.receiptcache, data, len); + txcontext.receiptlen = len; + txcontext.receipt_ready_flag = true; + }); +} + +void DwinScreen::clearrxcache() { + CriticalContext cc; + txcontext.receipt_ready_flag = false; + txcontext.receiptlen = 0; +} +void DwinScreen::sendcmd(uint8_t* cmd, size_t len) { + // printf("sendcmd:"); + // for (size_t i = 0; i < len; i++) { + // ZLOGE(TAG,"%02X ", cmd[i]); + // } + // printf("\n"); + m_uarthandler.tx(cmd, len); + // m_com.send((char*)cmd, len); +} + +bool DwinScreen::sendcmdblock(int overtime) { + clearrxcache(); + sendcmd(txcontext.txcache, txcontext.txlen); + for (int i = 0; i < overtime; i++) { + if (txcontext.receipt_ready_flag) { + return true; + } else { + m_uarthandler.forceCchedule(); + chip_delay_ms(1); + } + } + return false; +} + +bool DwinScreen::write_varspace(uint16_t regaddr, uint8_t* data, uint8_t len, int overtime) { + /** + * @brief + * + * 2byte 1byte cmd add val + * 5AA5 datalen 0x82 2 xbyte + * + */ + txcontext.txcache[0] = 0x5A; + txcontext.txcache[1] = 0xA5; + txcontext.txcache[2] = 0; // data len + txcontext.txcache[3] = 0x82; + txcontext.txcache[4] = regaddr >> 8; + txcontext.txcache[5] = regaddr & 0xFF; + + memcpy(&txcontext.txcache[6], data, len); + txcontext.txcache[2] = len + 1 + 2; // + + txcontext.txlen = 6 + len; + + if (!sendcmdblock(overtime)) { + ZLOGE(TAG, "write_varspace failed"); + return false; + } + return true; +} +bool DwinScreen::read_varspace(uint16_t regaddr, uint8_t* data, uint8_t len, int overtime) { + /** + * @brief + * + * 2byte 1byte cmd add val + * 5AA5 datalen 0x82 2 xbyte + * + */ + txcontext.txcache[0] = 0x5A; + txcontext.txcache[1] = 0xA5; + txcontext.txcache[2] = 0; // data len + txcontext.txcache[3] = 0x83; + txcontext.txcache[4] = regaddr >> 8; + txcontext.txcache[5] = regaddr & 0xFF; + txcontext.txcache[6] = len / 2; // word len + + txcontext.txcache[2] = 4; // + txcontext.txlen = 7; + + if (!sendcmdblock(overtime)) { + ZLOGE(TAG, "read_varspace failed"); + return false; + } + memcpy(data, &txcontext.receiptcache[7], len); + return true; +} + +bool DwinScreen::write_reg16(uint16_t regaddr, uint16_t data, int overtime) { // + uint8_t data8[2]; + data8[0] = data >> 8; + data8[1] = data & 0xFF; + + return write_reg(regaddr, data8, 2, overtime); +} + +bool DwinScreen::read_reg16(uint16_t regaddr, uint16_t& data, int overtime) { + uint8_t data8[2]; + bool suc = read_reg(regaddr, data8, 2, overtime); + if (!suc) return false; + + data = data8[0] << 8 | data8[1]; + return true; +} + +bool DwinScreen::write_varspace16(uint16_t regaddr, uint16_t data, int overtime) { // + uint8_t data8[2]; + data8[0] = data >> 8; + data8[1] = data & 0xFF; + + return write_varspace(regaddr, data8, 2, overtime); +} + +bool DwinScreen::write_varspace16_muti(uint16_t regaddr, uint16_t* data, size_t n16, int overtime) { + for (size_t i = 0; i < n16; i++) { + m_tx_pre_processcache[i * 2] = data[i] >> 8; + m_tx_pre_processcache[i * 2 + 1] = data[i] & 0xFF; + } + return write_varspace(regaddr, m_tx_pre_processcache, n16 * 2, overtime); +} + +bool DwinScreen::read_varspace16_muti(uint16_t regaddr, uint16_t* data, size_t n16, int overtime) { + // TODO: CHECK BUFSIZE + memset(m_rd_pre_processcache, 0, sizeof(m_rd_pre_processcache)); + bool suc = read_varspace(regaddr, m_rd_pre_processcache, n16 * 2, overtime); + if (!suc) return false; + + for (size_t i = 0; i < n16; i++) { + data[i] = m_rd_pre_processcache[i * 2] << 8 | m_rd_pre_processcache[i * 2 + 1]; + } + return true; +} + +bool DwinScreen::read_varspace16(uint16_t regaddr, uint16_t& data, int overtime) { + uint8_t data8[2]; + bool suc = read_varspace(regaddr, data8, 2, overtime); + if (!suc) return false; + + data = data8[0] << 8 | data8[1]; + return true; +} + +bool DwinScreen::write_varspace8(uint16_t regaddr, uint16_t subadd, uint16_t data, int overtime) { + uint16_t val = 0; + bool suc = read_varspace16(regaddr, val, overtime); + if (!suc) return false; + + if (subadd == 0) { + // H + val = val & 0x00FF; + val = val | ((data << 8) & 0xff00); + } else { + // L + val = val & 0xFF00; + val = val | (data & 0xff); + } + + suc = write_varspace16(regaddr, val, overtime); + if (!suc) return false; + return true; +} +bool DwinScreen::read_varspace8(uint16_t regaddr, uint16_t subadd, uint16_t& data, int overtime) { + uint16_t val = 0; + bool suc = read_varspace16(regaddr, val, overtime); + if (!suc) return false; + + if (subadd == 0) { + // H + data = val >> 8; + } else { + // L + data = val & 0xff; + } + return true; +} + +bool DwinScreen::write_reg(uint16_t regaddr, uint8_t* data, size_t len, int overtime) { + /** + * @brief + * + * 2byte 1byte cmd add val + * 5AA5 datalen 0x82 2 xbyte + * + */ + txcontext.txcache[0] = 0x5A; + txcontext.txcache[1] = 0xA5; + txcontext.txcache[2] = 0; // data len + txcontext.txcache[3] = 0x80; + txcontext.txcache[4] = regaddr >> 8; + txcontext.txcache[5] = regaddr & 0xFF; + + memcpy(&txcontext.txcache[6], data, len); + txcontext.txcache[2] = len + 1 + 2; // + + txcontext.txlen = 6 + len; + + if (!sendcmdblock(overtime)) { + ZLOGE(TAG, "write_reg failed"); + return false; + } + return true; +} +bool DwinScreen::read_reg(uint16_t regaddr, uint8_t* data, size_t len, int overtime) { + /** + * @brief + * + * 2byte 1byte cmd add val + * 5AA5 datalen 0x82 2 xbyte + * + */ + txcontext.txcache[0] = 0x5A; + txcontext.txcache[1] = 0xA5; + txcontext.txcache[2] = 0; // data len + txcontext.txcache[3] = 0x81; + txcontext.txcache[4] = regaddr >> 8; + txcontext.txcache[5] = regaddr & 0xFF; + txcontext.txcache[6] = len / 2; // word len + + txcontext.txcache[2] = 4; // + txcontext.txlen = 7; + + if (!sendcmdblock(overtime)) { + ZLOGE(TAG, "read_varspace failed"); + return false; + } + memcpy(data, &txcontext.receiptcache[7], len); + return true; +} + +bool DwinScreen::set_page(uint16_t pageid) { + uint16_t data[2] = {0x5A01, pageid}; + return write_varspace16_muti(0x84, data, 2, 10); +} +uint16_t DwinScreen::get_page() { + uint16_t page = 0; + read_varspace16(0x14, page, 100); + return page; +} +bool DwinScreen::ping() { + uint16_t page = 0; + bool suc = read_varspace16(0x14, page, 100); + return suc; +} + +bool DwinScreen::set_brightness(uint16_t brightness) { + // 5A A5 04 82 0082 0A + uint8_t data[3] = {0, 0x82, (uint8_t)brightness}; + return write_varspace(0x82, data, 3, 10); +} +bool DwinScreen::set_rtc(uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second) { + year = year - 2000; + + uint16_t year_month = year << 8 | month; + uint16_t day_hour = day << 8 | hour; + uint16_t min_second = minute << 8 | second; + uint16_t data[4] = {0x5AA5, year_month, day_hour, min_second}; + return write_varspace16_muti(0x9C, data, 4, 10); +} + +bool DwinScreen::get_rtc(Date* date) { + uint16_t data[4] = {0}; + bool suc = read_varspace16_muti(0x10, data, 4, 10); + // printf("data[0]:%04X data[1]:%04X data[2]:%04X data[3]:%04X\n", data[0], data[1], data[2], data[3]); + date->year = (data[0] >> 8) + 2000; + date->month = data[0] & 0xFF; + date->day = data[1] >> 8; + date->weekdaynum = data[1] & 0xFF; + date->hour = data[2] >> 8; + date->minute = data[2] & 0xFF; + date->second = data[3] >> 8; + // printf("year:%d month:%d day:%d weekdaynum:%d hour:%d minute:%d second:%d\n", // + // date->year, date->month, date->day, date->weekdaynum, date->hour, date->minute, date->second); + return suc; +} diff --git a/components/dwin/dwin_screen.hpp b/components/dwin/dwin_screen.hpp new file mode 100644 index 0000000..300bbbf --- /dev/null +++ b/components/dwin/dwin_screen.hpp @@ -0,0 +1,96 @@ +#pragma once +#include "sdk\hal\zhal.hpp" +namespace iflytop { +using namespace std; + +/** + * @brief + * + * 2byte 1byte cmd data crc + * 5AA5 01 0x82/0x83 1->249 + * + * 2byte 1byte cmd data crc + * 5AA5 01 0x81/0x80 1->249 + */ + +#define TX_CACHE_SIZE 256 +#define RX_CACHE_SIZE 256 + +class DwinScreen { + public: + class Date { + public: + uint16_t year; + uint16_t month; + uint16_t day; + uint16_t hour; + uint16_t minute; + uint16_t second; + uint16_t weekdaynum; // 星期几 + }; + + private: + class TxContext { + public: + uint8_t txcache[TX_CACHE_SIZE]; + uint8_t txlen; + uint8_t receiptcache[RX_CACHE_SIZE]; + uint8_t receiptlen; + bool receipt_ready_flag = false; + }; + + private: + UART_HandleTypeDef* m_huart; + ZUART m_uarthandler; + + TxContext txcontext; + + uint8_t m_tx_pre_processcache[TX_CACHE_SIZE]; + uint8_t m_rd_pre_processcache[RX_CACHE_SIZE]; + + bool enablecrc = false; + + public: + /** + * @brief + * + * @param huart 串口 + * @param baudrate 波特率(暂时不支持设置) + */ + void init(UART_HandleTypeDef* huart, int __ = 0); + + public: + bool set_page(uint16_t pageid); + uint16_t get_page(); + bool set_brightness(uint16_t brightness); + bool set_rtc(uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second); + bool get_rtc(Date* date); + + bool ping(); + + public: + bool write_reg16(uint16_t regaddr, uint16_t data, int overtime); + bool read_reg16(uint16_t regaddr, uint16_t& data, int overtime); + + bool write_reg(uint16_t regaddr, uint8_t* data, size_t len, int overtime); + bool read_reg(uint16_t regaddr, uint8_t* data, size_t len, int overtime); + + bool write_varspace16(uint16_t regaddr, uint16_t data, int overtime); + bool read_varspace16(uint16_t regaddr, uint16_t& data, int overtime); + + bool write_varspace16_muti(uint16_t regaddr, uint16_t* data, size_t n16, int overtime); + bool read_varspace16_muti(uint16_t regaddr, uint16_t* data, size_t n16, int overtime); + + bool write_varspace8(uint16_t regaddr, uint16_t subadd, uint16_t data, int overtime); + bool read_varspace8(uint16_t regaddr, uint16_t subadd, uint16_t& data, int overtime); + + bool write_varspace(uint16_t regaddr, uint8_t* data, uint8_t len, int overtime); + bool read_varspace(uint16_t regaddr, uint8_t* data, uint8_t len, int overtime); + + private: + void clearrxcache(); + void sendcmd(uint8_t* cmd, size_t len); + bool sendcmdblock(int overtime); +}; + +} // namespace iflytop \ No newline at end of file diff --git a/hal/zuart.cpp b/hal/zuart.cpp index b811b85..da13c58 100644 --- a/hal/zuart.cpp +++ b/hal/zuart.cpp @@ -167,6 +167,8 @@ void ZUART::periodicJob() { } } +void ZUART::forceCchedule() { periodicJob(); } + /******************************************************************************* * 中断 * *******************************************************************************/ diff --git a/hal/zuart.hpp b/hal/zuart.hpp index 6f5f1b7..1e7087c 100644 --- a/hal/zuart.hpp +++ b/hal/zuart.hpp @@ -44,8 +44,9 @@ class ZUART { bool tx(const char *data); bool tx(uint8_t *data, size_t len); bool startRxIt(); - + void clearRxData(); + void forceCchedule(); public: void HAL_UART_TxCpltCallback();