mirror of
https://github.com/digistump/DigistumpArduino.git
synced 2025-04-28 07:39:02 -07:00
421 lines
13 KiB
C++
421 lines
13 KiB
C++
//#include <Arduino.h>
|
|
#if ARDUINO >= 100
|
|
#include "Arduino.h"
|
|
#define WIRE_WRITE Wire.write
|
|
#else
|
|
#include "WProgram.h"
|
|
#define WIRE_WRITE Wire.send
|
|
#endif
|
|
#include <Wire.h>
|
|
#include "MicrOledPro.h"
|
|
|
|
#define I2C_ADDR 0x78 >> 1
|
|
|
|
void LCD_SH1106::WriteCommand(unsigned char ins)
|
|
{
|
|
Wire.beginTransmission(I2C_ADDR);//0x78 >> 1
|
|
WIRE_WRITE(0x00);//0x00
|
|
WIRE_WRITE(ins);
|
|
Wire.endTransmission();
|
|
}
|
|
|
|
void LCD_SH1106::WriteData(unsigned char dat)
|
|
{
|
|
Wire.beginTransmission(I2C_ADDR);//0x78 >> 1
|
|
WIRE_WRITE(0x40);//0x40
|
|
WIRE_WRITE(dat);
|
|
Wire.endTransmission();
|
|
}
|
|
|
|
void LCD_SH1106::setCursor(unsigned char x, unsigned char y)
|
|
{
|
|
m_col = x + 2;
|
|
m_row = y;
|
|
WriteCommand(0xb0 + m_row);
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
}
|
|
|
|
void LCD_SH1106::clear(byte x, byte y, byte width, byte height)
|
|
{
|
|
WriteCommand(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0
|
|
WriteCommand(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0
|
|
WriteCommand(SSD1306_SETSTARTLINE | 0x0); // line #0
|
|
|
|
height >>= 3;
|
|
width >>= 3;
|
|
y >>= 3;
|
|
#ifdef TWBR
|
|
uint8_t twbrbackup = TWBR;
|
|
TWBR = 18; // upgrade to 400KHz!
|
|
#endif
|
|
for (byte i = 0; i < height; i++) {
|
|
// send a bunch of data in one xmission
|
|
WriteCommand(0xB0 + i + y);//set page address
|
|
WriteCommand((x + 2) & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (x >> 4));//set higher column address
|
|
|
|
for(byte j = 0; j < 8; j++){
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte k = 0; k < width; k++) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
Wire.endTransmission();
|
|
}
|
|
}
|
|
#ifdef TWBR
|
|
TWBR = twbrbackup;
|
|
#endif
|
|
setCursor(0, 0);
|
|
}
|
|
|
|
size_t LCD_SH1106::write(uint8_t c)
|
|
{
|
|
if (c == '\n') {
|
|
setCursor(0, m_row + ((m_font == FONT_SIZE_SMALL) ? 1 : 2));
|
|
return 1;
|
|
} else if (c == '\r') {
|
|
m_col = 0;
|
|
return 1;
|
|
}
|
|
|
|
#ifdef TWBR
|
|
uint8_t twbrbackup = TWBR;
|
|
TWBR = 18; // upgrade to 400KHz!
|
|
#endif
|
|
#ifndef MEMORY_SAVING
|
|
if (m_font == FONT_SIZE_SMALL) {
|
|
#endif
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
if (c > 0x20 && c < 0x7f) {
|
|
c -= 0x21;
|
|
for (byte i = 0; i < 5; i++) {
|
|
byte d = pgm_read_byte(&font5x8[c][i]);
|
|
WIRE_WRITE(d);
|
|
if (m_flags & FLAG_PIXEL_DOUBLE_H) WIRE_WRITE(d);
|
|
}
|
|
WIRE_WRITE(0);
|
|
} else {
|
|
for (byte i = (m_flags & FLAG_PIXEL_DOUBLE_H) ? 11 : 6; i > 0; i--) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
}
|
|
Wire.endTransmission();
|
|
m_col += (m_flags & FLAG_PIXEL_DOUBLE_H) ? 11 : 6;
|
|
if (m_col >= 128) {
|
|
m_col = 0;
|
|
m_row ++;
|
|
}
|
|
#ifndef MEMORY_SAVING
|
|
} else {
|
|
if (c > 0x20 && c < 0x7f) {
|
|
c -= 0x21;
|
|
|
|
WriteCommand(0xB0 + m_row);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte i = 0; i <= 14; i += 2) {
|
|
byte d = pgm_read_byte(&font8x16_terminal[c][i]);
|
|
WIRE_WRITE(d);
|
|
if (m_flags & FLAG_PIXEL_DOUBLE_H) WIRE_WRITE(d);
|
|
}
|
|
Wire.endTransmission();
|
|
|
|
WriteCommand(0xB0 + m_row + 1);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte i = 1; i <= 15; i += 2) {
|
|
byte d = pgm_read_byte(&font8x16_terminal[c][i]);
|
|
WIRE_WRITE(d);
|
|
if (m_flags & FLAG_PIXEL_DOUBLE_H) WIRE_WRITE(d);
|
|
}
|
|
Wire.endTransmission();
|
|
} else {
|
|
WriteCommand(0xB0 + m_row);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte i = (m_flags & FLAG_PIXEL_DOUBLE_H) ? 16 : 8; i > 0; i--) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
Wire.endTransmission();
|
|
|
|
WriteCommand(0xB0 + m_row + 1);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte i = (m_flags & FLAG_PIXEL_DOUBLE_H) ? 16 : 8; i > 0; i--) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
Wire.endTransmission();
|
|
}
|
|
m_col += (m_flags & FLAG_PIXEL_DOUBLE_H) ? 17 : 9;
|
|
if (m_col >= 128) {
|
|
m_col = 0;
|
|
m_row += 2;
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef TWBR
|
|
TWBR = twbrbackup;
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
void LCD_SH1106::writeDigit(byte n)
|
|
{
|
|
#ifdef TWBR
|
|
uint8_t twbrbackup = TWBR;
|
|
TWBR = 18; // upgrade to 400KHz!
|
|
#endif
|
|
if (m_font == FONT_SIZE_SMALL) {
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
if (n <= 9) {
|
|
n += '0' - 0x21;
|
|
for (byte i = 0; i < 5; i++) {
|
|
WIRE_WRITE(pgm_read_byte(&font5x8[n][i]));
|
|
}
|
|
WIRE_WRITE(0);
|
|
} else {
|
|
for (byte i = 0; i < 6; i++) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
}
|
|
Wire.endTransmission();
|
|
m_col += 6;
|
|
} else if (m_font == FONT_SIZE_MEDIUM) {
|
|
write(n <= 9 ? ('0' + n) : ' ');
|
|
#ifndef MEMORY_SAVING
|
|
} else if (m_font == FONT_SIZE_LARGE) {
|
|
if (n <= 9) {
|
|
byte i;
|
|
WriteCommand(0xB0 + m_row);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (i = 0; i < 16; i ++) {
|
|
byte d = pgm_read_byte(&digits16x16[n][i]);
|
|
WIRE_WRITE(d);
|
|
if (m_flags & FLAG_PIXEL_DOUBLE_H) WIRE_WRITE(d);
|
|
}
|
|
Wire.endTransmission();
|
|
|
|
WriteCommand(0xB0 + m_row + 1);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (; i < 32; i ++) {
|
|
byte d = pgm_read_byte(&digits16x16[n][i]);
|
|
WIRE_WRITE(d);
|
|
if (m_flags & FLAG_PIXEL_DOUBLE_H) WIRE_WRITE(d);
|
|
}
|
|
Wire.endTransmission();
|
|
} else {
|
|
WriteCommand(0xB0 + m_row);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte i = (m_flags & FLAG_PIXEL_DOUBLE_H) ? 32 : 16; i > 0; i--) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
Wire.endTransmission();
|
|
|
|
WriteCommand(0xB0 + m_row + 1);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte i = (m_flags & FLAG_PIXEL_DOUBLE_H) ? 32 : 16; i > 0; i--) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
Wire.endTransmission();
|
|
}
|
|
m_col += (m_flags & FLAG_PIXEL_DOUBLE_H) ? 30 : 16;
|
|
#endif
|
|
} else {
|
|
if (n <= 9) {
|
|
byte i;
|
|
WriteCommand(0xB0 + m_row);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (i = 0; i < 16; i ++) {
|
|
byte d = pgm_read_byte(&digits16x24[n][i * 3]);
|
|
WIRE_WRITE(d);
|
|
if (m_flags & FLAG_PIXEL_DOUBLE_H) WIRE_WRITE(d);
|
|
}
|
|
Wire.endTransmission();
|
|
|
|
WriteCommand(0xB0 + m_row + 1);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (i = 0; i < 16; i ++) {
|
|
byte d = pgm_read_byte(&digits16x24[n][i * 3 + 1]);
|
|
WIRE_WRITE(d);
|
|
if (m_flags & FLAG_PIXEL_DOUBLE_H) WIRE_WRITE(d);
|
|
}
|
|
Wire.endTransmission();
|
|
|
|
WriteCommand(0xB0 + m_row + 2);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (i = 0; i < 16; i ++) {
|
|
byte d = pgm_read_byte(&digits16x24[n][i * 3 + 2]);
|
|
WIRE_WRITE(d);
|
|
if (m_flags & FLAG_PIXEL_DOUBLE_H) WIRE_WRITE(d);
|
|
}
|
|
Wire.endTransmission();
|
|
} else {
|
|
WriteCommand(0xB0 + m_row);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte i = (m_flags & FLAG_PIXEL_DOUBLE_H) ? 32 : 16; i > 0; i--) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
Wire.endTransmission();
|
|
|
|
WriteCommand(0xB0 + m_row + 1);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte i = (m_flags & FLAG_PIXEL_DOUBLE_H) ? 32 : 16; i > 0; i--) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
Wire.endTransmission();
|
|
|
|
WriteCommand(0xB0 + m_row + 2);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte i = (m_flags & FLAG_PIXEL_DOUBLE_H) ? 32 : 16; i > 0; i--) {
|
|
WIRE_WRITE(0);
|
|
}
|
|
Wire.endTransmission();
|
|
}
|
|
m_col += (m_flags & FLAG_PIXEL_DOUBLE_H) ? 30 : 16;
|
|
}
|
|
#ifdef TWBR
|
|
TWBR = twbrbackup;
|
|
#endif
|
|
}
|
|
|
|
void LCD_SH1106::draw(const PROGMEM byte* buffer, byte width, byte height)
|
|
{
|
|
#ifdef TWBR
|
|
uint8_t twbrbackup = TWBR;
|
|
TWBR = 18; // upgrade to 400KHz!
|
|
#endif
|
|
|
|
WriteCommand(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0
|
|
WriteCommand(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0
|
|
WriteCommand(SSD1306_SETSTARTLINE | 0x0); // line #0
|
|
|
|
const PROGMEM byte *p = buffer;
|
|
height >>= 3;
|
|
width >>= 3;
|
|
for (byte i = 0; i < height; i++) {
|
|
// send a bunch of data in one xmission
|
|
WriteCommand(0xB0 + i + m_row);//set page address
|
|
WriteCommand(m_col & 0xf);//set lower column address
|
|
WriteCommand(0x10 | (m_col >> 4));//set higher column address
|
|
|
|
for(byte j = 0; j < 8; j++){
|
|
Wire.beginTransmission(I2C_ADDR);
|
|
WIRE_WRITE(0x40);
|
|
for (byte k = 0; k < width; k++, p++) {
|
|
WIRE_WRITE(pgm_read_byte(p));
|
|
}
|
|
Wire.endTransmission();
|
|
}
|
|
}
|
|
#ifdef TWBR
|
|
TWBR = twbrbackup;
|
|
#endif
|
|
m_col += width;
|
|
}
|
|
|
|
void LCD_SH1106::begin()
|
|
{
|
|
Wire.begin();
|
|
|
|
WriteCommand(0xAE); /*display off*/
|
|
|
|
WriteCommand(0x02); /*set lower column address*/
|
|
WriteCommand(0x10); /*set higher column address*/
|
|
|
|
WriteCommand(0x40); /*set display start line*/
|
|
|
|
WriteCommand(0xB0); /*set page address*/
|
|
|
|
WriteCommand(0x81); /*contract control*/
|
|
WriteCommand(0x80); /*128*/
|
|
|
|
WriteCommand(0xA1); /*set segment remap*/
|
|
|
|
WriteCommand(0xA6); /*normal / reverse*/
|
|
|
|
WriteCommand(0xA8); /*multiplex ratio*/
|
|
WriteCommand(0x3F); /*duty = 1/32*/
|
|
|
|
WriteCommand(0xad); /*set charge pump enable*/
|
|
WriteCommand(0x8b); /*external VCC */
|
|
|
|
WriteCommand(0x30); /*0X30---0X33 set VPP 9V liangdu!!!!*/
|
|
|
|
WriteCommand(0xC8); /*Com scan direction*/
|
|
|
|
WriteCommand(0xD3); /*set display offset*/
|
|
WriteCommand(0x00); /* 0x20 */
|
|
|
|
WriteCommand(0xD5); /*set osc division*/
|
|
WriteCommand(0x80);
|
|
|
|
WriteCommand(0xD9); /*set pre-charge period*/
|
|
WriteCommand(0x1f); /*0x22*/
|
|
|
|
WriteCommand(0xDA); /*set COM pins*/
|
|
WriteCommand(0x12);
|
|
|
|
WriteCommand(0xdb); /*set vcomh*/
|
|
WriteCommand(0x40);
|
|
|
|
WriteCommand(0xAF); /*display ON*/
|
|
|
|
clear();
|
|
}
|