44// Driver for SSD1306/SSD1309/SH1106 display *
55// ***************************************************************************************************
66// 25-02-2021, ES: Correct bug, isSH1106 was always set. *
7+ // 04-05-2022, ES: Uses Wire library now
78// ***************************************************************************************************
8- #include < driver/i2c .h>
9+ #include < Wire .h>
910#include < string.h>
1011#include " oled.h"
1112
12- char * dbgprint ( const char * format, ... ) ; // Print a formatted debug line
13+ char * dbgprint ( const char * format, ... ) ; // Print a formatted debug line
1314
15+ uint16_t oledtyp ; // Type of OLED
1416OLED * tft ; // Object for display
1517scrseg_struct OLED_tftdata[TFTSECS ] = // Screen divided in 3 segments + 1 overlay
1618{ // One text line is 8 pixels
@@ -21,9 +23,16 @@ scrseg_struct OLED_tftdata[TFTSECS] = // Screen divided in 3 seg
2123} ;
2224
2325
24- bool oled_dsp_begin ( uint8_t sda_pin, uint8_t scl_pin )
26+ // ***********************************************************************************************
27+ // O L E D _ D S P _ B E G I N *
28+ // ***********************************************************************************************
29+ // Init display. *
30+ // ***********************************************************************************************
31+ bool oled_dsp_begin ( uint8_t sda_pin, uint8_t scl_pin, uint16_t olt )
2532{
26- dbgprint ( " Init OLED, I2C pins %d,%d" ,
33+ oledtyp = olt ; // Save OLED type
34+ dbgprint ( " Init OLED %d, I2C pins %d,%d" ,
35+ oledtyp,
2736 sda_pin,
2837 scl_pin ) ;
2938 if ( ( sda_pin >= 0 ) &&
@@ -40,44 +49,6 @@ bool oled_dsp_begin ( uint8_t sda_pin, uint8_t scl_pin )
4049}
4150
4251
43- // ***********************************************************************************************
44- // O L E D :: W R I 2 C C H A N *
45- // ***********************************************************************************************
46- // Write 1 byte to the I2C buffer. *
47- // ***********************************************************************************************
48- void OLED::wrI2Cchan ( uint8_t b ) // Send 1 byte to I2C buffer
49- {
50- i2c_master_write_byte ( i2Cchan, b, true ) ; // Add 1 byte to I2C buffer
51- }
52-
53-
54- // ***********************************************************************************************
55- // O L E D :: O P E N I 2 C C H A N *
56- // ***********************************************************************************************
57- // Open an I2c channel for communication. *
58- // ***********************************************************************************************
59- void OLED::openI2Cchan ()
60- {
61- i2Cchan = i2c_cmd_link_create () ; // Create the link
62- i2c_master_start ( i2Cchan ) ; // Start collecting data in buffer
63- wrI2Cchan ( (OLED_I2C_ADDRESS << 1 ) | I2C_MASTER_WRITE ) ; // Send I2C address and write bit
64- }
65-
66-
67- // ***********************************************************************************************
68- // O L E D :: C L O S E I 2 C C H A N *
69- // ***********************************************************************************************
70- // Seend buffer and close the I2c channel. *
71- // ***********************************************************************************************
72- void OLED::closeI2Cchan ()
73- {
74- i2c_master_stop ( i2Cchan ) ; // Stop filling buffer
75- i2c_master_cmd_begin ( I2C_NUM_0 , i2Cchan, // Start actual transfer
76- 10 / portTICK_PERIOD_MS ) ; // Time-out
77- i2c_cmd_link_delete ( i2Cchan ) ; // Delete the link
78- }
79-
80-
8152// ***********************************************************************************************
8253// O L E D :: P R I N T *
8354// ***********************************************************************************************
@@ -96,8 +67,8 @@ void OLED::print ( char c )
9667 {
9768 xchar = SCREEN_WIDTH ; // Yes, force next line
9869 }
99- xchar += ( OLEDFONTWIDTH + 1 ) ; // Move x cursor
100- if ( xchar > ( SCREEN_WIDTH - OLEDFONTWIDTH ) ) // End of line?
70+ xchar += ( OLEDFONTWIDTH + 1 ) ; // Move x cursor
71+ if ( xchar > ( SCREEN_WIDTH - OLEDFONTWIDTH ) ) // End of line?
10172 {
10273 xchar = 0 ; // Yes, mimic CR
10374 ychar = ( ychar + 1 ) & 7 ; // And LF
@@ -119,9 +90,9 @@ void OLED::print ( const char* str )
11990 }
12091}
12192
122-
93+ # ifdef EXCLUDEDDRAWBITMAP
12394// ***********************************************************************************************
124- // OLED :: D R A W B I T M A P *
95+ // O L E D :: D R A W B I T M A P *
12596// ***********************************************************************************************
12697// Copy a bitmap to the display buffer. *
12798// ***********************************************************************************************
@@ -159,7 +130,7 @@ void OLED::drawBitmap ( uint8_t x, uint8_t y, uint8_t* buf, uint8_t w, uint8_t h
159130 ssdbuf[pg].dirty = true ; // Page has been changed
160131 }
161132}
162-
133+ # endif
163134
164135// ***********************************************************************************************
165136// O L E D :: D I S P L A Y *
@@ -169,32 +140,33 @@ void OLED::drawBitmap ( uint8_t x, uint8_t y, uint8_t* buf, uint8_t w, uint8_t h
169140void OLED::display ()
170141{
171142 uint8_t pg ; // Page number 0..OLED_NPAG - 1
172- static uint8_t fillbuf[] = { 0 , 0 , 0 , 0 } ; // To clear 4 bytes of SH1106 RAM
173143
174144 for ( pg = 0 ; pg < OLED_NPAG ; pg++ )
175145 {
176146 if ( ssdbuf[pg].dirty ) // Refresh needed?
177147 {
178148 ssdbuf[pg].dirty = false ; // Yes, set page to "up-to-date"
179- openI2Cchan ( ) ; // Open I2C channel
180- wrI2Cchan ( OLED_CONTROL_BYTE_CMD_SINGLE ) ; // Set single byte command mode
181- wrI2Cchan ( 0xB0 | pg ) ; // Set page address
182- if ( isSH1106 || isSSD1309 ) // Is it an SH1106 or SSD1309?
149+ Wire. beginTransmission ( OLED_I2C_ADDRESS ) ; // Begin transmission
150+ Wire. write ( ( uint8_t ) OLED_CONTROL_BYTE_CMD_SINGLE ) ; // Set single byte command mode
151+ Wire. write ( ( uint8_t )( 0xB0 | pg ) ) ; // Set page address
152+ if ( ( oledtyp == 1106 ) || ( oledtyp == 1309 ) ) // Is it an SH1106/ SSD1309?
183153 {
184- wrI2Cchan ( 0x00 ) ; // Set lower column address to 0
185- wrI2Cchan ( 0x10 ) ; // Set higher column address to 0
154+ Wire. write ( ( uint8_t ) 0x00 ) ; // Set lower column address to 0
155+ Wire. write ( ( uint8_t ) 0x10 ) ; // Set higher column address to 0
186156 }
187- closeI2Cchan () ; // Send and close I2C channel
188- // Channel is closed and reopened because of limited buffer space
189- openI2Cchan () ; // Open I2C channel again
190- wrI2Cchan ( OLED_CONTROL_BYTE_DATA_STREAM ) ; // Set multi byte data mode
191- if ( isSH1106 ) // Is it a SH1106?
157+ Wire.write ( (uint8_t )OLED_CONTROL_BYTE_DATA_STREAM ) ; // Set multi byte data mode
158+ if ( oledtyp == 1106 ) // Is it an SH1106?
192159 {
193- i2c_master_write ( i2Cchan, fillbuf, 4 , true ) ; // Yes, fill extra RAM with zeroes
160+ uint8_t fillbuf[] = { 0 , 0 , 0 , 0 } ; // To clear 4 bytes of SH1106 RAM
161+ Wire.write ( fillbuf, 4 ) ; // Yes, fill extra RAM with zeroes
194162 }
195- i2c_master_write ( i2Cchan, ssdbuf[pg].page , 128 , // Send 1 page with data
196- true ) ;
197- closeI2Cchan () ; // Send and close I2C channel
163+ Wire.write ( ssdbuf[pg].page , 64 ) ; // Send 1st half page with data
164+ Wire.endTransmission () ; // End of transmission
165+ // Channel is closed and reopened because of limited buffer space
166+ Wire.beginTransmission ( OLED_I2C_ADDRESS ) ; // Begin transmission
167+ Wire.write ( (uint8_t )OLED_CONTROL_BYTE_DATA_STREAM ) ; // Set multi byte data mode
168+ Wire.write ( ssdbuf[pg].page + 64 , 64 ) ; // Send 2nd half page with data
169+ Wire.endTransmission () ; // End of transmission
198170 }
199171 }
200172}
@@ -271,15 +243,6 @@ void OLED::fillRect ( uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color
271243// ***********************************************************************************************
272244OLED ::OLED ( uint8_t sda, uint8_t scl )
273245{
274- i2c_config_t i2c_config = // Set-up of I2C configuration
275- {
276- I2C_MODE_MASTER ,
277- (gpio_num_t )sda, // Pull ups for sda and scl
278- GPIO_PULLUP_ENABLE ,
279- (gpio_num_t )scl,
280- GPIO_PULLUP_ENABLE ,
281- 400000 // High speed
282- } ;
283246 uint8_t initbuf[] = // Initial commands to init OLED
284247 {
285248 OLED_CONTROL_BYTE_CMD_STREAM , // Stream next bytes
@@ -301,22 +264,12 @@ OLED::OLED ( uint8_t sda, uint8_t scl )
301264 OLED_CMD_SCROLL_OFF , // Stop scrolling
302265 OLED_CMD_DISPLAY_ON // Display on
303266 } ;
304- #if defined ( OLED1106 ) // Is it an SH1106?
305- isSH1106 = true ; // Set display type
306- #endif
307- dbgprint ( " ISSH116 is %d" , (int )isSH1106 ) ;
308- #if defined ( OLED1309 ) // Is it an SSD1309?
309- isSSD1309 = true ; // Set display type
310- #endif
311- dbgprint ( " ISSSD1309 is %d" , (int )isSSD1309 ) ;
312267 ssdbuf = (page_struct*) malloc ( 8 * sizeof (page_struct) ) ; // Create buffer for screen
313268 font = OLEDfont ;
314- i2c_param_config ( I2C_NUM_0 , &i2c_config ) ;
315- i2c_driver_install ( I2C_NUM_0 , I2C_MODE_MASTER , 0 , 0 , 0 ) ;
316- openI2Cchan () ; // Open I2C channel
317- i2c_master_write ( i2Cchan, initbuf, sizeof (initbuf),
318- true ) ;
319- closeI2Cchan () ; // Send and close I2C channel
269+ Wire.begin ( sda, scl ) ; // , 150000 ) ; // Init I2c
270+ Wire.beginTransmission ( OLED_I2C_ADDRESS ) ; // Begin transmission
271+ Wire.write ( initbuf, sizeof (initbuf) ) ; // Write init buffer
272+ Wire.endTransmission () ; // End of transmission
320273 clear () ; // Clear the display
321274}
322275
0 commit comments