Blame | Last modification | View Log | RSS feed
#include "maindefs.h"
#include "oled_ssd1331.h"
#include "spi.h"
#include "string.h"
#include "Adafruit_GFX.h"
#include <delays.h>
void SSD1331_Init() {
GFX_Init(SSD1331_LCDWIDTH, SSD1331_LCDHEIGHT);
}
void SSD1331_Begin() {
unsigned char buffer[37];
// Toggle reset pin
LATBbits.LATB6 = 0;
Delay10KTCYx(1);
LATBbits.LATB6 = 1;
// Initialization Sequence
buffer[0] = SSD1331_CMD_DISPLAYOFF; // 0xAE
buffer[1] = SSD1331_CMD_SETREMAP; // 0xA0
#if defined SSD1331_COLORORDER_RGB
buffer[2] = 0x72; // RGB Color
#else
buffer[2] = 0x76; // BGR Color
#endif
buffer[3] = SSD1331_CMD_STARTLINE; // 0xA1
buffer[4] = 0x0;
buffer[5] = SSD1331_CMD_DISPLAYOFFSET; // 0xA2
buffer[6] = 0x0;
buffer[7] = SSD1331_CMD_NORMALDISPLAY; // 0xA4
buffer[8] = SSD1331_CMD_SETMULTIPLEX; // 0xA8
buffer[9] = 0x3F; // 0x3F 1/64 duty
buffer[10] = SSD1331_CMD_SETMASTER; // 0xAD
buffer[11] = 0x8E;
buffer[12] = SSD1331_CMD_POWERMODE; // 0xB0
buffer[13] = 0x0B;
buffer[14] = SSD1331_CMD_PRECHARGE; // 0xB1
buffer[15] = 0x31;
buffer[16] = SSD1331_CMD_CLOCKDIV; // 0xB3
buffer[17] = 0xF0; // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
buffer[18] = SSD1331_CMD_PRECHARGEA; // 0x8A
buffer[19] = 0x64;
buffer[20] = SSD1331_CMD_PRECHARGEB; // 0x8B
buffer[21] = 0x78;
buffer[22] = SSD1331_CMD_PRECHARGEA; // 0x8C
buffer[23] = 0x64;
buffer[24] = SSD1331_CMD_PRECHARGELEVEL; // 0xBB
buffer[25] = 0x3A;
buffer[26] = SSD1331_CMD_VCOMH; // 0xBE
buffer[27] = 0x3E;
buffer[28] = SSD1331_CMD_MASTERCURRENT; // 0x87
buffer[29] = 0x06;
buffer[30] = SSD1331_CMD_CONTRASTA; // 0x81
buffer[31] = 0x91;
buffer[32] = SSD1331_CMD_CONTRASTB; // 0x82
buffer[33] = 0x50;
buffer[34] = SSD1331_CMD_CONTRASTC; // 0x83
buffer[35] = 0x7D;
buffer[36] = SSD1331_CMD_DISPLAYON; //--turn on oled panel
LATBbits.LATB5 = 0; // D/C low (cmd)
SPI2_Write(buffer, 37);
}
void SSD1331_GoTo(int x, int y) {
unsigned char buffer[6];
if ((x >= SSD1331_LCDWIDTH) || (y >= SSD1331_LCDHEIGHT)) return;
// set x and y coordinate
buffer[0] = (SSD1331_CMD_SETCOLUMN);
buffer[1] = (x);
buffer[2] = (SSD1331_LCDWIDTH - 1);
buffer[3] = (SSD1331_CMD_SETROW);
buffer[4] = (y);
buffer[5] = (SSD1331_LCDHEIGHT - 1);
LATBbits.LATB5 = 0; // D/C low (cmd)
SPI2_Write(buffer, 6);
}
void SSD1331_Reset() {
}
void SSD1331_Command(unsigned char cmd) {
LATBbits.LATB5 = 0; // D/C low (cmd)
SPI2_Write(&cmd, 1);
}
void SSD1331_Data(unsigned char data) {
LATBbits.LATB5 = 1; // D/C high (data)
SPI2_Write(&data, 1);
}
void SSD1331_Draw_Pixel(int x, int y, unsigned int color) {
unsigned char buffer[2];
buffer[0] = color >> 8;
buffer[1] = color;
if ((x < 0) || (x >= GFX_width()) || (y < 0) || (y >= GFX_height())) return;
// check rotation, move pixel around if necessary
switch (GFX_getRotation()) {
case 1:
GFX_Swap(&x, &y);
x = SSD1331_LCDWIDTH - x - 1;
break;
case 2:
x = SSD1331_LCDWIDTH - x - 1;
y = SSD1331_LCDHEIGHT - y - 1;
break;
case 3:
GFX_Swap(&x, &y);
y = SSD1331_LCDHEIGHT - y - 1;
break;
}
SSD1331_GoTo(x, y);
// setup for data
LATBbits.LATB5 = 1; // D/C high (data)
SPI2_Write(buffer, 2);
}
void SSD1331_Draw_Line(int x0, int y0, int x1, int y1, unsigned int color) {
unsigned char buffer[8];
// check rotation, move pixel around if necessary
switch (GFX_getRotation()) {
case 1:
GFX_Swap(&x0, &y0);
GFX_Swap(&x1, &y1);
x0 = SSD1331_LCDWIDTH - x0 - 1;
x1 = SSD1331_LCDWIDTH - x1 - 1;
break;
case 2:
x0 = SSD1331_LCDWIDTH - x0 - 1;
y0 = SSD1331_LCDHEIGHT - y0 - 1;
x1 = SSD1331_LCDWIDTH - x1 - 1;
y1 = SSD1331_LCDHEIGHT - y1 - 1;
break;
case 3:
GFX_Swap(&x0, &y0);
GFX_Swap(&x1, &y1);
y0 = SSD1331_LCDHEIGHT - y0 - 1;
y1 = SSD1331_LCDHEIGHT - y1 - 1;
break;
}
// Boundary check
if ((y0 >= SSD1331_LCDHEIGHT) && (y1 >= SSD1331_LCDHEIGHT))
return;
if ((x0 >= SSD1331_LCDWIDTH) && (x1 >= SSD1331_LCDWIDTH))
return;
if (x0 >= SSD1331_LCDWIDTH)
x0 = SSD1331_LCDWIDTH - 1;
if (y0 >= SSD1331_LCDHEIGHT)
y0 = SSD1331_LCDHEIGHT - 1;
if (x1 >= SSD1331_LCDWIDTH)
x1 = SSD1331_LCDWIDTH - 1;
if (y1 >= SSD1331_LCDHEIGHT)
y1 = SSD1331_LCDHEIGHT - 1;
if (x0 < 0)
x0 = 0;
if (y0 < 0)
y0 = 0;
if (x1 < 0)
x1 = 0;
if (y1 < 0)
y1 = 0;
buffer[0] = SSD1331_CMD_DRAWLINE;
buffer[1] = x0;
buffer[2] = y0;
buffer[3] = x1;
buffer[4] = y1;
buffer[5] = (color >> 11) << 1;
buffer[6] = (color >> 5) & 0x3F;
buffer[7] = (color << 1) & 0x3F;
LATBbits.LATB5 = 0; // D/C low (cmd)
SPI2_Write(buffer, 8);
}
void SSD1331_Draw_Rect(int tx0, int ty0, int tx1, int ty1, unsigned int color) {
unsigned char buffer[13];
int x0,y0,x1,y1;
// check rotation, move pixel around if necessary
switch (GFX_getRotation()) {
case 0:
x0 = tx0;
y0 = ty0;
x1 = tx1;
y1 = ty1;
break;
case 1:
x0 = SSD1331_LCDWIDTH - ty1 - 1;
y0 = tx0;
x1 = SSD1331_LCDWIDTH - ty0 - 1;
y1 = tx1;
break;
case 2:
x0 = SSD1331_LCDWIDTH - tx1 - 1;
y0 = SSD1331_LCDHEIGHT - ty1 - 1;
x1 = SSD1331_LCDWIDTH - tx0 - 1;
y1 = SSD1331_LCDHEIGHT - ty0 - 1;
break;
case 3:
x0 = ty0;
y0 = SSD1331_LCDHEIGHT - tx1 - 1;
x1 = ty1;
y1 = SSD1331_LCDHEIGHT - tx0 - 1;
break;
}
// Boundary check
if ((y0 >= SSD1331_LCDHEIGHT) && (y1 >= SSD1331_LCDHEIGHT))
return;
if ((x0 >= SSD1331_LCDWIDTH) && (x1 >= SSD1331_LCDWIDTH))
return;
if (x0 >= SSD1331_LCDWIDTH)
x0 = SSD1331_LCDWIDTH - 1;
if (y0 >= SSD1331_LCDHEIGHT)
y0 = SSD1331_LCDHEIGHT - 1;
if (x1 >= SSD1331_LCDWIDTH)
x1 = SSD1331_LCDWIDTH - 1;
if (y1 >= SSD1331_LCDHEIGHT)
y1 = SSD1331_LCDHEIGHT - 1;
if (x0 < 0)
x0 = 0;
if (y0 < 0)
y0 = 0;
if (x1 < 0)
x1 = 0;
if (y1 < 0)
y1 = 0;
buffer[0] = SSD1331_CMD_FILL;
buffer[1] = 0;
buffer[2] = SSD1331_CMD_DRAWRECT;
buffer[3] = x0;
buffer[4] = y0;
buffer[5] = x1;
buffer[6] = y1;
buffer[7] = (color >> 11) << 1;
buffer[8] = (color >> 5) & 0x3F;
buffer[9] = (color << 1) & 0x3F;
buffer[10] = 0;
buffer[11] = 0;
buffer[12] = 0;
LATBbits.LATB5 = 0; // D/C low (cmd)
SPI2_Write(buffer, 13);
}
void SSD1331_Fill_Rect(int tx0, int ty0, int tx1, int ty1, unsigned int color) {
unsigned char buffer[13];
int x0,y0,x1,y1;
// check rotation, move pixel around if necessary
switch (GFX_getRotation()) {
case 0:
x0 = tx0;
y0 = ty0;
x1 = tx1;
y1 = ty1;
break;
case 1:
x0 = SSD1331_LCDWIDTH - ty1 - 1;
y0 = tx0;
x1 = SSD1331_LCDWIDTH - ty0 - 1;
y1 = tx1;
break;
case 2:
x0 = SSD1331_LCDWIDTH - tx1 - 1;
y0 = SSD1331_LCDHEIGHT - ty1 - 1;
x1 = SSD1331_LCDWIDTH - tx0 - 1;
y1 = SSD1331_LCDHEIGHT - ty0 - 1;
break;
case 3:
x0 = ty0;
y0 = SSD1331_LCDHEIGHT - tx1 - 1;
x1 = ty1;
y1 = SSD1331_LCDHEIGHT - tx0 - 1;
break;
}
// Boundary check
if ((y0 >= SSD1331_LCDHEIGHT) && (y1 >= SSD1331_LCDHEIGHT))
return;
if ((x0 >= SSD1331_LCDWIDTH) && (x1 >= SSD1331_LCDWIDTH))
return;
if (x0 >= SSD1331_LCDWIDTH)
x0 = SSD1331_LCDWIDTH - 1;
if (y0 >= SSD1331_LCDHEIGHT)
y0 = SSD1331_LCDHEIGHT - 1;
if (x1 >= SSD1331_LCDWIDTH)
x1 = SSD1331_LCDWIDTH - 1;
if (y1 >= SSD1331_LCDHEIGHT)
y1 = SSD1331_LCDHEIGHT - 1;
if (x0 < 0)
x0 = 0;
if (y0 < 0)
y0 = 0;
if (x1 < 0)
x1 = 0;
if (y1 < 0)
y1 = 0;
buffer[0] = SSD1331_CMD_FILL;
buffer[1] = 1;
buffer[2] = SSD1331_CMD_DRAWRECT;
buffer[3] = x0;
buffer[4] = y0;
buffer[5] = x1;
buffer[6] = y1;
buffer[7] = (color >> 11) << 1;
buffer[8] = (color >> 5) & 0x3F;
buffer[9] = (color << 1) & 0x3F;
buffer[10] = (color >> 11) << 1;
buffer[11] = (color >> 5) & 0x3F;
buffer[12] = (color << 1) & 0x3F;
LATBbits.LATB5 = 0; // D/C low (cmd)
SPI2_Write(buffer, 13);
Delay1KTCYx(4);
}
void SSD1331_Clear_Display() {
unsigned char buffer[5];
buffer[0] = SSD1331_CMD_CLEARWINDOW;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = SSD1331_LCDWIDTH-1;
buffer[4] = SSD1331_LCDHEIGHT-1;
LATBbits.LATB5 = 0; // D/C low (cmd)
SPI2_Write(buffer, 5);
Delay1KTCYx(4);
}
unsigned int SSD1331_Color565(unsigned char r, unsigned char g, unsigned char b) {
unsigned int c;
c = r >> 3;
c <<= 6;
c |= g >> 2;
c <<= 5;
c |= b >> 3;
return c;
}
void SSD1331_Test_DrawLines(unsigned int color) {
int x, y;
GFX_clearScreen();
for (x = 0; x < GFX_width() - 1; x += 6) {
GFX_drawLine(0, 0, x, GFX_height() - 1, color);
}
for (y = 0; y < GFX_height() - 1; y += 6) {
GFX_drawLine(0, 0, GFX_width() - 1, y, color);
}
GFX_clearScreen();
for (x = 0; x < GFX_width() - 1; x += 6) {
GFX_drawLine(GFX_width() - 1, 0, x, GFX_height() - 1, color);
}
for (y = 0; y < GFX_height() - 1; y += 6) {
GFX_drawLine(GFX_width() - 1, 0, 0, y, color);
}
GFX_clearScreen();
for (x = 0; x < GFX_width() - 1; x += 6) {
GFX_drawLine(0, GFX_height() - 1, x, 0, color);
}
for (y = 0; y < GFX_height() - 1; y += 6) {
GFX_drawLine(0, GFX_height() - 1, GFX_width() - 1, y, color);
}
GFX_clearScreen();
for (x = 0; x < GFX_width() - 1; x += 6) {
GFX_drawLine(GFX_width() - 1, GFX_height() - 1, x, 0, color);
}
for (y = 0; y < GFX_height() - 1; y += 6) {
GFX_drawLine(GFX_width() - 1, GFX_height() - 1, 0, y, color);
}
}
void SSD1331_Test_DrawRect(unsigned int color) {
int x;
GFX_clearScreen();
if (GFX_height() < GFX_width()) {
for (x = 0; x < GFX_height() - 1; x += 6) {
GFX_drawRect((GFX_width() - 1) / 2 - x / 2, (GFX_height() - 1) / 2 - x / 2, x, x, color);
}
} else {
for (x = 0; x < GFX_width() - 1; x += 6) {
GFX_drawRect((GFX_width() - 1) / 2 - x / 2, (GFX_height() - 1) / 2 - x / 2, x, x, color);
}
}
}
void SSD1331_Test_FillRect(unsigned int color1, unsigned int color2) {
int x;
GFX_clearScreen();
if (GFX_height() < GFX_width()) {
for (x = GFX_height() - 1; x > 6; x -= 6) {
GFX_fillRect((GFX_width() - 1) / 2 - x / 2, (GFX_height() - 1) / 2 - x / 2, x, x, color1);
GFX_drawRect((GFX_width() - 1) / 2 - x / 2, (GFX_height() - 1) / 2 - x / 2, x, x, color2);
}
} else {
for (x = GFX_width() - 1; x > 6; x -= 6) {
GFX_fillRect((GFX_width() - 1) / 2 - x / 2, (GFX_height() - 1) / 2 - x / 2, x, x, color1);
GFX_drawRect((GFX_width() - 1) / 2 - x / 2, (GFX_height() - 1) / 2 - x / 2, x, x, color2);
}
}
}
void SSD1331_Test_DrawCircle(unsigned int radius, unsigned int color) {
int x, y;
for (x = 0; x < GFX_width() - 1 + radius; x += radius * 2) {
for (y = 0; y < GFX_height() - 1 + radius; y += radius * 2) {
GFX_drawCircle(x, y, radius, color);
}
}
}
void SSD1331_Test_FillCircle(unsigned int radius, unsigned int color) {
unsigned char x, y;
for (x = radius; x < GFX_width() - 1; x += radius * 2) {
for (y = radius; y < GFX_height() - 1; y += radius * 2) {
GFX_fillCircle(x, y, radius, color);
}
}
}
void SSD1331_Test_DrawTria(void) {
int color = 0xF800;
int t;
int w = GFX_width() / 2;
int x = GFX_height();
int y = 0;
int z = GFX_width();
GFX_clearScreen();
for (t = 0; t <= 15; t += 1) {
GFX_drawTriangle(w, y, y, x, z, x, color);
x -= 4;
y += 4;
z -= 4;
color += 100;
}
}
void SSD1331_Test_DrawRoundRect(void) {
int color = 100;
int i, t, x, y, w, h;
GFX_clearScreen();
for (t = 0; t <= 4; t += 1) {
x = 0;
y = 0;
w = GFX_width();
h = GFX_height();
for (i = 0; i <= 24; i += 1) {
GFX_drawRoundRect(x, y, w, h, 5, color);
x += 2;
y += 3;
w -= 4;
h -= 6;
color += 1100;
}
color += 100;
}
}
void SSD1331_Test_MediaButtons(void) {
// play
GFX_clearScreen();
GFX_fillRoundRect(25, 10, 78, 60, 8, SSD1331_WHITE);
GFX_fillTriangle(42, 20, 42, 60, 90, 40, SSD1331_RED);
Delay10KTCYx(100);
// pause
GFX_fillRoundRect(25, 90, 78, 60, 8, SSD1331_WHITE);
GFX_fillRoundRect(39, 98, 20, 45, 5, SSD1331_GREEN);
GFX_fillRoundRect(69, 98, 20, 45, 5, SSD1331_GREEN);
Delay10KTCYx(100);
// play color
GFX_fillTriangle(42, 20, 42, 60, 90, 40, SSD1331_BLUE);
Delay10KTCYx(100);
// pause color
GFX_fillRoundRect(39, 98, 20, 45, 5, SSD1331_RED);
GFX_fillRoundRect(69, 98, 20, 45, 5, SSD1331_RED);
// play color
GFX_fillTriangle(42, 20, 42, 60, 90, 40, SSD1331_GREEN);
}
void SSD1331_Test_Pattern(void) {
unsigned char buffer[2];
unsigned int i, j;
SSD1331_GoTo(0, 0);
for (i = 0; i < 64; i++) {
for (j = 0; j < 96; j++) {
if (i > 55) {
buffer[0] = (SSD1331_WHITE >> 8);
buffer[1] = (SSD1331_WHITE);
} else if (i > 47) {
buffer[0] = (SSD1331_BLUE >> 8);
buffer[1] = (SSD1331_BLUE);
} else if (i > 39) {
buffer[0] = (SSD1331_GREEN >> 8);
buffer[1] = (SSD1331_GREEN);
} else if (i > 31) {
buffer[0] = (SSD1331_CYAN >> 8);
buffer[1] = (SSD1331_CYAN);
} else if (i > 23) {
buffer[0] = (SSD1331_RED >> 8);
buffer[1] = (SSD1331_RED);
} else if (i > 15) {
buffer[0] = (SSD1331_MAGENTA >> 8);
buffer[1] = (SSD1331_MAGENTA);
} else if (i > 7) {
buffer[0] = (SSD1331_YELLOW >> 8);
buffer[1] = (SSD1331_YELLOW);
} else {
buffer[0] = (SSD1331_BLACK >> 8);
buffer[1] = (SSD1331_BLACK);
}
LATBbits.LATB5 = 1; // D/C high (data)
SPI2_Write(buffer, 2);
}
}
}