0,0 → 1,538 |
#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); |
} |
} |
} |