Merge pull request #41 from penfold42/sh1106
Working Sh1106 display support
This commit is contained in:
commit
02b165c288
4 changed files with 40 additions and 48 deletions
|
@ -65,28 +65,29 @@ void SSD1306::InitHardware()
|
||||||
|
|
||||||
SetContrast(GetContrast());
|
SetContrast(GetContrast());
|
||||||
|
|
||||||
SendCommand(SSD1306_CMD_ENTIRE_DISPLAY_ON);
|
SendCommand(SSD1306_CMD_TEST_DISPLAY_OFF); // 0xA4 - DONT force entire display on
|
||||||
|
|
||||||
SendCommand(SSD1306_CMD_NORMAL_DISPLAY); // 0xA6 = non inverted
|
SendCommand(SSD1306_CMD_NORMAL_DISPLAY); // 0xA6 = non inverted
|
||||||
|
|
||||||
SendCommand(SSD1306_CMD_SET_PRE_CHARGE_PERIOD); // 0xD9
|
SendCommand(SSD1306_CMD_SET_PRE_CHARGE_PERIOD); // 0xD9
|
||||||
SendCommand(0xF1);
|
SendCommand(0xF1);
|
||||||
|
|
||||||
SendCommand(SSD1306_CMD_SET_VCOMH_DESELECT_LEVEL);
|
SendCommand(SSD1306_CMD_SET_VCOMH_DESELECT_LEVEL); // 0xDB
|
||||||
SendCommand(0x40);
|
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(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(0x14); // external = 0x10 internal = 0x14
|
||||||
|
|
||||||
SendCommand(SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE); // Set Memory 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();
|
Home();
|
||||||
|
|
||||||
SendCommand(SSD1306_CMD_DEACTIVATE_SCROLL);
|
if (type != 1106)
|
||||||
|
SendCommand(SSD1306_CMD_DEACTIVATE_SCROLL); // 0x2E
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD1306::SendCommand(u8 command)
|
void SSD1306::SendCommand(u8 command)
|
||||||
|
@ -120,26 +121,19 @@ void SSD1306::MoveCursorByte(u8 row, u8 col)
|
||||||
if (row > 7) { row = 7; }
|
if (row > 7) { row = 7; }
|
||||||
|
|
||||||
if (type == 1106)
|
if (type == 1106)
|
||||||
SetDisplayWindow(col+2, 129, row, 7); // sh1106 has 132x64 ram, display is centreed
|
col += 2; // sh1106 uses columns 2..129
|
||||||
else
|
|
||||||
SetDisplayWindow(col+0, 127, row, 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SSD1306::MoveCursorCharacter(u8 row, u8 col)
|
SendCommand(SSD1306_CMD_SET_PAGE | row); // 0xB0 page address
|
||||||
{
|
SendCommand(SSD1306_CMD_SET_COLUMN_LOW | (col & 0xf)); // 0x00 column address lower bits
|
||||||
if (col > 15) { col = 15; }
|
SendCommand(SSD1306_CMD_SET_COLUMN_HIGH | (col >> 4)); // 0x10 column address upper bits
|
||||||
if (row > 7) { row = 7; }
|
|
||||||
|
|
||||||
MoveCursorByte(row, col << 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD1306::RefreshScreen()
|
void SSD1306::RefreshScreen()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
Home();
|
for (i = 0; i < 8; i++)
|
||||||
for (i = 0; i < SSD1306_128x64_BYTES; i++)
|
|
||||||
{
|
{
|
||||||
SendData(frame[i]);
|
RefreshPage(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,12 +143,19 @@ void SSD1306::RefreshRows(u32 start, u32 amountOfRows)
|
||||||
|
|
||||||
start <<= 1;
|
start <<= 1;
|
||||||
amountOfRows <<= 1;
|
amountOfRows <<= 1;
|
||||||
|
for (i = start; i < start+amountOfRows; i++)
|
||||||
|
{
|
||||||
|
RefreshPage(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MoveCursorCharacter(start, 0);
|
void SSD1306::RefreshPage(u32 page)
|
||||||
|
{
|
||||||
start *= 128;
|
int i;
|
||||||
int end = start + amountOfRows * 128;
|
int start = page*128;
|
||||||
|
int end = page*128 + 128;
|
||||||
|
|
||||||
|
MoveCursorByte(page, 0);
|
||||||
for (i = start; i < end; i++)
|
for (i = start; i < end; i++)
|
||||||
{
|
{
|
||||||
SendData(frame[i]);
|
SendData(frame[i]);
|
||||||
|
@ -169,14 +170,12 @@ void SSD1306::ClearScreen()
|
||||||
|
|
||||||
void SSD1306::DisplayOn()
|
void SSD1306::DisplayOn()
|
||||||
{
|
{
|
||||||
SendCommand(SSD1306_CMD_DISPLAY_ON);
|
SendCommand(SSD1306_CMD_DISPLAY_ON); // 0xAF
|
||||||
ClearScreen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD1306::DisplayOff()
|
void SSD1306::DisplayOff()
|
||||||
{
|
{
|
||||||
ClearScreen();
|
SendCommand(SSD1306_CMD_DISPLAY_OFF); // 0xAE
|
||||||
SendCommand(SSD1306_CMD_DISPLAY_OFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD1306::SetContrast(u8 value)
|
void SSD1306::SetContrast(u8 value)
|
||||||
|
@ -193,18 +192,7 @@ void SSD1306::SetVCOMDeselect(u8 value)
|
||||||
SendCommand( (value & 7) << 4 );
|
SendCommand( (value & 7) << 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSD1306::SetDisplayWindow(u8 x1, u8 x2, u8 y1, u8 y2)
|
void SSD1306::PlotText(int x, int y, char* str, bool inverse)
|
||||||
{
|
|
||||||
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;
|
int i;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
|
@ -79,7 +79,7 @@ public:
|
||||||
SSD1306(int BSCMaster = 1, u8 address = 0x3C, int flip = 0, int type=1306);
|
SSD1306(int BSCMaster = 1, u8 address = 0x3C, int flip = 0, int type=1306);
|
||||||
|
|
||||||
void PlotCharacter(int x, int y, char ascii, bool inverse);
|
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 InitHardware();
|
||||||
void DisplayOn();
|
void DisplayOn();
|
||||||
|
@ -90,6 +90,7 @@ public:
|
||||||
|
|
||||||
void ClearScreen();
|
void ClearScreen();
|
||||||
void RefreshScreen();
|
void RefreshScreen();
|
||||||
|
void RefreshPage(u32 page);
|
||||||
void RefreshRows(u32 start, u32 amountOfRows);
|
void RefreshRows(u32 start, u32 amountOfRows);
|
||||||
void SetDisplayWindow(u8 x1, u8 y1, u8 x2, u8 y2);
|
void SetDisplayWindow(u8 x1, u8 y1, u8 x2, u8 y2);
|
||||||
void PlotPixel(int x, int y, int c);
|
void PlotPixel(int x, int y, int c);
|
||||||
|
@ -101,7 +102,6 @@ protected:
|
||||||
|
|
||||||
void Home();
|
void Home();
|
||||||
void MoveCursorByte(u8 row, u8 col);
|
void MoveCursorByte(u8 row, u8 col);
|
||||||
void MoveCursorCharacter(u8 row, u8 col);
|
|
||||||
|
|
||||||
unsigned char frame[SSD1306_128x64_BYTES];
|
unsigned char frame[SSD1306_128x64_BYTES];
|
||||||
|
|
||||||
|
@ -114,6 +114,9 @@ protected:
|
||||||
#endif
|
#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_MEMORY_ADDRESSING_MODE 0x20
|
||||||
#define SSD1306_CMD_SET_COLUMN_ADDRESS 0x21
|
#define SSD1306_CMD_SET_COLUMN_ADDRESS 0x21
|
||||||
#define SSD1306_CMD_SET_PAGE_ADDRESS 0x22
|
#define SSD1306_CMD_SET_PAGE_ADDRESS 0x22
|
||||||
|
@ -121,8 +124,8 @@ protected:
|
||||||
#define SSD1306_CMD_ACTIVATE_SCROLL 0x2F
|
#define SSD1306_CMD_ACTIVATE_SCROLL 0x2F
|
||||||
#define SSD1306_CMD_SET_CONTRAST_CONTROL 0x81 // Set Contrast Control for BANK0
|
#define SSD1306_CMD_SET_CONTRAST_CONTROL 0x81 // Set Contrast Control for BANK0
|
||||||
#define SSD1306_ENABLE_CHARGE_PUMP 0x8D
|
#define SSD1306_ENABLE_CHARGE_PUMP 0x8D
|
||||||
#define SSD1306_CMD_ENTIRE_DISPLAY_ON 0xA4
|
#define SSD1306_CMD_TEST_DISPLAY_OFF 0xA4
|
||||||
#define SSD1306_CMD_ENTIRE_DISPLAY_OFF 0xA5
|
#define SSD1306_CMD_TEST_DISPLAY_ON 0xA5
|
||||||
#define SSD1306_CMD_NORMAL_DISPLAY 0xA6 // 1 = on pixel
|
#define SSD1306_CMD_NORMAL_DISPLAY 0xA6 // 1 = on pixel
|
||||||
#define SSD1306_CMD_INVERT_DISPLAY 0xA7 // 0 = on pixel
|
#define SSD1306_CMD_INVERT_DISPLAY 0xA7 // 0 = on pixel
|
||||||
#define SSD1306_CMD_DISPLAY_OFF 0xAE
|
#define SSD1306_CMD_DISPLAY_OFF 0xAE
|
||||||
|
|
|
@ -40,9 +40,9 @@ void ScreenLCD::Open(u32 widthDesired, u32 heightDesired, u32 colourDepth, int B
|
||||||
height = heightDesired;
|
height = heightDesired;
|
||||||
|
|
||||||
ssd1306 = new SSD1306(BSCMaster, LCDAddress, LCDFlip, LCDType);
|
ssd1306 = new SSD1306(BSCMaster, LCDAddress, LCDFlip, LCDType);
|
||||||
ssd1306->DisplayOn();
|
ssd1306->ClearScreen();
|
||||||
|
|
||||||
ssd1306->RefreshScreen();
|
ssd1306->RefreshScreen();
|
||||||
|
ssd1306->DisplayOn();
|
||||||
|
|
||||||
opened = true;
|
opened = true;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
u32 ScreenLCD::PrintText(bool petscii, u32 x, u32 y, char *ptr, RGBA TxtColour, RGBA BkColour, bool measureOnly, u32* width, u32* height)
|
||||||
{
|
{
|
||||||
int len = 0;
|
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;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -372,6 +372,7 @@ void InitialiseLCD()
|
||||||
screenLCD = new ScreenLCD();
|
screenLCD = new ScreenLCD();
|
||||||
screenLCD->Open(128, 64, 1, i2cBusMaster, i2cLcdAddress, i2cLcdFlip, i2cLcdModel);
|
screenLCD->Open(128, 64, 1, i2cBusMaster, i2cLcdAddress, i2cLcdFlip, i2cLcdModel);
|
||||||
screenLCD->SetContrast(i2cLcdOnContrast);
|
screenLCD->SetContrast(i2cLcdOnContrast);
|
||||||
|
screenLCD->ClearInit(0); // sh1106 needs this
|
||||||
|
|
||||||
bool logo_done = false;
|
bool logo_done = false;
|
||||||
if (strcasecmp(options.GetLcdLogoName(), "1541ii") == 0)
|
if (strcasecmp(options.GetLcdLogoName(), "1541ii") == 0)
|
||||||
|
@ -404,7 +405,7 @@ void InitialiseLCD()
|
||||||
|
|
||||||
if (!logo_done)
|
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 x = (128 - 8*strlen(tempBuffer) ) /2;
|
||||||
int y = (64-16)/2;
|
int y = (64-16)/2;
|
||||||
screenLCD->PrintText(0, x, y, tempBuffer, 0x0);
|
screenLCD->PrintText(0, x, y, tempBuffer, 0x0);
|
||||||
|
|
Loading…
Reference in a new issue