Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_ssd1316.c

332 lines · 11.5 KB · C

1/*
2
3 u8x8_d_ssd1316.c
4
5 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
6
7 Copyright (c) 2019, 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 SSD1316: 128x39 OLED
36
37 https://github.com/olikraus/u8g2/issues/919
38
39*/
40
41
42#include "u8x8.h"
43
44static const uint8_t u8x8_d_ssd1316_128x32_powersave0_seq[] = {
45 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
46 U8X8_C(0x0af), /* display on */
47 U8X8_END_TRANSFER(), /* disable chip */
48 U8X8_END() /* end of sequence */
49};
50
51static const uint8_t u8x8_d_ssd1316_128x32_powersave1_seq[] = {
52 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
53 U8X8_C(0x0ae), /* display off */
54 U8X8_END_TRANSFER(), /* disable chip */
55 U8X8_END() /* end of sequence */
56};
57
58static const uint8_t u8x8_d_ssd1316_128x32_flip0_seq[] = {
59 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
60 U8X8_C(0x0a1), /* segment remap a0/a1*/
61 U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
62 U8X8_END_TRANSFER(), /* disable chip */
63 U8X8_END() /* end of sequence */
64};
65
66static const uint8_t u8x8_d_ssd1316_128x32_flip1_seq[] = {
67 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
68 U8X8_C(0x0a0), /* segment remap a0/a1*/
69 U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
70 U8X8_END_TRANSFER(), /* disable chip */
71 U8X8_END() /* end of sequence */
72};
73
74
75
76
77/*===================================================*/
78
79static uint8_t u8x8_d_ssd1316_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
80{
81 uint8_t x, c;
82 uint8_t *ptr;
83 switch(msg)
84 {
85 /* handled by the calling function
86 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
87 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1316_128x32_display_info);
88 break;
89 */
90 /* handled by the calling function
91 case U8X8_MSG_DISPLAY_INIT:
92 u8x8_d_helper_display_init(u8x8);
93 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1316_128x32_init_seq);
94 break;
95 */
96 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
97 if ( arg_int == 0 )
98 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1316_128x32_powersave0_seq);
99 else
100 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1316_128x32_powersave1_seq);
101 break;
102 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
103 if ( arg_int == 0 )
104 {
105 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1316_128x32_flip0_seq);
106 u8x8->x_offset = u8x8->display_info->default_x_offset;
107 }
108 else
109 {
110 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1316_128x32_flip1_seq);
111 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
112 }
113 break;
114#ifdef U8X8_WITH_SET_CONTRAST
115 case U8X8_MSG_DISPLAY_SET_CONTRAST:
116 u8x8_cad_StartTransfer(u8x8);
117 u8x8_cad_SendCmd(u8x8, 0x081 );
118 u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
119 u8x8_cad_EndTransfer(u8x8);
120 break;
121#endif
122 case U8X8_MSG_DISPLAY_DRAW_TILE:
123 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
124 x *= 8;
125 x += u8x8->x_offset;
126
127 u8x8_cad_StartTransfer(u8x8);
128
129 u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
130 u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15))); /* probably wrong, should be SendCmd */
131 u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos)); /* probably wrong, should be SendCmd */
132
133 do
134 {
135 c = ((u8x8_tile_t *)arg_ptr)->cnt;
136 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
137 u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
138 arg_int--;
139 } while( arg_int > 0 );
140
141 u8x8_cad_EndTransfer(u8x8);
142 break;
143 default:
144 return 0;
145 }
146 return 1;
147}
148
149/*===================================================*/
150
151
152/* QT-2832TSWUG02/ZJY-2832TSWZG02 */
153static const uint8_t u8x8_d_ssd1316_128x32_init_seq[] = {
154
155 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
156
157
158 U8X8_C(0x0ae), /* display off */
159 U8X8_C(0x040), /* start line */
160 U8X8_CA(0x081, 0x045), /* QG-2832TSWZG02 datasheet */
161
162 U8X8_C(0x0a6), /* none inverted normal display mode */
163 U8X8_CA(0x0a8, 0x01f), /* multiplex ratio, duty = 1/32 */
164
165 U8X8_C(0x0a1), /* segment remap a0/a1*/
166 U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
167
168 U8X8_CA(0x0d3, 0x000), /* display offset */
169 U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
170 U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1*/
171 U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
172 U8X8_CA(0x0db, 0x020), /* vcomh deselect level */
173 U8X8_CA(0x08d, 0x015), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, */
174
175 //U8X8_CA(0x0a2, 0x000), /* set display start line to 0 */
176 //U8X8_CA(0x020, 0x000), /* horizontal addressing mode */
177
178
179 // Flipmode
180 //U8X8_C(0x0a1), /* segment remap a0/a1*/
181 //U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
182
183 U8X8_C(0x02e), /* Deactivate scroll */
184 //U8X8_C(0x0a4), /* output ram to display */
185
186 U8X8_END_TRANSFER(), /* disable chip */
187 U8X8_END() /* end of sequence */
188};
189
190
191
192
193static const u8x8_display_info_t u8x8_ssd1316_128x32_display_info =
194{
195 /* chip_enable_level = */ 0,
196 /* chip_disable_level = */ 1,
197
198 /* post_chip_enable_wait_ns = */ 20,
199 /* pre_chip_disable_wait_ns = */ 10,
200 /* reset_pulse_width_ms = */ 100, /* reset time */
201 /* post_reset_wait_ms = */ 100, /* reset delay */
202 /* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
203 /* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
204 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
205 /* spi_mode = */ 0, /* active high, rising edge */
206 /* i2c_bus_clock_100kHz = */ 4,
207 /* data_setup_time_ns = */ 40,
208 /* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
209 /* tile_width = */ 16,
210 /* tile_height = */ 4,
211 /* default_x_offset = */ 0,
212 /* flipmode_x_offset = */ 0,
213 /* pixel_width = */ 128,
214 /* pixel_height = */ 32
215};
216
217uint8_t u8x8_d_ssd1316_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
218{
219
220 if ( u8x8_d_ssd1316_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
221 return 1;
222
223 switch(msg)
224 {
225 case U8X8_MSG_DISPLAY_INIT:
226 u8x8_d_helper_display_init(u8x8);
227 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1316_128x32_init_seq);
228 break;
229 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
230 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1316_128x32_display_info);
231 break;
232 default:
233 return 0;
234 }
235 return 1;
236}
237
238
239/*===================================================*/
240/*
241QG-9632TLBZG02
242https://datasheet.lcsc.com/lcsc/1804162033_Shenzhen-Allvision-Tech-QG-9632TLBZG02_C91216.pdf
243https://github.com/olikraus/u8g2/issues/1938
244
24596x32
246*/
247
248static const uint8_t u8x8_d_ssd1316_96x32_init_seq[] = {
249
250 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
251
252
253 U8X8_C(0x0ae), /* display off */
254 U8X8_C(0x040), /* start line */
255 U8X8_CA(0x081, 0x045), /* QG-2832TSWZG02 datasheet: 0x081, 0x45 */
256 /* QG-9632: 0x81, 0x60 */
257
258 U8X8_C(0x0a6), /* none inverted normal display mode */
259 U8X8_CA(0x0a8, 0x01f), /* multiplex ratio, duty = 1/32 */
260
261 U8X8_C(0x0a1), /* segment remap a0/a1*/
262 U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
263
264 U8X8_CA(0x0d3, 0x000), /* display offset */
265 U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
266 U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1*/
267 U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
268 U8X8_CA(0x0db, 0x020), /* vcomh deselect level */
269 U8X8_CA(0x08d, 0x015), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, */
270 /* QG-9632: 0x8d, 0x10 */
271
272 //U8X8_CA(0x0a2, 0x000), /* set display start line to 0 */
273 //U8X8_CA(0x020, 0x000), /* horizontal addressing mode */
274
275
276 // Flipmode
277 //U8X8_C(0x0a1), /* segment remap a0/a1*/
278 //U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
279
280 U8X8_C(0x02e), /* Deactivate scroll */
281 //U8X8_C(0x0a4), /* output ram to display */
282
283 U8X8_END_TRANSFER(), /* disable chip */
284 U8X8_END() /* end of sequence */
285};
286
287
288static const u8x8_display_info_t u8x8_ssd1316_96x32_display_info =
289{
290 /* chip_enable_level = */ 0,
291 /* chip_disable_level = */ 1,
292
293 /* post_chip_enable_wait_ns = */ 20,
294 /* pre_chip_disable_wait_ns = */ 10,
295 /* reset_pulse_width_ms = */ 100, /* reset time */
296 /* post_reset_wait_ms = */ 100, /* reset delay */
297 /* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
298 /* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
299 /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
300 /* spi_mode = */ 0, /* active high, rising edge */
301 /* i2c_bus_clock_100kHz = */ 4,
302 /* data_setup_time_ns = */ 40,
303 /* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
304 /* tile_width = */ 12,
305 /* tile_height = */ 4,
306 /* default_x_offset = */ 0,
307 /* flipmode_x_offset = */ 0,
308 /* pixel_width = */ 96,
309 /* pixel_height = */ 32
310};
311
312uint8_t u8x8_d_ssd1316_96x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
313{
314
315 if ( u8x8_d_ssd1316_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
316 return 1;
317
318 switch(msg)
319 {
320 case U8X8_MSG_DISPLAY_INIT:
321 u8x8_d_helper_display_init(u8x8);
322 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1316_96x32_init_seq);
323 break;
324 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
325 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1316_96x32_display_info);
326 break;
327 default:
328 return 0;
329 }
330 return 1;
331}
332