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.

340 lines
9.9 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "dwin_screen.hpp"
  2. #include <string.h>
  3. namespace iflytop {
  4. namespace dwin {
  5. DwinScreen g_dwinScreen;
  6. }
  7. } // namespace iflytop
  8. using namespace iflytop;
  9. using namespace iflytop::dwin;
  10. #define TAG "dwin"
  11. DwinScreen& DwinScreen::ins() { return g_dwinScreen; }
  12. void DwinScreen::init(UART_HandleTypeDef* huart, DwinScreenCfg dwcfg) {
  13. m_huart = huart;
  14. m_dwcfg = dwcfg;
  15. ZUART::cfg_t cfg;
  16. cfg.huart = m_huart;
  17. cfg.name = "DwinScreenUart";
  18. cfg.rxbuffersize = RX_CACHE_SIZE;
  19. cfg.rxovertime_ms = 2;
  20. m_uarthandler.initialize(&cfg);
  21. m_uarthandler.startRxIt();
  22. m_uarthandler.setrxcb([this](uint8_t* data, size_t len) {
  23. // irq
  24. if (txcontext.receipt_ready_flag) {
  25. return;
  26. }
  27. memcpy(txcontext.receiptcache, data, len);
  28. txcontext.receiptlen = len;
  29. txcontext.receipt_ready_flag = true;
  30. });
  31. m_rammanager.init(dwcfg.freeRawStartAddr, dwcfg.freeRawEndAddr);
  32. m_textDisplayerManager.init(dwcfg.textDisplayerStartAddr, dwcfg.textDisplayerEndAddr);
  33. m_varIconManager.init(dwcfg.varIconStartAddr, dwcfg.varIconEndAddr);
  34. dumpram();
  35. }
  36. void DwinScreen::dumpram() {
  37. ZLOGI(TAG, "ram :(%d/%d)", m_rammanager.totalsize(1) - m_rammanager.remainsize(1), m_rammanager.totalsize(1));
  38. ZLOGI(TAG, "textDisplayer :(%d/%d)",
  39. m_textDisplayerManager.totalsize(m_dwcfg.textDisplayerSize) - m_textDisplayerManager.remainsize(m_dwcfg.textDisplayerSize),
  40. m_textDisplayerManager.totalsize(m_dwcfg.textDisplayerSize));
  41. ZLOGI(TAG, "varIcon :(%d/%d)", m_varIconManager.totalsize(m_dwcfg.varIconSize) - m_varIconManager.remainsize(m_dwcfg.varIconSize),
  42. m_varIconManager.totalsize(m_dwcfg.varIconSize));
  43. }
  44. uint16_t DwinScreen::alloc_free_ram(uint16_t size) { return m_rammanager.alloc(size); }
  45. uint16_t DwinScreen::alloc_one_text_displayer() { return m_textDisplayerManager.alloc(m_dwcfg.textDisplayerSize); }
  46. uint16_t DwinScreen::alloc_one_var_icon() {
  47. uint16_t addr = m_varIconManager.alloc(m_dwcfg.varIconSize);
  48. return addr;
  49. }
  50. uint16_t DwinScreen::mem_free_ram_remain() { return m_rammanager.remainsize(1); }
  51. uint16_t DwinScreen::mem_one_text_displayer_remain() { return m_textDisplayerManager.remainsize(m_dwcfg.textDisplayerSize); }
  52. uint16_t DwinScreen::mem_one_var_icon_remain() { return m_varIconManager.remainsize(m_dwcfg.varIconSize); }
  53. void DwinScreen::clearrxcache() {
  54. CriticalContext cc;
  55. txcontext.receipt_ready_flag = false;
  56. txcontext.receiptlen = 0;
  57. }
  58. void DwinScreen::sendcmd(uint8_t* cmd, size_t len) {
  59. // printf("sendcmd:");
  60. // for (size_t i = 0; i < len; i++) {
  61. // ZLOGE(TAG,"%02X ", cmd[i]);
  62. // }
  63. // printf("\n");
  64. m_uarthandler.tx(cmd, len);
  65. // m_com.send((char*)cmd, len);
  66. }
  67. bool DwinScreen::sendcmdblock(int overtime) {
  68. clearrxcache();
  69. sendcmd(txcontext.txcache, txcontext.txlen);
  70. for (int i = 0; i < overtime; i++) {
  71. if (txcontext.receipt_ready_flag) {
  72. return true;
  73. } else {
  74. zos_delay(1);
  75. }
  76. }
  77. return false;
  78. }
  79. bool DwinScreen::write_varspace(uint16_t regaddr, uint8_t* data, uint8_t len, int overtime) {
  80. /**
  81. * @brief
  82. *
  83. * 2byte 1byte cmd add val
  84. * 5AA5 datalen 0x82 2 xbyte
  85. *
  86. */
  87. txcontext.txcache[0] = 0x5A;
  88. txcontext.txcache[1] = 0xA5;
  89. txcontext.txcache[2] = 0; // data len
  90. txcontext.txcache[3] = 0x82;
  91. txcontext.txcache[4] = regaddr >> 8;
  92. txcontext.txcache[5] = regaddr & 0xFF;
  93. memcpy(&txcontext.txcache[6], data, len);
  94. txcontext.txcache[2] = len + 1 + 2; //
  95. txcontext.txlen = 6 + len;
  96. if (!sendcmdblock(overtime)) {
  97. ZLOGE(TAG, "write_varspace failed");
  98. return false;
  99. }
  100. return true;
  101. }
  102. bool DwinScreen::read_varspace(uint16_t regaddr, uint8_t* data, uint8_t len, int overtime) {
  103. /**
  104. * @brief
  105. *
  106. * 2byte 1byte cmd add val
  107. * 5AA5 datalen 0x82 2 xbyte
  108. *
  109. */
  110. txcontext.txcache[0] = 0x5A;
  111. txcontext.txcache[1] = 0xA5;
  112. txcontext.txcache[2] = 0; // data len
  113. txcontext.txcache[3] = 0x83;
  114. txcontext.txcache[4] = regaddr >> 8;
  115. txcontext.txcache[5] = regaddr & 0xFF;
  116. txcontext.txcache[6] = len / 2; // word len
  117. txcontext.txcache[2] = 4; //
  118. txcontext.txlen = 7;
  119. if (!sendcmdblock(overtime)) {
  120. ZLOGE(TAG, "read_varspace failed");
  121. return false;
  122. }
  123. memcpy(data, &txcontext.receiptcache[7], len);
  124. return true;
  125. }
  126. bool DwinScreen::write_reg16(uint16_t regaddr, uint16_t data, int overtime) { //
  127. uint8_t data8[2];
  128. data8[0] = data >> 8;
  129. data8[1] = data & 0xFF;
  130. return write_reg(regaddr, data8, 2, overtime);
  131. }
  132. bool DwinScreen::read_reg16(uint16_t regaddr, uint16_t& data, int overtime) {
  133. uint8_t data8[2];
  134. bool suc = read_reg(regaddr, data8, 2, overtime);
  135. if (!suc) return false;
  136. data = data8[0] << 8 | data8[1];
  137. return true;
  138. }
  139. bool DwinScreen::write_varspace16(uint16_t regaddr, uint16_t data, int overtime) { //
  140. uint8_t data8[2];
  141. data8[0] = data >> 8;
  142. data8[1] = data & 0xFF;
  143. return write_varspace(regaddr, data8, 2, overtime);
  144. }
  145. bool DwinScreen::write_varspace16_muti(uint16_t regaddr, uint16_t* data, size_t n16, int overtime) {
  146. for (size_t i = 0; i < n16; i++) {
  147. m_tx_pre_processcache[i * 2] = data[i] >> 8;
  148. m_tx_pre_processcache[i * 2 + 1] = data[i] & 0xFF;
  149. }
  150. return write_varspace(regaddr, m_tx_pre_processcache, n16 * 2, overtime);
  151. }
  152. bool DwinScreen::read_varspace16_muti(uint16_t regaddr, uint16_t* data, size_t n16, int overtime) {
  153. // TODO: CHECK BUFSIZE
  154. memset(m_rd_pre_processcache, 0, sizeof(m_rd_pre_processcache));
  155. bool suc = read_varspace(regaddr, m_rd_pre_processcache, n16 * 2, overtime);
  156. if (!suc) return false;
  157. for (size_t i = 0; i < n16; i++) {
  158. data[i] = m_rd_pre_processcache[i * 2] << 8 | m_rd_pre_processcache[i * 2 + 1];
  159. }
  160. return true;
  161. }
  162. bool DwinScreen::read_varspace16(uint16_t regaddr, uint16_t& data, int overtime) {
  163. uint8_t data8[2];
  164. bool suc = read_varspace(regaddr, data8, 2, overtime);
  165. if (!suc) return false;
  166. data = data8[0] << 8 | data8[1];
  167. return true;
  168. }
  169. bool DwinScreen::write_varspace8(uint16_t regaddr, uint16_t subadd, uint16_t data, int overtime) {
  170. uint16_t val = 0;
  171. bool suc = read_varspace16(regaddr, val, overtime);
  172. if (!suc) return false;
  173. if (subadd == 0) {
  174. // H
  175. val = val & 0x00FF;
  176. val = val | ((data << 8) & 0xff00);
  177. } else {
  178. // L
  179. val = val & 0xFF00;
  180. val = val | (data & 0xff);
  181. }
  182. suc = write_varspace16(regaddr, val, overtime);
  183. if (!suc) return false;
  184. return true;
  185. }
  186. bool DwinScreen::read_varspace8(uint16_t regaddr, uint16_t subadd, uint16_t& data, int overtime) {
  187. uint16_t val = 0;
  188. bool suc = read_varspace16(regaddr, val, overtime);
  189. if (!suc) return false;
  190. if (subadd == 0) {
  191. // H
  192. data = val >> 8;
  193. } else {
  194. // L
  195. data = val & 0xff;
  196. }
  197. return true;
  198. }
  199. bool DwinScreen::write_reg(uint16_t regaddr, uint8_t* data, size_t len, int overtime) {
  200. /**
  201. * @brief
  202. *
  203. * 2byte 1byte cmd add val
  204. * 5AA5 datalen 0x82 2 xbyte
  205. *
  206. */
  207. txcontext.txcache[0] = 0x5A;
  208. txcontext.txcache[1] = 0xA5;
  209. txcontext.txcache[2] = 0; // data len
  210. txcontext.txcache[3] = 0x80;
  211. txcontext.txcache[4] = regaddr >> 8;
  212. txcontext.txcache[5] = regaddr & 0xFF;
  213. memcpy(&txcontext.txcache[6], data, len);
  214. txcontext.txcache[2] = len + 1 + 2; //
  215. txcontext.txlen = 6 + len;
  216. if (!sendcmdblock(overtime)) {
  217. ZLOGE(TAG, "write_reg failed");
  218. return false;
  219. }
  220. return true;
  221. }
  222. bool DwinScreen::read_reg(uint16_t regaddr, uint8_t* data, size_t len, int overtime) {
  223. /**
  224. * @brief
  225. *
  226. * 2byte 1byte cmd add val
  227. * 5AA5 datalen 0x82 2 xbyte
  228. *
  229. */
  230. txcontext.txcache[0] = 0x5A;
  231. txcontext.txcache[1] = 0xA5;
  232. txcontext.txcache[2] = 0; // data len
  233. txcontext.txcache[3] = 0x81;
  234. txcontext.txcache[4] = regaddr >> 8;
  235. txcontext.txcache[5] = regaddr & 0xFF;
  236. txcontext.txcache[6] = len / 2; // word len
  237. txcontext.txcache[2] = 4; //
  238. txcontext.txlen = 7;
  239. if (!sendcmdblock(overtime)) {
  240. ZLOGE(TAG, "read_varspace failed");
  241. return false;
  242. }
  243. memcpy(data, &txcontext.receiptcache[7], len);
  244. return true;
  245. }
  246. bool DwinScreen::set_page(uint16_t pageid) {
  247. uint16_t data[2] = {0x5A01, pageid};
  248. return write_varspace16_muti(0x84, data, 2, 10);
  249. }
  250. uint16_t DwinScreen::get_page() {
  251. uint16_t page = 0;
  252. read_varspace16(0x14, page, 100);
  253. return page;
  254. }
  255. bool DwinScreen::ping() {
  256. uint16_t page = 0;
  257. bool suc = read_varspace16(0x14, page, 100);
  258. return suc;
  259. }
  260. bool DwinScreen::set_brightness(uint16_t brightness) {
  261. // 5A A5 04 82 0082 0A
  262. uint8_t data[3] = {0, 0x82, (uint8_t)brightness};
  263. return write_varspace(0x82, data, 3, 10);
  264. }
  265. bool DwinScreen::set_rtc(uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second) {
  266. year = year - 2000;
  267. uint16_t year_month = year << 8 | month;
  268. uint16_t day_hour = day << 8 | hour;
  269. uint16_t min_second = minute << 8 | second;
  270. uint16_t data[4] = {0x5AA5, year_month, day_hour, min_second};
  271. return write_varspace16_muti(0x9C, data, 4, 10);
  272. }
  273. bool DwinScreen::get_rtc(Date* date) {
  274. uint16_t data[4] = {0};
  275. bool suc = read_varspace16_muti(0x10, data, 4, 10);
  276. // printf("data[0]:%04X data[1]:%04X data[2]:%04X data[3]:%04X\n", data[0], data[1], data[2], data[3]);
  277. // date->year = (data[0] >> 8) + 2000;
  278. // date->month = data[0] & 0xFF;
  279. // date->day = data[1] >> 8;
  280. // date->weekdaynum = data[1] & 0xFF;
  281. // date->hour = data[2] >> 8;
  282. // date->minute = data[2] & 0xFF;
  283. // date->second = data[3] >> 8;
  284. date->year = (data[0] & 0xff) + 2000;
  285. date->month = data[1] >> 8;
  286. date->day = data[1] & 0xFF;
  287. date->weekdaynum = data[2] >> 8;
  288. date->hour = data[2] & 0xFF;
  289. date->minute = data[3] >> 8;
  290. date->second = data[3] & 0xFF;
  291. printf("year:%d month:%d day:%d weekdaynum:%d hour:%d minute:%d second:%d\n", //
  292. date->year, date->month, date->day, date->weekdaynum, date->hour, date->minute, date->second);
  293. return suc;
  294. }