Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_uc1628.c

457 lines · 14.4 KB · C

1/*
2
3 u8x8_d_uc1628.c
4
5 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
6
7 Copyright (c) 2017, 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 UC1628: Monochrome 163x256 driver
35
36 CAD: 011
37
38*/
39
40#include "u8x8.h"
41
42static const uint8_t u8x8_d_uc1628_powersave0_seq[] = {
43 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
44 U8X8_CA( 0x0c9, 0x0ad ), /* display enable */
45 U8X8_END_TRANSFER(), /* disable chip */
46 U8X8_END() /* end of sequence */
47};
48
49static const uint8_t u8x8_d_uc1628_powersave1_seq[] = {
50 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
51 U8X8_CA( 0x0c9, 0x0ac ), /* display disable */
52 U8X8_END_TRANSFER(), /* disable chip */
53 U8X8_END() /* end of sequence */
54};
55
56
57static const uint8_t u8x8_d_uc1628_flip0_seq[] = {
58 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
59 U8X8_C( 0x0c4 ),
60 U8X8_END_TRANSFER(),
61 U8X8_END() /* end of sequence */
62};
63
64static const uint8_t u8x8_d_uc1628_flip1_seq[] = {
65 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
66 U8X8_C( 0x0c2 ),
67 U8X8_END_TRANSFER(), /* disable chip */
68 U8X8_END() /* end of sequence */
69};
70
71static uint8_t u8x8_d_uc1628_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
72{
73 uint8_t x, c;
74 uint8_t *ptr;
75 switch(msg)
76 {
77 /* handled by the calling function
78 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
79 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st75256_256x128_display_info);
80 break;
81 */
82 /* handled by the calling function
83 case U8X8_MSG_DISPLAY_INIT:
84 u8x8_d_helper_display_init(u8x8);
85 u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_init_seq);
86 break;
87 */
88 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
89 if ( arg_int == 0 )
90 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_powersave0_seq);
91 else
92 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_powersave1_seq);
93
94 break;
95#ifdef U8X8_WITH_SET_CONTRAST
96 case U8X8_MSG_DISPLAY_SET_CONTRAST:
97
98 u8x8_cad_StartTransfer(u8x8);
99
100 u8x8_cad_SendCmd(u8x8, 0x081 ); /* volume control */
101 u8x8_cad_SendArg(u8x8, 0 ); /* always 0 */
102 u8x8_cad_SendArg(u8x8, arg_int); /* 8 bit */
103
104 u8x8_cad_EndTransfer(u8x8);
105 break;
106#endif
107 case U8X8_MSG_DISPLAY_DRAW_TILE:
108
109 u8x8_cad_StartTransfer(u8x8);
110 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
111 x *= 8;
112
113 // TODO: u8x8->x_offset IS MISSING here
114
115 u8x8_cad_SendCmd(u8x8, 0x004 ); /* col */
116 u8x8_cad_SendArg(u8x8, x);
117
118 u8x8_cad_SendCmd(u8x8, 0x060 ); /* row */
119 u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos));
120
121 u8x8_cad_SendCmd(u8x8, 0x001 ); // write data
122
123 do
124 {
125 c = ((u8x8_tile_t *)arg_ptr)->cnt;
126 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
127 /* SendData can not handle more than 255 bytes, treat c > 31 correctly */
128 if ( c > 31 )
129 {
130 u8x8_cad_SendData(u8x8, 248, ptr); /* 31*8=248 */
131 ptr+=248;
132 c -= 31;
133 }
134
135 u8x8_cad_SendData(u8x8, c*8, ptr);
136 arg_int--;
137 } while( arg_int > 0 );
138
139 u8x8_cad_EndTransfer(u8x8);
140 break;
141 default:
142 return 0;
143 }
144 return 1;
145}
146
147/*=============================================*/
148/* 256x128, https://github.com/olikraus/u8g2/issues/2260 */
149
150static const u8x8_display_info_t u8x8_uc1628_256x128_display_info =
151{
152 /* chip_enable_level = */ 0,
153 /* chip_disable_level = */ 1,
154
155 /* post_chip_enable_wait_ns = */ 10,
156 /* pre_chip_disable_wait_ns = */ 10,
157 /* reset_pulse_width_ms = */ 5,
158 /* post_reset_wait_ms = */ 5, /**/
159 /* sda_setup_time_ns = */ 25, /* */
160 /* sck_pulse_width_ns = */ 100, /* */
161 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
162 /* spi_mode = */ 0, /* active high, rising edge */
163 /* i2c_bus_clock_100kHz = */ 4, /* 400KHz */
164 /* data_setup_time_ns = */ 45,
165 /* write_pulse_width_ns = */ 125,
166 /* tile_width = */ 32,
167 /* tile_height = */ 16,
168 /* default_x_offset = */ 0, /* */
169 /* flipmode_x_offset = */ 0, /* */
170 /* pixel_width = */ 256,
171 /* pixel_height = */ 128
172};
173
174static const uint8_t u8x8_d_uc1628_256x128_init_seq[] = {
175 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
176
177 U8X8_DLY(20),
178
179 U8X8_C( 0x010 ), /* Termp.: Reset default */
180 U8X8_C( 0x012 ), /* Termp.: Reset default */
181 U8X8_C( 0x014 ), /* Termp.: Reset default */
182
183 /* assign temperature independent framerate */
184 /* 0x00d = 81,9Hz (reset default) */
185 /* 0x000 = 40.0 Hz (min) */
186 /* 0x01f = 140.0 Hz (max) */
187
188 U8X8_CAA( 0x016, 0x000, 0x00d ), /* 1st arg: temp. point, 2nd arg: frame rate */
189
190 U8X8_CA( 0x040, 0x000 ), /* scroll line */
191
192 U8X8_C( 0x020 ), /* temp compensation */
193 U8X8_C( 0x02d ), /* charge pump control */
194 U8X8_C( 0x0eb ), /* LCD Bias: 0xe8=6, ... 0xeb=12 ... 0xed=14 */
195
196 U8X8_CAA( 0x081, 0x000, 0x048 ), /* Contrast, 1st arg is always 0 */
197
198 U8X8_CA( 0x0b8, 0x000 ), /* OTP control: Idle & Ignore */
199
200 U8X8_CA( 0x0f1, 0x07f ), /* set COM end */
201 U8X8_CA( 0x0f2, 0x000 ), /* set partial display start */
202 U8X8_CA( 0x0f3, 0x07f ), /* set partial display end */
203
204 U8X8_C( 0x088 ), /* auto increment control */
205
206 U8X8_C( 0x0c4 ), /* XY mirror in bit 1 & 2 */
207
208 U8X8_DLY(100),
209
210 U8X8_END_TRANSFER(), /* disable chip */
211 U8X8_END() /* end of sequence */
212};
213
214
215uint8_t u8x8_d_uc1628_256x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
216{
217 if ( u8x8_d_uc1628_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
218 return 1;
219 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
220 {
221 u8x8_SetI2CAddress(u8x8, 0x070); /* lowest I2C adr of the UC1628 */
222 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1628_256x128_display_info);
223 return 1;
224 }
225 else if ( msg == U8X8_MSG_DISPLAY_INIT )
226 {
227 u8x8_d_helper_display_init(u8x8);
228 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_256x128_init_seq);
229 return 1;
230 }
231 else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
232 {
233 if ( arg_int == 0 )
234 {
235 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip0_seq);
236 u8x8->x_offset = u8x8->display_info->default_x_offset;
237 }
238 else
239 {
240 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip1_seq);
241 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
242 }
243 return 1;
244 }
245 return 0;
246}
247
248
249/*=============================================*/
250/* 256x32, https://github.com/olikraus/u8g2/issues/2260 */
251
252static const u8x8_display_info_t u8x8_uc1628_256x32_display_info =
253{
254 /* chip_enable_level = */ 0,
255 /* chip_disable_level = */ 1,
256
257 /* post_chip_enable_wait_ns = */ 10,
258 /* pre_chip_disable_wait_ns = */ 10,
259 /* reset_pulse_width_ms = */ 5,
260 /* post_reset_wait_ms = */ 5, /**/
261 /* sda_setup_time_ns = */ 25, /* */
262 /* sck_pulse_width_ns = */ 100, /* */
263 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
264 /* spi_mode = */ 0, /* active high, rising edge */
265 /* i2c_bus_clock_100kHz = */ 4, /* 400KHz */
266 /* data_setup_time_ns = */ 45,
267 /* write_pulse_width_ns = */ 125,
268 /* tile_width = */ 32,
269 /* tile_height = */ 4,
270 /* default_x_offset = */ 0, /* */
271 /* flipmode_x_offset = */ 0, /* */
272 /* pixel_width = */ 256,
273 /* pixel_height = */ 32
274};
275
276static const uint8_t u8x8_d_uc1628_256x32_init_seq[] = {
277 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
278
279 U8X8_DLY(20),
280
281 U8X8_C( 0x010 ), /* Termp.: Reset default */
282 U8X8_C( 0x012 ), /* Termp.: Reset default */
283 U8X8_C( 0x014 ), /* Termp.: Reset default */
284
285 /* assign temperature independent framerate */
286 /* 0x00d = 81,9Hz (reset default) */
287 /* 0x000 = 40.0 Hz (min) */
288 /* 0x01f = 140.0 Hz (max) */
289
290 U8X8_CAA( 0x016, 0x000, 0x00d ), /* 1st arg: temp. point, 2nd arg: frame rate */
291
292 U8X8_CA( 0x040, 0x000 ), /* scroll line */
293
294 U8X8_C( 0x020 ), /* temp compensation */
295 U8X8_C( 0x02d ), /* charge pump control */
296 U8X8_C( 0x0e8 ), /* LCD Bias: 0xe8=6, ... 0xeb=12 ... 0xed=14 */
297
298 U8X8_CAA( 0x081, 0x000, 0x048 ), /* Contrast, 1st arg is always 0 */
299
300 U8X8_CA( 0x0b8, 0x000 ), /* OTP control: Idle & Ignore */
301
302 U8X8_CA( 0x0f1, 0x01f ), /* set COM end */
303 U8X8_CA( 0x0f2, 0x000 ), /* set partial display start */
304 U8X8_CA( 0x0f3, 0x07f ), /* set partial display end */
305
306 U8X8_C( 0x088 ), /* auto increment control */
307
308 U8X8_C( 0x0c4 ), /* XY mirror in bit 1 & 2 */
309
310 U8X8_DLY(100),
311
312 U8X8_END_TRANSFER(), /* disable chip */
313 U8X8_END() /* end of sequence */
314};
315
316
317uint8_t u8x8_d_uc1628_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
318{
319 if ( u8x8_d_uc1628_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
320 return 1;
321 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
322 {
323 u8x8_SetI2CAddress(u8x8, 0x070); /* lowest I2C adr of the UC1628 */
324 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1628_256x32_display_info);
325 return 1;
326 }
327 else if ( msg == U8X8_MSG_DISPLAY_INIT )
328 {
329 u8x8_d_helper_display_init(u8x8);
330 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_256x32_init_seq);
331 return 1;
332 }
333 else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
334 {
335 if ( arg_int == 0 )
336 {
337 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip0_seq);
338 u8x8->x_offset = u8x8->display_info->default_x_offset;
339 }
340 else
341 {
342 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip1_seq);
343 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
344 }
345 return 1;
346 }
347 return 0;
348}
349
350
351/*=============================================*/
352/* 128x64, https://github.com/olikraus/u8g2/issues/2260
353
354 2 Oct 2023: Probably the LCD Bias is wrong, it should be reduced, maybe 0xea or so
355 Moreover the COM end should be halfed (0x03f) --> Done, but not tested
356
357*/
358
359static const u8x8_display_info_t u8x8_uc1628_128x64_display_info =
360{
361 /* chip_enable_level = */ 0,
362 /* chip_disable_level = */ 1,
363
364 /* post_chip_enable_wait_ns = */ 10,
365 /* pre_chip_disable_wait_ns = */ 10,
366 /* reset_pulse_width_ms = */ 5,
367 /* post_reset_wait_ms = */ 5, /**/
368 /* sda_setup_time_ns = */ 25, /* */
369 /* sck_pulse_width_ns = */ 100, /* */
370 /* sck_clock_hz = */ 4000000UL, /* 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, /* 400KHz */
373 /* data_setup_time_ns = */ 45,
374 /* write_pulse_width_ns = */ 125,
375 /* tile_width = */ 16,
376 /* tile_height = */ 8,
377 /* default_x_offset = */ 0, /* */
378 /* flipmode_x_offset = */ 0, /* */
379 /* pixel_width = */ 128,
380 /* pixel_height = */ 64
381};
382
383static const uint8_t u8x8_d_uc1628_128x64_init_seq[] = {
384 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
385
386 U8X8_DLY(20),
387
388 U8X8_C( 0x010 ), /* Termp.: Reset default */
389 U8X8_C( 0x012 ), /* Termp.: Reset default */
390 U8X8_C( 0x014 ), /* Termp.: Reset default */
391
392 /* assign temperature independent framerate */
393 /* 0x00d = 81,9Hz (reset default) */
394 /* 0x000 = 40.0 Hz (min) */
395 /* 0x01f = 140.0 Hz (max) */
396
397 U8X8_CAA( 0x016, 0x000, 0x00d ), /* 1st arg: temp. point, 2nd arg: frame rate */
398
399 U8X8_CA( 0x040, 0x000 ), /* scroll line */
400
401 U8X8_C( 0x020 ), /* temp compensation */
402 U8X8_C( 0x02d ), /* charge pump control */
403 U8X8_C( 0x0eb ), /* LCD Bias: 0xe8=6, ... 0xeb=12 ... 0xed=14 */
404
405 U8X8_CAA( 0x081, 0x000, 0x048 ), /* Contrast, 1st arg is always 0 */
406
407 U8X8_CA( 0x0b8, 0x000 ), /* OTP control: Idle & Ignore */
408
409 U8X8_CA( 0x0f1, 0x03f ), /* set COM end */
410 U8X8_CA( 0x0f2, 0x000 ), /* set partial display start */
411 U8X8_CA( 0x0f3, 0x07f ), /* set partial display end */
412
413 U8X8_C( 0x088 ), /* auto increment control */
414
415 U8X8_C( 0x0c4 ), /* XY mirror in bit 1 & 2 */
416
417 U8X8_DLY(100),
418
419 U8X8_END_TRANSFER(), /* disable chip */
420 U8X8_END() /* end of sequence */
421};
422
423
424uint8_t u8x8_d_uc1628_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
425{
426 if ( u8x8_d_uc1628_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
427 return 1;
428 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
429 {
430 u8x8_SetI2CAddress(u8x8, 0x070); /* lowest I2C adr of the UC1628 */
431 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1628_128x64_display_info);
432 return 1;
433 }
434 else if ( msg == U8X8_MSG_DISPLAY_INIT )
435 {
436 u8x8_d_helper_display_init(u8x8);
437 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_128x64_init_seq);
438 return 1;
439 }
440 else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
441 {
442 if ( arg_int == 0 )
443 {
444 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip0_seq);
445 u8x8->x_offset = u8x8->display_info->default_x_offset;
446 }
447 else
448 {
449 u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip1_seq);
450 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
451 }
452 return 1;
453 }
454 return 0;
455}
456
457