|
1 /* |
|
2 |
|
3 u8x8_d_ssd1327.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 |
|
36 |
|
37 #include "u8x8.h" |
|
38 |
|
39 |
|
40 static const uint8_t u8x8_d_ssd1327_96x96_powersave0_seq[] = { |
|
41 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
42 U8X8_C(0x0af), /* display on */ |
|
43 U8X8_END_TRANSFER(), /* disable chip */ |
|
44 U8X8_END() /* end of sequence */ |
|
45 }; |
|
46 |
|
47 static const uint8_t u8x8_d_ssd1327_96x96_powersave1_seq[] = { |
|
48 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
49 U8X8_C(0x0ae), /* display off */ |
|
50 U8X8_END_TRANSFER(), /* disable chip */ |
|
51 U8X8_END() /* end of sequence */ |
|
52 }; |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 /* |
|
58 input: |
|
59 one tile (8 Bytes) |
|
60 output: |
|
61 Tile for ssd1327 (32 Bytes) |
|
62 */ |
|
63 |
|
64 static uint8_t u8x8_ssd1327_8to32_dest_buf[32]; |
|
65 |
|
66 static uint8_t *u8x8_ssd1327_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr) |
|
67 { |
|
68 uint8_t v; |
|
69 uint8_t a,b; |
|
70 uint8_t i, j; |
|
71 uint8_t *dest; |
|
72 |
|
73 for( j = 0; j < 4; j++ ) |
|
74 { |
|
75 dest = u8x8_ssd1327_8to32_dest_buf; |
|
76 dest += j; |
|
77 a =*ptr; |
|
78 ptr++; |
|
79 b = *ptr; |
|
80 ptr++; |
|
81 for( i = 0; i < 8; i++ ) |
|
82 { |
|
83 v = 0; |
|
84 if ( a&1 ) v |= 0xf0; |
|
85 if ( b&1 ) v |= 0x0f; |
|
86 *dest = v; |
|
87 dest+=4; |
|
88 a >>= 1; |
|
89 b >>= 1; |
|
90 } |
|
91 } |
|
92 |
|
93 return u8x8_ssd1327_8to32_dest_buf; |
|
94 } |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 static uint8_t u8x8_d_ssd1327_96x96_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
100 { |
|
101 uint8_t x, y, c; |
|
102 uint8_t *ptr; |
|
103 switch(msg) |
|
104 { |
|
105 /* handled by the calling function |
|
106 case U8X8_MSG_DISPLAY_SETUP_MEMORY: |
|
107 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_96x96_display_info); |
|
108 break; |
|
109 */ |
|
110 /* handled by the calling function |
|
111 case U8X8_MSG_DISPLAY_INIT: |
|
112 u8x8_d_helper_display_init(u8x8); |
|
113 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_init_seq); |
|
114 break; |
|
115 */ |
|
116 case U8X8_MSG_DISPLAY_SET_POWER_SAVE: |
|
117 if ( arg_int == 0 ) |
|
118 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_powersave0_seq); |
|
119 else |
|
120 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_powersave1_seq); |
|
121 break; |
|
122 #ifdef U8X8_WITH_SET_CONTRAST |
|
123 case U8X8_MSG_DISPLAY_SET_CONTRAST: |
|
124 u8x8_cad_StartTransfer(u8x8); |
|
125 u8x8_cad_SendCmd(u8x8, 0x081 ); |
|
126 u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1327 has range from 0 to 255 */ |
|
127 u8x8_cad_EndTransfer(u8x8); |
|
128 break; |
|
129 #endif |
|
130 case U8X8_MSG_DISPLAY_DRAW_TILE: |
|
131 u8x8_cad_StartTransfer(u8x8); |
|
132 x = ((u8x8_tile_t *)arg_ptr)->x_pos; |
|
133 x *= 4; |
|
134 x+=u8x8->x_offset/2; |
|
135 |
|
136 y = (((u8x8_tile_t *)arg_ptr)->y_pos); |
|
137 y *= 8; |
|
138 |
|
139 u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address, moved out of the loop (issue 302) */ |
|
140 u8x8_cad_SendArg(u8x8, y); |
|
141 u8x8_cad_SendArg(u8x8, y+7); |
|
142 |
|
143 |
|
144 do |
|
145 { |
|
146 c = ((u8x8_tile_t *)arg_ptr)->cnt; |
|
147 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; |
|
148 |
|
149 do |
|
150 { |
|
151 u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */ |
|
152 u8x8_cad_SendArg(u8x8, x ); /* start */ |
|
153 u8x8_cad_SendArg(u8x8, x+3 ); /* end */ |
|
154 |
|
155 |
|
156 u8x8_cad_SendData(u8x8, 32, u8x8_ssd1327_8to32(u8x8, ptr)); |
|
157 ptr += 8; |
|
158 x += 4; |
|
159 c--; |
|
160 } while( c > 0 ); |
|
161 |
|
162 //x += 4; |
|
163 arg_int--; |
|
164 } while( arg_int > 0 ); |
|
165 |
|
166 u8x8_cad_EndTransfer(u8x8); |
|
167 break; |
|
168 default: |
|
169 return 0; |
|
170 } |
|
171 return 1; |
|
172 } |
|
173 |
|
174 /*=============================================*/ |
|
175 /* Seeedstudio Grove OLED 96x96 */ |
|
176 |
|
177 static const u8x8_display_info_t u8x8_ssd1327_96x96_display_info = |
|
178 { |
|
179 /* chip_enable_level = */ 0, |
|
180 /* chip_disable_level = */ 1, |
|
181 |
|
182 /* post_chip_enable_wait_ns = */ 20, |
|
183 /* pre_chip_disable_wait_ns = */ 10, |
|
184 /* reset_pulse_width_ms = */ 100, |
|
185 /* post_reset_wait_ms = */ 100, /**/ |
|
186 /* sda_setup_time_ns = */ 100, /* */ |
|
187 /* sck_pulse_width_ns = */ 100, /* */ |
|
188 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ |
|
189 /* spi_mode = */ 0, /* active high, rising edge */ |
|
190 /* i2c_bus_clock_100kHz = */ 1, /* use 1 instead of 4, because the SSD1327 seems to be very slow */ |
|
191 /* data_setup_time_ns = */ 40, |
|
192 /* write_pulse_width_ns = */ 60, |
|
193 /* tile_width = */ 12, |
|
194 /* tile_hight = */ 12, |
|
195 /* default_x_offset = */ 16, |
|
196 /* flipmode_x_offset = */ 16, |
|
197 /* pixel_width = */ 96, |
|
198 /* pixel_height = */ 96 |
|
199 }; |
|
200 |
|
201 /* https://github.com/SeeedDocument/Grove_OLED_1.12/raw/master/resources/LY120-096096.pdf */ |
|
202 /* http://www.seeedstudio.com/wiki/index.php?title=Twig_-_OLED_96x96 */ |
|
203 /* values from u8glib */ |
|
204 /* |
|
205 Re-map setting in Graphic Display Data RAM, command 0x0a0 |
|
206 Bit 0: Column Address Re-map |
|
207 Bit 1: Nibble Re-map |
|
208 Bit 2: Horizontal/Vertical Address Increment |
|
209 Bit 3: Not used, must be 0 |
|
210 |
|
211 Bit 4: COM Re-map |
|
212 Bit 5: Not used, must be 0 |
|
213 Bit 6: COM Split Odd Even |
|
214 Bit 7: Not used, must be 0 |
|
215 */ |
|
216 |
|
217 |
|
218 static const uint8_t u8x8_d_ssd1327_96x96_init_seq[] = { |
|
219 |
|
220 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
221 |
|
222 U8X8_CA(0x0fd, 0x012), /* unlock display, usually not required because the display is unlocked after reset */ |
|
223 U8X8_C(0x0ae), /* display off */ |
|
224 //U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */ |
|
225 U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x05f * 1/64 duty */ |
|
226 U8X8_CA(0x0a1, 0x000), /* display start line */ |
|
227 //U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */ |
|
228 |
|
229 U8X8_CA(0x0a2, 0x020), /* display offset, shift mapping ram counter */ |
|
230 U8X8_CA(0x0a0, 0x051), /* remap configuration */ |
|
231 |
|
232 |
|
233 U8X8_CA(0x0ab, 0x001), /* Enable internal VDD regulator (RESET) */ |
|
234 //U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */ |
|
235 U8X8_CA(0x081, 0x053), /* contrast, brightness, 0..128 */ |
|
236 //U8X8_CA(0x0b1, 0x055), /* phase length */ |
|
237 U8X8_CA(0x0b1, 0x051), /* phase length */ |
|
238 //U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */ |
|
239 U8X8_CA(0x0b3, 0x001), /* set display clock divide ratio/oscillator frequency */ |
|
240 |
|
241 //? U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */ |
|
242 //? U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */ |
|
243 |
|
244 U8X8_C(0x0b9), /* use linear lookup table */ |
|
245 |
|
246 //U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */ |
|
247 U8X8_CA(0x0bc, 0x008), /* pre-charge voltage level */ |
|
248 //U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */ |
|
249 U8X8_CA(0x0be, 0x007), /* VCOMH voltage */ |
|
250 U8X8_CA(0x0b6, 0x001), /* second precharge */ |
|
251 U8X8_CA(0x0d5, 0x062), /* enable second precharge, internal vsl (bit0 = 0) */ |
|
252 |
|
253 |
|
254 |
|
255 U8X8_C(0x0a4), /* normal display mode */ |
|
256 |
|
257 U8X8_END_TRANSFER(), /* disable chip */ |
|
258 U8X8_END() /* end of sequence */ |
|
259 }; |
|
260 |
|
261 |
|
262 static const uint8_t u8x8_d_ssd1327_seeed_96x96_flip0_seq[] = { |
|
263 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
264 U8X8_CA(0x0a2, 0x020), /* display offset, shift mapping ram counter */ |
|
265 U8X8_CA(0x0a0, 0x051), /* remap configuration */ |
|
266 U8X8_END_TRANSFER(), /* disable chip */ |
|
267 U8X8_END() /* end of sequence */ |
|
268 }; |
|
269 |
|
270 static const uint8_t u8x8_d_ssd1327_seeed_96x96_flip1_seq[] = { |
|
271 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
272 U8X8_CA(0x0a2, 0x060), /* display offset, shift mapping ram counter */ |
|
273 U8X8_CA(0x0a0, 0x042), /* remap configuration */ |
|
274 U8X8_END_TRANSFER(), /* disable chip */ |
|
275 U8X8_END() /* end of sequence */ |
|
276 }; |
|
277 |
|
278 |
|
279 uint8_t u8x8_d_ssd1327_seeed_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
280 { |
|
281 if ( u8x8_d_ssd1327_96x96_generic(u8x8, msg, arg_int, arg_ptr) != 0 ) |
|
282 return 1; |
|
283 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY ) |
|
284 { |
|
285 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_96x96_display_info); |
|
286 return 1; |
|
287 } |
|
288 else if ( msg == U8X8_MSG_DISPLAY_INIT ) |
|
289 { |
|
290 u8x8_d_helper_display_init(u8x8); |
|
291 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_init_seq); |
|
292 return 1; |
|
293 } |
|
294 else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE ) |
|
295 { |
|
296 if ( arg_int == 0 ) |
|
297 { |
|
298 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_seeed_96x96_flip0_seq); |
|
299 u8x8->x_offset = u8x8->display_info->default_x_offset; |
|
300 } |
|
301 else |
|
302 { |
|
303 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_seeed_96x96_flip1_seq); |
|
304 u8x8->x_offset = u8x8->display_info->flipmode_x_offset; |
|
305 } |
|
306 return 1; |
|
307 } |
|
308 return 0; |
|
309 } |
|
310 |
|
311 /*=============================================*/ |
|
312 /* EA W128128 round OLED 128x128 */ |
|
313 /* issue #641 */ |
|
314 /* https://www.lcd-module.de/fileadmin/eng/pdf/grafik/W128128-XR.pdf */ |
|
315 |
|
316 static const u8x8_display_info_t u8x8_ssd1327_ea_w128128_display_info = |
|
317 { |
|
318 /* chip_enable_level = */ 0, |
|
319 /* chip_disable_level = */ 1, |
|
320 |
|
321 /* post_chip_enable_wait_ns = */ 20, |
|
322 /* pre_chip_disable_wait_ns = */ 10, |
|
323 /* reset_pulse_width_ms = */ 100, |
|
324 /* post_reset_wait_ms = */ 100, /**/ |
|
325 /* sda_setup_time_ns = */ 100, /* */ |
|
326 /* sck_pulse_width_ns = */ 100, /* */ |
|
327 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ |
|
328 /* spi_mode = */ 0, /* active high, rising edge */ |
|
329 /* i2c_bus_clock_100kHz = */ 1, /* use 1 instead of 4, because the SSD1327 seems to be very slow */ |
|
330 /* data_setup_time_ns = */ 40, |
|
331 /* write_pulse_width_ns = */ 60, |
|
332 /* tile_width = */ 16, |
|
333 /* tile_hight = */ 16, |
|
334 /* default_x_offset = */ 0, |
|
335 /* flipmode_x_offset = */ 0, |
|
336 /* pixel_width = */ 128, |
|
337 /* pixel_height = */ 128 |
|
338 }; |
|
339 |
|
340 /* this is a copy of the init sequence for the seeed 96x96 oled */ |
|
341 static const uint8_t u8x8_d_ssd1327_ea_w128128_init_seq[] = { |
|
342 |
|
343 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
344 |
|
345 U8X8_CA(0x0fd, 0x012), /* unlock display, usually not required because the display is unlocked after reset */ |
|
346 U8X8_C(0x0ae), /* display off */ |
|
347 //U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */ |
|
348 U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x05f * 1/64 duty */ |
|
349 U8X8_CA(0x0a1, 0x000), /* display start line */ |
|
350 //U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */ |
|
351 |
|
352 U8X8_CA(0x0a2, 0x010), /* display offset, shift mapping ram counter */ |
|
353 U8X8_CA(0x0a0, 0x051), /* remap configuration */ |
|
354 |
|
355 |
|
356 U8X8_CA(0x0ab, 0x001), /* Enable internal VDD regulator (RESET) */ |
|
357 //U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */ |
|
358 U8X8_CA(0x081, 0x053), /* contrast, brightness, 0..128 */ |
|
359 //U8X8_CA(0x0b1, 0x055), /* phase length */ |
|
360 U8X8_CA(0x0b1, 0x051), /* phase length */ |
|
361 //U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */ |
|
362 U8X8_CA(0x0b3, 0x001), /* set display clock divide ratio/oscillator frequency */ |
|
363 |
|
364 //? U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */ |
|
365 //? U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */ |
|
366 |
|
367 U8X8_C(0x0b9), /* use linear lookup table */ |
|
368 |
|
369 //U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */ |
|
370 U8X8_CA(0x0bc, 0x008), /* pre-charge voltage level */ |
|
371 //U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */ |
|
372 U8X8_CA(0x0be, 0x007), /* VCOMH voltage */ |
|
373 U8X8_CA(0x0b6, 0x001), /* second precharge */ |
|
374 U8X8_CA(0x0d5, 0x062), /* enable second precharge, internal vsl (bit0 = 0) */ |
|
375 |
|
376 U8X8_C(0x0a4), /* normal display mode */ |
|
377 |
|
378 U8X8_END_TRANSFER(), /* disable chip */ |
|
379 U8X8_END() /* end of sequence */ |
|
380 }; |
|
381 |
|
382 |
|
383 |
|
384 static const uint8_t u8x8_d_ssd1327_ea_w128128_flip0_seq[] = { |
|
385 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
386 U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */ |
|
387 U8X8_CA(0x0a0, 0x051), /* remap configuration */ |
|
388 U8X8_END_TRANSFER(), /* disable chip */ |
|
389 U8X8_END() /* end of sequence */ |
|
390 }; |
|
391 |
|
392 static const uint8_t u8x8_d_ssd1327_ea_w128128_flip1_seq[] = { |
|
393 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
394 U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */ |
|
395 U8X8_CA(0x0a0, 0x042), /* remap configuration */ |
|
396 U8X8_END_TRANSFER(), /* disable chip */ |
|
397 U8X8_END() /* end of sequence */ |
|
398 }; |
|
399 |
|
400 uint8_t u8x8_d_ssd1327_ea_w128128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
401 { |
|
402 if ( u8x8_d_ssd1327_96x96_generic(u8x8, msg, arg_int, arg_ptr) != 0 ) |
|
403 return 1; |
|
404 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY ) |
|
405 { |
|
406 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_ea_w128128_display_info); |
|
407 return 1; |
|
408 } |
|
409 else if ( msg == U8X8_MSG_DISPLAY_INIT ) |
|
410 { |
|
411 u8x8_d_helper_display_init(u8x8); |
|
412 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_ea_w128128_init_seq); |
|
413 return 1; |
|
414 } |
|
415 else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE ) |
|
416 { |
|
417 if ( arg_int == 0 ) |
|
418 { |
|
419 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_ea_w128128_flip0_seq); |
|
420 u8x8->x_offset = u8x8->display_info->default_x_offset; |
|
421 } |
|
422 else |
|
423 { |
|
424 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_ea_w128128_flip1_seq); |
|
425 u8x8->x_offset = u8x8->display_info->flipmode_x_offset; |
|
426 } |
|
427 return 1; |
|
428 } |
|
429 return 0; |
|
430 } |
|
431 |
|
432 /*=============================================*/ |
|
433 /* MIDAS MCOT128128C1V-YM 128x128 Module */ |
|
434 |
|
435 |
|
436 static const u8x8_display_info_t u8x8_ssd1327_128x128_display_info = |
|
437 { |
|
438 /* chip_enable_level = */ 0, |
|
439 /* chip_disable_level = */ 1, |
|
440 |
|
441 /* post_chip_enable_wait_ns = */ 20, |
|
442 /* pre_chip_disable_wait_ns = */ 10, |
|
443 /* reset_pulse_width_ms = */ 100, |
|
444 /* post_reset_wait_ms = */ 100, /**/ |
|
445 /* sda_setup_time_ns = */ 100, /* */ |
|
446 /* sck_pulse_width_ns = */ 100, /* */ |
|
447 /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ |
|
448 /* spi_mode = */ 0, /* active high, rising edge */ |
|
449 /* i2c_bus_clock_100kHz = */ 1, /* use 1 instead of 4, because the SSD1327 seems to be very slow, Update 9 Aug 2019: The OLED from aliexpress supports 400kHz */ |
|
450 /* data_setup_time_ns = */ 40, |
|
451 /* write_pulse_width_ns = */ 60, |
|
452 /* tile_width = */ 16, |
|
453 /* tile_hight = */ 16, |
|
454 /* default_x_offset = */ 0, |
|
455 /* flipmode_x_offset = */ 0, |
|
456 /* pixel_width = */ 128, |
|
457 /* pixel_height = */ 128 |
|
458 }; |
|
459 |
|
460 /* https://github.com/SeeedDocument/Grove_OLED_1.12/raw/master/resources/LY120-096096.pdf */ |
|
461 /* http://www.seeedstudio.com/wiki/index.php?title=Twig_-_OLED_96x96 */ |
|
462 /* values from u8glib */ |
|
463 /* |
|
464 Re-map setting in Graphic Display Data RAM, command 0x0a0 |
|
465 Bit 0: Column Address Re-map |
|
466 Bit 1: Nibble Re-map |
|
467 Bit 2: Horizontal/Vertical Address Increment |
|
468 Bit 3: Not used, must be 0 |
|
469 |
|
470 Bit 4: COM Re-map |
|
471 Bit 5: Not used, must be 0 |
|
472 Bit 6: COM Split Odd Even |
|
473 Bit 7: Not used, must be 0 |
|
474 */ |
|
475 |
|
476 |
|
477 static const uint8_t u8x8_d_ssd1327_128x128_init_seq[] = { |
|
478 |
|
479 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
480 |
|
481 |
|
482 U8X8_CA(0x0fd, 0x012), /* unlock display, usually not required because the display is unlocked after reset */ |
|
483 U8X8_C(0x0ae), /* display off */ |
|
484 //U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */ |
|
485 //U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x05f * 1/64 duty */ |
|
486 U8X8_CA(0x0a8, 0x07f), /* multiplex ratio: 0x05f * 1/128duty */ |
|
487 U8X8_CA(0x0a1, 0x000), /* display start line */ |
|
488 //U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */ |
|
489 |
|
490 U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */ |
|
491 U8X8_CA(0x0a0, 0x051), /* remap configuration */ |
|
492 |
|
493 |
|
494 U8X8_CA(0x0ab, 0x001), /* Enable internal VDD regulator (RESET) */ |
|
495 //U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */ |
|
496 U8X8_CA(0x081, 0x053), /* contrast, brightness, 0..128 */ |
|
497 //U8X8_CA(0x0b1, 0x055), /* phase length */ |
|
498 U8X8_CA(0x0b1, 0x051), /* phase length */ |
|
499 //U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */ |
|
500 U8X8_CA(0x0b3, 0x001), /* set display clock divide ratio/oscillator frequency */ |
|
501 |
|
502 //? U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */ |
|
503 //? U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */ |
|
504 |
|
505 U8X8_C(0x0b9), /* use linear lookup table */ |
|
506 |
|
507 //U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */ |
|
508 U8X8_CA(0x0bc, 0x008), /* pre-charge voltage level */ |
|
509 //U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */ |
|
510 U8X8_CA(0x0be, 0x007), /* VCOMH voltage */ |
|
511 U8X8_CA(0x0b6, 0x001), /* second precharge */ |
|
512 U8X8_CA(0x0d5, 0x062), /* enable second precharge, internal vsl (bit0 = 0) */ |
|
513 |
|
514 |
|
515 |
|
516 U8X8_C(0x0a4), /* normal display mode */ |
|
517 |
|
518 U8X8_END_TRANSFER(), /* disable chip */ |
|
519 U8X8_END() /* end of sequence */ |
|
520 }; |
|
521 |
|
522 |
|
523 static const uint8_t u8x8_d_ssd1327_128x128_flip0_seq[] = { |
|
524 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
525 U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */ |
|
526 U8X8_CA(0x0a0, 0x051), /* remap configuration */ |
|
527 U8X8_END_TRANSFER(), /* disable chip */ |
|
528 U8X8_END() /* end of sequence */ |
|
529 }; |
|
530 |
|
531 static const uint8_t u8x8_d_ssd1327_128x128_flip1_seq[] = { |
|
532 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
533 U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */ |
|
534 U8X8_CA(0x0a0, 0x042), /* remap configuration */ |
|
535 U8X8_END_TRANSFER(), /* disable chip */ |
|
536 U8X8_END() /* end of sequence */ |
|
537 }; |
|
538 |
|
539 |
|
540 uint8_t u8x8_d_ssd1327_midas_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
541 { |
|
542 /* call the 96x96 procedure at the moment */ |
|
543 if ( u8x8_d_ssd1327_96x96_generic(u8x8, msg, arg_int, arg_ptr) != 0 ) |
|
544 return 1; |
|
545 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY ) |
|
546 { |
|
547 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_128x128_display_info); |
|
548 return 1; |
|
549 } |
|
550 else if ( msg == U8X8_MSG_DISPLAY_INIT ) |
|
551 { |
|
552 u8x8_d_helper_display_init(u8x8); |
|
553 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_128x128_init_seq); |
|
554 return 1; |
|
555 } |
|
556 else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE ) |
|
557 { |
|
558 if ( arg_int == 0 ) |
|
559 { |
|
560 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_128x128_flip0_seq); |
|
561 u8x8->x_offset = u8x8->display_info->default_x_offset; |
|
562 } |
|
563 else |
|
564 { |
|
565 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_128x128_flip1_seq); |
|
566 u8x8->x_offset = u8x8->display_info->flipmode_x_offset; |
|
567 } |
|
568 return 1; |
|
569 } |
|
570 return 0; |
|
571 } |
|
572 |
|
573 |
|
574 /*=============================================*/ |
|
575 /* |
|
576 Waveshare 128x128 Module |
|
577 https://www.waveshare.com/w/upload/8/80/1.5inch_OLED_Module_User_Manual_EN.pdf |
|
578 https://github.com/olikraus/u8g2/issues/880 |
|
579 |
|
580 This is mostly a takeover of the EA display. |
|
581 */ |
|
582 |
|
583 /* https://github.com/SeeedDocument/Grove_OLED_1.12/raw/master/resources/LY120-096096.pdf */ |
|
584 /* http://www.seeedstudio.com/wiki/index.php?title=Twig_-_OLED_96x96 */ |
|
585 /* values from u8glib */ |
|
586 /* |
|
587 Re-map setting in Graphic Display Data RAM, command 0x0a0 |
|
588 Bit 0: Column Address Re-map |
|
589 Bit 1: Nibble Re-map |
|
590 Bit 2: Horizontal/Vertical Address Increment |
|
591 Bit 3: Not used, must be 0 |
|
592 |
|
593 Bit 4: COM Re-map |
|
594 Bit 5: Not used, must be 0 |
|
595 Bit 6: COM Split Odd Even |
|
596 Bit 7: Not used, must be 0 |
|
597 */ |
|
598 |
|
599 /* takeover from https://github.com/olikraus/u8g2/issues/880 */ |
|
600 static const uint8_t u8x8_d_ssd1327_ws_128x128_init_seq[] = { |
|
601 |
|
602 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ |
|
603 |
|
604 U8X8_C(0x0ae), //--turn off oled panel |
|
605 U8X8_CAA(0x015, 0x000, 0x07f), //set column address, start column 0, end column 127 |
|
606 U8X8_CAA(0x075, 0x000, 0x07f), //set row address, start row 0, end row 127 |
|
607 U8X8_CA(0x081, 0x080), //set contrast control |
|
608 U8X8_CA(0x0a0, 0x051), //gment remap, 51 |
|
609 U8X8_CA(0x0a1, 0x000), //start line |
|
610 U8X8_CA(0x0a2, 0x000), //display offset |
|
611 U8X8_CAA(0x0a4, 0x0a8, 0x07f), //rmal display, set multiplex ratio |
|
612 U8X8_CA(0x0b1, 0x0f1), //set phase leghth |
|
613 U8X8_CA(0x0b3, 0x000), //set dclk, 80Hz:0xc1 90Hz:0xe1 100Hz:0x00 110Hz:0x30 120Hz:0x50 130Hz:0x70 01 |
|
614 U8X8_CA(0x0ab, 0x001), // |
|
615 U8X8_CA(0x0b6, 0x00f), //set phase leghth |
|
616 U8X8_CA(0x0be, 0x00f), |
|
617 U8X8_CA(0x0bc, 0x008), |
|
618 U8X8_CA(0x0d5, 0x062), |
|
619 U8X8_CA(0x0fd, 0x012), |
|
620 |
|
621 U8X8_END_TRANSFER(), /* disable chip */ |
|
622 U8X8_END() /* end of sequence */ |
|
623 }; |
|
624 |
|
625 |
|
626 uint8_t u8x8_d_ssd1327_ws_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) |
|
627 { |
|
628 /* call the 96x96 procedure at the moment */ |
|
629 if ( u8x8_d_ssd1327_96x96_generic(u8x8, msg, arg_int, arg_ptr) != 0 ) |
|
630 return 1; |
|
631 if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY ) |
|
632 { |
|
633 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_ea_w128128_display_info); |
|
634 return 1; |
|
635 } |
|
636 else if ( msg == U8X8_MSG_DISPLAY_INIT ) |
|
637 { |
|
638 u8x8_d_helper_display_init(u8x8); |
|
639 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_ws_128x128_init_seq); |
|
640 return 1; |
|
641 } |
|
642 else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE ) |
|
643 { |
|
644 if ( arg_int == 0 ) |
|
645 { |
|
646 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_ea_w128128_flip0_seq); |
|
647 u8x8->x_offset = u8x8->display_info->default_x_offset; |
|
648 } |
|
649 else |
|
650 { |
|
651 u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_ea_w128128_flip1_seq); |
|
652 u8x8->x_offset = u8x8->display_info->flipmode_x_offset; |
|
653 } |
|
654 return 1; |
|
655 } |
|
656 return 0; |
|
657 } |