Blame | Last modification | View Log | Download | RSS feed
#include "maindefs.h"#include "oled_ssd1306.h"#include "spi.h"#include "string.h"#include "Adafruit_GFX.h"#include <delays.h>// 512 (128x32) or 1024 (128x64) bytes allocated for LCD buffer// See linker file for details#ifdef GFX_SSD1306static unsigned char LCD_Buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,#if (SSD1306_LCDHEIGHT == 64)0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00#endif};#elsestatic unsigned char LCD_Buffer[1];#endifvoid SSD1306_Init() {GFX_Init(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT);}void SSD1306_Begin(unsigned char vccstate) {// Toggle reset pinLATBbits.LATB6 = 0;Delay10KTCYx(1);LATBbits.LATB6 = 1;#if defined SSD1306_128_32// Init sequence for 128x32 OLED moduleSSD1306_Command(SSD1306_DISPLAYOFF); // 0xAESSD1306_Command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5SSD1306_Command(0x80); // The suggested ratio 0x80SSD1306_Command(SSD1306_SETMULTIPLEX); // 0xA8SSD1306_Command(0x1F);SSD1306_Command(SSD1306_SETDISPLAYOFFSET); // 0xD3SSD1306_Command(0x0); // No offsetSSD1306_Command(SSD1306_SETSTARTLINE | 0x0); // Line #0SSD1306_Command(SSD1306_CHARGEPUMP); // 0x8Dif (vccstate == SSD1306_EXTERNALVCC) {SSD1306_Command(0x10);} else {SSD1306_Command(0x14);}SSD1306_Command(SSD1306_MEMORYMODE); // 0x20SSD1306_Command(0x00); // 0x0 act like ks0108SSD1306_Command(SSD1306_SEGREMAP | 0x1);SSD1306_Command(SSD1306_COMSCANDEC);SSD1306_Command(SSD1306_SETCOMPINS); // 0xDASSD1306_Command(0x02);SSD1306_Command(SSD1306_SETCONTRAST); // 0x81SSD1306_Command(0x8F);SSD1306_Command(SSD1306_SETPRECHARGE); // 0xd9if (vccstate == SSD1306_EXTERNALVCC) {SSD1306_Command(0x22);} else {SSD1306_Command(0xF1);}SSD1306_Command(SSD1306_SETVCOMDETECT); // 0xDBSSD1306_Command(0x40);SSD1306_Command(SSD1306_DISPLAYALLON_RESUME); // 0xA4SSD1306_Command(SSD1306_NORMALDISPLAY); // 0xA6#endif#if defined SSD1306_128_64// Init sequence for 128x64 OLED moduleSSD1306_Command(SSD1306_DISPLAYOFF); // 0xAESSD1306_Command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5SSD1306_Command(0x80); // The suggested ratio 0x80SSD1306_Command(SSD1306_SETMULTIPLEX); // 0xA8SSD1306_Command(0x3F);SSD1306_Command(SSD1306_SETDISPLAYOFFSET); // 0xD3SSD1306_Command(0x0); // No offsetSSD1306_Command(SSD1306_SETSTARTLINE | 0x0); // Line #0SSD1306_Command(SSD1306_CHARGEPUMP); // 0x8Dif (vccstate == SSD1306_EXTERNALVCC) {SSD1306_Command(0x10);} else {SSD1306_Command(0x14);}SSD1306_Command(SSD1306_MEMORYMODE); // 0x20SSD1306_Command(0x00); // 0x0 act like ks0108SSD1306_Command(SSD1306_SEGREMAP | 0x1);SSD1306_Command(SSD1306_COMSCANDEC);SSD1306_Command(SSD1306_SETCOMPINS); // 0xDASSD1306_Command(0x12);SSD1306_Command(SSD1306_SETCONTRAST); // 0x81if (vccstate == SSD1306_EXTERNALVCC) {SSD1306_Command(0x9F);} else {SSD1306_Command(0xCF);}SSD1306_Command(SSD1306_SETPRECHARGE); // 0xd9if (vccstate == SSD1306_EXTERNALVCC) {SSD1306_Command(0x22);} else {SSD1306_Command(0xF1);}SSD1306_Command(SSD1306_SETVCOMDETECT); // 0xDBSSD1306_Command(0x40);SSD1306_Command(SSD1306_DISPLAYALLON_RESUME); // 0xA4SSD1306_Command(SSD1306_NORMALDISPLAY); // 0xA6#endifSSD1306_Command(SSD1306_DISPLAYON); // Turn on OLED panel}void SSD1306_Command(unsigned char cmd) {unsigned char c = cmd;LATBbits.LATB5 = 0; // D/C low (cmd)SPI2_Write(&c, 1);}void SSD1306_Data(unsigned char data) {unsigned char c = data;LATBbits.LATB5 = 1; // D/C high (data)SPI2_Write(&c, 1);}void SSD1306_Clear_Display() {memset(LCD_Buffer, 0, (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8));}void SSD1306_Invert_Display(unsigned char c) {if (c) {SSD1306_Command(SSD1306_INVERTDISPLAY);} else {SSD1306_Command((SSD1306_NORMALDISPLAY));}}void SSD1306_Display() {unsigned int i;unsigned char c = 0;SSD1306_Command(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0SSD1306_Command(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0SSD1306_Command(SSD1306_SETSTARTLINE | 0x0); // line #0LATBbits.LATB5 = 1; // D/C high (data)SPI2_Write(LCD_Buffer, SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8);// if (SSD1306_LCDHEIGHT == 32) {// SPI2_Write_Repeat(0, SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8);// }}void SSD1306_Draw_Pixel(int x, int y, unsigned int color) {if ((x < 0) || (x >= GFX_width()) || (y < 0) || (y >= GFX_height()))return;// check rotation, move pixel around if necessaryswitch (GFX_getRotation()) {case 1:GFX_Swap(&x, &y);x = SSD1306_LCDWIDTH - x - 1;break;case 2:x = SSD1306_LCDWIDTH - x - 1;y = SSD1306_LCDHEIGHT - y - 1;break;case 3:GFX_Swap(&x, &y);y = SSD1306_LCDHEIGHT - y - 1;break;}// x is which columnif (color == SSD1306_WHITE)LCD_Buffer[x + (y / 8) * SSD1306_LCDWIDTH] |= 1<<(y % 8);elseLCD_Buffer[x + (y / 8) * SSD1306_LCDWIDTH] &= ~(1<<(y % 8));}void SSD1306_Test_DrawChar() {unsigned char i;GFX_setTextSize(1);GFX_setTextColor(SSD1306_WHITE);GFX_setCursor(0, 0);for (i = 0; i < 168; i++) {if (i == '\n') continue;GFX_write(i);// if ((i > 0) && (i % 21 == 0))// GFX_write('\n');}SSD1306_Display();}void SSD1306_Test_DrawCircle() {int i;for (i = 0; i < GFX_height(); i += 2) {GFX_drawCircle(GFX_width() / 2, GFX_height() / 2, i, SSD1306_WHITE);SSD1306_Display();}}void SSD1306_Test_DrawRect(void) {int i;for (i = 0; i < GFX_height() / 2; i += 2) {GFX_drawRect(i, i, GFX_width() - 2 * i, GFX_height() - 2 * i, SSD1306_WHITE);SSD1306_Display();}}void SSD1306_Test_FillRect(void) {unsigned char color = 1;int i;for (i = 0; i < GFX_height() / 2; i += 3) {// alternate colorsGFX_fillRect(i, i, GFX_width() - i * 2, GFX_height() - i * 2, color % 2);SSD1306_Display();color++;}}void SSD1306_Test_DrawTriangle(void) {int i;int min = GFX_width() < GFX_height() ? GFX_width() : GFX_height();for (i = 0; i < min / 2; i += 5) {GFX_drawTriangle(GFX_width() / 2, GFX_height() / 2 - i,GFX_width() / 2 - i, GFX_height() / 2 + i,GFX_width() / 2 + i, GFX_height() / 2 + i, SSD1306_WHITE);SSD1306_Display();}}void SSD1306_Test_FillTriangle(void) {unsigned char color = SSD1306_WHITE;int i;int min = GFX_width() < GFX_height() ? GFX_width() : GFX_height();for (i = min / 2; i > 0; i -= 5) {GFX_fillTriangle(GFX_width() / 2, GFX_height() / 2 - i,GFX_width() / 2 - i, GFX_height() / 2 + i,GFX_width() / 2 + i, GFX_height() / 2 + i, SSD1306_WHITE);if (color == SSD1306_WHITE) color = SSD1306_BLACK;else color = SSD1306_WHITE;SSD1306_Display();}}void SSD1306_Test_DrawRoundRect(void) {int i;for (i = 0; i < GFX_height() / 2 - 2; i += 2) {GFX_drawRoundRect(i, i, GFX_width() - 2 * i, GFX_height() - 2 * i, GFX_height() / 4, SSD1306_WHITE);SSD1306_Display();}}void SSD1306_Test_FillRoundRect(void) {unsigned char color = SSD1306_WHITE;int i;for (i = 0; i < GFX_height() / 2 - 2; i += 2) {GFX_fillRoundRect(i, i, GFX_width() - 2 * i, GFX_height() - 2 * i, GFX_height() / 4, color);if (color == SSD1306_WHITE) color = SSD1306_BLACK;else color = SSD1306_WHITE;SSD1306_Display();}}void SSD1306_Test_DrawLine(void) {int i;for (i = 0; i < GFX_width(); i += 4) {GFX_drawLine(0, 0, i, GFX_height() - 1, SSD1306_WHITE);SSD1306_Display();}for (i = 0; i < GFX_height(); i += 4) {GFX_drawLine(0, 0, GFX_width() - 1, i, SSD1306_WHITE);SSD1306_Display();}Delay10KTCYx(255);SSD1306_Clear_Display();for (i = 0; i < GFX_width(); i += 4) {GFX_drawLine(0, GFX_height() - 1, i, 0, SSD1306_WHITE);SSD1306_Display();}for (i = GFX_height() - 1; i >= 0; i -= 4) {GFX_drawLine(0, GFX_height() - 1, GFX_width() - 1, i, SSD1306_WHITE);SSD1306_Display();}Delay10KTCYx(255);SSD1306_Clear_Display();for (i = GFX_width() - 1; i >= 0; i -= 4) {GFX_drawLine(GFX_width() - 1, GFX_height() - 1, i, 0, SSD1306_WHITE);SSD1306_Display();}for (i = GFX_height() - 1; i >= 0; i -= 4) {GFX_drawLine(GFX_width() - 1, GFX_height() - 1, 0, i, SSD1306_WHITE);SSD1306_Display();}Delay10KTCYx(255);SSD1306_Clear_Display();for (i = 0; i < GFX_height(); i += 4) {GFX_drawLine(GFX_width() - 1, 0, 0, i, SSD1306_WHITE);SSD1306_Display();}for (i = 0; i < GFX_width(); i += 4) {GFX_drawLine(GFX_width() - 1, 0, i, GFX_height() - 1, SSD1306_WHITE);SSD1306_Display();}Delay10KTCYx(255);}