Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_uc1638.c

380 lines · 13.5 KB · C

1/*
2
3 u8x8_d_uc1638.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 Support for the UC1638 controller
36
37 20 Jun 2021:
38 The u8x8_d_uc1638_192x96 is tested and works.
39 The u8x8_d_uc1638_160x128 will probably not work, there is no display to test this
40 WARNING; The u8x8_d_uc1638_160x128 also has an inverted CS signal !!!
41 Changed the SPI mode from 3 to 0, because it work nicely with mode 0
42
43
44*/
45#include "u8x8.h"
46
47
48
49
50
51static const uint8_t u8x8_d_uc1638_powersave0_seq[] = {
52 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
53 U8X8_CA(0x0c9, 0x0ad), /* display on */ /* UC1638 B/W mode */
54 U8X8_END_TRANSFER(), /* disable chip */
55 U8X8_END() /* end of sequence */
56};
57
58static const uint8_t u8x8_d_uc1638_powersave1_seq[] = {
59 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
60 U8X8_CA(0x0c9, 0x0ac), /* display off */ /* UC1638 */
61 U8X8_END_TRANSFER(), /* disable chip */
62 U8X8_END() /* end of sequence */
63};
64
65static const uint8_t u8x8_d_uc1638_flip0_seq[] = {
66 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
67 U8X8_C(0x0c2), /* LCD Mapping */ /* UC1638*/
68 U8X8_END_TRANSFER(), /* disable chip */
69 U8X8_END() /* end of sequence */
70};
71
72static const uint8_t u8x8_d_uc1638_flip1_seq[] = {
73 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
74 U8X8_C(0x0c4), /* LCD Mapping */ /* UC1638*/
75 U8X8_END_TRANSFER(), /* disable chip */
76 U8X8_END() /* end of sequence */
77};
78
79
80uint8_t u8x8_d_uc1638_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
81{
82 uint8_t x, y, c;
83 uint8_t *ptr;
84 switch(msg)
85 {
86 case U8X8_MSG_DISPLAY_DRAW_TILE:
87 u8x8_cad_StartTransfer(u8x8);
88
89 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
90 x += u8x8->x_offset & 15;
91 x *= 8;
92
93 u8x8_cad_SendCmd(u8x8, 0x004); /* UC1638 */
94 u8x8_cad_SendArg(u8x8, x);
95
96 y = ((u8x8_tile_t *)arg_ptr)->y_pos;
97 y += u8x8->x_offset >> 4;
98
99 u8x8_cad_SendCmd(u8x8, 0x060 | (y&15)); /* UC1638 */
100 u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4)); /* UC1638 */
101
102
103 u8x8_cad_SendCmd(u8x8, 0x001); /* UC1638 */
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_uc1638_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 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
125 if ( arg_int == 0 )
126 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_powersave0_seq);
127 else
128 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_powersave1_seq);
129 break;
130 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
131 if ( arg_int == 0 )
132 {
133 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_flip0_seq);
134 u8x8->x_offset = u8x8->display_info->default_x_offset;
135 }
136 else
137 {
138 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_flip1_seq);
139 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
140 }
141 break;
142#ifdef U8X8_WITH_SET_CONTRAST
143 case U8X8_MSG_DISPLAY_SET_CONTRAST:
144 u8x8_cad_StartTransfer(u8x8);
145 u8x8_cad_SendCmd(u8x8, 0x081 );
146 u8x8_cad_SendArg(u8x8, arg_int ); /* uc1638 has range from 0 to 255 */
147 u8x8_cad_EndTransfer(u8x8);
148 break;
149#endif
150 default:
151 return 0;
152 }
153 return 1;
154}
155
156
157/*================================================*/
158/* uc1638 160x128 */
159
160/* values taken from uc1608 */
161static const u8x8_display_info_t u8x8_uc1638_160x128_display_info =
162{
163 /* chip_enable_level = */ 1, /* uc1638 has high active CS */
164 /* chip_disable_level = */ 0,
165
166 /* post_chip_enable_wait_ns = */ 10, /* */
167 /* pre_chip_disable_wait_ns = */ 20, /* */
168 /* reset_pulse_width_ms = */ 5, /* */
169 /* post_reset_wait_ms = */ 150,
170 /* sda_setup_time_ns = */ 25, /* */
171 /* sck_pulse_width_ns = */ 65, /* */
172 /* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
173 /* spi_mode = */ 0, /* active high, rising edge */
174 /* i2c_bus_clock_100kHz = */ 4,
175 /* data_setup_time_ns = */ 30, /* */
176 /* write_pulse_width_ns = */ 35, /* */
177 /* tile_width = */ 20, /* width of 20*8=160 pixel */
178 /* tile_height = */ 16,
179 /* default_x_offset = */ 0, /* lower nibble: x offset, upper nibble: y offset */
180 /* flipmode_x_offset = */ 0, /* lower nibble: x offset, upper nibble: y offset */
181 /* pixel_width = */ 160,
182 /* pixel_height = */ 128
183};
184
185static const uint8_t u8x8_d_uc1638_160x128_init_seq[] = {
186
187 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
188
189 U8X8_CA(0x0e1, 0x0e2), /* software reset */ /* UC1638*/
190 U8X8_END_TRANSFER(), /* disable chip, requirement for I2C */
191 U8X8_DLY(5), /* 5 ms */
192
193 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
194
195 U8X8_C(0x024), /* set temp comp*/
196 U8X8_C(0x0c0), /* mirror y and mirror x */ /* WAS: c2 */
197 U8X8_C(0x0a2), /* line rate */
198 U8X8_C(0x0d6), /* gray scale 2 */
199 U8X8_C(0x0eb), /* set bias*/
200 U8X8_C(0x095), /* set 1 bit per pixel, pattern 0*/
201 U8X8_C(0x089), /* set auto increment, low bits are AC2 AC1 AC0 */ /* WAS 89 */
202
203
204 U8X8_CA(0x081, 0x0a0), /* set contrast */ /* UC1638*/
205
206
207 U8X8_END_TRANSFER(), /* disable chip */
208 U8X8_END() /* end of sequence */
209};
210
211uint8_t u8x8_d_uc1638_160x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
212{
213 /* call common procedure first and handle messages there */
214 if ( u8x8_d_uc1638_common(u8x8, msg, arg_int, arg_ptr) == 0 )
215 {
216 /* msg not handled, then try here */
217 switch(msg)
218 {
219 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
220 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1638_160x128_display_info);
221 break;
222 case U8X8_MSG_DISPLAY_INIT:
223 u8x8_d_helper_display_init(u8x8);
224 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_160x128_init_seq);
225 break;
226 default:
227 return 0; /* msg unknown */
228 }
229 }
230 return 1;
231}
232
233
234/*================================================*/
235
236/* LG192962-DW-V33, uc1638 192x96, https://github.com/olikraus/u8g2/issues/371 */
237
238static const u8x8_display_info_t u8x8_uc1638_192x96_display_info =
239{
240 /* chip_enable_level = */ 0, /* low active CS for this display */
241 /* chip_disable_level = */ 1,
242
243 /* post_chip_enable_wait_ns = */ 10, /* */
244 /* pre_chip_disable_wait_ns = */ 20, /* */
245 /* reset_pulse_width_ms = */ 5, /* */
246 /* post_reset_wait_ms = */ 150,
247 /* sda_setup_time_ns = */ 25, /* */
248 /* sck_pulse_width_ns = */ 65, /* */
249 /* sck_clock_hz = */ 2000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
250 /* spi_mode = */ 0, /* active high, rising edge */
251 /* i2c_bus_clock_100kHz = */ 4,
252 /* data_setup_time_ns = */ 30, /* */
253 /* write_pulse_width_ns = */ 35, /* */
254 /* tile_width = */ 24, /* width of 24*8=192 pixel */
255 /* tile_height = */ 12,
256 /* default_x_offset = */ 8*16+0, /* lower nibble: x offset, upper nibble: y offset */
257 /* flipmode_x_offset = */ 0*16+6, /* lower nibble: x offset, upper nibble: y offset */
258 /* pixel_width = */ 192,
259 /* pixel_height = */ 96
260};
261
262static const uint8_t u8x8_d_uc1638_192x96_init_seq[] = {
263
264 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
265
266 U8X8_CA(0x0e1, 0x0e2), /* software reset */ /* UC1638*/
267 U8X8_DLY(5), /* 5 ms */
268
269 U8X8_C(0x024), /* set temp comp*/
270 U8X8_C(0x0c2), /* mirror y and mirror x */
271 U8X8_C(0x0a2), /* line rate */
272 U8X8_C(0x02d), /* charge pump */
273 U8X8_C(0x0ea), /* set bias*/
274 U8X8_CA(0x081, 160), /* set contrast */
275 //U8X8_C(0x0d6), /* gray scale 2 */
276 U8X8_C(0x095), /* set 1 bit per pixel, pattern 0*/
277 U8X8_C(0x086), /* COM scan */
278 U8X8_CA(0x0f1, 159), /* COM End*/
279 U8X8_C(0x089), /* set auto increment, low bits are AC2 AC1 AC0 */ /* WAS 89 */
280 //U8X8_C(0x086), /* scan function 0x86 or 0x87: no effect*/
281
282 U8X8_END_TRANSFER(), /* disable chip */
283 U8X8_END() /* end of sequence */
284};
285
286uint8_t u8x8_d_uc1638_192x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
287{
288 /* call common procedure first and handle messages there */
289 if ( u8x8_d_uc1638_common(u8x8, msg, arg_int, arg_ptr) == 0 )
290 {
291 /* msg not handled, then try here */
292 switch(msg)
293 {
294 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
295 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1638_192x96_display_info);
296 break;
297 case U8X8_MSG_DISPLAY_INIT:
298 u8x8_d_helper_display_init(u8x8);
299 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_192x96_init_seq);
300 break;
301 default:
302 return 0; /* msg unknown */
303 }
304 }
305 return 1;
306}
307
308/*================================================*/
309/* issue https://github.com/olikraus/u8g2/issues/2075 */
310
311static const u8x8_display_info_t u8x8_uc1638_240x128_display_info =
312{
313 /* chip_enable_level = */ 0, /* low active CS for this display */
314 /* chip_disable_level = */ 1,
315
316 /* post_chip_enable_wait_ns = */ 10, /* */
317 /* pre_chip_disable_wait_ns = */ 20, /* */
318 /* reset_pulse_width_ms = */ 5, /* */
319 /* post_reset_wait_ms = */ 150,
320 /* sda_setup_time_ns = */ 25, /* */
321 /* sck_pulse_width_ns = */ 65, /* */
322 /* sck_clock_hz = */ 2000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
323 /* spi_mode = */ 0, /* active high, rising edge */
324 /* i2c_bus_clock_100kHz = */ 4,
325 /* data_setup_time_ns = */ 30, /* */
326 /* write_pulse_width_ns = */ 35, /* */
327 /* tile_width = */ 30, /* width of 30*8=240 pixel */
328 /* tile_height = */ 16,
329 /* default_x_offset = */ 0*16+0, /* lower nibble: x offset, upper nibble: y offset */
330 /* flipmode_x_offset = */ 4*16+0, /* lower nibble: x offset, upper nibble: y offset */
331 /* pixel_width = */ 240,
332 /* pixel_height = */ 128
333};
334
335static const uint8_t u8x8_d_uc1638_240x128_init_seq[] = {
336
337 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
338
339 U8X8_CA(0x0e1, 0x0e2), /* software reset */ /* UC1638*/
340 U8X8_DLY(5), /* 5 ms */
341
342 U8X8_C(0x024), /* set temp comp*/
343 U8X8_C(0x0c2), /* mirror y and mirror x */
344 U8X8_C(0x0a2), /* line rate */
345 //U8X8_C(0x02d), /* charge pump, issue 2075: not used */
346 U8X8_C(0x0eb), /* set bias, issue 2075: 0x0eb*/
347 U8X8_CA(0x081, 120), /* set contrast, issue 2075 */
348 //U8X8_C(0x0d6), /* gray scale 2 */
349 U8X8_C(0x095), /* set 1 bit per pixel, pattern 0*/
350 //U8X8_C(0x086), /* COM scan, issue 2075: not used */
351 //U8X8_CA(0x0f1, 159), /* COM End, issue 2075: not used */
352 U8X8_C(0x089), /* set auto increment, low bits are AC2 AC1 AC0 */ /* WAS 89 */
353 //U8X8_C(0x086), /* scan function 0x86 or 0x87: no effect*/
354
355 U8X8_END_TRANSFER(), /* disable chip */
356 U8X8_END() /* end of sequence */
357};
358
359uint8_t u8x8_d_uc1638_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
360{
361 /* call common procedure first and handle messages there */
362 if ( u8x8_d_uc1638_common(u8x8, msg, arg_int, arg_ptr) == 0 )
363 {
364 /* msg not handled, then try here */
365 switch(msg)
366 {
367 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
368 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1638_240x128_display_info);
369 break;
370 case U8X8_MSG_DISPLAY_INIT:
371 u8x8_d_helper_display_init(u8x8);
372 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_240x128_init_seq);
373 break;
374 default:
375 return 0; /* msg unknown */
376 }
377 }
378 return 1;
379}
380