Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcU8x8lib.cpp

1912 lines · 55.3 KB · C++

1/*
2
3 U8x8lib.cpp
4
5 Arduino specific low level functions
6
7
8 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
9
10 Copyright (c) 2016, olikraus@gmail.com
11 All rights reserved.
12
13 Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15
16 * Redistributions of source code must retain the above copyright notice, this list
17 of conditions and the following disclaimer.
18
19 * Redistributions in binary form must reproduce the above copyright notice, this
20 list of conditions and the following disclaimer in the documentation and/or other
21 materials provided with the distribution.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
28 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
37*/
38
39
40#include "U8x8lib.h"
41
42#ifdef ARDUINO
43
44#ifdef U8X8_HAVE_HW_SPI
45#include <SPI.h>
46#endif
47
48#ifdef U8X8_HAVE_HW_I2C
49# ifdef U8X8_HAVE_HW_I2C_TEENSY3
50# include <i2c_t3.h>
51# else
52# include <Wire.h>
53# ifdef U8X8_HAVE_2ND_HW_I2C
54# if defined(MINICORE) && defined(__AVR_ATmega328PB__)
55# include <Wire1.h>
56# endif
57# endif
58# endif
59#endif /* U8X8_HAVE_HW_I2C */
60
61#endif /* ARDUINO */
62
63
64
65/*=============================================*/
66
67size_t U8X8::write(uint8_t v)
68{
69 if ( v == '\n' )
70 {
71 uint8_t dy = u8x8_pgm_read(u8x8.font+3); /* new 2019 format */
72 ty+=dy;
73 tx=0;
74 }
75 else
76 {
77 uint8_t dx = u8x8_pgm_read(u8x8.font+2); /* new 2019 format */
78 u8x8_DrawGlyph(&u8x8, tx, ty, v);
79
80 tx+=dx;
81 }
82 return 1;
83}
84
85
86
87/*=============================================*/
88/*=== ARDUINO GPIO & DELAY ===*/
89
90#ifdef ARDUINO
91#ifdef U8X8_USE_PINS
92extern "C" uint8_t u8x8_gpio_and_delay_arduino(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
93{
94 uint8_t i;
95 switch(msg)
96 {
97 case U8X8_MSG_GPIO_AND_DELAY_INIT:
98
99 for( i = 0; i < U8X8_PIN_CNT; i++ )
100 if ( u8x8->pins[i] != U8X8_PIN_NONE )
101 {
102 if ( i < U8X8_PIN_OUTPUT_CNT )
103 {
104 pinMode(u8x8->pins[i], OUTPUT);
105 }
106 else
107 {
108#ifdef INPUT_PULLUP
109 pinMode(u8x8->pins[i], INPUT_PULLUP);
110#else
111 pinMode(u8x8->pins[i], OUTPUT);
112 digitalWrite(u8x8->pins[i], 1);
113#endif
114 }
115 }
116
117 break;
118
119#ifndef __AVR__
120 /* this case is not compiled for any AVR, because AVR uC are so slow */
121 /* that this delay does not matter */
122 case U8X8_MSG_DELAY_NANO:
123 delayMicroseconds(arg_int==0?0:1);
124 break;
125#endif
126
127 case U8X8_MSG_DELAY_10MICRO:
128 /* not used at the moment */
129 break;
130
131 case U8X8_MSG_DELAY_100NANO:
132 /* not used at the moment */
133 break;
134
135 case U8X8_MSG_DELAY_MILLI:
136 delay(arg_int);
137 break;
138 case U8X8_MSG_DELAY_I2C:
139 /* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
140 delayMicroseconds(arg_int<=2?5:2);
141 break;
142 case U8X8_MSG_GPIO_I2C_CLOCK:
143 case U8X8_MSG_GPIO_I2C_DATA:
144 if ( arg_int == 0 )
145 {
146 // the next two lines are swapped https://github.com/olikraus/u8g2/issues/2744
147 // pinMode(u8x8_GetPinValue(u8x8, msg), OUTPUT);
148 digitalWrite(u8x8_GetPinValue(u8x8, msg), 0);
149 pinMode(u8x8_GetPinValue(u8x8, msg), OUTPUT);
150 }
151 else
152 {
153#ifdef INPUT_PULLUP
154 pinMode(u8x8_GetPinValue(u8x8, msg), INPUT_PULLUP);
155#else
156 pinMode(u8x8_GetPinValue(u8x8, msg), OUTPUT);
157 digitalWrite(u8x8_GetPinValue(u8x8, msg), 1);
158#endif
159 }
160 break;
161 default:
162 if ( msg >= U8X8_MSG_GPIO(0) )
163 {
164 i = u8x8_GetPinValue(u8x8, msg);
165 if ( i != U8X8_PIN_NONE )
166 {
167 if ( u8x8_GetPinIndex(u8x8, msg) < U8X8_PIN_OUTPUT_CNT )
168 {
169 digitalWrite(i, arg_int);
170 }
171 else
172 {
173 if ( u8x8_GetPinIndex(u8x8, msg) == U8X8_PIN_OUTPUT_CNT )
174 {
175 // call yield() for the first pin only, u8x8 will always request all the pins, so this should be ok
176 yield();
177 }
178 u8x8_SetGPIOResult(u8x8, digitalRead(i) == 0 ? 0 : 1);
179 }
180 }
181 break;
182 }
183
184 return 0;
185 }
186 return 1;
187}
188#endif // U8X8_USE_PINS
189
190
191
192
193/*=============================================*/
194/*=== 3 WIRE SOFTWARE SPI ===*/
195
196/*
197 replacement for a more faster u8x8_byte_3wire_sw_spi
198 in general u8x8_byte_3wire_sw_spi could be a fallback:
199
200 uint8_t u8x8_byte_arduino_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
201 {
202 return u8x8_byte_3wire_sw_spi(u8x8, msg,arg_int, arg_ptr);
203 }
204
205
206
207*/
208
209#ifndef __AVR_ARCH__
210#define __AVR_ARCH__ 0
211#endif
212
213#if !defined(U8X8_USE_PINS)
214 /* no pin information (very strange), so fallback */
215 uint8_t u8x8_byte_arduino_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
216 {
217 return u8x8_byte_3wire_sw_spi(u8x8, msg,arg_int, arg_ptr);
218 }
219
220#elif __AVR_ARCH__ == 4 || __AVR_ARCH__ == 5 || __AVR_ARCH__ == 51 || __AVR_ARCH__ == 6 || __AVR_ARCH__ == 103
221
222/* this function completely replaces u8x8_byte_4wire_sw_spi*/
223extern "C" uint8_t u8x8_byte_arduino_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
224{
225 uint8_t i;
226 uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
227 uint16_t b;
228 uint8_t *data;
229
230 /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */
231 /* so, it should be possible to use multiple displays with different pins */
232
233 static volatile uint8_t *arduino_clock_port;
234
235 static uint8_t arduino_clock_mask;
236 static uint8_t arduino_clock_n_mask;
237
238 static volatile uint8_t *arduino_data_port;
239 static uint8_t arduino_data_mask;
240 static uint8_t arduino_data_n_mask;
241
242 static uint8_t last_dc;
243
244
245 switch(msg)
246 {
247 case U8X8_MSG_BYTE_SEND:
248
249 data = (uint8_t *)arg_ptr;
250 if ( takeover_edge == 0 )
251 {
252 while( arg_int > 0 )
253 {
254 b = *data;
255 if ( last_dc != 0 )
256 b |= 256;
257 data++;
258 arg_int--;
259 /* issue 156, check for speed */
260#if F_CPU <= 17000000
261 if ( b == 0 )
262 {
263 *arduino_data_port &= arduino_data_n_mask;
264 for( i = 0; i < 9; i++ )
265 {
266 *arduino_clock_port |= arduino_clock_mask;
267 *arduino_clock_port &= arduino_clock_n_mask;
268 }
269 }
270 else
271#endif
272 {
273 for( i = 0; i < 9; i++ )
274 {
275 if ( b & 256 )
276 *arduino_data_port |= arduino_data_mask;
277 else
278 *arduino_data_port &= arduino_data_n_mask;
279
280 *arduino_clock_port |= arduino_clock_mask;
281 b <<= 1;
282 *arduino_clock_port &= arduino_clock_n_mask;
283 }
284 }
285 }
286 }
287 else
288 {
289 while( arg_int > 0 )
290 {
291 b = *data;
292 if ( last_dc != 0 )
293 b |= 256;
294 data++;
295 arg_int--;
296 /* issue 156, check for speed */
297#if F_CPU <= 17000000
298 if ( b == 0 )
299 {
300 *arduino_data_port &= arduino_data_n_mask;
301 for( i = 0; i < 9; i++ )
302 {
303 *arduino_clock_port &= arduino_clock_n_mask;
304 *arduino_clock_port |= arduino_clock_mask;
305 }
306 }
307 else
308#endif
309 {
310 for( i = 0; i < 9; i++ )
311 {
312 if ( b & 256 )
313 *arduino_data_port |= arduino_data_mask;
314 else
315 *arduino_data_port &= arduino_data_n_mask;
316
317 *arduino_clock_port &= arduino_clock_n_mask;
318 b <<= 1;
319 *arduino_clock_port |= arduino_clock_mask;
320 }
321 }
322 }
323 }
324 break;
325
326 case U8X8_MSG_BYTE_INIT:
327 /* disable chipselect */
328 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
329 /* no wait required here */
330
331 /* for SPI: setup correct level of the clock signal */
332 u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
333 break;
334 case U8X8_MSG_BYTE_SET_DC:
335 last_dc = arg_int;
336 break;
337 case U8X8_MSG_BYTE_START_TRANSFER:
338 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
339 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
340
341 /* there is no consistency checking for u8x8->pins[U8X8_PIN_SPI_CLOCK] */
342
343 arduino_clock_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_CLOCK]));
344 arduino_clock_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_CLOCK]);
345 arduino_clock_n_mask = ~arduino_clock_mask;
346
347 /* there is no consistency checking for u8x8->pins[U8X8_PIN_SPI_DATA] */
348
349 arduino_data_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_DATA]));
350 arduino_data_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_DATA]);
351 arduino_data_n_mask = ~arduino_data_mask;
352
353 break;
354 case U8X8_MSG_BYTE_END_TRANSFER:
355 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
356 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
357 break;
358 default:
359 return 0;
360 }
361 return 1;
362}
363
364#else
365 /* fallback */
366 uint8_t u8x8_byte_arduino_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
367 {
368 return u8x8_byte_3wire_sw_spi(u8x8, msg,arg_int, arg_ptr);
369 }
370
371#endif
372
373
374
375
376
377/*=============================================*/
378/*=== 4 WIRE SOFTWARE SPI ===*/
379
380/*
381 replacement for a more faster u8x8_byte_4wire_sw_spi
382 in general u8x8_byte_4wire_sw_spi could be a fallback:
383
384 uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
385 {
386 return u8x8_byte_4wire_sw_spi(u8x8, msg,arg_int, arg_ptr);
387 }
388
389
390
391*/
392
393#ifndef __AVR_ARCH__
394#define __AVR_ARCH__ 0
395#endif
396
397#if !defined(U8X8_USE_PINS)
398 /* no pin information (very strange), so fallback */
399 uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
400 {
401 return u8x8_byte_4wire_sw_spi(u8x8, msg,arg_int, arg_ptr);
402 }
403
404#elif __AVR_ARCH__ == 4 || __AVR_ARCH__ == 5 || __AVR_ARCH__ == 51 || __AVR_ARCH__ == 6 || __AVR_ARCH__ == 103
405
406/* this function completely replaces u8x8_byte_4wire_sw_spi*/
407extern "C" uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
408{
409 uint8_t SREG_backup;
410 uint8_t i, b;
411 uint8_t *data;
412 uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
413 //uint8_t not_takeover_edge = 1 - takeover_edge;
414
415 /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */
416 /* so, it should be possible to use multiple displays with different pins */
417
418 static volatile uint8_t *arduino_clock_port;
419
420 static uint8_t arduino_clock_mask;
421 static uint8_t arduino_clock_n_mask;
422
423 static volatile uint8_t *arduino_data_port;
424 static uint8_t arduino_data_mask;
425 static uint8_t arduino_data_n_mask;
426
427
428
429 switch(msg)
430 {
431 case U8X8_MSG_BYTE_SEND:
432
433 data = (uint8_t *)arg_ptr;
434 if ( takeover_edge == 0 )
435 {
436 while( arg_int > 0 )
437 {
438 b = *data;
439 data++;
440 arg_int--;
441 SREG_backup = SREG; cli();
442 /* issue 156, check for speed */
443#if F_CPU <= 17000000
444 if ( b == 0 )
445 {
446 *arduino_data_port &= arduino_data_n_mask;
447 for( i = 0; i < 8; i++ )
448 {
449 *arduino_clock_port |= arduino_clock_mask;
450 *arduino_clock_port &= arduino_clock_n_mask;
451 }
452 }
453 else
454#endif
455 {
456 for( i = 0; i < 8; i++ )
457 {
458 if ( b & 128 )
459 *arduino_data_port |= arduino_data_mask;
460 else
461 *arduino_data_port &= arduino_data_n_mask;
462
463 *arduino_clock_port |= arduino_clock_mask;
464 b <<= 1;
465 *arduino_clock_port &= arduino_clock_n_mask;
466 }
467 }
468 SREG = SREG_backup;
469 }
470 }
471 else
472 {
473 while( arg_int > 0 )
474 {
475 b = *data;
476 data++;
477 arg_int--;
478 SREG_backup = SREG; cli();
479 /* issue 156, check for speed */
480#if F_CPU <= 17000000
481 if ( b == 0 )
482 {
483 *arduino_data_port &= arduino_data_n_mask;
484 for( i = 0; i < 8; i++ )
485 {
486 *arduino_clock_port &= arduino_clock_n_mask;
487 *arduino_clock_port |= arduino_clock_mask;
488 }
489 }
490 else
491#endif
492 {
493 for( i = 0; i < 8; i++ )
494 {
495 if ( b & 128 )
496 *arduino_data_port |= arduino_data_mask;
497 else
498 *arduino_data_port &= arduino_data_n_mask;
499
500 *arduino_clock_port &= arduino_clock_n_mask;
501 b <<= 1;
502 *arduino_clock_port |= arduino_clock_mask;
503 }
504 }
505 SREG = SREG_backup;
506 }
507 }
508 break;
509
510 case U8X8_MSG_BYTE_INIT:
511 /* disable chipselect */
512 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
513 /* no wait required here */
514
515 /* for SPI: setup correct level of the clock signal */
516 u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
517 break;
518 case U8X8_MSG_BYTE_SET_DC:
519 u8x8_gpio_SetDC(u8x8, arg_int);
520 break;
521 case U8X8_MSG_BYTE_START_TRANSFER:
522 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
523 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
524
525 /* there is no consistency checking for u8x8->pins[U8X8_PIN_SPI_CLOCK] */
526
527 arduino_clock_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_CLOCK]));
528 arduino_clock_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_CLOCK]);
529 arduino_clock_n_mask = ~arduino_clock_mask;
530
531
532
533 /* there is no consistency checking for u8x8->pins[U8X8_PIN_SPI_DATA] */
534
535 arduino_data_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_DATA]));
536 arduino_data_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_DATA]);
537 arduino_data_n_mask = ~arduino_data_mask;
538
539 break;
540 case U8X8_MSG_BYTE_END_TRANSFER:
541 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
542 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
543 break;
544 default:
545 return 0;
546 }
547 return 1;
548}
549
550#elif defined(__SAM3X8E__) /* Arduino DUE */
551
552/* this function completely replaces u8x8_byte_4wire_sw_spi*/
553extern "C" uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
554{
555 uint8_t i, b;
556 uint16_t us = ((u8x8->display_info->sck_pulse_width_ns + 999)/1000);
557 uint8_t *data;
558 uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
559 //uint8_t not_takeover_edge = 1 - takeover_edge;
560
561 /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */
562 /* so, it should be possible to use multiple displays with different pins */
563
564 /*
565 static volatile uint32_t *arduino_clock_port;
566 static uint32_t arduino_clock_mask;
567 static uint32_t arduino_clock_n_mask;
568
569 static volatile uint32_t *arduino_data_port;
570 static uint32_t arduino_data_mask;
571 static uint32_t arduino_data_n_mask;
572 */
573
574 static WoReg *arduinoSetClockPort, *arduinoUnsetClockPort;
575 static uint32_t arduino_clock_mask;
576
577 static WoReg *arduinoSetDataPort, *arduinoUnsetDataPort;
578 static uint32_t arduino_data_mask;
579
580 switch(msg)
581 {
582 case U8X8_MSG_BYTE_SEND:
583
584 data = (uint8_t *)arg_ptr;
585 if ( takeover_edge == 0 )
586 {
587 while( arg_int > 0 )
588 {
589 b = *data;
590 data++;
591 arg_int--;
592 {
593 for( i = 0; i < 8; i++ )
594 {
595 /*
596 if ( b & 128 )
597 *arduino_data_port |= arduino_data_mask;
598 else
599 *arduino_data_port &= arduino_data_n_mask;
600 */
601 if (b & 128)
602 *arduinoSetDataPort = arduino_data_mask;
603 else
604 *arduinoUnsetDataPort = arduino_data_mask;
605
606 //delayMicroseconds(us);
607 //*arduino_clock_port |= arduino_clock_mask;
608 *arduinoSetClockPort = arduino_clock_mask;
609 b <<= 1;
610 delayMicroseconds(us);
611 //*arduino_clock_port &= arduino_clock_n_mask;
612 *arduinoUnsetClockPort = arduino_clock_mask;
613 }
614 }
615 }
616 }
617 else
618 {
619 while( arg_int > 0 )
620 {
621 b = *data;
622 data++;
623 arg_int--;
624 {
625 for( i = 0; i < 8; i++ )
626 {
627 /*
628 if ( b & 128 )
629 *arduino_data_port |= arduino_data_mask;
630 else
631 *arduino_data_port &= arduino_data_n_mask;
632 */
633 if (b & 128)
634 *arduinoSetDataPort = arduino_data_mask;
635 else
636 *arduinoUnsetDataPort = arduino_data_mask;
637
638 //delayMicroseconds(us);
639 //*arduino_clock_port &= arduino_clock_n_mask;
640 *arduinoUnsetClockPort = arduino_clock_mask;
641 b <<= 1;
642 delayMicroseconds(us);
643 //*arduino_clock_port |= arduino_clock_mask;
644 *arduinoSetClockPort = arduino_clock_mask;
645 }
646 }
647 }
648 }
649 break;
650
651 case U8X8_MSG_BYTE_INIT:
652 /* disable chipselect */
653 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
654 /* no wait required here */
655
656 /* for SPI: setup correct level of the clock signal */
657 u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
658 break;
659 case U8X8_MSG_BYTE_SET_DC:
660 u8x8_gpio_SetDC(u8x8, arg_int);
661 break;
662 case U8X8_MSG_BYTE_START_TRANSFER:
663 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
664 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
665
666 /* there is no consistency checking for u8x8->pins[U8X8_PIN_SPI_CLOCK] */
667
668 /*
669 arduino_clock_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_CLOCK]));
670 arduino_clock_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_CLOCK]);
671 arduino_clock_n_mask = ~arduino_clock_mask;
672
673 arduino_data_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_DATA]));
674 arduino_data_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_DATA]);
675 arduino_data_n_mask = ~arduino_data_mask;
676 */
677
678 arduinoSetClockPort = &digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_CLOCK])->PIO_SODR;
679 arduinoUnsetClockPort = &digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_CLOCK])->PIO_CODR;
680 arduino_clock_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_CLOCK]);
681
682 arduinoSetDataPort = &digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_DATA])->PIO_SODR;
683 arduinoUnsetDataPort = &digitalPinToPort(u8x8->pins[U8X8_PIN_SPI_DATA])->PIO_CODR;
684 arduino_data_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_SPI_DATA]);
685
686
687 break;
688 case U8X8_MSG_BYTE_END_TRANSFER:
689 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
690 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
691 break;
692 default:
693 return 0;
694 }
695 return 1;
696}
697
698
699#else
700 /* fallback */
701 uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
702 {
703 return u8x8_byte_4wire_sw_spi(u8x8, msg,arg_int, arg_ptr);
704 }
705
706#endif
707
708
709/*=============================================*/
710/*=== 3 WIRE HARDWARE SPI with 8 bit HW SPI Subsystem ===*/
711/*
712references:
713 https://github.com/olikraus/ucglib/blob/master/cppsrc/Ucglib.cpp#L581
714 https://github.com/olikraus/u8g2/issues/1041
715*/
716
717static uint8_t arduino_hw_spi_3w_buffer[9];
718static uint8_t arduino_hw_spi_3w_bytepos;
719static uint16_t arduino_hw_spi_3w_dc; // 0 = dc==0, 256 = dc==1
720
721static void arduino_hw_spi_3w_init()
722{
723 memset(arduino_hw_spi_3w_buffer, 0, 9);
724 arduino_hw_spi_3w_bytepos = 0;
725}
726
727static void arduino_hw_spi_3w_flush(void)
728{
729#ifdef U8X8_HAVE_HW_SPI
730 uint8_t i;
731 for(i = 0; i <= arduino_hw_spi_3w_bytepos; i++)
732 {
733 SPI.transfer(arduino_hw_spi_3w_buffer[i]);
734 }
735#endif
736}
737
738static void arduino_hw_spi_3w_sendbyte(uint8_t data)
739{
740 static union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } data16; // well well, not legal ISO 9899 code
741
742 data16.val = (arduino_hw_spi_3w_dc + data) << (7 - arduino_hw_spi_3w_bytepos);
743#ifdef __BYTE_ORDER__
744#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
745 arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.msb;
746 ++arduino_hw_spi_3w_bytepos;
747 arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.lsb;
748#else
749 arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.lsb;
750 ++arduino_hw_spi_3w_bytepos;
751 arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.msb;
752#endif
753#else // __BYTE_ORDER__ not defined (no gcc)
754 // assume little endian
755 arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.msb;
756 ++arduino_hw_spi_3w_bytepos;
757 arduino_hw_spi_3w_buffer[arduino_hw_spi_3w_bytepos] |= data16.lsb;
758#endif
759
760 if (arduino_hw_spi_3w_bytepos == 8)
761 {
762 arduino_hw_spi_3w_flush();
763 arduino_hw_spi_3w_init();
764 }
765}
766
767extern "C" uint8_t u8x8_byte_arduino_3wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
768{
769#ifdef U8X8_HAVE_HW_SPI
770
771 uint8_t *data;
772 uint8_t internal_spi_mode;
773
774 switch(msg)
775 {
776 case U8X8_MSG_BYTE_SEND:
777 data = (uint8_t *)arg_ptr;
778 while(arg_int > 0) {
779 arduino_hw_spi_3w_sendbyte((uint8_t)*data);
780 data++;
781 arg_int--;
782 }
783 break;
784
785 case U8X8_MSG_BYTE_INIT:
786 if ( u8x8->bus_clock == 0 ) /* issue 769 */
787 u8x8->bus_clock = u8x8->display_info->sck_clock_hz;
788 /* disable chipselect */
789 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
790
791#if defined(ESP_PLATFORM) || defined(ARDUINO_ARCH_ESP32)
792 /* ESP32 has the following begin: SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t mosi=MOSI, int8_t ss=-1); */
793 /* not sure about ESP8266 */
794 /* apply bugfix from PR 2123 */
795 //if ( u8x8->pins[U8X8_PIN_I2C_CLOCK] != U8X8_PIN_NONE && u8x8->pins[U8X8_PIN_I2C_DATA] != U8X8_PIN_NONE )
796 if ( u8x8->pins[U8X8_PIN_SPI_CLOCK] != U8X8_PIN_NONE && u8x8->pins[U8X8_PIN_SPI_DATA] != U8X8_PIN_NONE )
797 {
798 /* SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t mosi=MOSI, int8_t ss=-1); */
799 /* actually MISO is not used, but what else could be used here??? */
800 //SPI.begin(u8x8->pins[U8X8_PIN_I2C_CLOCK], MISO, u8x8->pins[U8X8_PIN_I2C_DATA]);
801 SPI.begin(u8x8->pins[U8X8_PIN_SPI_CLOCK], MISO, u8x8->pins[U8X8_PIN_SPI_DATA]);
802 }
803 else
804 {
805 SPI.begin();
806 }
807#else
808 SPI.begin();
809#endif
810 break;
811
812 case U8X8_MSG_BYTE_SET_DC:
813 arduino_hw_spi_3w_dc = arg_int ? 256 : 0;
814 break;
815
816 case U8X8_MSG_BYTE_START_TRANSFER:
817 /* SPI mode has to be mapped to the mode of the current controller;
818 at least Uno, Due, 101 have different SPI_MODEx values */
819 internal_spi_mode = 0;
820 switch(u8x8->display_info->spi_mode) {
821 case 0: internal_spi_mode = SPI_MODE0; break;
822 case 1: internal_spi_mode = SPI_MODE1; break;
823 case 2: internal_spi_mode = SPI_MODE2; break;
824 case 3: internal_spi_mode = SPI_MODE3; break;
825 }
826
827#if ARDUINO >= 10600
828 SPI.beginTransaction(
829 SPISettings(u8x8->bus_clock, MSBFIRST, internal_spi_mode));
830#else
831 SPI.begin();
832 if (u8x8->display_info->sck_pulse_width_ns < 70)
833 SPI.setClockDivider(SPI_CLOCK_DIV2);
834 else if (u8x8->display_info->sck_pulse_width_ns < 140)
835 SPI.setClockDivider(SPI_CLOCK_DIV4);
836 else
837 SPI.setClockDivider(SPI_CLOCK_DIV8);
838 SPI.setDataMode(internal_spi_mode);
839 SPI.setBitOrder(MSBFIRST);
840#endif
841 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
842 u8x8->gpio_and_delay_cb(
843 u8x8,
844 U8X8_MSG_DELAY_NANO,
845 u8x8->display_info->post_chip_enable_wait_ns,
846 NULL);
847 arduino_hw_spi_3w_init();
848 break;
849
850 case U8X8_MSG_BYTE_END_TRANSFER:
851 u8x8->gpio_and_delay_cb(
852 u8x8,
853 U8X8_MSG_DELAY_NANO,
854 u8x8->display_info->pre_chip_disable_wait_ns,
855 NULL);
856 if (arduino_hw_spi_3w_bytepos)
857 arduino_hw_spi_3w_flush();
858 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
859
860#if ARDUINO >= 10600
861 SPI.endTransaction();
862#else
863 SPI.end();
864#endif
865 break;
866
867 default:
868 return 0;
869 }
870
871#endif // U8X8_HAVE_HW_SPI
872
873
874 return 1;
875}
876
877
878/*=============================================*/
879/*=== 4 WIRE HARDWARE SPI ===*/
880
881#ifdef U8X8_USE_PINS
882
883extern "C" uint8_t u8x8_byte_arduino_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
884{
885#ifdef U8X8_HAVE_HW_SPI
886
887#if !defined(ESP_PLATFORM)
888 uint8_t *data;
889#endif
890
891 uint8_t internal_spi_mode;
892
893 switch(msg)
894 {
895 case U8X8_MSG_BYTE_SEND:
896
897
898
899#if defined(ESP_PLATFORM)
900 //T.M.L 2023-02-28: use the block transfer function on ESP, which does not overwrite the buffer.
901 SPI.writeBytes((uint8_t*)arg_ptr, arg_int);
902#else
903 // 1.6.5 offers a block transfer, but the problem is, that the
904 // buffer is overwritten with the incoming data
905 // so it can not be used...
906 // SPI.transfer((uint8_t *)arg_ptr, arg_int);
907
908 data = (uint8_t *)arg_ptr;
909 while( arg_int > 0 )
910 {
911 SPI.transfer((uint8_t)*data);
912 data++;
913 arg_int--;
914 }
915#endif
916
917 break;
918 case U8X8_MSG_BYTE_INIT:
919 if ( u8x8->bus_clock == 0 ) /* issue 769 */
920 u8x8->bus_clock = u8x8->display_info->sck_clock_hz;
921 /* disable chipselect */
922 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
923
924 /* no wait required here */
925
926 /* for SPI: setup correct level of the clock signal */
927 // removed, use SPI.begin() instead: pinMode(11, OUTPUT);
928 // removed, use SPI.begin() instead: pinMode(13, OUTPUT);
929 // removed, use SPI.begin() instead: digitalWrite(13, u8x8_GetSPIClockPhase(u8x8));
930
931 /* setup hardware with SPI.begin() instead of previous digitalWrite() and pinMode() calls */
932
933
934 /* issue #377 */
935 /* issue #378: removed ESP8266 support, which is implemented differently */
936#if defined(ESP_PLATFORM) || defined(ARDUINO_ARCH_ESP32)
937 /* ESP32 has the following begin: SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t mosi=MOSI, int8_t ss=-1); */
938 /* not sure about ESP8266 */
939 if ( u8x8->pins[U8X8_PIN_SPI_CLOCK] != U8X8_PIN_NONE && u8x8->pins[U8X8_PIN_SPI_DATA] != U8X8_PIN_NONE )
940 {
941 /* SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t mosi=MOSI, int8_t ss=-1); */
942 /* actually MISO is not used, but what else could be used here??? */
943 SPI.begin(u8x8->pins[U8X8_PIN_SPI_CLOCK], MISO, u8x8->pins[U8X8_PIN_SPI_DATA]);
944 }
945 else
946 {
947 SPI.begin();
948 }
949#else
950 SPI.begin();
951#endif
952
953
954
955 break;
956
957 case U8X8_MSG_BYTE_SET_DC:
958 u8x8_gpio_SetDC(u8x8, arg_int);
959 break;
960
961 case U8X8_MSG_BYTE_START_TRANSFER:
962 /* SPI mode has to be mapped to the mode of the current controller, at least Uno, Due, 101 have different SPI_MODEx values */
963 internal_spi_mode = 0;
964 switch(u8x8->display_info->spi_mode)
965 {
966 case 0: internal_spi_mode = SPI_MODE0; break;
967 case 1: internal_spi_mode = SPI_MODE1; break;
968 case 2: internal_spi_mode = SPI_MODE2; break;
969 case 3: internal_spi_mode = SPI_MODE3; break;
970 }
971
972#if ARDUINO >= 10600
973 SPI.beginTransaction(SPISettings(u8x8->bus_clock, MSBFIRST, internal_spi_mode));
974#else
975 SPI.begin();
976
977 if ( u8x8->display_info->sck_pulse_width_ns < 70 )
978 SPI.setClockDivider( SPI_CLOCK_DIV2 );
979 else if ( u8x8->display_info->sck_pulse_width_ns < 140 )
980 SPI.setClockDivider( SPI_CLOCK_DIV4 );
981 else
982 SPI.setClockDivider( SPI_CLOCK_DIV8 );
983 SPI.setDataMode(internal_spi_mode);
984 SPI.setBitOrder(MSBFIRST);
985#endif
986
987 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
988 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
989 break;
990
991 case U8X8_MSG_BYTE_END_TRANSFER:
992 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
993 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
994
995#if ARDUINO >= 10600
996 SPI.endTransaction();
997#else
998 SPI.end();
999#endif
1000
1001 break;
1002 default:
1003 return 0;
1004 }
1005
1006#else /* U8X8_HAVE_HW_SPI */
1007
1008#endif /* U8X8_HAVE_HW_SPI */
1009 return 1;
1010}
1011
1012
1013/* issue #244 */
1014extern "C" uint8_t u8x8_byte_arduino_2nd_hw_spi(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
1015{
1016#ifdef U8X8_HAVE_2ND_HW_SPI
1017 uint8_t *data;
1018 uint8_t internal_spi_mode;
1019
1020 switch(msg)
1021 {
1022 case U8X8_MSG_BYTE_SEND:
1023
1024 // 1.6.5 offers a block transfer, but the problem is, that the
1025 // buffer is overwritten with the incoming data
1026 // so it can not be used...
1027 // SPI.transfer((uint8_t *)arg_ptr, arg_int);
1028
1029 data = (uint8_t *)arg_ptr;
1030 while( arg_int > 0 )
1031 {
1032 SPI1.transfer((uint8_t)*data);
1033 data++;
1034 arg_int--;
1035 }
1036
1037 break;
1038 case U8X8_MSG_BYTE_INIT:
1039 if ( u8x8->bus_clock == 0 ) /* issue 769 */
1040 u8x8->bus_clock = u8x8->display_info->sck_clock_hz;
1041 /* disable chipselect */
1042 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
1043 /* no wait required here */
1044
1045 /* for SPI1: setup correct level of the clock signal */
1046 // removed, use SPI.begin() instead: pinMode(11, OUTPUT);
1047 // removed, use SPI.begin() instead: pinMode(13, OUTPUT);
1048 // removed, use SPI.begin() instead: digitalWrite(13, u8x8_GetSPIClockPhase(u8x8));
1049
1050 /* setup hardware with SPI.begin() instead of previous digitalWrite() and pinMode() calls */
1051 SPI1.begin();
1052
1053 break;
1054
1055 case U8X8_MSG_BYTE_SET_DC:
1056 u8x8_gpio_SetDC(u8x8, arg_int);
1057 break;
1058
1059 case U8X8_MSG_BYTE_START_TRANSFER:
1060 /* SPI1 mode has to be mapped to the mode of the current controller, at least Uno, Due, 101 have different SPI_MODEx values */
1061 internal_spi_mode = 0;
1062 switch(u8x8->display_info->spi_mode)
1063 {
1064 case 0: internal_spi_mode = SPI_MODE0; break;
1065 case 1: internal_spi_mode = SPI_MODE1; break;
1066 case 2: internal_spi_mode = SPI_MODE2; break;
1067 case 3: internal_spi_mode = SPI_MODE3; break;
1068 }
1069
1070#if ARDUINO >= 10600
1071 SPI1.beginTransaction(SPISettings(u8x8->bus_clock, MSBFIRST, internal_spi_mode));
1072#else
1073 SPI1.begin();
1074
1075 if ( u8x8->display_info->sck_pulse_width_ns < 70 )
1076 SPI1.setClockDivider( SPI_CLOCK_DIV2 );
1077 else if ( u8x8->display_info->sck_pulse_width_ns < 140 )
1078 SPI1.setClockDivider( SPI_CLOCK_DIV4 );
1079 else
1080 SPI1.setClockDivider( SPI_CLOCK_DIV8 );
1081 SPI1.setDataMode(internal_spi_mode);
1082 SPI1.setBitOrder(MSBFIRST);
1083#endif
1084
1085 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
1086 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
1087 break;
1088
1089 case U8X8_MSG_BYTE_END_TRANSFER:
1090 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
1091 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
1092
1093#if ARDUINO >= 10600
1094 SPI1.endTransaction();
1095#else
1096 SPI1.end();
1097#endif
1098
1099 break;
1100 default:
1101 return 0;
1102 }
1103
1104#else
1105#endif
1106 return 1;
1107}
1108
1109/*=============================================*/
1110/* fast SW I2C for AVR uC */
1111
1112
1113#if !defined(U8X8_USE_PINS)
1114 /* no pin information (very strange), so fallback */
1115extern "C" uint8_t u8x8_byte_arduino_sw_i2c(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
1116{
1117 return u8x8_byte_sw_i2c(u8x8, msg,arg_int, arg_ptr);
1118}
1119
1120#elif !defined(U8X8_USE_ARDUINO_AVR_SW_I2C_OPTIMIZATION)
1121
1122extern "C" uint8_t u8x8_byte_arduino_sw_i2c(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
1123{
1124 return u8x8_byte_sw_i2c(u8x8, msg,arg_int, arg_ptr);
1125}
1126
1127#elif __AVR_ARCH__ == 4 || __AVR_ARCH__ == 5 || __AVR_ARCH__ == 51 || __AVR_ARCH__ == 6 || __AVR_ARCH__ == 103
1128
1129
1130/* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */
1131/* so, it should be possible to use multiple displays with different pins */
1132
1133static volatile uint8_t *arduino_i2c_clock_port;
1134
1135static uint8_t arduino_i2c_clock_mask;
1136static uint8_t arduino_i2c_clock_n_mask;
1137
1138static volatile uint8_t *arduino_i2c_data_port;
1139static uint8_t arduino_i2c_data_mask;
1140static uint8_t arduino_i2c_data_n_mask;
1141
1142/*
1143 software i2c,
1144 ignores ACK response (which is anyway not provided by some displays)
1145 also does not allow reading from the device
1146*/
1147static void i2c_delay(u8x8_t *u8x8) U8X8_NOINLINE;
1148static void i2c_delay(u8x8_t *u8x8)
1149{
1150 //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_10MICRO, u8x8->display_info->i2c_bus_clock_100kHz);
1151 u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_I2C, u8x8->display_info->i2c_bus_clock_100kHz);
1152}
1153
1154static void i2c_init(u8x8_t *u8x8)
1155{
1156 *arduino_i2c_clock_port |= arduino_i2c_clock_mask;
1157 *arduino_i2c_data_port |= arduino_i2c_data_mask;
1158 i2c_delay(u8x8);
1159}
1160
1161/* actually, the scl line is not observed, so this procedure does not return a value */
1162
1163static void i2c_read_scl_and_delay(u8x8_t *u8x8)
1164{
1165 /* set as input (line will be high) */
1166 *arduino_i2c_clock_port |= arduino_i2c_clock_mask;
1167
1168 i2c_delay(u8x8);
1169}
1170
1171static void i2c_clear_scl(u8x8_t *u8x8)
1172{
1173 *arduino_i2c_clock_port &= arduino_i2c_clock_n_mask;
1174}
1175
1176static void i2c_read_sda(u8x8_t *u8x8)
1177{
1178 /* set as input (line will be high) */
1179 *arduino_i2c_data_port |= arduino_i2c_data_mask;
1180}
1181
1182static void i2c_clear_sda(u8x8_t *u8x8)
1183{
1184 /* set open collector and drive low */
1185 *arduino_i2c_data_port &= arduino_i2c_data_n_mask;
1186}
1187
1188static void i2c_start(u8x8_t *u8x8)
1189{
1190 if ( u8x8->i2c_started != 0 )
1191 {
1192 /* if already started: do restart */
1193 i2c_read_sda(u8x8); /* SDA = 1 */
1194 i2c_delay(u8x8);
1195 i2c_read_scl_and_delay(u8x8);
1196 }
1197 i2c_read_sda(u8x8);
1198 /* send the start condition, both lines go from 1 to 0 */
1199 i2c_clear_sda(u8x8);
1200 i2c_delay(u8x8);
1201 i2c_clear_scl(u8x8);
1202 u8x8->i2c_started = 1;
1203}
1204
1205
1206static void i2c_stop(u8x8_t *u8x8)
1207{
1208 /* set SDA to 0 */
1209 i2c_clear_sda(u8x8);
1210 i2c_delay(u8x8);
1211
1212 /* now release all lines */
1213 i2c_read_scl_and_delay(u8x8);
1214
1215 /* set SDA to 1 */
1216 i2c_read_sda(u8x8);
1217 i2c_delay(u8x8);
1218 u8x8->i2c_started = 0;
1219}
1220
1221static void i2c_write_bit(u8x8_t *u8x8, uint8_t val)
1222{
1223 if (val)
1224 i2c_read_sda(u8x8);
1225 else
1226 i2c_clear_sda(u8x8);
1227
1228 i2c_delay(u8x8);
1229 i2c_read_scl_and_delay(u8x8);
1230 i2c_clear_scl(u8x8);
1231}
1232
1233static void i2c_read_bit(u8x8_t *u8x8)
1234{
1235 //uint8_t val;
1236 /* do not drive SDA */
1237 i2c_read_sda(u8x8);
1238 i2c_delay(u8x8);
1239 i2c_read_scl_and_delay(u8x8);
1240 i2c_read_sda(u8x8);
1241 i2c_delay(u8x8);
1242 i2c_clear_scl(u8x8);
1243 //return val;
1244}
1245
1246static void i2c_write_byte(u8x8_t *u8x8, uint8_t b)
1247{
1248 i2c_write_bit(u8x8, b & 128);
1249 i2c_write_bit(u8x8, b & 64);
1250 i2c_write_bit(u8x8, b & 32);
1251 i2c_write_bit(u8x8, b & 16);
1252 i2c_write_bit(u8x8, b & 8);
1253 i2c_write_bit(u8x8, b & 4);
1254 i2c_write_bit(u8x8, b & 2);
1255 i2c_write_bit(u8x8, b & 1);
1256
1257 /* read ack from client */
1258 /* 0: ack was given by client */
1259 /* 1: nothing happend during ack cycle */
1260 i2c_read_bit(u8x8);
1261}
1262
1263
1264extern "C" uint8_t u8x8_byte_arduino_sw_i2c(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
1265{
1266 uint8_t *data;
1267
1268 switch(msg)
1269 {
1270 case U8X8_MSG_BYTE_SEND:
1271 data = (uint8_t *)arg_ptr;
1272
1273 while( arg_int > 0 )
1274 {
1275 i2c_write_byte(u8x8, *data);
1276 data++;
1277 arg_int--;
1278 }
1279
1280 break;
1281
1282 case U8X8_MSG_BYTE_INIT:
1283 pinMode(u8x8->pins[U8X8_PIN_I2C_CLOCK], OUTPUT);
1284 digitalWrite(u8x8->pins[U8X8_PIN_I2C_CLOCK], 1);
1285
1286 pinMode(u8x8->pins[U8X8_PIN_I2C_DATA], OUTPUT);
1287 digitalWrite(u8x8->pins[U8X8_PIN_I2C_DATA], 1);
1288
1289 i2c_init(u8x8);
1290 break;
1291 case U8X8_MSG_BYTE_SET_DC:
1292 break;
1293 case U8X8_MSG_BYTE_START_TRANSFER:
1294
1295 /* there is no consistency checking for u8x8->pins[U8X8_PIN_I2C_CLOCK] */
1296
1297 arduino_i2c_clock_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_I2C_CLOCK]));
1298 arduino_i2c_clock_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_I2C_CLOCK]);
1299 arduino_i2c_clock_n_mask = ~arduino_i2c_clock_mask;
1300
1301 /* there is no consistency checking for u8x8->pins[U8X8_PIN_I2C_DATA] */
1302
1303 arduino_i2c_data_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_I2C_DATA]));
1304 arduino_i2c_data_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_I2C_DATA]);
1305 arduino_i2c_data_n_mask = ~arduino_i2c_data_mask;
1306
1307 i2c_start(u8x8);
1308 i2c_write_byte(u8x8, u8x8_GetI2CAddress(u8x8));
1309
1310 break;
1311 case U8X8_MSG_BYTE_END_TRANSFER:
1312 i2c_stop(u8x8);
1313 break;
1314 default:
1315 return 0;
1316 }
1317 return 1;
1318
1319}
1320
1321#else
1322
1323/* not AVR architecture, fallback */
1324extern "C" uint8_t u8x8_byte_arduino_sw_i2c(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
1325{
1326 return u8x8_byte_sw_i2c(u8x8, msg,arg_int, arg_ptr);
1327}
1328
1329#endif
1330
1331/*=============================================*/
1332/*=== HARDWARE I2C ===*/
1333
1334extern "C" uint8_t u8x8_byte_arduino_hw_i2c(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
1335{
1336#ifdef U8X8_HAVE_HW_I2C
1337 switch(msg)
1338 {
1339 case U8X8_MSG_BYTE_SEND:
1340 Wire.write((uint8_t *)arg_ptr, (int)arg_int);
1341 break;
1342 case U8X8_MSG_BYTE_INIT:
1343 if ( u8x8->bus_clock == 0 ) /* issue 769 */
1344 u8x8->bus_clock = u8x8->display_info->i2c_bus_clock_100kHz * 100000UL;
1345#if defined(ESP8266) || defined(ARDUINO_ARCH_ESP8266) || defined(ESP_PLATFORM) || defined(ARDUINO_ARCH_ESP32)
1346 /* for ESP8266/ESP32, Wire.begin has two more arguments: clock and data */
1347 if ( u8x8->pins[U8X8_PIN_I2C_CLOCK] != U8X8_PIN_NONE && u8x8->pins[U8X8_PIN_I2C_DATA] != U8X8_PIN_NONE )
1348 {
1349 // second argument for the wire lib is the clock pin. In u8g2, the first argument of the clock pin in the clock/data pair
1350 Wire.begin((int)u8x8->pins[U8X8_PIN_I2C_DATA] , u8x8->pins[U8X8_PIN_I2C_CLOCK]);
1351 }
1352 else
1353 {
1354 Wire.begin();
1355 }
1356#else
1357 Wire.begin();
1358#endif
1359 break;
1360 case U8X8_MSG_BYTE_SET_DC:
1361 break;
1362 case U8X8_MSG_BYTE_START_TRANSFER:
1363#if ARDUINO >= 10600
1364 /* not sure when the setClock function was introduced, but it is there since 1.6.0 */
1365 /* if there is any error with Wire.setClock() just remove this function call by */
1366 /* defining U8X8_DO_NOT_SET_WIRE_CLOCK */
1367#ifndef U8X8_DO_NOT_SET_WIRE_CLOCK
1368 Wire.setClock(u8x8->bus_clock);
1369#endif
1370#endif
1371 Wire.beginTransmission(u8x8_GetI2CAddress(u8x8)>>1);
1372 break;
1373 case U8X8_MSG_BYTE_END_TRANSFER:
1374 Wire.endTransmission();
1375 break;
1376 default:
1377 return 0;
1378 }
1379#endif
1380 return 1;
1381}
1382
1383extern "C" uint8_t u8x8_byte_arduino_2nd_hw_i2c(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
1384{
1385#ifdef U8X8_HAVE_2ND_HW_I2C
1386 switch(msg)
1387 {
1388 case U8X8_MSG_BYTE_SEND:
1389 Wire1.write((uint8_t *)arg_ptr, (int)arg_int);
1390 break;
1391 case U8X8_MSG_BYTE_INIT:
1392 if ( u8x8->bus_clock == 0 ) /* issue 769 */
1393 u8x8->bus_clock = u8x8->display_info->i2c_bus_clock_100kHz * 100000UL;
1394 Wire1.begin();
1395 break;
1396 case U8X8_MSG_BYTE_SET_DC:
1397 break;
1398 case U8X8_MSG_BYTE_START_TRANSFER:
1399#if ARDUINO >= 10600
1400 /* not sure when the setClock function was introduced, but it is there since 1.6.0 */
1401 /* if there is any error with Wire.setClock() just remove this function call by */
1402 /* defining U8X8_DO_NOT_SET_WIRE_CLOCK */
1403#ifndef U8X8_DO_NOT_SET_WIRE_CLOCK
1404 Wire1.setClock(u8x8->bus_clock);
1405#endif
1406#endif
1407 Wire1.beginTransmission(u8x8_GetI2CAddress(u8x8)>>1);
1408 break;
1409 case U8X8_MSG_BYTE_END_TRANSFER:
1410 Wire1.endTransmission();
1411 break;
1412 default:
1413 return 0;
1414 }
1415#endif
1416 return 1;
1417}
1418
1419#endif // U8X8_USE_PINS
1420
1421/*=============================================*/
1422
1423/*
1424 replacement for a more faster u8x8_byte_8bit_8080mode
1425 in general u8x8_byte_8bit_8080mode could be a fallback:
1426
1427 uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
1428 {
1429 return u8x8_byte_8bit_8080mode(u8x8, msg,arg_int, arg_ptr);
1430 }
1431
1432
1433
1434*/
1435
1436#ifndef __AVR_ARCH__
1437#define __AVR_ARCH__ 0
1438#endif
1439
1440#if !defined(U8X8_USE_PINS)
1441 /* no pin information (very strange), so fallback */
1442extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
1443{
1444 return u8x8_byte_8bit_8080mode(u8x8, msg,arg_int, arg_ptr);
1445}
1446
1447#elif __AVR_ARCH__ == 4 || __AVR_ARCH__ == 5 || __AVR_ARCH__ == 51 || __AVR_ARCH__ == 6 || __AVR_ARCH__ == 103
1448
1449/* this function completly replaces u8x8_byte_8bit_8080mode*/
1450extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
1451{
1452 uint8_t i, b;
1453 uint8_t *data;
1454
1455 /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */
1456 /* so, it should be possible to use multiple displays with different pins */
1457
1458 static volatile uint8_t *arduino_e_port;
1459 static volatile uint8_t arduino_e_mask;
1460 static volatile uint8_t arduino_e_n_mask;
1461
1462 static volatile uint8_t *arduino_data_port[8];
1463 static volatile uint8_t arduino_data_mask[8];
1464 static volatile uint8_t arduino_data_n_mask[8];
1465
1466 switch(msg)
1467 {
1468 case U8X8_MSG_BYTE_SEND:
1469 data = (uint8_t *)arg_ptr;
1470 while( arg_int > 0 )
1471 {
1472 b = *data;
1473 data++;
1474 arg_int--;
1475 for( i = 0; i < 8; i++ )
1476 {
1477 if ( b & 1 )
1478 *arduino_data_port[i] |= arduino_data_mask[i];
1479 else
1480 *arduino_data_port[i] &= arduino_data_n_mask[i];
1481 b >>= 1;
1482
1483 }
1484
1485 *arduino_e_port &= arduino_e_n_mask;
1486
1487
1488 /* AVR Architecture is very slow, extra call is not required */
1489 //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
1490 u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
1491
1492 *arduino_e_port |= arduino_e_mask;
1493
1494 /* AVR Architecture is very slow, extra call is not required */
1495 //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
1496 u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
1497
1498 }
1499 break;
1500
1501 case U8X8_MSG_BYTE_INIT:
1502 /* disable chipselect */
1503 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
1504 /* no wait required here */
1505
1506 /* ensure that the enable signal is high */
1507 u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
1508 break;
1509 case U8X8_MSG_BYTE_SET_DC:
1510 u8x8_gpio_SetDC(u8x8, arg_int);
1511 break;
1512 case U8X8_MSG_BYTE_START_TRANSFER:
1513 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
1514 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
1515
1516 /* there is no consistency checking for u8x8->pins[U8X8_PIN_E] */
1517
1518 arduino_e_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_E]));
1519 arduino_e_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_E]);
1520 arduino_e_n_mask = ~arduino_e_mask;
1521
1522 /* there is no consistency checking for u8x8->pins[U8X8_PIN_D0] */
1523
1524 for( i = 0; i < 8; i++ )
1525 {
1526 arduino_data_port[i] = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_D0+i]));
1527 arduino_data_mask[i] = digitalPinToBitMask(u8x8->pins[U8X8_PIN_D0+i]);
1528 arduino_data_n_mask[i] = ~arduino_data_mask[i];
1529 }
1530
1531 break;
1532 case U8X8_MSG_BYTE_END_TRANSFER:
1533 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
1534 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
1535 break;
1536 default:
1537 return 0;
1538 }
1539 return 1;
1540}
1541
1542#else
1543 /* fallback */
1544extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
1545{
1546 return u8x8_byte_8bit_8080mode(u8x8, msg,arg_int, arg_ptr);
1547}
1548
1549#endif
1550
1551
1552/*=============================================*/
1553
1554/*
1555 replacement for a more faster u8x8_byte_ks0108
1556 in general u8x8_byte_ks0108 could be a fallback:
1557
1558 uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
1559 {
1560 return u8x8_byte_ks0108(u8x8, msg,arg_int, arg_ptr);
1561 }
1562
1563
1564
1565*/
1566
1567#ifndef __AVR_ARCH__
1568#define __AVR_ARCH__ 0
1569#endif
1570
1571#if !defined(U8X8_USE_PINS)
1572 /* no pin information (very strange), so fallback */
1573extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
1574{
1575 return u8x8_byte_ks0108(u8x8, msg,arg_int, arg_ptr);
1576}
1577
1578#elif __AVR_ARCH__ == 4 || __AVR_ARCH__ == 5 || __AVR_ARCH__ == 51 || __AVR_ARCH__ == 6 || __AVR_ARCH__ == 103
1579
1580/* this function completly replaces u8x8_byte_ks0108*/
1581extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
1582{
1583 uint8_t i, b;
1584 uint8_t *data;
1585
1586 /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */
1587 /* so, it should be possible to use multiple displays with different pins */
1588
1589 static volatile uint8_t *arduino_e_port;
1590 static volatile uint8_t arduino_e_mask;
1591 static volatile uint8_t arduino_e_n_mask;
1592
1593 static volatile uint8_t *arduino_data_port[8];
1594 static volatile uint8_t arduino_data_mask[8];
1595 static volatile uint8_t arduino_data_n_mask[8];
1596
1597 switch(msg)
1598 {
1599 case U8X8_MSG_BYTE_SEND:
1600 data = (uint8_t *)arg_ptr;
1601 while( arg_int > 0 )
1602 {
1603 b = *data;
1604 data++;
1605 arg_int--;
1606 for( i = 0; i < 8; i++ )
1607 {
1608 if ( b & 1 )
1609 *arduino_data_port[i] |= arduino_data_mask[i];
1610 else
1611 *arduino_data_port[i] &= arduino_data_n_mask[i];
1612 b >>= 1;
1613
1614 }
1615
1616 *arduino_e_port |= arduino_e_mask;
1617
1618
1619 /* AVR Architecture is very slow, extra call is not required */
1620 u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
1621
1622 *arduino_e_port &= arduino_e_n_mask;
1623
1624 /* AVR Architecture is very slow, extra call is not required */
1625 u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
1626
1627 }
1628 break;
1629
1630 case U8X8_MSG_BYTE_INIT:
1631 /* disable chipselect */
1632 u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
1633 /* no wait required here */
1634
1635 /* ensure that the enable signal is low */
1636 u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
1637 break;
1638 case U8X8_MSG_BYTE_SET_DC:
1639 u8x8_gpio_SetDC(u8x8, arg_int);
1640 break;
1641 case U8X8_MSG_BYTE_START_TRANSFER:
1642 u8x8_byte_set_ks0108_cs(u8x8, arg_int);
1643 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
1644
1645 /* there is no consistency checking for u8x8->pins[U8X8_PIN_E] */
1646
1647 arduino_e_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_E]));
1648 arduino_e_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_E]);
1649 arduino_e_n_mask = ~arduino_e_mask;
1650
1651 /* there is no consistency checking for u8x8->pins[U8X8_PIN_D0] */
1652
1653 for( i = 0; i < 8; i++ )
1654 {
1655 arduino_data_port[i] = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_D0+i]));
1656 arduino_data_mask[i] = digitalPinToBitMask(u8x8->pins[U8X8_PIN_D0+i]);
1657 arduino_data_n_mask[i] = ~arduino_data_mask[i];
1658 }
1659
1660 break;
1661 case U8X8_MSG_BYTE_END_TRANSFER:
1662 u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
1663 u8x8_byte_set_ks0108_cs(u8x8, arg_int);
1664 break;
1665 default:
1666 return 0;
1667 }
1668 return 1;
1669}
1670
1671#else
1672 /* fallback */
1673extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
1674{
1675 return u8x8_byte_ks0108(u8x8, msg,arg_int, arg_ptr);
1676}
1677
1678#endif
1679#endif /*ARDUINO*/
1680
1681
1682
1683
1684
1685
1686
1687
1688#ifdef U8X8_USE_PINS
1689
1690/*
1691 use U8X8_PIN_NONE as value for "reset", if there is no reset line
1692*/
1693
1694void u8x8_SetPin_4Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset)
1695{
1696 u8x8_SetPin(u8x8, U8X8_PIN_SPI_CLOCK, clock);
1697 u8x8_SetPin(u8x8, U8X8_PIN_SPI_DATA, data);
1698 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1699 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1700 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1701}
1702
1703#ifdef _obsolete_com_specific_setup
1704void u8x8_Setup_4Wire_SW_SPI(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset)
1705{
1706 u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_4wire_sw_spi, u8x8_gpio_and_delay_arduino);
1707
1708 /* assign individual pin values (only for ARDUINO, if pin_list is available) */
1709 u8x8_SetPin(u8x8, U8X8_PIN_SPI_CLOCK, clock);
1710 u8x8_SetPin(u8x8, U8X8_PIN_SPI_DATA, data);
1711 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1712 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1713 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1714}
1715#endif /* obsolete com specific setup */
1716
1717void u8x8_SetPin_3Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset)
1718{
1719 u8x8_SetPin(u8x8, U8X8_PIN_SPI_CLOCK, clock);
1720 u8x8_SetPin(u8x8, U8X8_PIN_SPI_DATA, data);
1721 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1722 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1723}
1724
1725#ifdef _obsolete_com_specific_setup
1726void u8x8_Setup_3Wire_SW_SPI(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset)
1727{
1728 u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_3wire_sw_spi, u8x8_gpio_and_delay_arduino);
1729
1730 /* assign individual pin values (only for ARDUINO, if pin_list is available) */
1731 u8x8_SetPin(u8x8, U8X8_PIN_SPI_CLOCK, clock);
1732 u8x8_SetPin(u8x8, U8X8_PIN_SPI_DATA, data);
1733 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1734 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1735}
1736#endif /* obsolete com specific setup */
1737
1738/*
1739 use U8X8_PIN_NONE as value for "reset", if there is no reset line
1740*/
1741void u8x8_SetPin_3Wire_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t reset)
1742{
1743 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1744 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1745}
1746
1747/*
1748 use U8X8_PIN_NONE as value for "reset", if there is no reset line
1749*/
1750void u8x8_SetPin_4Wire_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t dc, uint8_t reset)
1751{
1752 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1753 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1754 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1755}
1756
1757void u8x8_SetPin_ST7920_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t reset)
1758{
1759 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1760 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1761}
1762
1763
1764#ifdef _obsolete_com_specific_setup
1765void u8x8_Setup_4Wire_HW_SPI(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t cs, uint8_t dc, uint8_t reset)
1766{
1767 u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino);
1768
1769 /* assign individual pin values (only for ARDUINO, if pin_list is available) */
1770 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1771 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1772 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1773}
1774#endif /* obsolete com specific setup */
1775
1776
1777void u8x8_SetPin_SW_I2C(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t reset)
1778{
1779 u8x8_SetPin(u8x8, U8X8_PIN_I2C_CLOCK, clock);
1780 u8x8_SetPin(u8x8, U8X8_PIN_I2C_DATA, data);
1781 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1782}
1783
1784#ifdef _obsolete_com_specific_setup
1785void u8x8_Setup_SSD13xx_SW_I2C(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t clock, uint8_t data, uint8_t reset)
1786{
1787 u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_ssd13xx_sw_i2c, u8x8_gpio_and_delay_arduino);
1788
1789 /* assign individual pin values (only for ARDUINO, if pin_list is available) */
1790 u8x8_SetPin(u8x8, U8X8_PIN_I2C_CLOCK, clock);
1791 u8x8_SetPin(u8x8, U8X8_PIN_I2C_DATA, data);
1792 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1793}
1794#endif /* obsolete com specific setup */
1795
1796void u8x8_SetPin_HW_I2C(u8x8_t *u8x8, uint8_t reset, uint8_t clock, uint8_t data)
1797{
1798 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1799 u8x8_SetPin(u8x8, U8X8_PIN_I2C_CLOCK, clock);
1800 u8x8_SetPin(u8x8, U8X8_PIN_I2C_DATA, data);
1801}
1802
1803void u8x8_SetPin_8Bit_6800(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset)
1804{
1805 u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
1806 u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
1807 u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
1808 u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
1809 u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
1810 u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
1811 u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
1812 u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
1813 u8x8_SetPin(u8x8, U8X8_PIN_E, enable);
1814 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1815 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1816 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1817}
1818
1819#ifdef _obsolete_com_specific_setup
1820void u8x8_Setup_8Bit_6800(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset)
1821{
1822 u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_8bit_6800mode, u8x8_gpio_and_delay_arduino);
1823
1824 /* assign individual pin values (only for ARDUINO, if pin_list is available) */
1825 u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
1826 u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
1827 u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
1828 u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
1829 u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
1830 u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
1831 u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
1832 u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
1833 u8x8_SetPin(u8x8, U8X8_PIN_E, enable);
1834 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1835 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1836 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1837}
1838#endif /* obsolete com specific setup */
1839
1840
1841void u8x8_SetPin_8Bit_8080(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t wr, uint8_t cs, uint8_t dc, uint8_t reset)
1842{
1843 u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
1844 u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
1845 u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
1846 u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
1847 u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
1848 u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
1849 u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
1850 u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
1851 u8x8_SetPin(u8x8, U8X8_PIN_E, wr);
1852 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1853 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1854 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1855}
1856
1857
1858#ifdef _obsolete_com_specific_setup
1859void u8x8_Setup_8Bit_8080(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t wr, uint8_t cs, uint8_t dc, uint8_t reset)
1860{
1861 u8x8_Setup(u8x8, display_cb, u8x8_cad_001, u8x8_byte_8bit_8080mode, u8x8_gpio_and_delay_arduino);
1862
1863 /* assign individual pin values (only for ARDUINO, if pin_list is available) */
1864 u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
1865 u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
1866 u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
1867 u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
1868 u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
1869 u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
1870 u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
1871 u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
1872 u8x8_SetPin(u8x8, U8X8_PIN_E, wr);
1873 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs);
1874 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1875 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1876}
1877#endif /* obsolete com specific setup */
1878
1879void u8x8_SetPin_KS0108(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset)
1880{
1881 u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
1882 u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
1883 u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
1884 u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
1885 u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
1886 u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
1887 u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
1888 u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
1889 u8x8_SetPin(u8x8, U8X8_PIN_E, enable);
1890 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1891 u8x8_SetPin(u8x8, U8X8_PIN_CS, cs0);
1892 u8x8_SetPin(u8x8, U8X8_PIN_CS1, cs1);
1893 u8x8_SetPin(u8x8, U8X8_PIN_CS2, cs2);
1894 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1895}
1896
1897void u8x8_SetPin_SED1520(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t dc, uint8_t e1, uint8_t e2, uint8_t reset)
1898{
1899 u8x8_SetPin(u8x8, U8X8_PIN_D0, d0);
1900 u8x8_SetPin(u8x8, U8X8_PIN_D1, d1);
1901 u8x8_SetPin(u8x8, U8X8_PIN_D2, d2);
1902 u8x8_SetPin(u8x8, U8X8_PIN_D3, d3);
1903 u8x8_SetPin(u8x8, U8X8_PIN_D4, d4);
1904 u8x8_SetPin(u8x8, U8X8_PIN_D5, d5);
1905 u8x8_SetPin(u8x8, U8X8_PIN_D6, d6);
1906 u8x8_SetPin(u8x8, U8X8_PIN_D7, d7);
1907 u8x8_SetPin(u8x8, U8X8_PIN_E, e1);
1908 u8x8_SetPin(u8x8, U8X8_PIN_CS, e2);
1909 u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
1910 u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
1911}
1912#endif // U8X8_USE_PINS