Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8x8_d_ssd1363.c

344 lines · 10.5 KB · C

1/*
2
3 u8x8_d_ssd1363.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 SSD1363:
36 320 x 160 dot matrix
37 16 gray scale
38
39 https://github.com/olikraus/u8g2/issues/2490
40
41*/
42#include "u8x8.h"
43
44
45
46
47static const uint8_t u8x8_d_ssd1363_powersave0_seq[] = {
48 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
49 U8X8_C(0x0af), /* ssd1363: display on */
50 U8X8_END_TRANSFER(), /* disable chip */
51 U8X8_END() /* end of sequence */
52};
53
54static const uint8_t u8x8_d_ssd1363_powersave1_seq[] = {
55 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
56 U8X8_C(0x0ae), /* ssd1363: display off */
57 U8X8_END_TRANSFER(), /* disable chip */
58 U8X8_END() /* end of sequence */
59};
60
61
62
63/* interpret b as a monochrome bit pattern, write value 15 for high bit and value 0 for a low bit */
64/* topbit (msb) is sent last */
65/* example: b = 0x083 will send 0xff, 0x00, 0x00, 0xf0 */
66
67
68
69/*
70 input:
71 one tile (8 Bytes)
72 output:
73 Tile for SSD1363 (32 Bytes)
74*/
75
76static uint8_t u8x8_ssd1363_to32_dest_buf[32];
77
78static uint8_t *u8x8_ssd1363_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
79{
80 uint8_t a;
81 uint8_t i;
82 uint8_t *dest;
83
84 dest = u8x8_ssd1363_to32_dest_buf;
85
86 if ( ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0 && ptr[4] == 0 && ptr[5] == 0 && ptr[6] == 0 && ptr[7] == 0 )
87 {
88 for( i = 0; i < 32; i++ )
89 *dest++ = 0;
90 return u8x8_ssd1363_to32_dest_buf;
91 }
92
93 a = 1;
94 for( i = 0; i < 8; i++ )
95 {
96 dest[0] = 0;
97 dest[1] = 0;
98 dest[2] = 0;
99 dest[3] = 0;
100 if ( ptr[0] & a )
101 dest[1] |= 0x0f;
102 if ( ptr[1] & a )
103 dest[1] |= 0xf0;
104 if ( ptr[2] & a )
105 dest[0] |= 0x0f;
106 if ( ptr[3] & a )
107 dest[0] |= 0xf0;
108
109 if ( ptr[4] & a )
110 dest[3] |= 0x0f;
111 if ( ptr[5] & a )
112 dest[3] |= 0xf0;
113 if ( ptr[6] & a )
114 dest[2] |= 0x0f;
115 if ( ptr[7] & a )
116 dest[2] |= 0xf0;
117
118 a <<= 1;
119 dest += 4;
120 }
121
122
123 return u8x8_ssd1363_to32_dest_buf;
124}
125
126
127uint8_t u8x8_d_ssd1363_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
128{
129 uint8_t x;
130 uint8_t y, c;
131 uint8_t *ptr;
132 switch(msg)
133 {
134 /* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
135 /*
136 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
137 break;
138 case U8X8_MSG_DISPLAY_INIT:
139 u8x8_d_helper_display_init(u8x8);
140 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_256x128_init_seq);
141 break;
142 */
143 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
144 if ( arg_int == 0 )
145 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_powersave0_seq);
146 else
147 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_powersave1_seq);
148 break;
149#ifdef U8X8_WITH_SET_CONTRAST
150 case U8X8_MSG_DISPLAY_SET_CONTRAST:
151 u8x8_cad_StartTransfer(u8x8);
152 u8x8_cad_SendCmd(u8x8, 0x0C1 );
153 u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1363 has range from 0 to 255 */
154 u8x8_cad_EndTransfer(u8x8);
155 break;
156#endif
157 case U8X8_MSG_DISPLAY_DRAW_TILE:
158 u8x8_cad_StartTransfer(u8x8);
159 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
160 x *= 2; // only every 4th col can be addressed
161 x += u8x8->x_offset;
162
163 y = (((u8x8_tile_t *)arg_ptr)->y_pos);
164 y *= 8;
165
166
167 u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address, moved out of the loop (issue 302) */
168 u8x8_cad_SendArg(u8x8, y);
169 u8x8_cad_SendArg(u8x8, y+7);
170
171 do
172 {
173 c = ((u8x8_tile_t *)arg_ptr)->cnt;
174 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
175
176 do
177 {
178 u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
179 u8x8_cad_SendArg(u8x8, x ); /* start */
180 u8x8_cad_SendArg(u8x8, x+1 ); /* end */
181
182 u8x8_cad_SendCmd(u8x8, 0x05c ); /* write to ram */
183
184 u8x8_cad_SendData(u8x8, 32, u8x8_ssd1363_8to32(u8x8, ptr));
185
186 ptr += 8;
187 x += 2;
188 c--;
189 } while( c > 0 );
190
191 //x += 2;
192 arg_int--;
193 } while( arg_int > 0 );
194
195 u8x8_cad_EndTransfer(u8x8);
196 break;
197 default:
198 return 0;
199 }
200 return 1;
201}
202
203/*=========================================================*/
204
205static const uint8_t u8x8_d_ssd1363_256x128_flip0_seq[] = {
206 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
207 U8X8_CAA(0x0a0, 0x032, 0x000), /* remap */
208 U8X8_CA(0xa2, 0x20), /* display offset, shift mapping ram counter */
209 U8X8_END_TRANSFER(), /* disable chip */
210 U8X8_END() /* end of sequence */
211};
212
213static const uint8_t u8x8_d_ssd1363_256x128_flip1_seq[] = {
214 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
215 U8X8_CAA(0x0a0, 0x020, 0x000), /* remap */
216 U8X8_CA(0xa2, 0x80), /* display offset, shift mapping ram counter */
217 U8X8_END_TRANSFER(), /* disable chip */
218 U8X8_END() /* end of sequence */
219};
220
221
222/*=========================================================*/
223/*
224 https://github.com/olikraus/u8g2/issues/2490
225 ZJY270S0700XG21
226*/
227
228
229static const u8x8_display_info_t u8x8_ssd1363_256x128_display_info =
230{
231 /* chip_enable_level = */ 0,
232 /* chip_disable_level = */ 1,
233
234 /* post_chip_enable_wait_ns = */ 20,
235 /* pre_chip_disable_wait_ns = */ 10,
236 /* reset_pulse_width_ms = */ 100, /* ssd1363: 2 us */
237 /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
238 /* sda_setup_time_ns = */ 50, /* 15ns, but cycle time is 100ns, so use 100/2 */
239 /* sck_pulse_width_ns = */ 50, /* 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
240 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215), 10 MHz (issue 301) */
241 /* spi_mode = */ 0, /* active high, rising edge */
242 /* i2c_bus_clock_100kHz = */ 4,
243 /* data_setup_time_ns = */ 10,
244 /* write_pulse_width_ns = */ 150, /* ssd1363: cycle time is 300ns, so use 300/2 = 150 */
245 /* tile_width = */ 32, /* 256 pixel, so we require 32 bytes for this */
246 /* tile_height = */ 16,
247 /* default_x_offset = */ 8, /* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
248 /* flipmode_x_offset = */ 8,
249 /* pixel_width = */ 256,
250 /* pixel_height = */ 128
251};
252
253
254static const uint8_t u8x8_d_ssd1363_256x128_init_seq[] = {
255
256 U8X8_DLY(1),
257 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
258 U8X8_DLY(1),
259
260 U8X8_CA(0xfd, 0x12), /* unlock */
261 U8X8_C(0xae), /* display off */
262 U8X8_CA(0xb3, 0x30), /* clock divide ratio/oscillator frequency (midas: 0x30 ) */
263 U8X8_CA(0xca, 127), /* multiplex ratio (3..159) */
264 U8X8_CA(0xa2, 0x20), /* display offset, shift mapping ram counter */
265
266 U8X8_CA(0xa1, 0x00), /* display start line */
267
268 //U8X8_CA(0xab, 0x01), /* Enable Internal VDD Regulator */
269/*
270 A[0]=0b, Horizontal address increment [reset] ***
271 A[0]=1b, Vertical address increment
272
273 A[1]=0b, Disable Column Address Re-map [reset]
274 A[1]=1b, Enable Column Address Re-map ***
275
276 A[4]=0b, Scan from COM0 to COM[N –1] [reset]
277 A[4]=1b, Scan from COM[N-1] to COM0, where N is the ***
278
279 Multiplex ratio
280 A[5]=0b, Disable COM Split Odd Even [reset] ***
281 A[5]=1b, Enable COM Split Odd Even
282
283 B[4], Enable / disable Dual COM Line mode
284 0b, Disable Dual COM mode [reset]
285 1b, Enable Dual COM mode (MUX ≤ 79)
286
287 0x16 = 00010110
288*/
289 U8X8_CAA(0xa0, 0x32, 0x000), /* Set Re-Map / Dual COM Line Mode (midas datasheet) */
290 U8X8_CAA(0xb4, 0x32, 0x00c), /* Display Enhancement A (midas datasheet) NOT DOCUMENTED */
291 //U8X8_CA(0xc7, 0x0f), /* Set Scale Factor of Segment Output Current Control */
292 U8X8_CA(0xc1, 0xff), /* contrast */
293 U8X8_CA(0xba, 0x03), /* voltage config: Vp pin is connected to cap */
294 U8X8_C(0xb9), /* linear grayscale */
295 U8X8_CA(0xad, 0x90), /* internal IREF: 0x90, external IREF: 0x80 */
296
297 U8X8_CA(0xb1, 0x74), /* Phase 1 (Reset) & Phase 2 (Pre-Charge) Period Adjustment (midas) */
298 U8X8_CA(0xbb, 0x0c), /* precharge voltage */
299
300 U8X8_CA(0xb6, 0xc8), /* second pre charge (midas) */
301 U8X8_CA(0xbe, 0x04), /* vcomh (midas) */
302
303 U8X8_C(0xa6), /* normal display */
304 U8X8_C(0xa9), /* exit partial display */
305
306
307 U8X8_DLY(1), /* delay 2ms */
308
309
310 U8X8_END_TRANSFER(), /* disable chip */
311 U8X8_END() /* end of sequence */
312};
313
314uint8_t u8x8_d_ssd1363_256x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
315{
316 switch(msg)
317 {
318 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
319 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1363_256x128_display_info);
320 break;
321 case U8X8_MSG_DISPLAY_INIT:
322 u8x8_d_helper_display_init(u8x8);
323 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_256x128_init_seq);
324 break;
325 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
326 if ( arg_int == 0 )
327 {
328 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_256x128_flip0_seq);
329 u8x8->x_offset = u8x8->display_info->default_x_offset;
330 }
331 else
332 {
333 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_256x128_flip1_seq);
334 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
335 }
336 break;
337
338 default:
339 return u8x8_d_ssd1363_common(u8x8, msg, arg_int, arg_ptr);
340 }
341 return 1;
342}
343
344