|
1 /* |
|
2 |
|
3 u8x8_d_uc1611.c |
|
4 |
|
5 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) |
|
6 |
|
7 Copyright (c) 2016, olikraus@gmail.com |
|
8 All rights reserved. |
|
9 |
|
10 Redistribution and use in source and binary forms, with or without modification, |
|
11 are permitted provided that the following conditions are met: |
|
12 |
|
13 * Redistributions of source code must retain the above copyright notice, this list |
|
14 of conditions and the following disclaimer. |
|
15 |
|
16 * Redistributions in binary form must reproduce the above copyright notice, this |
|
17 list of conditions and the following disclaimer in the documentation and/or other |
|
18 materials provided with the distribution. |
|
19 |
|
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
|
21 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
|
22 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
23 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
|
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
26 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
27 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
30 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
|
32 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
33 |
|
34 |
|
35 6 Nov 2016: Not yet finished |
|
36 |
|
37 There are two controller: |
|
38 UC1611s 160x256 |
|
39 UC1611 160x240 |
|
40 |
|
41 Differences: |
|
42 UC1611 0xa8 cmd: enables 80 display rows |
|
43 UC1611s 0xa8 cmd: controlls graylevels |
|
44 |
|
45 UC1611 0xc0 cmd: single byte command for LCD mapping control |
|
46 UC1611s 0xc0 cmd: double byte command for LCD mapping control |
|
47 |
|
48 |
|
49 */ |
|
50 #include "u8x8.h" |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 static const uint8_t u8x8_d_uc1611s_powersave0_seq[] = { |
|
57 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
58 U8X8_C(0x0a9), /* display on, UC1611s */ |
|
59 U8X8_END_TRANSFER(), /* disable chip */ |
|
60 U8X8_END() /* end of sequence */ |
|
61 }; |
|
62 |
|
63 static const uint8_t u8x8_d_uc1611s_powersave1_seq[] = { |
|
64 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
65 U8X8_C(0x0a8), /* display off, enter sleep mode, UC1611s */ |
|
66 U8X8_END_TRANSFER(), /* disable chip */ |
|
67 U8X8_END() /* end of sequence */ |
|
68 }; |
|
69 |
|
70 static const uint8_t u8x8_d_uc1611s_flip0_seq[] = { |
|
71 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
72 U8X8_CA(0x0c0, 0x004), /* LCD Mapping */ |
|
73 U8X8_END_TRANSFER(), /* disable chip */ |
|
74 U8X8_END() /* end of sequence */ |
|
75 }; |
|
76 |
|
77 static const uint8_t u8x8_d_uc1611s_flip1_seq[] = { |
|
78 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
79 U8X8_CA(0x0c0, 0x002), /* LCD Mapping */ |
|
80 U8X8_END_TRANSFER(), /* disable chip */ |
|
81 U8X8_END() /* end of sequence */ |
|
82 }; |
|
83 |
|
84 uint8_t u8x8_d_uc1611_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
85 { |
|
86 uint8_t x, y, c; |
|
87 uint8_t *ptr; |
|
88 switch(msg) |
|
89 { |
|
90 case U8X8_MSG_DISPLAY_DRAW_TILE: |
|
91 u8x8_cad_StartTransfer(u8x8); |
|
92 |
|
93 x = ((u8x8_tile_t *)arg_ptr)->x_pos; |
|
94 x *= 8; |
|
95 x += u8x8->x_offset; |
|
96 |
|
97 u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15))); |
|
98 u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) ); |
|
99 |
|
100 y = ((u8x8_tile_t *)arg_ptr)->y_pos; |
|
101 u8x8_cad_SendCmd(u8x8, 0x060 | (y&15)); |
|
102 u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4)); |
|
103 |
|
104 c = ((u8x8_tile_t *)arg_ptr)->cnt; |
|
105 c *= 8; |
|
106 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; |
|
107 do |
|
108 { |
|
109 u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */ |
|
110 arg_int--; |
|
111 } while( arg_int > 0 ); |
|
112 |
|
113 u8x8_cad_EndTransfer(u8x8); |
|
114 break; |
|
115 /* handled in the calling procedure |
|
116 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
117 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_128x64_display_info); |
|
118 break; |
|
119 case U8X8_MSG_DISPLAY_INIT: |
|
120 u8x8_d_helper_display_init(u8x8); |
|
121 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq); |
|
122 break; |
|
123 */ |
|
124 #ifdef U8X8_WITH_SET_CONTRAST |
|
125 case U8X8_MSG_DISPLAY_SET_CONTRAST: |
|
126 u8x8_cad_StartTransfer(u8x8); |
|
127 u8x8_cad_SendCmd(u8x8, 0x081 ); |
|
128 u8x8_cad_SendArg(u8x8, arg_int ); /* uc1611 has range from 0 to 255 */ |
|
129 u8x8_cad_EndTransfer(u8x8); |
|
130 break; |
|
131 #endif |
|
132 default: |
|
133 return 0; |
|
134 } |
|
135 return 1; |
|
136 } |
|
137 |
|
138 /*================================================*/ |
|
139 /* EA DOGM240 */ |
|
140 |
|
141 |
|
142 /* |
|
143 UC1611 has two chip select inputs (CS0 and CS1). |
|
144 CS0 is low active, CS1 is high active. It will depend on the display |
|
145 module whether the display has a is low or high active chip select. |
|
146 */ |
|
147 |
|
148 static const u8x8_display_info_t u8x8_uc1611_240x64_display_info = |
|
149 { |
|
150 /* chip_enable_level = */ 0, |
|
151 /* chip_disable_level = */ 1, |
|
152 |
|
153 /* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */ |
|
154 /* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */ |
|
155 /* reset_pulse_width_ms = */ 1, |
|
156 /* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */ |
|
157 /* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */ |
|
158 /* sck_pulse_width_ns = */ 60, /* half of cycle time */ |
|
159 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ |
|
160 /* spi_mode = */ 0, /* active high, rising edge */ |
|
161 /* i2c_bus_clock_100kHz = */ 4, |
|
162 /* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */ |
|
163 /* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */ |
|
164 /* tile_width = */ 30, /* width of 30*8=240 pixel */ |
|
165 /* tile_hight = */ 8, |
|
166 /* default_x_offset = */ 0, |
|
167 /* flipmode_x_offset = */ 0, |
|
168 /* pixel_width = */ 240, |
|
169 /* pixel_height = */ 64 |
|
170 }; |
|
171 |
|
172 static const uint8_t u8x8_d_uc1611_ea_dogm240_init_seq[] = { |
|
173 |
|
174 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
175 U8X8_C(0x02f), /* internal pump control */ |
|
176 U8X8_CA(0x0f1, 63), /* set COM end */ |
|
177 U8X8_CA(0x0f2, 0x000), /* display line start */ |
|
178 U8X8_CA(0x0f3, 63), /* display line end */ |
|
179 U8X8_C(0x0a3), /* line rate */ |
|
180 U8X8_CA(0x081, 0x0a4), /* set contrast, EA default: 0x0b7 */ |
|
181 |
|
182 //U8X8_C(0x0a9), /* display enable */ |
|
183 |
|
184 U8X8_C(0x0d1), /* display pattern */ |
|
185 U8X8_C(0x089), /* auto increment */ |
|
186 U8X8_CA(0x0c0, 0x004), /* LCD Mapping */ |
|
187 U8X8_C(0x000), /* column low nibble */ |
|
188 U8X8_C(0x010), /* column high nibble */ |
|
189 U8X8_C(0x060), /* page adr low */ |
|
190 U8X8_C(0x070), /* page adr high */ |
|
191 |
|
192 |
|
193 U8X8_END_TRANSFER(), /* disable chip */ |
|
194 U8X8_END() /* end of sequence */ |
|
195 }; |
|
196 |
|
197 /* UC1611s 240x64 display */ |
|
198 uint8_t u8x8_d_uc1611_ea_dogm240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
199 { |
|
200 /* call common procedure first and handle messages there */ |
|
201 if ( u8x8_d_uc1611_common(u8x8, msg, arg_int, arg_ptr) == 0 ) |
|
202 { |
|
203 /* msg not handled, then try here */ |
|
204 switch(msg) |
|
205 { |
|
206 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
207 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_240x64_display_info); |
|
208 break; |
|
209 case U8X8_MSG_DISPLAY_INIT: |
|
210 u8x8_d_helper_display_init(u8x8); |
|
211 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_ea_dogm240_init_seq); |
|
212 break; |
|
213 case U8X8_MSG_DISPLAY_SET_POWER_SAVE: |
|
214 if ( arg_int == 0 ) |
|
215 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave0_seq); |
|
216 else |
|
217 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave1_seq); |
|
218 break; |
|
219 case U8X8_MSG_DISPLAY_SET_FLIP_MODE: |
|
220 if ( arg_int == 0 ) |
|
221 { |
|
222 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip0_seq); |
|
223 u8x8->x_offset = u8x8->display_info->default_x_offset; |
|
224 } |
|
225 else |
|
226 { |
|
227 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip1_seq); |
|
228 u8x8->x_offset = u8x8->display_info->flipmode_x_offset; |
|
229 } |
|
230 break; |
|
231 default: |
|
232 return 0; /* msg unknown */ |
|
233 } |
|
234 } |
|
235 return 1; |
|
236 } |
|
237 |
|
238 /*================================================*/ |
|
239 /* EA DOGXL240 */ |
|
240 |
|
241 static const uint8_t u8x8_d_uc1611_ea_dogxl240_init_seq[] = { |
|
242 |
|
243 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
244 U8X8_C(0x02f), /* internal pump control */ |
|
245 U8X8_CA(0x0f1, 0x07f), /* set COM end */ |
|
246 U8X8_CA(0x0f2, 0x000), /* display line start */ |
|
247 U8X8_CA(0x0f3, 127), /* display line end */ |
|
248 U8X8_C(0x0a3), /* line rate */ |
|
249 U8X8_CA(0x081, 0x08f), /* set contrast */ |
|
250 |
|
251 //U8X8_C(0x0a9), /* display enable */ |
|
252 |
|
253 U8X8_C(0x0d1), /* display pattern */ |
|
254 U8X8_C(0x089), /* auto increment */ |
|
255 U8X8_CA(0x0c0, 0x004), /* LCD Mapping */ |
|
256 U8X8_C(0x000), /* column low nibble */ |
|
257 U8X8_C(0x010), /* column high nibble */ |
|
258 U8X8_C(0x060), /* page adr low */ |
|
259 U8X8_C(0x070), /* page adr high */ |
|
260 |
|
261 |
|
262 U8X8_END_TRANSFER(), /* disable chip */ |
|
263 U8X8_END() /* end of sequence */ |
|
264 }; |
|
265 |
|
266 static const u8x8_display_info_t u8x8_uc1611_240x128_display_info = |
|
267 { |
|
268 /* chip_enable_level = */ 0, |
|
269 /* chip_disable_level = */ 1, |
|
270 |
|
271 /* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */ |
|
272 /* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */ |
|
273 /* reset_pulse_width_ms = */ 1, |
|
274 /* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */ |
|
275 /* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */ |
|
276 /* sck_pulse_width_ns = */ 60, /* half of cycle time */ |
|
277 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ |
|
278 /* spi_mode = */ 0, /* active high, rising edge */ |
|
279 /* i2c_bus_clock_100kHz = */ 4, |
|
280 /* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */ |
|
281 /* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */ |
|
282 /* tile_width = */ 30, /* width of 30*8=240 pixel */ |
|
283 /* tile_hight = */ 16, |
|
284 /* default_x_offset = */ 0, |
|
285 /* flipmode_x_offset = */ 0, |
|
286 /* pixel_width = */ 240, |
|
287 /* pixel_height = */ 128 |
|
288 }; |
|
289 |
|
290 /* UC1611s 240x128 display */ |
|
291 uint8_t u8x8_d_uc1611_ea_dogxl240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
292 { |
|
293 /* call common procedure first and handle messages there */ |
|
294 if ( u8x8_d_uc1611_common(u8x8, msg, arg_int, arg_ptr) == 0 ) |
|
295 { |
|
296 /* msg not handled, then try here */ |
|
297 switch(msg) |
|
298 { |
|
299 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
300 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_240x128_display_info); |
|
301 break; |
|
302 case U8X8_MSG_DISPLAY_INIT: |
|
303 u8x8_d_helper_display_init(u8x8); |
|
304 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_ea_dogxl240_init_seq); |
|
305 break; |
|
306 case U8X8_MSG_DISPLAY_SET_POWER_SAVE: |
|
307 if ( arg_int == 0 ) |
|
308 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave0_seq); |
|
309 else |
|
310 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave1_seq); |
|
311 break; |
|
312 case U8X8_MSG_DISPLAY_SET_FLIP_MODE: |
|
313 if ( arg_int == 0 ) |
|
314 { |
|
315 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip0_seq); |
|
316 u8x8->x_offset = u8x8->display_info->default_x_offset; |
|
317 } |
|
318 else |
|
319 { |
|
320 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip1_seq); |
|
321 u8x8->x_offset = u8x8->display_info->flipmode_x_offset; |
|
322 } |
|
323 break; |
|
324 default: |
|
325 return 0; /* msg unknown */ |
|
326 } |
|
327 } |
|
328 return 1; |
|
329 } |
|
330 |
|
331 /*================================================*/ |
|
332 /* EMERGING DISPLAY, EW50850FLWP 240x160 */ |
|
333 /* active high CS (CS1), UC1611 display */ |
|
334 |
|
335 static const uint8_t u8x8_d_uc1611_ew50850_init_seq[] = { |
|
336 |
|
337 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
338 U8X8_C(0x02f), /* internal pump control */ |
|
339 U8X8_CA(0x0f1, 159), /* set COM end */ |
|
340 U8X8_CA(0x0f2, 0), /* display line start */ |
|
341 U8X8_CA(0x0f3, 159), /* display line end */ |
|
342 U8X8_C(0x0a3), /* line rate */ |
|
343 U8X8_CA(0x081, 75), /* set contrast */ |
|
344 |
|
345 //U8X8_C(0x0a9), /* display enable */ |
|
346 |
|
347 U8X8_C(0x0d2), /* gray level mode: 16 gray shades */ |
|
348 U8X8_C(0x089), /* auto increment */ |
|
349 U8X8_C(0x0c0), /* LCD Mapping Bit 0: MSF, Bit 1: MX, Bit 2: MY */ |
|
350 U8X8_C(0x000), /* column low nibble */ |
|
351 U8X8_C(0x010), /* column high nibble */ |
|
352 U8X8_C(0x060), /* page adr low */ |
|
353 U8X8_C(0x070), /* page adr high */ |
|
354 |
|
355 U8X8_END_TRANSFER(), /* disable chip */ |
|
356 U8X8_END() /* end of sequence */ |
|
357 }; |
|
358 |
|
359 static const u8x8_display_info_t u8x8_uc1611_ew50850_display_info = |
|
360 { |
|
361 /* chip_enable_level = */ 1, /* active high */ |
|
362 /* chip_disable_level = */ 0, |
|
363 |
|
364 /* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */ |
|
365 /* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */ |
|
366 /* reset_pulse_width_ms = */ 1, |
|
367 /* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */ |
|
368 /* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */ |
|
369 /* sck_pulse_width_ns = */ 60, /* half of cycle time */ |
|
370 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ |
|
371 /* spi_mode = */ 0, /* active high, rising edge */ |
|
372 /* i2c_bus_clock_100kHz = */ 4, |
|
373 /* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */ |
|
374 /* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */ |
|
375 /* tile_width = */ 30, /* width of 30*8=240 pixel */ |
|
376 /* tile_hight = */ 20, /* height: 160 pixel */ |
|
377 /* default_x_offset = */ 0, |
|
378 /* flipmode_x_offset = */ 0, |
|
379 /* pixel_width = */ 240, |
|
380 /* pixel_height = */ 160 |
|
381 }; |
|
382 |
|
383 static const uint8_t u8x8_d_uc1611_alt_flip0_seq[] = { |
|
384 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
385 U8X8_C(0x0c0), /* LCD Mapping Bit 0: MSF, Bit 1: MX, Bit 2: MY */ |
|
386 U8X8_END_TRANSFER(), /* disable chip */ |
|
387 U8X8_END() /* end of sequence */ |
|
388 }; |
|
389 |
|
390 static const uint8_t u8x8_d_uc1611_alt_flip1_seq[] = { |
|
391 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
392 U8X8_C(0x0c6), /* LCD Mapping Bit 0: MSF, Bit 1: MX, Bit 2: MY */ |
|
393 U8X8_END_TRANSFER(), /* disable chip */ |
|
394 U8X8_END() /* end of sequence */ |
|
395 }; |
|
396 |
|
397 static const uint8_t u8x8_d_uc1611_powersave0_seq[] = { |
|
398 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
399 U8X8_C(0x0af), /* display on, UC1611 */ |
|
400 U8X8_END_TRANSFER(), /* disable chip */ |
|
401 U8X8_END() /* end of sequence */ |
|
402 }; |
|
403 |
|
404 static const uint8_t u8x8_d_uc1611_powersave1_seq[] = { |
|
405 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
406 U8X8_C(0x0a8), /* display off, enter sleep mode, UC1611 */ |
|
407 U8X8_END_TRANSFER(), /* disable chip */ |
|
408 U8X8_END() /* end of sequence */ |
|
409 }; |
|
410 |
|
411 |
|
412 /* EW50850, 240x160 */ |
|
413 uint8_t u8x8_d_uc1611_ew50850(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
414 { |
|
415 uint8_t x, y, c, i, v, m0, m1, ai; |
|
416 uint8_t *ptr; |
|
417 /* msg not handled, then try here */ |
|
418 switch(msg) |
|
419 { |
|
420 case U8X8_MSG_DISPLAY_DRAW_TILE: |
|
421 u8x8_cad_StartTransfer(u8x8); |
|
422 |
|
423 x = ((u8x8_tile_t *)arg_ptr)->x_pos; |
|
424 x *= 8; |
|
425 x += u8x8->x_offset; |
|
426 |
|
427 y = ((u8x8_tile_t *)arg_ptr)->y_pos; |
|
428 y*=4; |
|
429 m0 = 1; |
|
430 m1 = 2; |
|
431 for( i = 0; i < 4; i++ ) |
|
432 { |
|
433 u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15))); |
|
434 u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) ); |
|
435 |
|
436 u8x8_cad_SendCmd(u8x8, 0x060 | (y&15)); |
|
437 u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4)); |
|
438 |
|
439 ai = arg_int; |
|
440 do |
|
441 { |
|
442 c = ((u8x8_tile_t *)arg_ptr)->cnt; |
|
443 c *= 8; |
|
444 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; |
|
445 while( c > 0 ) |
|
446 { |
|
447 v = 0; |
|
448 if ( *ptr & m0 ) |
|
449 v|= 0x0f; |
|
450 if ( *ptr & m1 ) |
|
451 v|= 0xf0; |
|
452 u8x8_cad_SendData(u8x8, 1, &v); /* note: SendData can not handle more than 255 bytes */ |
|
453 c--; |
|
454 ptr++; |
|
455 } |
|
456 ai--; |
|
457 } while( ai > 0 ); |
|
458 |
|
459 m0 <<= 2; |
|
460 m1 <<= 2; |
|
461 y++; |
|
462 } |
|
463 u8x8_cad_EndTransfer(u8x8); |
|
464 break; |
|
465 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
466 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_ew50850_display_info); |
|
467 break; |
|
468 case U8X8_MSG_DISPLAY_INIT: |
|
469 u8x8_d_helper_display_init(u8x8); |
|
470 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_ew50850_init_seq); |
|
471 break; |
|
472 case U8X8_MSG_DISPLAY_SET_POWER_SAVE: |
|
473 if ( arg_int == 0 ) |
|
474 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_powersave0_seq); |
|
475 else |
|
476 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_powersave1_seq); |
|
477 break; |
|
478 case U8X8_MSG_DISPLAY_SET_FLIP_MODE: |
|
479 if ( arg_int == 0 ) |
|
480 { |
|
481 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_alt_flip0_seq); |
|
482 u8x8->x_offset = u8x8->display_info->default_x_offset; |
|
483 } |
|
484 else |
|
485 { |
|
486 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_alt_flip1_seq); |
|
487 u8x8->x_offset = u8x8->display_info->flipmode_x_offset; |
|
488 } |
|
489 break; |
|
490 #ifdef U8X8_WITH_SET_CONTRAST |
|
491 case U8X8_MSG_DISPLAY_SET_CONTRAST: |
|
492 u8x8_cad_StartTransfer(u8x8); |
|
493 u8x8_cad_SendCmd(u8x8, 0x081 ); |
|
494 u8x8_cad_SendArg(u8x8, arg_int ); /* uc1611 has range from 0 to 255 */ |
|
495 u8x8_cad_EndTransfer(u8x8); |
|
496 break; |
|
497 #endif |
|
498 default: |
|
499 return 0; /* msg unknown */ |
|
500 } |
|
501 return 1; |
|
502 } |
|
503 |
|
504 |
|
505 /*================================================*/ |
|
506 /* CG160160D, http://www.cloverdisplay.com/pdf/CG160160D.pdf */ |
|
507 |
|
508 /* |
|
509 UC1611 has two chip select inputs (CS0 and CS1). |
|
510 CS0 is low active, CS1 is high active. It will depend on the display |
|
511 module whether the display has a is low or high active chip select. |
|
512 |
|
513 Connect CS1 to 3.3V and CS0 to GPIO |
|
514 */ |
|
515 |
|
516 static const u8x8_display_info_t u8x8_uc1611_cg160160_display_info = |
|
517 { |
|
518 /* chip_enable_level = */ 0, /* use CS0 of the UC1611 */ |
|
519 /* chip_disable_level = */ 1, |
|
520 |
|
521 /* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */ |
|
522 /* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */ |
|
523 /* reset_pulse_width_ms = */ 1, |
|
524 /* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */ |
|
525 /* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */ |
|
526 /* sck_pulse_width_ns = */ 60, /* half of cycle time */ |
|
527 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ |
|
528 /* spi_mode = */ 0, /* active high, rising edge */ |
|
529 /* i2c_bus_clock_100kHz = */ 4, |
|
530 /* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */ |
|
531 /* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */ |
|
532 /* tile_width = */ 20, /* width of 20*8=160 pixel */ |
|
533 /* tile_hight = */ 20, |
|
534 /* default_x_offset = */ 0, |
|
535 /* flipmode_x_offset = */ 0, |
|
536 /* pixel_width = */ 160, |
|
537 /* pixel_height = */ 160 |
|
538 }; |
|
539 |
|
540 /* |
|
541 System Reset: E2H --> DONE |
|
542 Set Temp. Compensation: 24H --> DONE |
|
543 Set up LCD format specific parameters MX,MY,etc(double-byte command): C0H,04H --> FLIP0 |
|
544 Set line rate: A3H --> DONE |
|
545 Set Pump Control (internal Vlcd): 2FH --> DONE |
|
546 Set Isolation Clock Front (3 bytes command): 82H, 13H, 01H --> DONE |
|
547 Set Isolation Clock Back (3 bytes command): 82H, 14H, 00H --> DONE |
|
548 Set LCD Bias Ratio: EAH |
|
549 LCD Specific Operation Voltage Setting (double-byte command): 81H, 90H --> DONE |
|
550 Set RAM Address Control: 80H --> DOES NOT MAKE SENSE |
|
551 Set Page Addr. MSB: 72H --> DONE |
|
552 Set Page Addr. LSB : 60H --> DONE |
|
553 Set Column Addr. LSB: 00H --> DONE |
|
554 Set Column Addr.MSB: 10H --> DONE |
|
555 Window Program Enable : F8H --> NOT REQURED |
|
556 Window Starting Column (double-byte command): F4H , 00H --> NOT REQURED |
|
557 Window Ending Column (double-byte command): F6H, 9FH --> NOT REQURED |
|
558 Set one bit for one pixel: D1H --> DONE |
|
559 Set Display Enable: A9H |
|
560 */ |
|
561 |
|
562 static const uint8_t u8x8_d_uc1611_cg160160_init_seq[] = { |
|
563 |
|
564 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
565 U8X8_C(0x0e2), /* system reset */ |
|
566 U8X8_DLY(2), |
|
567 U8X8_C(0x024), /* Temp. Compensation to 0 = -0.05%/ Grad C */ |
|
568 U8X8_C(0x0a3), /* line rate */ |
|
569 U8X8_C(0x02f), /* internal pump control */ |
|
570 U8X8_CAA(0x082, 0x013, 0x001), /* Isolation front clock, "1" is the default value */ |
|
571 U8X8_CAA(0x082, 0x014, 0x000), /* Isolation back clock, "0" is the default value */ |
|
572 U8X8_C(0x0ea), /* bias ratio, default: 0x0ea */ |
|
573 U8X8_CA(0x081, 0x090), /* set contrast, CG160160: 0x090 */ |
|
574 |
|
575 //U8X8_CA(0x0f1, 159), /* set COM end */ |
|
576 //U8X8_CA(0x0f2, 0), /* display line start */ |
|
577 //U8X8_CA(0x0f3, 159), /* display line end */ |
|
578 |
|
579 //U8X8_C(0x0a9), /* display enable */ |
|
580 |
|
581 U8X8_C(0x089), /* RAM Address Control: auto increment */ |
|
582 U8X8_C(0x0d1), /* display pattern */ |
|
583 U8X8_CA(0x0c0, 0x004), /* LCD Mapping */ |
|
584 U8X8_C(0x000), /* column low nibble */ |
|
585 U8X8_C(0x010), /* column high nibble */ |
|
586 U8X8_C(0x060), /* page adr low */ |
|
587 U8X8_C(0x070), /* page adr high */ |
|
588 |
|
589 |
|
590 U8X8_END_TRANSFER(), /* disable chip */ |
|
591 U8X8_END() /* end of sequence */ |
|
592 }; |
|
593 |
|
594 /* cg160160 display */ |
|
595 uint8_t u8x8_d_uc1611_cg160160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
596 { |
|
597 /* call common procedure first and handle messages there */ |
|
598 if ( u8x8_d_uc1611_common(u8x8, msg, arg_int, arg_ptr) == 0 ) |
|
599 { |
|
600 /* msg not handled, then try here */ |
|
601 switch(msg) |
|
602 { |
|
603 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
604 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_cg160160_display_info); |
|
605 break; |
|
606 case U8X8_MSG_DISPLAY_INIT: |
|
607 u8x8_d_helper_display_init(u8x8); |
|
608 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_cg160160_init_seq); |
|
609 break; |
|
610 case U8X8_MSG_DISPLAY_SET_POWER_SAVE: |
|
611 if ( arg_int == 0 ) |
|
612 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave0_seq); |
|
613 else |
|
614 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave1_seq); |
|
615 break; |
|
616 case U8X8_MSG_DISPLAY_SET_FLIP_MODE: |
|
617 if ( arg_int == 0 ) |
|
618 { |
|
619 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip0_seq); |
|
620 u8x8->x_offset = u8x8->display_info->default_x_offset; |
|
621 } |
|
622 else |
|
623 { |
|
624 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip1_seq); |
|
625 u8x8->x_offset = u8x8->display_info->flipmode_x_offset; |
|
626 } |
|
627 break; |
|
628 default: |
|
629 return 0; /* msg unknown */ |
|
630 } |
|
631 } |
|
632 return 1; |
|
633 } |