From e34274c01eb1886103132438b70e1b32c3d479f7 Mon Sep 17 00:00:00 2001 From: penfold42 Date: Mon, 16 Jul 2018 21:11:55 +1000 Subject: [PATCH 1/4] Move to page mode to support sh1106 --- src/SSD1306.cpp | 72 +++++++++++++++++++++++++++++------------------ src/SSD1306.h | 1 + src/ScreenLCD.cpp | 4 +-- 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/SSD1306.cpp b/src/SSD1306.cpp index 91c1661..367e927 100644 --- a/src/SSD1306.cpp +++ b/src/SSD1306.cpp @@ -65,28 +65,30 @@ void SSD1306::InitHardware() SetContrast(GetContrast()); - SendCommand(SSD1306_CMD_ENTIRE_DISPLAY_ON); + SendCommand(SSD1306_CMD_ENTIRE_DISPLAY_ON); // 0xA4 - DONT force entire display on SendCommand(SSD1306_CMD_NORMAL_DISPLAY); // 0xA6 = non inverted SendCommand(SSD1306_CMD_SET_PRE_CHARGE_PERIOD); // 0xD9 SendCommand(0xF1); - SendCommand(SSD1306_CMD_SET_VCOMH_DESELECT_LEVEL); + SendCommand(SSD1306_CMD_SET_VCOMH_DESELECT_LEVEL); // 0xDB SendCommand(0x40); - SendCommand(SSD1306_CMD_SET_DISPLAY_CLOCK_DIVIDE_RATIO); + SendCommand(SSD1306_CMD_SET_DISPLAY_CLOCK_DIVIDE_RATIO); // 0xD5 SendCommand(0x80); // upper nibble is rate, lower nibble is divisor - SendCommand(SSD1306_ENABLE_CHARGE_PUMP); // Enable charge pump regulator + SendCommand(SSD1306_ENABLE_CHARGE_PUMP); // 0x8D Enable charge pump regulator SendCommand(0x14); // external = 0x10 internal = 0x14 - SendCommand(SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE); // Set Memory Addressing Mode - SendCommand(0x00); // 00 - Horizontal Addressing Mode + SendCommand(SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE); // 0x20 Set Memory Addressing Mode +// SendCommand(0x00); // 00 - Horizontal Addressing Mode + SendCommand(0x10); // 10 - Page Addressing Mode for SH1106 compatibility Home(); - SendCommand(SSD1306_CMD_DEACTIVATE_SCROLL); + if (type != 1106) + SendCommand(SSD1306_CMD_DEACTIVATE_SCROLL); // 0x2E } void SSD1306::SendCommand(u8 command) @@ -120,9 +122,11 @@ void SSD1306::MoveCursorByte(u8 row, u8 col) if (row > 7) { row = 7; } if (type == 1106) - SetDisplayWindow(col+2, 129, row, 7); // sh1106 has 132x64 ram, display is centreed - else - SetDisplayWindow(col+0, 127, row, 7); + col += 2; + + SendCommand(0xB0 + row); // page address + SendCommand(0x00 | (col & 0xf)); // column address lower bits + SendCommand(0x10 | (col >> 4)); // column address upper bits } void SSD1306::MoveCursorCharacter(u8 row, u8 col) @@ -136,13 +140,25 @@ void SSD1306::MoveCursorCharacter(u8 row, u8 col) void SSD1306::RefreshScreen() { int i; - Home(); - for (i = 0; i < SSD1306_128x64_BYTES; i++) + for (i = 0; i < 8; i++) { - SendData(frame[i]); + RefreshPage(i); } } +/* +void SSD1306::RefreshRows(u32 start, u32 numRows) +{ + start <<=1; + numRows <<=1; + int i; + for (i = start; i < numRows; i++) + { + RefreshPage(i); + } +} +*/ + void SSD1306::RefreshRows(u32 start, u32 amountOfRows) { int i; @@ -160,6 +176,19 @@ void SSD1306::RefreshRows(u32 start, u32 amountOfRows) SendData(frame[i]); } } +void SSD1306::RefreshPage(u32 page) +{ + MoveCursorByte(page, 0); + + int i; + int start = page*128; + int end = page*128 + 128; + + for (i = start; i < end; i++) + { + SendData(frame[i]); + } +} void SSD1306::ClearScreen() { @@ -169,14 +198,12 @@ void SSD1306::ClearScreen() void SSD1306::DisplayOn() { - SendCommand(SSD1306_CMD_DISPLAY_ON); - ClearScreen(); + SendCommand(SSD1306_CMD_DISPLAY_ON); // 0xAF } void SSD1306::DisplayOff() { - ClearScreen(); - SendCommand(SSD1306_CMD_DISPLAY_OFF); + SendCommand(SSD1306_CMD_DISPLAY_OFF); // 0xAE } void SSD1306::SetContrast(u8 value) @@ -193,17 +220,6 @@ void SSD1306::SetVCOMDeselect(u8 value) SendCommand( (value & 7) << 4 ); } -void SSD1306::SetDisplayWindow(u8 x1, u8 x2, u8 y1, u8 y2) -{ - SendCommand(SSD1306_CMD_SET_COLUMN_ADDRESS); // 0x21 Set Column Address (only for horizontal or vertical mode) - SendCommand(x1); // start 0 - SendCommand(x2); // end 127 - - SendCommand(SSD1306_CMD_SET_PAGE_ADDRESS); // 0x22 - SendCommand(y1); // start 0 - SendCommand(y2); // end 7 (so 8 vertical bytes == 64 row display) -} - void SSD1306::Plottext(int x, int y, char* str, bool inverse) { int i; diff --git a/src/SSD1306.h b/src/SSD1306.h index da8655d..6d5a9f9 100644 --- a/src/SSD1306.h +++ b/src/SSD1306.h @@ -90,6 +90,7 @@ public: void ClearScreen(); void RefreshScreen(); + void RefreshPage(u32 page); void RefreshRows(u32 start, u32 amountOfRows); void SetDisplayWindow(u8 x1, u8 y1, u8 x2, u8 y2); void PlotPixel(int x, int y, int c); diff --git a/src/ScreenLCD.cpp b/src/ScreenLCD.cpp index ca30a51..3acf39c 100644 --- a/src/ScreenLCD.cpp +++ b/src/ScreenLCD.cpp @@ -40,9 +40,9 @@ void ScreenLCD::Open(u32 widthDesired, u32 heightDesired, u32 colourDepth, int B height = heightDesired; ssd1306 = new SSD1306(BSCMaster, LCDAddress, LCDFlip, LCDType); - ssd1306->DisplayOn(); - + ssd1306->ClearScreen(); ssd1306->RefreshScreen(); + ssd1306->DisplayOn(); opened = true; } From 91ead26b2bd59526d44b5f6a11d45314dfa4e231 Mon Sep 17 00:00:00 2001 From: penfold42 Date: Mon, 16 Jul 2018 22:46:53 +1000 Subject: [PATCH 2/4] SH1106 support now works --- src/SSD1306.cpp | 33 +++------------------------------ src/SSD1306.h | 5 ++--- src/main.cpp | 1 + 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/src/SSD1306.cpp b/src/SSD1306.cpp index 367e927..0903db0 100644 --- a/src/SSD1306.cpp +++ b/src/SSD1306.cpp @@ -65,7 +65,7 @@ void SSD1306::InitHardware() SetContrast(GetContrast()); - SendCommand(SSD1306_CMD_ENTIRE_DISPLAY_ON); // 0xA4 - DONT force entire display on + SendCommand(SSD1306_CMD_TEST_DISPLAY_OFF); // 0xA4 - DONT force entire display on SendCommand(SSD1306_CMD_NORMAL_DISPLAY); // 0xA6 = non inverted @@ -129,14 +129,6 @@ void SSD1306::MoveCursorByte(u8 row, u8 col) SendCommand(0x10 | (col >> 4)); // column address upper bits } -void SSD1306::MoveCursorCharacter(u8 row, u8 col) -{ - if (col > 15) { col = 15; } - if (row > 7) { row = 7; } - - MoveCursorByte(row, col << 3); -} - void SSD1306::RefreshScreen() { int i; @@ -146,36 +138,17 @@ void SSD1306::RefreshScreen() } } -/* void SSD1306::RefreshRows(u32 start, u32 numRows) { start <<=1; numRows <<=1; - int i; - for (i = start; i < numRows; i++) + u32 i; + for (i = start; i < start+numRows; i++) { RefreshPage(i); } } -*/ -void SSD1306::RefreshRows(u32 start, u32 amountOfRows) -{ - int i; - - start <<= 1; - amountOfRows <<= 1; - - MoveCursorCharacter(start, 0); - - start *= 128; - int end = start + amountOfRows * 128; - - for (i = start; i < end; i++) - { - SendData(frame[i]); - } -} void SSD1306::RefreshPage(u32 page) { MoveCursorByte(page, 0); diff --git a/src/SSD1306.h b/src/SSD1306.h index 6d5a9f9..47ff9bb 100644 --- a/src/SSD1306.h +++ b/src/SSD1306.h @@ -102,7 +102,6 @@ protected: void Home(); void MoveCursorByte(u8 row, u8 col); - void MoveCursorCharacter(u8 row, u8 col); unsigned char frame[SSD1306_128x64_BYTES]; @@ -122,8 +121,8 @@ protected: #define SSD1306_CMD_ACTIVATE_SCROLL 0x2F #define SSD1306_CMD_SET_CONTRAST_CONTROL 0x81 // Set Contrast Control for BANK0 #define SSD1306_ENABLE_CHARGE_PUMP 0x8D -#define SSD1306_CMD_ENTIRE_DISPLAY_ON 0xA4 -#define SSD1306_CMD_ENTIRE_DISPLAY_OFF 0xA5 +#define SSD1306_CMD_TEST_DISPLAY_OFF 0xA4 +#define SSD1306_CMD_TEST_DISPLAY_ON 0xA5 #define SSD1306_CMD_NORMAL_DISPLAY 0xA6 // 1 = on pixel #define SSD1306_CMD_INVERT_DISPLAY 0xA7 // 0 = on pixel #define SSD1306_CMD_DISPLAY_OFF 0xAE diff --git a/src/main.cpp b/src/main.cpp index f5200c7..679dace 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -372,6 +372,7 @@ void InitialiseLCD() screenLCD = new ScreenLCD(); screenLCD->Open(128, 64, 1, i2cBusMaster, i2cLcdAddress, i2cLcdFlip, i2cLcdModel); screenLCD->SetContrast(i2cLcdOnContrast); + screenLCD->ClearInit(0); bool logo_done = false; if (strcasecmp(options.GetLcdLogoName(), "1541ii") == 0) From 4a1c56df411f9cac49fff21eb553e6ae01c128b5 Mon Sep 17 00:00:00 2001 From: penfold42 Date: Mon, 16 Jul 2018 23:15:46 +1000 Subject: [PATCH 3/4] s/Plottext/PlotText/g --- src/SSD1306.cpp | 2 +- src/SSD1306.h | 2 +- src/ScreenLCD.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SSD1306.cpp b/src/SSD1306.cpp index 0903db0..cfd5013 100644 --- a/src/SSD1306.cpp +++ b/src/SSD1306.cpp @@ -193,7 +193,7 @@ void SSD1306::SetVCOMDeselect(u8 value) SendCommand( (value & 7) << 4 ); } -void SSD1306::Plottext(int x, int y, char* str, bool inverse) +void SSD1306::PlotText(int x, int y, char* str, bool inverse) { int i; i = 0; diff --git a/src/SSD1306.h b/src/SSD1306.h index 47ff9bb..c06ea7c 100644 --- a/src/SSD1306.h +++ b/src/SSD1306.h @@ -79,7 +79,7 @@ public: SSD1306(int BSCMaster = 1, u8 address = 0x3C, int flip = 0, int type=1306); void PlotCharacter(int x, int y, char ascii, bool inverse); - void Plottext(int x, int y, char* str, bool inverse); + void PlotText(int x, int y, char* str, bool inverse); void InitHardware(); void DisplayOn(); diff --git a/src/ScreenLCD.cpp b/src/ScreenLCD.cpp index 3acf39c..bde0a30 100644 --- a/src/ScreenLCD.cpp +++ b/src/ScreenLCD.cpp @@ -100,7 +100,7 @@ void ScreenLCD::PlotRawImage(const u8* image, int x, int y, int w, int h) u32 ScreenLCD::PrintText(bool petscii, u32 x, u32 y, char *ptr, RGBA TxtColour, RGBA BkColour, bool measureOnly, u32* width, u32* height) { int len = 0; - ssd1306->Plottext(x >> 3, y >> 4, ptr, (BkColour & 0xffffff) != 0); + ssd1306->PlotText(x >> 3, y >> 4, ptr, (BkColour & 0xffffff) != 0); return len; } From ca2aa5e09f036d8efa6bf5c48081d0bfc96c568a Mon Sep 17 00:00:00 2001 From: penfold42 Date: Tue, 17 Jul 2018 09:37:53 +1000 Subject: [PATCH 4/4] Code cleanups --- src/SSD1306.cpp | 23 +++++++++++------------ src/SSD1306.h | 3 +++ src/main.cpp | 4 ++-- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/SSD1306.cpp b/src/SSD1306.cpp index cfd5013..d57c370 100644 --- a/src/SSD1306.cpp +++ b/src/SSD1306.cpp @@ -82,7 +82,6 @@ void SSD1306::InitHardware() SendCommand(0x14); // external = 0x10 internal = 0x14 SendCommand(SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE); // 0x20 Set Memory Addressing Mode -// SendCommand(0x00); // 00 - Horizontal Addressing Mode SendCommand(0x10); // 10 - Page Addressing Mode for SH1106 compatibility Home(); @@ -122,11 +121,11 @@ void SSD1306::MoveCursorByte(u8 row, u8 col) if (row > 7) { row = 7; } if (type == 1106) - col += 2; + col += 2; // sh1106 uses columns 2..129 - SendCommand(0xB0 + row); // page address - SendCommand(0x00 | (col & 0xf)); // column address lower bits - SendCommand(0x10 | (col >> 4)); // column address upper bits + SendCommand(SSD1306_CMD_SET_PAGE | row); // 0xB0 page address + SendCommand(SSD1306_CMD_SET_COLUMN_LOW | (col & 0xf)); // 0x00 column address lower bits + SendCommand(SSD1306_CMD_SET_COLUMN_HIGH | (col >> 4)); // 0x10 column address upper bits } void SSD1306::RefreshScreen() @@ -138,12 +137,13 @@ void SSD1306::RefreshScreen() } } -void SSD1306::RefreshRows(u32 start, u32 numRows) +void SSD1306::RefreshRows(u32 start, u32 amountOfRows) { - start <<=1; - numRows <<=1; - u32 i; - for (i = start; i < start+numRows; i++) + int i; + + start <<= 1; + amountOfRows <<= 1; + for (i = start; i < start+amountOfRows; i++) { RefreshPage(i); } @@ -151,12 +151,11 @@ void SSD1306::RefreshRows(u32 start, u32 numRows) void SSD1306::RefreshPage(u32 page) { - MoveCursorByte(page, 0); - int i; int start = page*128; int end = page*128 + 128; + MoveCursorByte(page, 0); for (i = start; i < end; i++) { SendData(frame[i]); diff --git a/src/SSD1306.h b/src/SSD1306.h index c06ea7c..f1ea8d9 100644 --- a/src/SSD1306.h +++ b/src/SSD1306.h @@ -114,6 +114,9 @@ protected: #endif +#define SSD1306_CMD_SET_COLUMN_LOW 0x00 +#define SSD1306_CMD_SET_COLUMN_HIGH 0x10 +#define SSD1306_CMD_SET_PAGE 0xB0 #define SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE 0x20 #define SSD1306_CMD_SET_COLUMN_ADDRESS 0x21 #define SSD1306_CMD_SET_PAGE_ADDRESS 0x22 diff --git a/src/main.cpp b/src/main.cpp index 679dace..d63819e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -372,7 +372,7 @@ void InitialiseLCD() screenLCD = new ScreenLCD(); screenLCD->Open(128, 64, 1, i2cBusMaster, i2cLcdAddress, i2cLcdFlip, i2cLcdModel); screenLCD->SetContrast(i2cLcdOnContrast); - screenLCD->ClearInit(0); + screenLCD->ClearInit(0); // sh1106 needs this bool logo_done = false; if (strcasecmp(options.GetLcdLogoName(), "1541ii") == 0) @@ -405,7 +405,7 @@ void InitialiseLCD() if (!logo_done) { - snprintf(tempBuffer, tempBufferSize, "Pixxxx V%d.%02d", versionMajor, versionMinor); + snprintf(tempBuffer, tempBufferSize, "Pi1541 V%d.%02d", versionMajor, versionMinor); int x = (128 - 8*strlen(tempBuffer) ) /2; int y = (64-16)/2; screenLCD->PrintText(0, x, y, tempBuffer, 0x0);