ucg_com_msg_api.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. ucg_com_msg_api.c
  3. Universal uC Color Graphics Library
  4. Copyright (c) 2014, olikraus@gmail.com
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without modification,
  7. are permitted provided that the following conditions are met:
  8. * Redistributions of source code must retain the above copyright notice, this list
  9. of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright notice, this
  11. list of conditions and the following disclaimer in the documentation and/or other
  12. materials provided with the distribution.
  13. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  14. CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  15. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  16. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  18. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  23. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  25. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "ucg.h"
  28. int16_t ucg_com_template_cb(ucg_t *ucg, int16_t msg, uint32_t arg, uint8_t *data)
  29. {
  30. switch(msg)
  31. {
  32. case UCG_COM_MSG_POWER_UP:
  33. break;
  34. case UCG_COM_MSG_POWER_DOWN:
  35. break;
  36. case UCG_COM_MSG_DELAY:
  37. break;
  38. case UCG_COM_MSG_CHANGE_RESET_LINE:
  39. break;
  40. case UCG_COM_MSG_CHANGE_CS_LINE:
  41. break;
  42. case UCG_COM_MSG_CHANGE_CD_LINE:
  43. break;
  44. case UCG_COM_MSG_SEND_BYTE:
  45. break;
  46. case UCG_COM_MSG_REPEAT_1_BYTE:
  47. break;
  48. case UCG_COM_MSG_REPEAT_2_BYTES:
  49. break;
  50. case UCG_COM_MSG_REPEAT_3_BYTES:
  51. break;
  52. case UCG_COM_MSG_SEND_STR:
  53. break;
  54. case UCG_COM_MSG_SEND_CD_DATA_SEQUENCE:
  55. break;
  56. }
  57. return 1;
  58. }
  59. void ucg_com_PowerDown(ucg_t *ucg)
  60. {
  61. if ( (ucg->com_status & UCG_COM_STATUS_MASK_POWER) != 0 )
  62. ucg->com_cb(ucg, UCG_COM_MSG_POWER_DOWN, 0, NULL);
  63. ucg->com_status &= ~UCG_COM_STATUS_MASK_POWER;
  64. }
  65. /*
  66. clk_speed in nano-seconds, range: 0..4095
  67. */
  68. int16_t ucg_com_PowerUp(ucg_t *ucg, uint16_t serial_clk_speed, uint16_t parallel_clk_speed)
  69. {
  70. int16_t r;
  71. ucg_com_info_t com_info;
  72. com_info.serial_clk_speed = serial_clk_speed;
  73. com_info.parallel_clk_speed = parallel_clk_speed;
  74. ucg_com_PowerDown(ucg);
  75. ucg->com_initial_change_sent = 0;
  76. r = ucg->com_cb(ucg, UCG_COM_MSG_POWER_UP, 0UL, (uint8_t *)&com_info);
  77. if ( r != 0 )
  78. {
  79. ucg->com_status |= UCG_COM_STATUS_MASK_POWER;
  80. }
  81. return r;
  82. }
  83. void ucg_com_SetLineStatus(ucg_t *ucg, uint8_t level, uint8_t mask, uint8_t msg)
  84. {
  85. if ( level == 0 )
  86. {
  87. if ( (ucg->com_initial_change_sent & mask) == 0 || (ucg->com_status & mask) == mask )
  88. {
  89. ucg->com_cb(ucg, msg, level, NULL);
  90. ucg->com_status &= ~mask;
  91. ucg->com_initial_change_sent |= mask;
  92. }
  93. }
  94. else
  95. {
  96. if ( (ucg->com_initial_change_sent & mask) == 0 || (ucg->com_status & mask) == 0 )
  97. {
  98. ucg->com_cb(ucg, msg, level, NULL);
  99. ucg->com_status |= mask;
  100. ucg->com_initial_change_sent |= mask;
  101. }
  102. }
  103. }
  104. void ucg_com_SetResetLineStatus(ucg_t *ucg, uint8_t level)
  105. {
  106. ucg_com_SetLineStatus(ucg, level, UCG_COM_STATUS_MASK_RESET, UCG_COM_MSG_CHANGE_RESET_LINE);
  107. }
  108. void ucg_com_SetCSLineStatus(ucg_t *ucg, uint8_t level)
  109. {
  110. ucg_com_SetLineStatus(ucg, level, UCG_COM_STATUS_MASK_CS, UCG_COM_MSG_CHANGE_CS_LINE);
  111. }
  112. void ucg_com_SetCDLineStatus(ucg_t *ucg, uint8_t level)
  113. {
  114. ucg_com_SetLineStatus(ucg, level, UCG_COM_STATUS_MASK_CD, UCG_COM_MSG_CHANGE_CD_LINE);
  115. }
  116. /* delay in microseconds */
  117. void ucg_com_DelayMicroseconds(ucg_t *ucg, uint16_t delay)
  118. {
  119. ucg->com_cb(ucg, UCG_COM_MSG_DELAY, delay, NULL);
  120. }
  121. /* delay in milliseconds */
  122. void ucg_com_DelayMilliseconds(ucg_t *ucg, uint16_t delay)
  123. {
  124. while( delay > 0 )
  125. {
  126. ucg_com_DelayMicroseconds(ucg, 1000);
  127. delay--;
  128. }
  129. }
  130. #ifndef ucg_com_SendByte
  131. void ucg_com_SendByte(ucg_t *ucg, uint8_t byte)
  132. {
  133. ucg->com_cb(ucg, UCG_COM_MSG_SEND_BYTE, byte, NULL);
  134. }
  135. #endif
  136. void ucg_com_SendRepeatByte(ucg_t *ucg, uint16_t cnt, uint8_t byte)
  137. {
  138. ucg->com_cb(ucg, UCG_COM_MSG_REPEAT_1_BYTE, cnt, &byte);
  139. }
  140. void ucg_com_SendRepeat2Bytes(ucg_t *ucg, uint16_t cnt, uint8_t *byte_ptr)
  141. {
  142. ucg->com_cb(ucg, UCG_COM_MSG_REPEAT_2_BYTES, cnt, byte_ptr);
  143. }
  144. #ifndef ucg_com_SendRepeat3Bytes
  145. void ucg_com_SendRepeat3Bytes(ucg_t *ucg, uint16_t cnt, uint8_t *byte_ptr)
  146. {
  147. ucg->com_cb(ucg, UCG_COM_MSG_REPEAT_3_BYTES, cnt, byte_ptr);
  148. }
  149. #endif
  150. void ucg_com_SendString(ucg_t *ucg, uint16_t cnt, const uint8_t *byte_ptr)
  151. {
  152. ucg->com_cb(ucg, UCG_COM_MSG_SEND_STR, cnt, (uint8_t *)byte_ptr);
  153. }
  154. void ucg_com_SendStringP(ucg_t *ucg, uint16_t cnt, const ucg_pgm_uint8_t *byte_ptr)
  155. {
  156. uint8_t b;
  157. while( cnt > 0 )
  158. {
  159. b = ucg_pgm_read(byte_ptr);
  160. //b = *byte_ptr;
  161. ucg->com_cb(ucg, UCG_COM_MSG_SEND_BYTE, b, NULL);
  162. byte_ptr++;
  163. cnt--;
  164. }
  165. }
  166. void ucg_com_SendCmdDataSequence(ucg_t *ucg, uint16_t cnt, const uint8_t *byte_ptr, uint8_t cd_line_status_at_end)
  167. {
  168. ucg->com_cb(ucg, UCG_COM_MSG_SEND_CD_DATA_SEQUENCE, cnt, (uint8_t *)byte_ptr);
  169. ucg_com_SetCDLineStatus(ucg, cd_line_status_at_end); // ensure that the status is set correctly for the CD line */
  170. }
  171. /*
  172. Command-Sequence Language
  173. CMD10 1x CMD Byte, 0x Argument Data Bytes
  174. CMD20 2x CMD Byte, 0x Argument Data Bytes
  175. CMD11 1x CMD Byte, 1x Argument Data Bytes
  176. CMD21 2x CMD Byte, 1x Argument Data Bytes
  177. CMD12 1x CMD Byte, 2x Argument Data Bytes
  178. CMD22 2x CMD Byte, 2x Argument Data Bytes
  179. CMD13 1x CMD Byte, 3x Argument Data Bytes
  180. CMD23 2x CMD Byte, 3x Argument Data Bytes
  181. CMD14 1x CMD Byte, 4x Argument Data Bytes
  182. CMD24 2x CMD Byte, 4x Argument Data Bytes
  183. DATA1 1x Data Bytes
  184. DATA2 2x Data Bytes
  185. DATA3 3x Data Bytes
  186. DATA4 4x Data Bytes
  187. DATA5 5x Data Bytes
  188. DATA6 6x Data Bytes
  189. RST_LOW Output 0 on reset line
  190. RST_HIGH Output 1 on reset line
  191. CS_LOW Output 0 on chip select line
  192. CS_HIGH Output 1 on chip select line
  193. DLY_MS Delay for specified amount of milliseconds (0..2000)
  194. DLY_US Delay for specified amount of microconds (0..2000)
  195. Configuration
  196. CFG_CD(c,a) Configure CMD/DATA line: "c" logic level CMD, "a" logic level CMD Args
  197. 0000xxxx End Marker
  198. 0001xxxx 1x CMD Byte, 0..15 Argument Data Bytes
  199. 0010xxxx 2x CMD Byte, 0..15 Argument Data Bytes
  200. 0011xxxx 3x CMD Byte, 0..15 Argument Data Bytes
  201. 0100xxxx
  202. 0101xxxx
  203. 0110xxxx Arg Bytes 0..15
  204. 0111xxxx Data Bytes 0...15
  205. 1000xxxx xxxxxxxx DLY MS
  206. 1001xxxx xxxxxxxx DLY US
  207. 1010sssss aaaaaaaa oooooooo (var0>>s)&a|o, send as argument
  208. 1011sssss aaaaaaaa oooooooo (var1>>s)&a|o, send as argument
  209. 1100xxxx
  210. 1101xxxx
  211. 1110xxxx
  212. 11110000 RST_LOW
  213. 11110001 RST_HIGH
  214. 1111001x
  215. 11110100 CS_LOW
  216. 11110101 CS_HIGH
  217. 1111011x
  218. 111110xx
  219. 111111ca CFG_CD(c,a)
  220. #define C10(c0) 0x010, (c0)
  221. #define C20(c0,c1) 0x020, (c0),(c1)
  222. #define C11(c0,a0) 0x011, (c0),(a0)
  223. #define C21(c0,c1,a0) 0x021, (c0),(c1),(a0)
  224. #define C12(c0,a0,a1) 0x012, (c0),(a0),(a1)
  225. #define C22(c0,c1,a0,a1) 0x022, (c0),(c1),(a0),(a1)
  226. #define C13(c0,a0,a1,a2) 0x013, (c0),(a0),(a1),(a2)
  227. #define C23(c0,c1,a0,a1,a2) 0x023, (c0),(c1),(a0),(a1),(a2)
  228. #define C14(c0,a0,a1,a2,a3) 0x013, (c0),(a0),(a1),(a2),(a3)
  229. #define C24(c0,c1,a0,a1,a2,a3) 0x023, (c0),(c1),(a0),(a1),(a2),(a3)
  230. #define UCG_DATA() 0x070
  231. #define D1(d0) 0x071, (d0)
  232. #define D2(d0,d1) 0x072, (d0),(d1)
  233. #define D3(d0,d1,d3) 0x073, (d0),(d1),(d2)
  234. #define D4(d0,d1,d3,d4) 0x074, (d0),(d1),(d2),(d3)
  235. #define D5(d0,d1,d3,d4,d5) 0x075, (d0),(d1),(d2),(d3),(d5)
  236. #define D6(d0,d1,d3,d4,d5,d6) 0x076, (d0),(d1),(d2),(d3),(d5),(d6)
  237. #define DLY_MS(t) 0x080 | (((t)>>8)&15), (t)&255
  238. #define DLY_US(t) 0x090 | (((t)>>8)&15), (t)&255
  239. s: Shift right
  240. a: And mask
  241. o: Or mask
  242. #define UCG_VARX(s,a,o) 0x0a0 | ((s)&15), (a), (o)
  243. #define UCG_VARY(s,a,o) 0x0b0 | ((s)&15), (a), (o)
  244. #define RST(level) 0x0f0 | ((level)&1)
  245. #define CS(level) 0x0f4 | ((level)&1)
  246. #define CFG_CD(c,a) 0x0fc | (((c)&1)<<1) | ((a)&1)
  247. #define END() 0x00
  248. */
  249. static void ucg_com_SendCmdArg(ucg_t *ucg, const ucg_pgm_uint8_t *data, uint8_t cmd_cnt, uint8_t arg_cnt)
  250. {
  251. ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd>>1)&1 );
  252. ucg_com_SendStringP(ucg, cmd_cnt, data);
  253. if ( arg_cnt > 0 )
  254. {
  255. data += cmd_cnt;
  256. ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
  257. ucg_com_SendStringP(ucg, arg_cnt, data);
  258. }
  259. }
  260. //void ucg_com_SendCmdSeq(ucg_t *ucg, const ucg_pgm_uint8_t *data)
  261. void ucg_com_SendCmdSeq(ucg_t *ucg, const ucg_pgm_uint8_t *data)
  262. {
  263. uint8_t b;
  264. uint8_t bb;
  265. uint8_t hi;
  266. uint8_t lo;
  267. for(;;)
  268. {
  269. b = ucg_pgm_read(data);
  270. //b = *data;
  271. hi = (b) >> 4;
  272. lo = (b) & 0x0f;
  273. switch( hi )
  274. {
  275. case 0:
  276. return; /* end marker */
  277. case 1:
  278. case 2:
  279. case 3:
  280. ucg_com_SendCmdArg(ucg, data+1, hi, lo);
  281. data+=1+hi+lo;
  282. break;
  283. case 6:
  284. ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
  285. ucg_com_SendStringP(ucg, lo, data+1);
  286. data+=1+lo;
  287. break;
  288. case 7: /* note: 0x070 is used to set data line status */
  289. ucg_com_SetCDLineStatus(ucg, ((ucg->com_cfg_cd>>1)&1)^1 );
  290. if ( lo > 0 )
  291. ucg_com_SendStringP(ucg, lo, data+1);
  292. data+=1+lo;
  293. break;
  294. case 8:
  295. data++;
  296. b = ucg_pgm_read(data);
  297. //b = *data;
  298. ucg_com_DelayMilliseconds(ucg, (((uint16_t)lo)<<8) + b );
  299. data++;
  300. break;
  301. case 9:
  302. data++;
  303. b = ucg_pgm_read(data);
  304. //b = *data;
  305. ucg_com_DelayMicroseconds(ucg, (((uint16_t)lo)<<8) + b );
  306. data++;
  307. break;
  308. case 10:
  309. data++;
  310. b = ucg_pgm_read(data);
  311. data++;
  312. bb = ucg_pgm_read(data);
  313. data++;
  314. //b = data[0];
  315. //bb = data[1];
  316. ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
  317. ucg_com_SendByte(ucg, (((uint8_t)(((ucg->arg.pixel.pos.x)>>lo)))&b)|bb );
  318. //data+=2;
  319. break;
  320. case 11:
  321. data++;
  322. b = ucg_pgm_read(data);
  323. data++;
  324. bb = ucg_pgm_read(data);
  325. data++;
  326. //b = data[0];
  327. //bb = data[1];
  328. ucg_com_SetCDLineStatus(ucg, (ucg->com_cfg_cd)&1 );
  329. ucg_com_SendByte(ucg, (((uint8_t)(((ucg->arg.pixel.pos.y)>>lo)))&b)|bb );
  330. //data+=2;
  331. break;
  332. case 15:
  333. hi = lo >> 2;
  334. lo &= 3;
  335. switch(hi)
  336. {
  337. case 0:
  338. ucg_com_SetResetLineStatus(ucg, lo&1);
  339. break;
  340. case 1:
  341. ucg_com_SetCSLineStatus(ucg, lo&1);
  342. break;
  343. case 3:
  344. ucg->com_cfg_cd = lo;
  345. break;
  346. }
  347. data++;
  348. break;
  349. default:
  350. return;
  351. }
  352. }
  353. }