components/u8g2/csrc/u8x8_d_st7567.c

changeset 0
88d965579617
equal deleted inserted replaced
-1:000000000000 0:88d965579617
1 /*
2
3 u8x8_d_st7567.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 #include "u8x8.h"
37
38
39
40
41 static const uint8_t u8x8_d_st7567_132x64_powersave0_seq[] = {
42 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
43 U8X8_C(0x0a4), /* all pixel off, issue 142 */
44 U8X8_C(0x0af), /* display on */
45 U8X8_END_TRANSFER(), /* disable chip */
46 U8X8_END() /* end of sequence */
47 };
48
49 static const uint8_t u8x8_d_st7567_132x64_powersave1_seq[] = {
50 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
51 U8X8_C(0x0ae), /* display off */
52 U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
53 U8X8_END_TRANSFER(), /* disable chip */
54 U8X8_END() /* end of sequence */
55 };
56
57 static const uint8_t u8x8_d_st7567_132x64_flip0_seq[] = {
58 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
59 U8X8_C(0x0a1), /* segment remap a0/a1*/
60 U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
61 U8X8_END_TRANSFER(), /* disable chip */
62 U8X8_END() /* end of sequence */
63 };
64
65 static const uint8_t u8x8_d_st7567_132x64_flip1_seq[] = {
66 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
67 U8X8_C(0x0a0), /* segment remap a0/a1*/
68 U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
69 U8X8_END_TRANSFER(), /* disable chip */
70 U8X8_END() /* end of sequence */
71 };
72
73 static const uint8_t u8x8_d_st7567_n_flip0_seq[] = {
74 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
75 U8X8_C(0x0a0), /* segment remap a0/a1*/
76 U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
77 U8X8_END_TRANSFER(), /* disable chip */
78 U8X8_END() /* end of sequence */
79 };
80
81 static const uint8_t u8x8_d_st7567_n_flip1_seq[] = {
82 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
83 U8X8_C(0x0a1), /* segment remap a0/a1*/
84 U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
85 U8X8_END_TRANSFER(), /* disable chip */
86 U8X8_END() /* end of sequence */
87 };
88
89
90
91 /*=====================================================*/
92
93
94 static const u8x8_display_info_t u8x8_st7567_132x64_display_info =
95 {
96 /* chip_enable_level = */ 0,
97 /* chip_disable_level = */ 1,
98
99 /* post_chip_enable_wait_ns = */ 150, /* */
100 /* pre_chip_disable_wait_ns = */ 50, /* */
101 /* reset_pulse_width_ms = */ 1,
102 /* post_reset_wait_ms = */ 1,
103 /* sda_setup_time_ns = */ 50, /* */
104 /* sck_pulse_width_ns = */ 120, /* */
105 /* sck_clock_hz = */ 4000000UL, /* */
106 /* spi_mode = */ 0, /* active high, rising edge */
107 /* i2c_bus_clock_100kHz = */ 4,
108 /* data_setup_time_ns = */ 40, /* */
109 /* write_pulse_width_ns = */ 80, /* */
110 /* tile_width = */ 17, /* width of 17*8=136 pixel */
111 /* tile_hight = */ 8,
112 /* default_x_offset = */ 0,
113 /* flipmode_x_offset = */ 0,
114 /* pixel_width = */ 132,
115 /* pixel_height = */ 64
116 };
117
118 static const uint8_t u8x8_d_st7567_132x64_init_seq[] = {
119
120 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
121
122 U8X8_C(0x0e2), /* soft reset */
123 U8X8_C(0x0ae), /* display off */
124 U8X8_C(0x040), /* set display start line to 0 */
125
126 U8X8_C(0x0a1), /* ADC set to reverse */
127 U8X8_C(0x0c0), /* common output mode */
128 // Flipmode
129 //U8X8_C(0x0a0), /* ADC set to reverse */
130 //U8X8_C(0x0c8), /* common output mode */
131
132 U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
133 U8X8_C(0x0a3), /* LCD bias 1/7 */
134 /* power on sequence from paxinstruments */
135 U8X8_C(0x028|4), /* all power control circuits on */
136 U8X8_DLY(50),
137 U8X8_C(0x028|6), /* all power control circuits on */
138 U8X8_DLY(50),
139 U8X8_C(0x028|7), /* all power control circuits on */
140 U8X8_DLY(50),
141
142 U8X8_C(0x026), /* v0 voltage resistor ratio */
143 U8X8_CA(0x081, 0x027), /* set contrast, contrast value*/
144
145 U8X8_C(0x0ae), /* display off */
146 U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
147
148 U8X8_END_TRANSFER(), /* disable chip */
149 U8X8_END() /* end of sequence */
150 };
151
152 /* pax instruments 132x64 display */
153 uint8_t u8x8_d_st7567_pi_132x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
154 {
155 uint8_t x, c;
156 uint8_t *ptr;
157 switch(msg)
158 {
159 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
160 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_132x64_display_info);
161 break;
162 case U8X8_MSG_DISPLAY_INIT:
163 u8x8_d_helper_display_init(u8x8);
164 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_init_seq);
165 break;
166 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
167 if ( arg_int == 0 )
168 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
169 else
170 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
171 break;
172 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
173 if ( arg_int == 0 )
174 {
175 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
176 u8x8->x_offset = u8x8->display_info->default_x_offset;
177 }
178 else
179 {
180 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
181 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
182 }
183 break;
184 #ifdef U8X8_WITH_SET_CONTRAST
185 case U8X8_MSG_DISPLAY_SET_CONTRAST:
186 u8x8_cad_StartTransfer(u8x8);
187 u8x8_cad_SendCmd(u8x8, 0x081 );
188 u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
189 u8x8_cad_EndTransfer(u8x8);
190 break;
191 #endif
192 case U8X8_MSG_DISPLAY_DRAW_TILE:
193 u8x8_cad_StartTransfer(u8x8);
194
195 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
196 x *= 8;
197 x += u8x8->x_offset;
198 u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
199 u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
200 u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
201
202 c = ((u8x8_tile_t *)arg_ptr)->cnt;
203 c *= 8;
204 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
205 /*
206 The following if condition checks the hardware limits of the st7567
207 controller: It is not allowed to write beyond the display limits.
208 This is in fact an issue within flip mode.
209 */
210 if ( c + x > 132u )
211 {
212 c = 132u;
213 c -= x;
214 }
215 do
216 {
217 u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
218 arg_int--;
219 } while( arg_int > 0 );
220
221 u8x8_cad_EndTransfer(u8x8);
222 break;
223 default:
224 return 0;
225 }
226 return 1;
227 }
228
229
230
231
232 /*=====================================================*/
233
234
235
236
237
238 static const u8x8_display_info_t u8x8_st7567_jlx12864_display_info =
239 {
240 /* chip_enable_level = */ 0,
241 /* chip_disable_level = */ 1,
242
243 /* post_chip_enable_wait_ns = */ 150, /* */
244 /* pre_chip_disable_wait_ns = */ 50, /* */
245 /* reset_pulse_width_ms = */ 1,
246 /* post_reset_wait_ms = */ 1,
247 /* sda_setup_time_ns = */ 50, /* */
248 /* sck_pulse_width_ns = */ 120, /* */
249 /* sck_clock_hz = */ 4000000UL, /* */
250 /* spi_mode = */ 0, /* active high, rising edge */
251 /* i2c_bus_clock_100kHz = */ 4,
252 /* data_setup_time_ns = */ 40, /* */
253 /* write_pulse_width_ns = */ 80, /* */
254 /* tile_width = */ 16, /* width of 16*8=128 pixel */
255 /* tile_hight = */ 8,
256 /* default_x_offset = */ 4,
257 /* flipmode_x_offset = */ 0,
258 /* pixel_width = */ 128,
259 /* pixel_height = */ 64
260 };
261
262 static const uint8_t u8x8_st7567_jlx12864_init_seq[] = {
263
264 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
265
266 U8X8_C(0x0e2), /* soft reset */
267 U8X8_C(0x0ae), /* display off */
268 U8X8_C(0x040), /* set display start line to 0 */
269
270 U8X8_C(0x0a1), /* ADC set to reverse */
271 U8X8_C(0x0c0), /* common output mode */
272 // Flipmode
273 //U8X8_C(0x0a0), /* ADC set to reverse */
274 //U8X8_C(0x0c8), /* common output mode */
275
276 U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
277 U8X8_C(0x0a3), /* LCD bias 1/7 */
278 /* power on sequence from paxinstruments */
279 U8X8_C(0x028|4), /* all power control circuits on */
280 U8X8_DLY(50),
281 U8X8_C(0x028|6), /* all power control circuits on */
282 U8X8_DLY(50),
283 U8X8_C(0x028|7), /* all power control circuits on */
284 U8X8_DLY(50),
285
286 U8X8_C(0x023), /* v0 voltage resistor ratio */
287 U8X8_CA(0x081, 42>>2), /* set contrast, contrast value*/
288
289 U8X8_C(0x0ae), /* display off */
290 U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
291
292 U8X8_END_TRANSFER(), /* disable chip */
293 U8X8_END() /* end of sequence */
294 };
295
296 /* JLX12864 display */
297 uint8_t u8x8_d_st7567_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
298 {
299 uint8_t x, c;
300 uint8_t *ptr;
301 switch(msg)
302 {
303 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
304 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_jlx12864_display_info);
305 break;
306 case U8X8_MSG_DISPLAY_INIT:
307 u8x8_d_helper_display_init(u8x8);
308 u8x8_cad_SendSequence(u8x8, u8x8_st7567_jlx12864_init_seq);
309 break;
310 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
311 if ( arg_int == 0 )
312 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
313 else
314 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
315 break;
316 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
317 if ( arg_int == 0 )
318 {
319 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
320 u8x8->x_offset = u8x8->display_info->default_x_offset;
321 }
322 else
323 {
324 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
325 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
326 }
327 break;
328 #ifdef U8X8_WITH_SET_CONTRAST
329 case U8X8_MSG_DISPLAY_SET_CONTRAST:
330 u8x8_cad_StartTransfer(u8x8);
331 u8x8_cad_SendCmd(u8x8, 0x081 );
332 u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
333 u8x8_cad_EndTransfer(u8x8);
334 break;
335 #endif
336 case U8X8_MSG_DISPLAY_DRAW_TILE:
337 u8x8_cad_StartTransfer(u8x8);
338
339 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
340 x *= 8;
341 x += u8x8->x_offset;
342 u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
343 u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
344 u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
345
346 c = ((u8x8_tile_t *)arg_ptr)->cnt;
347 c *= 8;
348 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
349 /*
350 The following if condition checks the hardware limits of the st7567
351 controller: It is not allowed to write beyond the display limits.
352 This is in fact an issue within flip mode.
353 */
354 if ( c + x > 132u )
355 {
356 c = 132u;
357 c -= x;
358 }
359 do
360 {
361 u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
362 arg_int--;
363 } while( arg_int > 0 );
364
365 u8x8_cad_EndTransfer(u8x8);
366 break;
367 default:
368 return 0;
369 }
370 return 1;
371 }
372
373
374 /*=====================================================*/
375
376
377
378 static const u8x8_display_info_t u8x8_st7567_enh_dg128064_display_info =
379 {
380 /* chip_enable_level = */ 0,
381 /* chip_disable_level = */ 1,
382
383 /* post_chip_enable_wait_ns = */ 150, /* */
384 /* pre_chip_disable_wait_ns = */ 50, /* */
385 /* reset_pulse_width_ms = */ 1,
386 /* post_reset_wait_ms = */ 1,
387 /* sda_setup_time_ns = */ 50, /* */
388 /* sck_pulse_width_ns = */ 120, /* */
389 /* sck_clock_hz = */ 4000000UL, /* */
390 /* spi_mode = */ 0, /* active high, rising edge */
391 /* i2c_bus_clock_100kHz = */ 4,
392 /* data_setup_time_ns = */ 40, /* */
393 /* write_pulse_width_ns = */ 80, /* */
394 /* tile_width = */ 16, /* width of 16*8=128 pixel */
395 /* tile_hight = */ 8,
396 /* default_x_offset = */ 0,
397 /* flipmode_x_offset = */ 4,
398 /* pixel_width = */ 128,
399 /* pixel_height = */ 64
400 };
401
402 static const u8x8_display_info_t u8x8_st7567_enh_dg128064i_display_info =
403 {
404 /* chip_enable_level = */ 0,
405 /* chip_disable_level = */ 1,
406
407 /* post_chip_enable_wait_ns = */ 150, /* */
408 /* pre_chip_disable_wait_ns = */ 50, /* */
409 /* reset_pulse_width_ms = */ 1,
410 /* post_reset_wait_ms = */ 1,
411 /* sda_setup_time_ns = */ 50, /* */
412 /* sck_pulse_width_ns = */ 120, /* */
413 /* sck_clock_hz = */ 4000000UL, /* */
414 /* spi_mode = */ 0, /* active high, rising edge */
415 /* i2c_bus_clock_100kHz = */ 4,
416 /* data_setup_time_ns = */ 40, /* */
417 /* write_pulse_width_ns = */ 80, /* */
418 /* tile_width = */ 16, /* width of 16*8=128 pixel */
419 /* tile_hight = */ 8,
420 /* default_x_offset = */ 4,
421 /* flipmode_x_offset = */ 0,
422 /* pixel_width = */ 128,
423 /* pixel_height = */ 64
424 };
425
426 static const uint8_t u8x8_st7567_enh_dg128064_init_seq[] = {
427
428 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
429
430 U8X8_C(0x0e2), /* soft reset */
431 U8X8_C(0x0ae), /* display off */
432 U8X8_C(0x040), /* set display start line to 0 */
433
434 U8X8_C(0x0a1), /* ADC set to reverse */
435 U8X8_C(0x0c0), /* common output mode */
436 // Flipmode
437 //U8X8_C(0x0a0), /* ADC set to reverse */
438 //U8X8_C(0x0c8), /* common output mode */
439
440 U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
441 U8X8_C(0x0a2), /* LCD bias 1/9 */
442 /* power on sequence from paxinstruments */
443 U8X8_C(0x028|4), /* all power control circuits on */
444 U8X8_DLY(50),
445 U8X8_C(0x028|6), /* all power control circuits on */
446 U8X8_DLY(50),
447 U8X8_C(0x028|7), /* all power control circuits on */
448 U8X8_DLY(50),
449
450 U8X8_C(0x023), /* v0 voltage resistor ratio */
451 U8X8_CA(0x081, 200>>2), /* set contrast, contrast value*/
452
453 U8X8_C(0x0ae), /* display off */
454 U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
455
456 U8X8_END_TRANSFER(), /* disable chip */
457 U8X8_END() /* end of sequence */
458 };
459
460 /* ENH-DG128064 transparent display */
461 static uint8_t u8x8_d_st7567_enh_dg128064_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
462 {
463 uint8_t x, c;
464 uint8_t *ptr;
465 switch(msg)
466 {
467 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
468 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_enh_dg128064_display_info);
469 break;
470 case U8X8_MSG_DISPLAY_INIT:
471 u8x8_d_helper_display_init(u8x8);
472 u8x8_cad_SendSequence(u8x8, u8x8_st7567_enh_dg128064_init_seq);
473 break;
474 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
475 if ( arg_int == 0 )
476 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
477 else
478 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
479 break;
480 #ifdef U8X8_WITH_SET_CONTRAST
481 case U8X8_MSG_DISPLAY_SET_CONTRAST:
482 u8x8_cad_StartTransfer(u8x8);
483 u8x8_cad_SendCmd(u8x8, 0x081 );
484 u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
485 u8x8_cad_EndTransfer(u8x8);
486 break;
487 #endif
488 case U8X8_MSG_DISPLAY_DRAW_TILE:
489 u8x8_cad_StartTransfer(u8x8);
490
491 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
492 x *= 8;
493 x += u8x8->x_offset;
494 u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
495 u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
496 u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
497
498 c = ((u8x8_tile_t *)arg_ptr)->cnt;
499 c *= 8;
500 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
501 /*
502 The following if condition checks the hardware limits of the st7567
503 controller: It is not allowed to write beyond the display limits.
504 This is in fact an issue within flip mode.
505 */
506 if ( c + x > 132u )
507 {
508 c = 132u;
509 c -= x;
510 }
511 do
512 {
513 u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
514 arg_int--;
515 } while( arg_int > 0 );
516
517 u8x8_cad_EndTransfer(u8x8);
518 break;
519 default:
520 return 0;
521 }
522 return 1;
523 }
524
525 uint8_t u8x8_d_st7567_enh_dg128064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
526 {
527 switch(msg)
528 {
529 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
530 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_enh_dg128064_display_info);
531 break;
532 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
533 if ( arg_int == 0 )
534 {
535 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_n_flip0_seq);
536 u8x8->x_offset = u8x8->display_info->default_x_offset;
537 }
538 else
539 {
540 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_n_flip1_seq);
541 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
542 }
543 break;
544 default:
545 return u8x8_d_st7567_enh_dg128064_generic(u8x8, msg, arg_int, arg_ptr);
546 }
547 return 1;
548 }
549
550 uint8_t u8x8_d_st7567_enh_dg128064i(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
551 {
552 switch(msg)
553 {
554 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
555 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_enh_dg128064i_display_info);
556 break;
557 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
558 if ( arg_int == 0 )
559 {
560 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
561 u8x8->x_offset = u8x8->display_info->default_x_offset;
562 }
563 else
564 {
565 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
566 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
567 }
568 break;
569 default:
570 return u8x8_d_st7567_enh_dg128064_generic(u8x8, msg, arg_int, arg_ptr);
571 }
572 return 1;
573 }
574
575
576 /*=====================================================*/
577 /* issue 657 */
578
579 static const u8x8_display_info_t u8x8_st7567_64x32_display_info =
580 {
581 /* chip_enable_level = */ 0,
582 /* chip_disable_level = */ 1,
583
584 /* post_chip_enable_wait_ns = */ 150, /* */
585 /* pre_chip_disable_wait_ns = */ 50, /* */
586 /* reset_pulse_width_ms = */ 1,
587 /* post_reset_wait_ms = */ 1,
588 /* sda_setup_time_ns = */ 50, /* */
589 /* sck_pulse_width_ns = */ 120, /* */
590 /* sck_clock_hz = */ 4000000UL, /* */
591 /* spi_mode = */ 0, /* active high, rising edge */
592 /* i2c_bus_clock_100kHz = */ 4,
593 /* data_setup_time_ns = */ 40, /* */
594 /* write_pulse_width_ns = */ 80, /* */
595 /* tile_width = */ 8,
596 /* tile_hight = */ 4,
597 /* default_x_offset = */ 32,
598 /* flipmode_x_offset = */ 32,
599 /* pixel_width = */ 64,
600 /* pixel_height = */ 32
601 };
602
603 static const uint8_t u8x8_st7567_64x32_init_seq[] = {
604
605 U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
606
607 U8X8_C(0x0e2), /* soft reset */
608 U8X8_C(0x0ae), /* display off */
609 U8X8_C(0x040), /* set display start line to 0 */
610
611 U8X8_C(0x0a1), /* ADC */
612 U8X8_C(0x0c0), /* common output mode */
613 // Flipmode
614 //U8X8_C(0x0a0), /* ADC */
615 //U8X8_C(0x0c8), /* common output mode */
616
617 U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
618 U8X8_C(0x0a2), /* LCD bias 1/9 */
619 U8X8_C(0x028|4), /* all power control circuits on */
620 U8X8_DLY(50),
621 U8X8_C(0x028|6), /* all power control circuits on */
622 U8X8_DLY(50),
623 U8X8_C(0x028|7), /* all power control circuits on */
624 U8X8_DLY(50),
625
626 U8X8_C(0x024), /* v0 voltage resistor ratio, taken from issue 657 */
627 U8X8_CA(0x081, 0x080), /* set contrast, contrast value*/
628
629 U8X8_C(0x0ae), /* display off */
630 U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
631
632 U8X8_END_TRANSFER(), /* disable chip */
633 U8X8_END() /* end of sequence */
634 };
635
636
637 uint8_t u8x8_d_st7567_64x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
638 {
639 uint8_t x, c;
640 uint8_t *ptr;
641 switch(msg)
642 {
643 case U8X8_MSG_DISPLAY_SETUP_MEMORY:
644 u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_64x32_display_info);
645 break;
646 case U8X8_MSG_DISPLAY_INIT:
647 u8x8_d_helper_display_init(u8x8);
648 u8x8_cad_SendSequence(u8x8, u8x8_st7567_64x32_init_seq);
649 break;
650 case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
651 if ( arg_int == 0 )
652 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
653 else
654 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
655 break;
656 case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
657 if ( arg_int == 0 )
658 {
659 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
660 u8x8->x_offset = u8x8->display_info->default_x_offset;
661 }
662 else
663 {
664 u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
665 u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
666 }
667 break;
668 #ifdef U8X8_WITH_SET_CONTRAST
669 case U8X8_MSG_DISPLAY_SET_CONTRAST:
670 u8x8_cad_StartTransfer(u8x8);
671 u8x8_cad_SendCmd(u8x8, 0x081 );
672 u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
673 u8x8_cad_EndTransfer(u8x8);
674 break;
675 #endif
676 case U8X8_MSG_DISPLAY_DRAW_TILE:
677 u8x8_cad_StartTransfer(u8x8);
678
679 x = ((u8x8_tile_t *)arg_ptr)->x_pos;
680 x *= 8;
681 x += u8x8->x_offset;
682 u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
683 u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
684 u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
685
686 c = ((u8x8_tile_t *)arg_ptr)->cnt;
687 c *= 8;
688 ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
689 /*
690 The following if condition checks the hardware limits of the st7567
691 controller: It is not allowed to write beyond the display limits.
692 This is in fact an issue within flip mode.
693 */
694 if ( c + x > 132u )
695 {
696 c = 132u;
697 c -= x;
698 }
699 do
700 {
701 u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
702 arg_int--;
703 } while( arg_int > 0 );
704
705 u8x8_cad_EndTransfer(u8x8);
706 break;
707 default:
708 return 0;
709 }
710 return 1;
711 }

mercurial