From b307ebe1afd0244162cf81f9b92c920c85bb8fd2 Mon Sep 17 00:00:00 2001 From: Peter Edwards Date: Sun, 17 May 2015 22:56:59 +0200 Subject: [PATCH] Added 1306 display module and font. --- config.h | 9 ++- disp_oled_SSD131x.c | 2 +- disp_oled_ssd1306.c | 183 ++++++++++++++++++++++++++++++++++++++++++++ font8x8.h | 100 ++++++++++++++++++++++++ version.h | 4 +- 5 files changed, 292 insertions(+), 6 deletions(-) create mode 100644 disp_oled_ssd1306.c create mode 100644 font8x8.h diff --git a/config.h b/config.h index da1562a..045c6b8 100644 --- a/config.h +++ b/config.h @@ -4,10 +4,13 @@ // LCD Definitions // I2C config and expander data lines -#define LCD_USE_1602_LCD_MODULE -#define LCD_I2C_ADDR 0x27 // I2C address for the LCD +#define LCD_USE_SSD1306_OLED_MODULE +#define LCD_I2C_ADDR 0x3C // I2C address for the OLED -//#define LCD_USE_SD131X_OLED_MODULE +//#define LCD_USE_1602_LCD_MODULE +//#define LCD_I2C_ADDR 0x27 // I2C address for the LCD + +//#define LCD_USE_SSD131X_OLED_MODULE //#define LCD_I2C_ADDR 0x3C // I2C address for the OLED diff --git a/disp_oled_SSD131x.c b/disp_oled_SSD131x.c index 7899fbe..236f2b5 100644 --- a/disp_oled_SSD131x.c +++ b/disp_oled_SSD131x.c @@ -1,5 +1,5 @@ #include "config.h" -#ifdef LCD_USE_SD131X_OLED_MODULE +#ifdef LCD_USE_SSD131X_OLED_MODULE #include #include "i2cmaster.h" diff --git a/disp_oled_ssd1306.c b/disp_oled_ssd1306.c new file mode 100644 index 0000000..21c8ff3 --- /dev/null +++ b/disp_oled_ssd1306.c @@ -0,0 +1,183 @@ +#include "config.h" +#ifdef LCD_USE_SSD1306_OLED_MODULE + +#include +#include "i2c_master.h" +#include "font8x8.h" + +#define NUM_COLS 16 +#define NUM_ROWS 2 +#define NUM_CHARS NUM_COLS * NUM_ROWS + +static uint8_t _addr; // I2C address +static uint8_t _row, _col; +static uint8_t _buffer[NUM_CHARS]; +static uint8_t _displayCursor; + +// Init Sequence +const uint8_t ssd1306_init_sequence [] PROGMEM = { + 0xAE, // Display OFF (sleep mode) + 0x20, 0b00, // Set Memory Addressing Mode + // 00=Horizontal Addressing Mode; 01=Vertical Addressing Mode; + // 10=Page Addressing Mode (RESET); 11=Invalid + 0xB0, // Set Page Start Address for Page Addressing Mode, 0-7 + 0xC8, // Set COM Output Scan Direction + 0x00, // ---set low column address + 0x10, // ---set high column address + 0x40, // --set start line address + 0x81, 0x3F, // Set contrast control register + 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. + 0xA6, // Set display mode. A6=Normal; A7=Inverse + 0xA8, 0x3F, // Set multiplex ratio (1 to 64) + 0xA4, // Output RAM to Display + // 0xA4=Output follows RAM content; 0xA5,Output ignores RAM content + 0xD3, 0x00, // Set display offset. 00 = no offset + 0xD5, // --set display clock divide ratio/oscillator frequency + 0xF0, // --set divide ratio + 0xD9, 0x22, // Set pre-charge period + 0xDA, 0x12, // Set com pins hardware configuration + 0xDB, // --set vcomh + 0x20, // 0x20,0.77xVcc + 0x8D, 0x14, // Set DC-DC enable + 0xAF // Display ON in normal mode +}; + + +void lcd_init(uint8_t lcd_addr) +{ + uint8_t i; + _addr = lcd_addr; + _row = 0; + _col = 0; + _displayCursor = 0; + + i2c_init(); + + for (i = 0; i < sizeof (ssd1306_init_sequence); i++) { + ssd1306_send_command(pgm_read_byte(&ssd1306_init_sequence[i])); + } + ssd1306_fillscreen(0); + memset(_buffer, 32, NUM_CHARS); +} + +void lcd_cursor() { + uint8_t curValue = _buffer[_row * NUM_COLS + _col]; + _displayCursor = 1; + write_raw(curValue, 1); +} + +void lcd_noCursor(){ + uint8_t curValue = _buffer[_row * NUM_COLS + _col]; + _displayCursor = 0; + write_raw(curValue, 0); +} + +void lcd_backlight() { + +} + +void lcd_noBacklight() { + +} + + +void write_raw(uint8_t value, uint8_t cursor) { + uint8_t i, v, col; + uint8_t c = value - 32; + + col = _col << 3; // convert to pixel + ssd1306_send_command_start(); + i2c_write(0xb0 + _row); + i2c_write((col & 0x0f) | 0x00); + i2c_write(((col & 0xf0) >> 4) | 0x10); + + ssd1306_send_data_start(); + for (i = 0; i < 8; i++) + { + v = pgm_read_byte(&font8x8[c * 8 + i]); + // add underline for cursor + if (cursor) v |= 0x80; + i2c_write(v); + } + i2c_stop(); +} + +void lcd_setCursor(uint8_t col, uint8_t row) +{ + if ((row < NUM_ROWS) && (col < NUM_COLS)) { + if (_displayCursor) { + uint8_t curValue = _buffer[_row * NUM_COLS + _col]; + write_raw(curValue, 0); + } + + _col = col; + _row = row; + + if (_displayCursor) { + uint8_t curValue = _buffer[_row * NUM_COLS + _col]; + write_raw(curValue, 1); + } + } +} + +// ---------------------------------------------------------------------------- + +void lcd_write(uint8_t value) { + write_raw(value, 0); + + _buffer[_row * NUM_COLS + _col] = value; + _col++; + if (_col >= NUM_COLS) { + _col = 0; + _row = (_row + 1) % NUM_ROWS; + } + if (_displayCursor) { + uint8_t curValue = _buffer[_row * NUM_COLS + _col]; + write_raw(curValue, 1); + } +} + +void lcd_print(char *s) { + while (*s) { + lcd_write(*s++); + } +} + +// ---------------------------------------------------------------------------- +void ssd1306_fillscreen(uint8_t fill) +{ + uint8_t m, n; + for (m = 0; m < 8; m++) + { + ssd1306_send_command_start(); + i2c_write(0xb0 + m); // page0 - page7 + i2c_write(0x00); // low column start address + i2c_write(0x10); // high column start address + ssd1306_send_data_start(); + for (n = 0; n < 128; n++) + { + i2c_write(fill); + } + i2c_stop(); + } +} + +void ssd1306_send_command_start(void) { + i2c_start(_addr << 1); + i2c_write(0x00); // command +} + +void ssd1306_send_command(uint8_t command) +{ + ssd1306_send_command_start(); + i2c_write(command); + i2c_stop(); +} + +void ssd1306_send_data_start(void) +{ + i2c_start(_addr << 1); + i2c_write(0x40); // data +} + +#endif diff --git a/font8x8.h b/font8x8.h new file mode 100644 index 0000000..0f929c1 --- /dev/null +++ b/font8x8.h @@ -0,0 +1,100 @@ +#include + +const uint8_t font8x8 [] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // [0x20] ' ' + 0x00, 0x00, 0x00, 0xDF, 0xDF, 0x00, 0x00, 0x00, // [0x21] '!' + 0x00, 0x03, 0x07, 0x00, 0x03, 0x07, 0x00, 0x00, // [0x22] '"' + 0x00, 0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00, 0x00, // [0x23] '#' + 0x00, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, 0x00, // [0x24] '$' + 0x43, 0x23, 0x10, 0x08, 0x04, 0x62, 0x61, 0x00, // [0x25] '%' + 0x38, 0x7C, 0x44, 0x7F, 0x3F, 0x04, 0x04, 0x00, // [0x26] '&' + 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, // [0x27] ''' + 0x00, 0x00, 0x7E, 0xFF, 0x81, 0x00, 0x00, 0x00, // [0x28] '(' + 0x00, 0x00, 0x81, 0xFF, 0x7E, 0x00, 0x00, 0x00, // [0x29] ')' + 0x08, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08, 0x00, // [0x2A] '*' + 0x00, 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, // [0x2B] '+' + 0x00, 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, // [0x2C] ',' + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, // [0x2D] '-' + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, // [0x2E] '.' + 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0x00, 0x00, // [0x2F] '/' + 0x3E, 0x7F, 0x51, 0x49, 0x45, 0x7F, 0x3E, 0x00, // [0x30] '0' + 0x00, 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, // [0x31] '1' + 0x72, 0x7B, 0x49, 0x49, 0x49, 0x4F, 0x46, 0x00, // [0x32] '2' + 0x22, 0x63, 0x41, 0x49, 0x49, 0x7F, 0x36, 0x00, // [0x33] '3' + 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7E, 0x7E, 0x00, // [0x34] '4' + 0x27, 0x6F, 0x49, 0x49, 0x49, 0x79, 0x31, 0x00, // [0x35] '5' + 0x3E, 0x7F, 0x49, 0x49, 0x49, 0x79, 0x30, 0x00, // [0x36] '6' + 0x01, 0x01, 0x01, 0x01, 0x01, 0x7F, 0x7E, 0x00, // [0x37] '7' + 0x36, 0x7F, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00, // [0x38] '8' + 0x06, 0x0F, 0x09, 0x09, 0x09, 0x7F, 0x7F, 0x00, // [0x39] '9' + 0x00, 0x00, 0x00, 0x63, 0x63, 0x00, 0x00, 0x00, // [0x3A] ':' + 0x00, 0x00, 0x80, 0xE3, 0x63, 0x00, 0x00, 0x00, // [0x3B] ';' + 0x00, 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, // [0x3C] '<' + 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, // [0x3D] '=' + 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00, // [0x3E] '>' + 0x02, 0x03, 0xD1, 0xD9, 0x09, 0x0F, 0x06, 0x00, // [0x3F] '?' + 0x3E, 0x7F, 0x41, 0x5D, 0x55, 0x5F, 0x0E, 0x00, // [0x40] '@' + 0x7E, 0x7F, 0x09, 0x09, 0x09, 0x7F, 0x7E, 0x00, // [0x41] 'A' + 0x7F, 0x7F, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00, // [0x42] 'B' + 0x3E, 0x7F, 0x41, 0x41, 0x41, 0x63, 0x22, 0x00, // [0x43] 'C' + 0x7F, 0x7F, 0x41, 0x41, 0x63, 0x3E, 0x1C, 0x00, // [0x44] 'D' + 0x7F, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x41, 0x00, // [0x45] 'E' + 0x7F, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x01, 0x00, // [0x46] 'F' + 0x3E, 0x7F, 0x41, 0x49, 0x49, 0x7B, 0x7A, 0x00, // [0x47] 'G' + 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x7F, 0x00, // [0x48] 'H' + 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x41, 0x41, 0x00, // [0x49] 'I' + 0x20, 0x61, 0x41, 0x7F, 0x3F, 0x01, 0x01, 0x00, // [0x4A] 'J' + 0x7F, 0x7F, 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, // [0x4B] 'K' + 0x7F, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, // [0x4C] 'L' + 0x7F, 0x7F, 0x06, 0x0C, 0x06, 0x7F, 0x7F, 0x00, // [0x4D] 'M' + 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00, // [0x4E] 'N' + 0x3E, 0x7F, 0x41, 0x41, 0x41, 0x7F, 0x3E, 0x00, // [0x4F] 'O' + 0x7F, 0x7F, 0x09, 0x09, 0x09, 0x0F, 0x06, 0x00, // [0x50] 'P' + 0x3E, 0x7F, 0x41, 0x61, 0xC1, 0xFF, 0xBE, 0x00, // [0x51] 'Q' + 0x7F, 0x7F, 0x09, 0x09, 0x09, 0x7F, 0x76, 0x00, // [0x52] 'R' + 0x26, 0x6F, 0x49, 0x49, 0x49, 0x7B, 0x32, 0x00, // [0x53] 'S' + 0x00, 0x01, 0x01, 0x7F, 0x7F, 0x01, 0x01, 0x00, // [0x54] 'T' + 0x3F, 0x7F, 0x40, 0x40, 0x40, 0x7F, 0x7F, 0x00, // [0x55] 'U' + 0x00, 0x07, 0x1F, 0x78, 0x78, 0x1F, 0x07, 0x00, // [0x56] 'V' + 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00, // [0x57] 'W' + 0x63, 0x77, 0x1C, 0x08, 0x1C, 0x77, 0x63, 0x00, // [0x58] 'X' + 0x27, 0x6F, 0x48, 0x48, 0x48, 0x7F, 0x3F, 0x00, // [0x59] 'Y' + 0x61, 0x71, 0x59, 0x4D, 0x47, 0x43, 0x41, 0x00, // [0x5A] 'Z' + 0x00, 0x00, 0xFF, 0xFF, 0x81, 0x81, 0x00, 0x00, // [0x5B] '[' + 0x00, 0x03, 0x0F, 0x3C, 0xF0, 0xC0, 0x00, 0x00, // [0x5C] '\\' + 0x00, 0x00, 0x81, 0x81, 0xFF, 0xFF, 0x00, 0x00, // [0x5D] ']' + 0x04, 0x06, 0x03, 0x01, 0x03, 0x06, 0x04, 0x00, // [0x5E] '^' + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, // [0x5F] '_' + 0x03, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, // [0x60] '`' + 0x38, 0x7C, 0x44, 0x44, 0x24, 0x7C, 0x78, 0x00, // [0x61] 'a' + 0x7F, 0x7F, 0x24, 0x44, 0x44, 0x7C, 0x38, 0x00, // [0x62] 'b' + 0x38, 0x7C, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, // [0x63] 'c' + 0x38, 0x7C, 0x44, 0x44, 0x24, 0x7F, 0x7F, 0x00, // [0x64] 'd' + 0x38, 0x7C, 0x54, 0x54, 0x54, 0x5C, 0x08, 0x00, // [0x65] 'e' + 0x00, 0x04, 0x7E, 0x7F, 0x05, 0x01, 0x00, 0x00, // [0x66] 'f' + 0x18, 0xBC, 0xA4, 0xA4, 0x94, 0xFC, 0x78, 0x00, // [0x67] 'g' + 0x7F, 0x7F, 0x08, 0x04, 0x04, 0x7C, 0x78, 0x00, // [0x68] 'h' + 0x00, 0x00, 0x00, 0x7D, 0x7D, 0x00, 0x00, 0x00, // [0x69] 'i' + 0x00, 0x40, 0x40, 0x40, 0x7D, 0x3D, 0x00, 0x00, // [0x6A] 'j' + 0x7F, 0x7F, 0x08, 0x08, 0x1C, 0x76, 0x62, 0x00, // [0x6B] 'k' + 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x00, // [0x6C] 'l' + 0x78, 0x7C, 0x18, 0x30, 0x18, 0x7C, 0x78, 0x00, // [0x6D] 'm' + 0x7C, 0x7C, 0x08, 0x04, 0x04, 0x7C, 0x78, 0x00, // [0x6E] 'n' + 0x38, 0x7C, 0x44, 0x44, 0x44, 0x7C, 0x38, 0x00, // [0x6F] 'o' + 0xFC, 0xFC, 0x28, 0x24, 0x24, 0x3C, 0x18, 0x00, // [0x70] 'p' + 0x1C, 0x1E, 0x22, 0x22, 0x12, 0xFE, 0xFE, 0x00, // [0x71] 'q' + 0x7C, 0x7C, 0x08, 0x04, 0x04, 0x0C, 0x08, 0x00, // [0x72] 'r' + 0x48, 0x5C, 0x54, 0x54, 0x54, 0x74, 0x20, 0x00, // [0x73] 's' + 0x3F, 0x7F, 0x44, 0x44, 0x44, 0x60, 0x20, 0x00, // [0x74] 't' + 0x3C, 0x7C, 0x40, 0x40, 0x20, 0x7C, 0x7C, 0x00, // [0x75] 'u' + 0x00, 0x0C, 0x3C, 0x70, 0x70, 0x3C, 0x0C, 0x00, // [0x76] 'v' + 0x3C, 0x7C, 0x30, 0x18, 0x30, 0x7C, 0x3C, 0x00, // [0x77] 'w' + 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00, // [0x78] 'x' + 0x0C, 0x5C, 0x50, 0x50, 0x50, 0x7C, 0x3C, 0x00, // [0x79] 'y' + 0x44, 0x64, 0x74, 0x54, 0x5C, 0x4C, 0x44, 0x00, // [0x7A] 'z' + 0x00, 0x08, 0x3E, 0x77, 0x41, 0x00, 0x00, 0x00, // [0x7B] '{' + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, // [0x7C] '|' + 0x00, 0x41, 0x77, 0x3E, 0x08, 0x00, 0x00, 0x00, // [0x7D] '}' + 0x00, 0x08, 0x08, 0x49, 0x2A, 0x1C, 0x08, 0x00, // [0x7E] '->' +// 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00, // [0x7E] '~' +}; diff --git a/version.h b/version.h index bc5b51c..ac4b67d 100644 --- a/version.h +++ b/version.h @@ -2,7 +2,7 @@ #define VERSION_H #define TAPUINO_MAJOR_VERSION 2 -#define TAPUINO_MINOR_VERSION 0 -#define TAPUINO_BUILD_VERSION 2 +#define TAPUINO_MINOR_VERSION 1 +#define TAPUINO_BUILD_VERSION 0 #endif \ No newline at end of file