A simple library for SSH1106 controlled GLCDs
Diff: SSH1106.cpp
- Revision:
- 1:ac9efaadd666
- Parent:
- 0:3cd0a11a2f91
- Child:
- 2:b55dd362afb9
--- a/SSH1106.cpp Mon Dec 19 15:02:30 2016 +0000 +++ b/SSH1106.cpp Mon Dec 19 23:23:41 2016 +0000 @@ -1,5 +1,5 @@ /** - * This is a simple library for SSH1106 controlled graphic LCD's. + * This is a simple library for SSH1106 controlled graphic LCD's. * Written for a cheap 1.3" OLED GLCD * See http://www.dx.com/p/open-smart-1-8-128-64-lcd-display-breakout-module-w-blue-backlit-444694 * @@ -25,14 +25,14 @@ _lcd->format(8,3); _lcd_cs->write(0); // enable SPI _lcd_cd->write(0); // COMMAND mode - + _lcd_rst->write(0); wait_ms(100); _lcd_rst->write(1); wait_ms(50); - _lcd->write(0xAE); // Display off + _lcd->write(0xAE); // Display off _lcd->write(0x02); // Set lower column address _lcd->write(0x10); // Set higher column address _lcd->write(0x40); // Set display start line @@ -48,19 +48,18 @@ _lcd->write(0x33); // VPP: 9v _lcd->write(0xC8); // Com scan direction _lcd->write(0xD3); // Display offset - _lcd->write(0x00); // 0x20 + _lcd->write(0x00); // 0x20 _lcd->write(0xD5); // Osc division - _lcd->write(0x80); + _lcd->write(0x80); _lcd->write(0xD9); // Pre-charge period - _lcd->write(0x1F); // 0x22 + _lcd->write(0x1F); // 0x22 _lcd->write(0xDA); // Set com pins - _lcd->write(0x12); + _lcd->write(0x12); _lcd->write(0xDB); // Set vcomh - _lcd->write(0x40); + _lcd->write(0x40); _lcd->write(0xAF); // Display ON - _lcd_cs->write(1); - _lcd_cd->write(1); - + _lcd_cs->write(1); + _lcd_cd->write(1); } void SSH1106::setContrast(char contrast) @@ -71,7 +70,7 @@ _lcd->write(contrast); // set contrast _lcd_cs->write(1); _lcd_cd->write(1); - } +} void SSH1106::setCursor(char column, char line) { @@ -194,4 +193,132 @@ cnt++; } } + _lcd_cs->write(1); +} + +void SSH1106::drawLineHor(char posx, char posy, char height, char width) +{ + char page, offset, offset2; + char buffer[2] = {0xFF, 0xFF}; + + _lcd_cs->write(0); + _lcd_cd->write(1); + + if(width+posx > LCDWIDTH) width = (LCDWIDTH-posx); // keep inside display area + + page = posy/8; + offset = posy - (page*8); + buffer[0] = buffer[0] >> (8-height); + buffer[0] = buffer[0] << offset; + + if((offset + height) > 8) { + offset2 = ((offset+height)-8); + buffer[1] = buffer[1] - (0xFF << (offset2)); + } + + SSH1106::setCursor(posx, page); + + for(int i=0; i<width; i++) _lcd->write(buffer[0]); + + if(buffer[1] != 0xFF && (page+1) < 8) { // only write if line takes up > 1 page & keep inside display area + SSH1106::setCursor(posx, (page+1)); + for(int i=0; i<width; i++) _lcd->write(buffer[1]); + } + _lcd_cs->write(1); +} + +void SSH1106::drawLineVert(char posx, char posy, char height, char width) +{ + char page, pagecount, offset, offset2; + + _lcd_cs->write(0); + _lcd_cd->write(1); + + page = posy/8; + pagecount = height/8; + offset2 = height - (pagecount*8); + + SSH1106::setCursor(posx, page); + for(int i=0; i<width; i++) _lcd->write((0xFF>>offset)); + + for(; pagecount > 1; pagecount--) { + page++; + SSH1106::setCursor(posx, page); + for(int i=0; i<width; i++) _lcd->write(0xFF); + } + + SSH1106::setCursor(posx, (page+1)); + for(int i=0; i<width; i++) _lcd->write((0xFF<<offset2)); + + _lcd_cs->write(1); +} + +void SSH1106::clearBuffer(void) +{ + for(int i=0; i<(LCDWIDTH*LCDPAGES); i++) buff[i] = 0; +} + +void SSH1106::update(void) +{ + int cnt = 0; + _lcd_cs->write(0); + _lcd_cd->write(1); + SSH1106::setCursor(0,0); + for(int row=0; row<8; row++) { + SSH1106::setCursor(0, row); + for(int column=0; column<128; column++) { + _lcd->write(buff[cnt]); + cnt++; + } + } + _lcd_cs->write(1); +} + +void SSH1106::drawbufferLineHor(char posx, char posy, char height, char width) +{ + char page, offset, offset2; + int cursor; + char buffer[2] = {0xFF, 0xFF}; + + if(width+posx > LCDWIDTH) width = (LCDWIDTH-posx); // keep inside display area + + page = posy/8; + offset = posy - (page*8); + buffer[0] = buffer[0] >> (8-height); + buffer[0] = buffer[0] << offset; + + if((offset + height) > 8) { + offset2 = ((offset+height)-8); + buffer[1] = buffer[1] - (0xFF << (offset2)); + } + + cursor = posx + (page*128); + + for(int i=0; i<width; i++) SSH1106::buff[cursor+i] |= buffer[0]; + + if(buffer[1] != 0xFF && (page+1) < 8) { // only write if line takes up > 1 page & keep inside display area + for(int i=0; i<width; i++) SSH1106::buff[cursor+i+128] |= buffer[1]; + } +} + +void SSH1106::drawbufferLineVert(char posx, char posy, char height, char width) +{ + char page, pagecount, offset, offset2; + int cursor; + + page = posy/8; + pagecount = height/8; + offset2 = height - (pagecount*8); + cursor = posx + (page*128); // LCDWIDTH + + for(int i=0; i<width; i++) SSH1106::buff[cursor+i] |= (0xFF>>offset); + + for(; pagecount > 1; pagecount--) { + page++; + cursor += 128; + for(int i=0; i<width; i++) SSH1106::buff[cursor+i] |= 0xFF; + } + + cursor += 128; + for(int i=0; i<width; i++) SSH1106::buff[cursor+i] |= (0xFF >> offset2); } \ No newline at end of file