6464 #define SSD1306_MODE_DATA digitalWrite (dcPin, HIGH);
6565#endif
6666
67- #if defined(SPI_HAS_TRANSACTION) && !defined(ARDUINO_STM32_FEATHER)
68- #define SPI_TRANSACTION_START \
69- spi->beginTransaction (spiSettings); \
70- SSD1306_SELECT
71- #define SPI_TRANSACTION_END \
72- SSD1306_DESELECT \
73- spi->endTransaction ();
74- #else
75- #define SPI_TRANSACTION_START SSD1306_SELECT
76- #define SPI_TRANSACTION_END SSD1306_DESELECT
67+ #if (ARDUINO >= 157)
68+ #define SETWIRECLOCK wire->setClock (WIRECLK)
69+ #define RESWIRECLOCK wire->setClock (restoreClk)
70+ #else // setClock() is not present in older Arduino Wire lib
71+ #define SETWIRECLOCK
72+ #define RESWIRECLOCK
73+ #endif
74+
75+ #if defined(SPI_HAS_TRANSACTION)
76+ #define SPI_TRANSACTION_START spi->beginTransaction (spiSettings)
77+ #define SPI_TRANSACTION_END spi->endTransaction ()
78+ #else // SPI transactions likewise not present in older Arduino SPI lib
79+ #define SPI_TRANSACTION_START
80+ #define SPI_TRANSACTION_END
7781#endif
7882
83+ // The definition of 'transaction' is broadened a bit in the context of
84+ // this library -- referring not just to SPI transactions (if supported
85+ // in the version of the SPI library being used), but also chip select
86+ // (if SPI is being used, whether hardware or soft), and also to the
87+ // beginning and end of I2C transfers (the Wire clock may be sped up before
88+ // issuing data to the display, then restored to the default rate afterward
89+ // so other I2C device types still work). All of these are encapsulated
90+ // in the TRANSACTION_* macros.
91+
7992#if defined(ARDUINO_STM32_FEATHER)
80- #define TRANSACTION_START if (!wire) { SPI_TRANSACTION_START }
81- #define TRANSACTION_END if (!wire) { SPI_TRANSACTION_END }
93+ // The WICED board currently has no SPIClass -- hardware SPI is not
94+ // supported by this library there -- nor is there a Wire setClock()
95+ // function, so the transaction start/end code is a little simpler...
96+ #define TRANSACTION_START if (!wire) { SSD1306_SELECT; }
97+ #define TRANSACTION_END if (!wire) { SSD1306_DESELECT; }
8298#else
83- #if (ARDUINO >= 157)
84- #define TRANSACTION_START \
85- if (wire) wire->setClock (WIRECLK); \
86- else { SPI_TRANSACTION_START }
87- #define TRANSACTION_END \
88- if (wire) wire->setClock (restoreClk); \
89- else { SPI_TRANSACTION_END }
90- #else
91- #define TRANSACTION_START if (spi) { SPI_TRANSACTION_START }
92- #define TRANSACTION_END if (spi) { SPI_TRANSACTION_END }
93- #endif
99+ // Everywhere else, check first if Wire, then hardware SPI, then soft SPI:
100+ #define TRANSACTION_START \
101+ if (wire) { \
102+ SETWIRECLOCK; \
103+ } else { \
104+ if (spi) { \
105+ SPI_TRANSACTION_START; \
106+ } \
107+ SSD1306_SELECT; \
108+ }
109+ #define TRANSACTION_END \
110+ if (wire) { \
111+ RESWIRECLOCK; \
112+ } else { \
113+ SSD1306_DESELECT; \
114+ if (spi) { \
115+ SPI_TRANSACTION_END; \
116+ } \
117+ }
94118#endif
95119
96120// CONSTRUCTORS, DESTRUCTOR ------------------------------------------------
@@ -246,7 +270,8 @@ void Adafruit_SSD1306::ssd1306_command(uint8_t c) {
246270
247271// ALLOCATE & INIT DISPLAY -------------------------------------------------
248272
249- boolean Adafruit_SSD1306::begin (uint8_t vcs, uint8_t addr, boolean reset) {
273+ boolean Adafruit_SSD1306::begin (uint8_t vcs, uint8_t addr, boolean reset,
274+ boolean periphBegin) {
250275
251276 if ((!buffer) && !(buffer = (uint8_t *)malloc (WIDTH * ((HEIGHT + 7 ) / 8 ))))
252277 return false ;
@@ -267,7 +292,11 @@ boolean Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, boolean reset) {
267292 // If I2C address is unspecified, use default
268293 // (0x3C for 32-pixel-tall displays, 0x3D for all others).
269294 i2caddr = addr ? addr : ((HEIGHT == 32 ) ? 0x3C : 0x3D );
270- wire->begin ();
295+ // TwoWire begin() function might be already performed by the calling
296+ // function if it has unusual circumstances (e.g. TWI variants that
297+ // can accept different SDA/SCL pins, or if two SSD1306 instances
298+ // with different addresses -- only a single begin() is needed).
299+ if (periphBegin) wire->begin ();
271300 } else { // Using one of the SPI modes, either soft or hardware
272301 pinMode (dcPin, OUTPUT); // Set data/command pin as output
273302 pinMode (csPin, OUTPUT); // Same for chip select
@@ -280,7 +309,8 @@ boolean Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, boolean reset) {
280309 SSD1306_DESELECT
281310#if !defined(ARDUINO_STM32_FEATHER)
282311 if (spi) { // Hardware SPI
283- spi->begin ();
312+ // SPI peripheral begin same as wire check above.
313+ if (periphBegin) spi->begin ();
284314 } else { // Soft SPI
285315#endif
286316 pinMode (mosiPin, OUTPUT); // MOSI and SCLK outputs
@@ -618,6 +648,12 @@ void Adafruit_SSD1306::display(void) {
618648 ssd1306_command1 (WIDTH - 1 ); // Column end address
619649
620650#if defined(ESP8266)
651+ // ESP8266 needs a periodic yield() call to avoid watchdog reset.
652+ // With the limited size of SSD1306 displays, and the fast bitrate
653+ // being used (1 MHz or more), I think one yield() immediately before
654+ // a screen write and one immediately after should cover it. But if
655+ // not, if this becomes a problem, yields() might be added in the
656+ // 32-byte transfer condition below.
621657 yield ();
622658#endif
623659 uint16_t count = WIDTH * ((HEIGHT + 7 ) / 8 );
@@ -642,6 +678,9 @@ void Adafruit_SSD1306::display(void) {
642678 while (count--) SPIwrite (*ptr++);
643679 }
644680 TRANSACTION_END
681+ #if defined(ESP8266)
682+ yield ();
683+ #endif
645684}
646685
647686// SCROLLING FUNCTIONS -----------------------------------------------------
0 commit comments