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.

296 lines
8.0 KiB

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