u8x8_d_uc1698.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*
  2. u8x8_d_uc1698.c
  3. Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
  4. Copyright (c) 2016, 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. There are one controller:
  27. UC1698u 160x160
  28. */
  29. #include "u8x8.h"
  30. static const uint8_t u8x8_d_uc1698u_powersave0_seq[] = {
  31. U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
  32. U8X8_C(0x0ad), //on/off mode /* display on, UC1698s */
  33. U8X8_END_TRANSFER(), /* disable chip */
  34. U8X8_END() /* end of sequence */
  35. };
  36. static const uint8_t u8x8_d_uc1698u_powersave1_seq[] = {
  37. U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
  38. U8X8_C(0x0ac), //on/off mode /* display off, UC1698s */
  39. U8X8_END_TRANSFER(), /* disable chip */
  40. U8X8_END() /* end of sequence */
  41. };
  42. static const uint8_t u8x8_d_uc1698u_flip0_seq[] = {
  43. U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
  44. U8X8_C(0x0c4), /* LCD Mapping */
  45. U8X8_END_TRANSFER(), /* disable chip */
  46. U8X8_END() /* end of sequence */
  47. };
  48. static const uint8_t u8x8_d_uc1698u_flip1_seq[] = {
  49. U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
  50. U8X8_C(0x0c0), /* LCD Mapping */
  51. U8X8_END_TRANSFER(), /* disable chip */
  52. U8X8_END() /* end of sequence */
  53. };
  54. static const uint8_t lut_nibble[16][2] = {
  55. {0x00, 0x00}, // 0b0000
  56. {0x00, 0x0F}, // 0b0001
  57. {0x00, 0xF0}, // 0b0010
  58. {0x00, 0xFF}, // 0b0011
  59. {0x0F, 0x00}, // 0b0100
  60. {0x0F, 0x0F}, // 0b0101
  61. {0x0F, 0xF0}, // 0b0110
  62. {0x0F, 0xFF}, // 0b0111
  63. {0xF0, 0x00}, // 0b1000
  64. {0xF0, 0x0F}, // 0b1001
  65. {0xF0, 0xF0}, // 0b1010
  66. {0xF0, 0xFF}, // 0b1011
  67. {0xFF, 0x00}, // 0b1100
  68. {0xFF, 0x0F}, // 0b1101
  69. {0xFF, 0xF0}, // 0b1110
  70. {0xFF, 0xFF}, // 0b1111
  71. };
  72. uint8_t u8x8_d_uc1698u_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  73. {
  74. uint8_t x, y, c;
  75. uint8_t *ptr;
  76. uint8_t data1=0, data2=0;
  77. switch(msg)
  78. {
  79. case U8X8_MSG_DISPLAY_DRAW_TILE:
  80. u8x8_cad_StartTransfer(u8x8);
  81. x = ((u8x8_tile_t *)arg_ptr)->x_pos;
  82. x = x<<3; // Fast multiplication by 8 with shift
  83. x /= 3; //The X-axis is addressed using 1 RAM cell. 1 cell is 3 pixels in 4k RGB format.
  84. x += u8x8->x_offset;
  85. u8x8_cad_SendCmd(u8x8,0xF4); //start X
  86. u8x8_cad_SendCmd(u8x8,x);
  87. y = ((u8x8_tile_t *)arg_ptr)->y_pos;
  88. y = y<<3;
  89. u8x8_cad_SendCmd(u8x8,0xF5); //start y
  90. u8x8_cad_SendCmd(u8x8,y);
  91. u8x8_cad_SendCmd(u8x8,0xF6); //width
  92. u8x8_cad_SendCmd(u8x8,x+53); // 53=159/3 The X-axis is addressed using 1 RAM cell. 1 cell is 3 pixels in 4k RGB format.
  93. u8x8_cad_SendCmd(u8x8,0xF7); //height
  94. u8x8_cad_SendCmd(u8x8,y+u8x8->display_info->tile_height); //20 tile_height
  95. data1 = (x>>0)&0x0F;
  96. data2 = (x>>4)&0x0F;
  97. data2 |= 0x10;
  98. u8x8_cad_SendCmd(u8x8,data1);
  99. u8x8_cad_SendCmd(u8x8,data2);
  100. data1=0, data2=0;
  101. data1 = (y>>0)&0x0F;
  102. data1 |= 0x60;
  103. data2 = (y>>4)&0x0F;
  104. data2 |= 0x70;
  105. u8x8_cad_SendCmd(u8x8,data1);
  106. u8x8_cad_SendCmd(u8x8,data2);
  107. c = ((u8x8_tile_t *)arg_ptr)->cnt;
  108. c = c<<3; // Fast multiplication by 8 with shift
  109. ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
  110. do
  111. {
  112. for (uint16_t i=0; i<c; i++)
  113. {
  114. const uint8_t *low = lut_nibble[*ptr & 0x0F];
  115. const uint8_t *high = lut_nibble[*ptr >> 4];
  116. uint8_t arr_4k[4];
  117. arr_4k[3] = low[1];
  118. arr_4k[2] = low[0];
  119. arr_4k[1] = high[1];
  120. arr_4k[0] = high[0];
  121. u8x8_cad_SendData(u8x8, 4, arr_4k);
  122. if ((i - 19) % 20 == 0)
  123. {
  124. u8x8_cad_SendData(u8x8, 1, NULL);
  125. }
  126. ptr++;
  127. }
  128. arg_int--;
  129. } while( arg_int > 0 );
  130. u8x8_cad_EndTransfer(u8x8);
  131. break;
  132. /* handled in the calling procedure
  133. case U8X8_MSG_DISPLAY_SETUP_MEMORY:
  134. u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_128x64_display_info);
  135. break;
  136. case U8X8_MSG_DISPLAY_INIT:
  137. u8x8_d_helper_display_init(u8x8);
  138. u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
  139. break;
  140. */
  141. #ifdef U8X8_WITH_SET_CONTRAST
  142. case U8X8_MSG_DISPLAY_SET_CONTRAST:
  143. u8x8_cad_StartTransfer(u8x8);
  144. u8x8_cad_SendCmd(u8x8, 0x081 );
  145. u8x8_cad_SendArg(u8x8, arg_int ); /* uc1611 has range from 0 to 255 */
  146. u8x8_cad_EndTransfer(u8x8);
  147. break;
  148. #endif
  149. default:
  150. return 0;
  151. }
  152. return 1;
  153. }
  154. /*================================================*/
  155. /* https://github.com/olikraus/u8g2/issues/2164 */
  156. static const u8x8_display_info_t u8x8_uc1698u_cg160160_display_info =
  157. {
  158. /* chip_enable_level = */ 0, /* use CS0 of the UC1611 */
  159. /* chip_disable_level = */ 1,
  160. /* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
  161. /* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
  162. /* reset_pulse_width_ms = */ 20,
  163. /* post_reset_wait_ms = */ 200, /* uc1611 datasheet, page 67 */
  164. /* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */
  165. /* sck_pulse_width_ns = */ 60, /* half of cycle time */
  166. /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
  167. /* spi_mode = */ 0, /* active high, rising edge */
  168. /* i2c_bus_clock_100kHz = */ 4,
  169. /* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */
  170. /* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */
  171. /* tile_width = */ 20, /* width of 20*8=160 pixel */
  172. /* tile_height = */ 20,
  173. /* default_x_offset = */ 37,
  174. /* flipmode_x_offset = */ 37,
  175. /* pixel_width = */ 160,
  176. /* pixel_height = */ 160
  177. };
  178. /*
  179. System Reset: E2H --> DONE
  180. Set Temp. Compensation: 24H --> DONE
  181. Set up LCD format specific parameters MX,MY,etc(double-byte command): C0H,04H --> FLIP0
  182. Set line rate: A3H --> DONE
  183. Set Pump Control (internal Vlcd): 2FH --> DONE
  184. Set Isolation Clock Front (3 bytes command): 82H, 13H, 01H --> DONE
  185. Set Isolation Clock Back (3 bytes command): 82H, 14H, 00H --> DONE
  186. Set LCD Bias Ratio: EAH
  187. LCD Specific Operation Voltage Setting (double-byte command): 81H, 90H --> DONE
  188. Set RAM Address Control: 80H --> DOES NOT MAKE SENSE
  189. Set Page Addr. MSB: 72H --> DONE
  190. Set Page Addr. LSB : 60H --> DONE
  191. Set Column Addr. LSB: 00H --> DONE
  192. Set Column Addr.MSB: 10H --> DONE
  193. Window Program Enable : F8H --> NOT REQURED
  194. Window Starting Column (double-byte command): F4H , 00H --> NOT REQURED
  195. Window Ending Column (double-byte command): F6H, 9FH --> NOT REQURED
  196. Set one bit for one pixel: D1H --> DONE
  197. Set Display Enable: A9H
  198. */
  199. static const uint8_t u8x8_d_uc1698u_cg160160_init_seq[] = {
  200. U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
  201. U8X8_C(0x0e2), /* system reset */
  202. U8X8_DLY(10),
  203. /*power control*/
  204. U8X8_C(0x0e9), //Bias Ratio:1/10 bias
  205. U8X8_C(0x02b), //power control set as internal power
  206. U8X8_C(0x024), //set temperate compensation as 0%
  207. U8X8_C(0x081), //electronic potentionmeter
  208. U8X8_C(0x096), //start contrast level
  209. /*display control*/
  210. U8X8_C(0x0a4), //all pixel off
  211. U8X8_C(0x0a6), //inverse display off
  212. /*lcd control*/
  213. U8X8_C(0x0c4), //Set LCD Maping Control (MY=1, MX=0)
  214. U8X8_C(0x0a1), //line rate 15.2klps
  215. U8X8_C(0x0d1), //rgb-rgb
  216. // U8X8_C(0x0d6), //64k color mode
  217. U8X8_C(0x0d5), //4k color mode
  218. U8X8_C(0x084), //12:partial display control disable
  219. /*n-line inversion*/
  220. U8X8_C(0x0c8),
  221. U8X8_C(0x010), //enable NIV
  222. /*com scan fuction*/
  223. U8X8_C(0x0da), //enable FRC,PWM,LRM sequence
  224. /*window*/
  225. U8X8_C(0x0f4), //wpc0:column
  226. U8X8_C(0x025), //start from 112
  227. U8X8_C(0x0f6), //wpc1
  228. U8X8_C(0x05A), //end:272
  229. U8X8_C(0x0f5), //wpp0:row
  230. U8X8_C(0x000), //start from 0
  231. U8X8_C(0x0f7), //wpp1
  232. U8X8_C(0x09F), //end 160
  233. U8X8_C(0x0f8), //inside mode
  234. U8X8_C(0x089), //RAM control /** Draw right then down **/
  235. /*scroll line*/
  236. U8X8_C(0x040), //low bit of scroll line
  237. U8X8_C(0x050), //high bit of scroll line
  238. U8X8_C(0x090), //14:FLT,FLB set
  239. U8X8_C(0x000),
  240. /*partial display*/
  241. U8X8_C(0x084), //12,set partial display control:off
  242. U8X8_C(0x0f1), //com end
  243. U8X8_C(0x09f), //160
  244. U8X8_C(0x0f2), //display start
  245. U8X8_C(0x000), //0
  246. U8X8_C(0x0f3), //display end
  247. U8X8_C(0x0a0), //160
  248. U8X8_C(0x0ac), //display OFF,select on/off mode.Green Enhance mode disable
  249. U8X8_END_TRANSFER(), /* disable chip */
  250. U8X8_END() /* end of sequence */
  251. };
  252. /* cg160160 display */
  253. uint8_t u8x8_d_uc1698_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  254. {
  255. /* call common procedure first and handle messages there */
  256. if ( u8x8_d_uc1698u_common(u8x8, msg, arg_int, arg_ptr) == 0 )
  257. {
  258. /* msg not handled, then try here */
  259. switch(msg)
  260. {
  261. case U8X8_MSG_DISPLAY_SETUP_MEMORY:
  262. u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1698u_cg160160_display_info);
  263. break;
  264. case U8X8_MSG_DISPLAY_INIT:
  265. u8x8_d_helper_display_init(u8x8);
  266. u8x8_cad_SendSequence(u8x8, u8x8_d_uc1698u_cg160160_init_seq);
  267. break;
  268. case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
  269. if ( arg_int == 0 )
  270. u8x8_cad_SendSequence(u8x8, u8x8_d_uc1698u_powersave0_seq);
  271. else
  272. u8x8_cad_SendSequence(u8x8, u8x8_d_uc1698u_powersave1_seq);
  273. break;
  274. case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
  275. if ( arg_int == 0 )
  276. {
  277. u8x8_cad_SendSequence(u8x8, u8x8_d_uc1698u_flip0_seq);
  278. u8x8->x_offset = u8x8->display_info->default_x_offset;
  279. }
  280. else
  281. {
  282. u8x8_cad_SendSequence(u8x8, u8x8_d_uc1698u_flip1_seq);
  283. u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
  284. }
  285. break;
  286. default:
  287. return 0; /* msg unknown */
  288. }
  289. }
  290. return 1;
  291. }