Rename and turned into a GFX subclass

This commit is contained in:
Ladyada 2012-03-15 14:57:15 -04:00
parent 8d5b297627
commit c999f4f161
4 changed files with 195 additions and 580 deletions

View file

@ -6,7 +6,9 @@
#include <util/delay.h>
#include <stdlib.h>
#include "SSD1306.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#include "glcdfont.c"
static uint8_t is_reversed = 0;
@ -86,181 +88,9 @@ static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
};
void SSD1306::drawbitmap(uint8_t x, uint8_t y,
const uint8_t *bitmap, uint8_t w, uint8_t h,
uint8_t color) {
for (uint8_t j=0; j<h; j++) {
for (uint8_t i=0; i<w; i++ ) {
if (pgm_read_byte(bitmap + i + (j/8)*w) & _BV(j%8)) {
setpixel(x+i, y+j, color);
}
}
}
}
void SSD1306::drawstring(uint8_t x, uint8_t line, char *c) {
while (c[0] != 0) {
drawchar(x, line, c[0]);
c++;
x += 6; // 6 pixels wide
if (x + 6 >= SSD1306_LCDWIDTH) {
x = 0; // ran out of this line
line++;
}
if (line >= (SSD1306_LCDHEIGHT/8))
return; // ran out of space :(
}
}
void SSD1306::drawchar(uint8_t x, uint8_t line, uint8_t c) {
if ((line >= SSD1306_LCDHEIGHT/8) || (x >= (SSD1306_LCDWIDTH - 6)))
return;
for (uint8_t i =0; i<5; i++ ) {
buffer[x + (line*128) ] = pgm_read_byte(font+(c*5)+i);
x++;
}
}
// bresenham's algorithm - thx wikpedia
void SSD1306::drawline(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
uint8_t color) {
uint8_t steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
swap(x0, y0);
swap(x1, y1);
}
if (x0 > x1) {
swap(x0, x1);
swap(y0, y1);
}
uint8_t dx, dy;
dx = x1 - x0;
dy = abs(y1 - y0);
int8_t err = dx / 2;
int8_t ystep;
if (y0 < y1) {
ystep = 1;
} else {
ystep = -1;}
for (; x0<x1; x0++) {
if (steep) {
setpixel(y0, x0, color);
} else {
setpixel(x0, y0, color);
}
err -= dy;
if (err < 0) {
y0 += ystep;
err += dx;
}
}
}
// filled rectangle
void SSD1306::fillrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
uint8_t color) {
// stupidest version - just pixels - but fast with internal buffer!
for (uint8_t i=x; i<x+w; i++) {
for (uint8_t j=y; j<y+h; j++) {
setpixel(i, j, color);
}
}
}
// draw a rectangle
void SSD1306::drawrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
uint8_t color) {
// stupidest version - just pixels - but fast with internal buffer!
for (uint8_t i=x; i<x+w; i++) {
setpixel(i, y, color);
setpixel(i, y+h-1, color);
}
for (uint8_t i=y; i<y+h; i++) {
setpixel(x, i, color);
setpixel(x+w-1, i, color);
}
}
// draw a circle outline
void SSD1306::drawcircle(uint8_t x0, uint8_t y0, uint8_t r,
uint8_t color) {
int8_t f = 1 - r;
int8_t ddF_x = 1;
int8_t ddF_y = -2 * r;
int8_t x = 0;
int8_t y = r;
setpixel(x0, y0+r, color);
setpixel(x0, y0-r, color);
setpixel(x0+r, y0, color);
setpixel(x0-r, y0, color);
while (x<y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
setpixel(x0 + x, y0 + y, color);
setpixel(x0 - x, y0 + y, color);
setpixel(x0 + x, y0 - y, color);
setpixel(x0 - x, y0 - y, color);
setpixel(x0 + y, y0 + x, color);
setpixel(x0 - y, y0 + x, color);
setpixel(x0 + y, y0 - x, color);
setpixel(x0 - y, y0 - x, color);
}
}
void SSD1306::fillcircle(uint8_t x0, uint8_t y0, uint8_t r,
uint8_t color) {
int8_t f = 1 - r;
int8_t ddF_x = 1;
int8_t ddF_y = -2 * r;
int8_t x = 0;
int8_t y = r;
for (uint8_t i=y0-r; i<=y0+r; i++) {
setpixel(x0, i, color);
}
while (x<y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
for (uint8_t i=y0-y; i<=y0+y; i++) {
setpixel(x0+x, i, color);
setpixel(x0-x, i, color);
}
for (uint8_t i=y0-x; i<=y0+x; i++) {
setpixel(x0+y, i, color);
setpixel(x0-y, i, color);
}
}
}
// the most basic function, set a single pixel
void SSD1306::setpixel(uint8_t x, uint8_t y, uint8_t color) {
void Adafruit_SSD1306::drawPixel(uint8_t x, uint8_t y, uint8_t color) {
if ((x >= SSD1306_LCDWIDTH) || (y >= SSD1306_LCDHEIGHT))
return;
@ -271,7 +101,16 @@ void SSD1306::setpixel(uint8_t x, uint8_t y, uint8_t color) {
buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~_BV((y%8));
}
void SSD1306::ssd1306_init(uint8_t vccstate) {
void Adafruit_SSD1306::begin(uint8_t vccstate) {
#ifdef SSD1306_128_64
this->WIDTH = 128;
this->HEIGHT = 64;
#endif
#ifdef SSD1306_128_32
this->WIDTH = 128;
this->HEIGHT = 32;
#endif
// set pin directions
pinMode(sid, OUTPUT);
pinMode(sclk, OUTPUT);
@ -279,6 +118,15 @@ void SSD1306::ssd1306_init(uint8_t vccstate) {
pinMode(rst, OUTPUT);
pinMode(cs, OUTPUT);
clkport = portOutputRegister(digitalPinToPort(sclk));
clkpinmask = digitalPinToBitMask(sclk);
mosiport = portOutputRegister(digitalPinToPort(sid));
mosipinmask = digitalPinToBitMask(sid);
csport = portOutputRegister(digitalPinToPort(cs));
cspinmask = digitalPinToBitMask(cs);
dcport = portOutputRegister(digitalPinToPort(dc));
dcpinmask = digitalPinToBitMask(dc);
digitalWrite(rst, HIGH);
// VDD (3.3V) goes high at start, lets just chill for a ms
delay(1);
@ -365,7 +213,7 @@ void SSD1306::ssd1306_init(uint8_t vccstate) {
}
void SSD1306::invert(uint8_t i) {
void Adafruit_SSD1306::invertDisplay(uint8_t i) {
if (i) {
ssd1306_command(SSD1306_INVERTDISPLAY);
} else {
@ -373,52 +221,79 @@ void SSD1306::invert(uint8_t i) {
}
}
inline void SSD1306::spiwrite(uint8_t c) {
shiftOut(sid, sclk, MSBFIRST, c);
}
void SSD1306::ssd1306_command(uint8_t c) {
digitalWrite(cs, HIGH);
digitalWrite(dc, LOW);
digitalWrite(cs, LOW);
spiwrite(c);
digitalWrite(cs, HIGH);
void Adafruit_SSD1306::ssd1306_command(uint8_t c) {
//digitalWrite(cs, HIGH);
*csport |= cspinmask;
//digitalWrite(dc, LOW);
*dcport &= ~dcpinmask;
//digitalWrite(cs, LOW);
*csport &= ~cspinmask;
fastSPIwrite(c);
//digitalWrite(cs, HIGH);
*csport |= cspinmask;
}
void SSD1306::ssd1306_data(uint8_t c) {
digitalWrite(cs, HIGH);
digitalWrite(dc, HIGH);
digitalWrite(cs, LOW);
spiwrite(c);
digitalWrite(cs, HIGH);
void Adafruit_SSD1306::ssd1306_data(uint8_t c) {
//digitalWrite(cs, HIGH);
*csport |= cspinmask;
//digitalWrite(dc, HIGH);
*dcport |= dcpinmask;
//digitalWrite(cs, LOW);
*csport &= ~cspinmask;
fastSPIwrite(c);
//digitalWrite(cs, HIGH);
*csport |= cspinmask;
}
void SSD1306::ssd1306_set_brightness(uint8_t val) {
}
void SSD1306::display(void) {
void Adafruit_SSD1306::display(void) {
ssd1306_command(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0
ssd1306_command(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0
ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
*csport |= cspinmask;
*dcport |= dcpinmask;
*csport &= ~cspinmask;
for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
ssd1306_data(buffer[i]);
fastSPIwrite(buffer[i]);
//ssd1306_data(buffer[i]);
}
// i wonder why we have to do this (check datasheet)
if (SSD1306_LCDHEIGHT == 32) {
for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
ssd1306_data(0);
//ssd1306_data(0);
fastSPIwrite(0);
}
}
*csport |= cspinmask;
}
// clear everything
void SSD1306::clear(void) {
void Adafruit_SSD1306::clearDisplay(void) {
memset(buffer, 0, (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8));
}
void SSD1306::clear_display(void) {
inline void Adafruit_SSD1306::fastSPIwrite(uint8_t d) {
for(uint8_t bit = 0x80; bit; bit >>= 1) {
*clkport &= ~clkpinmask;
if(d & bit) *mosiport |= mosipinmask;
else *mosiport &= ~mosipinmask;
*clkport |= clkpinmask;
}
//*csport |= cspinmask;
}
inline void Adafruit_SSD1306::slowSPIwrite(uint8_t d) {
for (int8_t i=7; i>=0; i--) {
digitalWrite(sclk, LOW);
if (d & _BV(i)) {
digitalWrite(sid, HIGH);
} else {
digitalWrite(sid, LOW);
}
digitalWrite(sclk, HIGH);
}
}

View file

@ -4,6 +4,8 @@
#include "WProgram.h"
#endif
#include <Adafruit_GFX.h>
#define swap(a, b) { uint8_t t = a; a = b; b = t; }
#define BLACK 0
@ -24,8 +26,8 @@
appropriate size
-----------------------------------------------------------------------*/
#define SSD1306_128_64
// #define SSD1306_128_32
//#define SSD1306_128_64
#define SSD1306_128_32
/*=========================================================================*/
#if defined SSD1306_128_64 && defined SSD1306_128_32
@ -79,42 +81,28 @@
#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2
class SSD1306 {
class Adafruit_SSD1306 : public Adafruit_GFX {
public:
SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS) :sid(SID), sclk(SCLK), dc(DC), rst(RST), cs(CS) {}
SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST) :sid(SID), sclk(SCLK), dc(DC), rst(RST), cs(-1) {}
Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS) :sid(SID), sclk(SCLK), dc(DC), rst(RST), cs(CS) {}
Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST) :sid(SID), sclk(SCLK), dc(DC), rst(RST), cs(-1) {}
void ssd1306_init(uint8_t switchvcc);
void begin(uint8_t switchvcc);
void ssd1306_command(uint8_t c);
void ssd1306_data(uint8_t c);
void ssd1306_set_brightness(uint8_t val);
void clear_display(void);
void clear();
void invert(uint8_t i);
void clearDisplay(void);
void invertDisplay(uint8_t i);
void display();
void setpixel(uint8_t x, uint8_t y, uint8_t color);
void fillcircle(uint8_t x0, uint8_t y0, uint8_t r,
uint8_t color);
void drawcircle(uint8_t x0, uint8_t y0, uint8_t r,
uint8_t color);
void drawrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
uint8_t color);
void fillrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
uint8_t color);
void drawline(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
uint8_t color);
void drawchar(uint8_t x, uint8_t line, uint8_t c);
void drawstring(uint8_t x, uint8_t line, char *c);
void drawbitmap(uint8_t x, uint8_t y,
const uint8_t *bitmap, uint8_t w, uint8_t h,
uint8_t color);
void drawPixel(uint8_t x, uint8_t y, uint8_t color);
private:
int8_t sid, sclk, dc, rst, cs;
void spiwrite(uint8_t c);
void fastSPIwrite(uint8_t c);
void slowSPIwrite(uint8_t c);
volatile uint8_t *mosiport, *clkport, *csport, *dcport;
uint8_t mosipinmask, clkpinmask, cspinmask, dcpinmask;
//uint8_t buffer[128*64/8];
};

View file

@ -4,9 +4,10 @@
#define OLED_MOSI 9
#define OLED_RESET 13
#include <SSD1306.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
#define NUMFLAKES 10
#define XPOS 0
@ -24,79 +25,65 @@ static unsigned char __attribute__ ((progmem)) logo16_glcd_bmp[]={
void setup() {
Serial.begin(9600);
// If you want to provide external 7-9V VCC, uncomment next line and comment the one after
//oled.ssd1306_init(SSD1306_EXTERNALVCC);
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
oled.ssd1306_init(SSD1306_SWITCHCAPVCC);
display.begin(SSD1306_SWITCHCAPVCC);
// init done
oled.display(); // show splashscreen
delay(2000);
oled.clear(); // clears the screen and buffer
// Fill screen
oled.fillrect(0, 0, SSD1306_LCDWIDTH-1, SSD1306_LCDHEIGHT-1, WHITE);
oled.display();
display.display(); // show splashscreen
delay(2000);
display.clearDisplay(); // clears the screen and buffer
// draw a single pixel
oled.setpixel(10, 10, WHITE);
oled.display();
display.drawPixel(10, 10, WHITE);
display.display();
delay(2000);
oled.clear();
display.clearDisplay();
// draw many lines
testdrawline();
oled.display();
display.display();
delay(2000);
oled.clear();
display.clearDisplay();
// draw rectangles
testdrawrect();
oled.display();
display.display();
delay(2000);
oled.clear();
display.clearDisplay();
// draw multiple rectangles
testfillrect();
oled.display();
display.display();
delay(2000);
oled.clear();
display.clearDisplay();
// draw mulitple circles
testdrawcircle();
oled.display();
display.display();
delay(2000);
oled.clear();
display.clearDisplay();
// draw a white circle, 10 pixel radius, at location (32,32)
oled.fillcircle(32, 32, 10, WHITE);
oled.display();
// draw a white circle, 10 pixel radius
display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
display.display();
delay(2000);
oled.clear();
display.clearDisplay();
// draw the first ~12 characters in the font
testdrawchar();
oled.display();
display.display();
delay(2000);
oled.clear();
// draw a string at location (0,0)
oled.drawstring(0, 0, "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation");
oled.display();
delay(2000);
oled.clear();
display.clearDisplay();
// miniature bitmap display
oled.drawbitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
oled.display();
display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
display.display();
// invert the display
oled.ssd1306_command(SSD1306_INVERTDISPLAY);
display.ssd1306_command(SSD1306_INVERTDISPLAY);
delay(1000);
oled.ssd1306_command(SSD1306_NORMALDISPLAY);
display.ssd1306_command(SSD1306_NORMALDISPLAY);
delay(1000);
// draw a bitmap icon and 'animate' movement
@ -104,15 +91,7 @@ void setup() {
}
void loop()
{
for (uint8_t i=0; i<SSD1306_LCDWIDTH; i++) {
for (uint8_t j=0; j<SSD1306_LCDHEIGHT; j++) {
oled.setpixel(i, j, WHITE);
oled.display();
}
}
void loop() {
}
@ -123,7 +102,7 @@ void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
// initialize
for (uint8_t f=0; f< NUMFLAKES; f++) {
icons[f][XPOS] = random() % SSD1306_LCDWIDTH;
icons[f][XPOS] = random() % display.width();
icons[f][YPOS] = 0;
icons[f][DELTAY] = random() % 5 + 1;
@ -138,19 +117,19 @@ void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
while (1) {
// draw each icon
for (uint8_t f=0; f< NUMFLAKES; f++) {
oled.drawbitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, WHITE);
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, WHITE);
}
oled.display();
display.display();
delay(200);
// then erase it + move it
for (uint8_t f=0; f< NUMFLAKES; f++) {
oled.drawbitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, BLACK);
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, BLACK);
// move it
icons[f][YPOS] += icons[f][DELTAY];
// if its gone, reinit
if (icons[f][YPOS] > SSD1306_LCDHEIGHT) {
icons[f][XPOS] = random() % SSD1306_LCDWIDTH;
if (icons[f][YPOS] > display.height()) {
icons[f][XPOS] = random() % display.width();
icons[f][YPOS] = 0;
icons[f][DELTAY] = random() % 5 + 1;
}
@ -160,48 +139,87 @@ void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
void testdrawchar(void) {
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
for (uint8_t i=0; i < 168; i++) {
oled.drawchar((i % 21) * 6, i/21, i);
if (i == '\n') continue;
display.write(i);
if ((i > 0) && (i % 21 == 0))
display.println();
}
display.display();
}
void testdrawcircle(void) {
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=2) {
oled.drawcircle(63, 31, i, WHITE);
}
}
void testdrawrect(void) {
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=2) {
oled.drawrect(i, i, SSD1306_LCDWIDTH-i, SSD1306_LCDHEIGHT-i, WHITE);
for (uint8_t i=0; i<display.height(); i+=2) {
display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
display.display();
}
}
void testfillrect(void) {
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i++) {
// alternate colors for moire effect
oled.fillrect(i, i, SSD1306_LCDWIDTH-i, SSD1306_LCDHEIGHT-i, i%2);
uint8_t color = 1;
for (uint8_t i=0; i<display.height()/2; i+=3) {
// alternate colors
display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
display.display();
color++;
}
}
void testdrawrect(void) {
for (uint8_t i=0; i<display.height()/2; i+=2) {
display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
display.display();
}
}
void testdrawline() {
for (uint8_t i=0; i<SSD1306_LCDWIDTH; i+=4) {
oled.drawline(0, 0, i, SSD1306_LCDHEIGHT-1, WHITE);
oled.display();
}
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=4) {
oled.drawline(0, 0, SSD1306_LCDWIDTH-1, i, WHITE);
oled.display();
}
Serial.println(display.width());
Serial.println(display.height());
delay(1000);
for (uint8_t i=0; i<display.width(); i+=4) {
display.drawLine(0, 0, i, display.height()-1, WHITE);
display.display();
}
for (uint8_t i=0; i<display.height(); i+=4) {
display.drawLine(0, 0, display.width()-1, i, WHITE);
display.display();
}
delay(250);
for (uint8_t i=0; i<SSD1306_LCDWIDTH; i+=4) {
oled.drawline(i, SSD1306_LCDHEIGHT-1, 0, 0, BLACK);
oled.display();
display.clearDisplay();
for (uint8_t i=0; i<display.width(); i+=4) {
display.drawLine(0, display.height()-1, i, 0, WHITE);
display.display();
}
for (uint8_t i=0; i<SSD1306_LCDHEIGHT; i+=4) {
oled.drawline(SSD1306_LCDWIDTH - 1, i, 0, 0, BLACK);
oled.display();
for (int8_t i=display.height()-1; i>=0; i-=4) {
display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
display.display();
}
delay(250);
display.clearDisplay();
for (int8_t i=display.width()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
display.display();
}
for (int8_t i=display.height()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
display.display();
}
delay(250);
display.clearDisplay();
for (uint8_t i=0; i<display.height(); i+=4) {
display.drawLine(display.width()-1, 0, 0, i, WHITE);
display.display();
}
for (uint8_t i=0; i<display.width(); i+=4) {
display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);
display.display();
}
delay(250);
}

View file

@ -1,266 +0,0 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
#ifndef FONT5X7_H
#define FONT5X7_H
// standard ascii 5x7 font
static unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
0x18, 0x3C, 0x7E, 0x3C, 0x18,
0x1C, 0x57, 0x7D, 0x57, 0x1C,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
0x00, 0x18, 0x3C, 0x18, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
0x00, 0x18, 0x24, 0x18, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
0x30, 0x48, 0x3A, 0x06, 0x0E,
0x26, 0x29, 0x79, 0x29, 0x26,
0x40, 0x7F, 0x05, 0x05, 0x07,
0x40, 0x7F, 0x05, 0x25, 0x3F,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
0x7F, 0x3E, 0x1C, 0x1C, 0x08,
0x08, 0x1C, 0x1C, 0x3E, 0x7F,
0x14, 0x22, 0x7F, 0x22, 0x14,
0x5F, 0x5F, 0x00, 0x5F, 0x5F,
0x06, 0x09, 0x7F, 0x01, 0x7F,
0x00, 0x66, 0x89, 0x95, 0x6A,
0x60, 0x60, 0x60, 0x60, 0x60,
0x94, 0xA2, 0xFF, 0xA2, 0x94,
0x08, 0x04, 0x7E, 0x04, 0x08,
0x10, 0x20, 0x7E, 0x20, 0x10,
0x08, 0x08, 0x2A, 0x1C, 0x08,
0x08, 0x1C, 0x2A, 0x08, 0x08,
0x1E, 0x10, 0x10, 0x10, 0x10,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
0x30, 0x38, 0x3E, 0x38, 0x30,
0x06, 0x0E, 0x3E, 0x0E, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14,
0x24, 0x2A, 0x7F, 0x2A, 0x12,
0x23, 0x13, 0x08, 0x64, 0x62,
0x36, 0x49, 0x56, 0x20, 0x50,
0x00, 0x08, 0x07, 0x03, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
0x08, 0x08, 0x3E, 0x08, 0x08,
0x00, 0x80, 0x70, 0x30, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x60, 0x60, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02,
0x3E, 0x51, 0x49, 0x45, 0x3E,
0x00, 0x42, 0x7F, 0x40, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46,
0x21, 0x41, 0x49, 0x4D, 0x33,
0x18, 0x14, 0x12, 0x7F, 0x10,
0x27, 0x45, 0x45, 0x45, 0x39,
0x3C, 0x4A, 0x49, 0x49, 0x31,
0x41, 0x21, 0x11, 0x09, 0x07,
0x36, 0x49, 0x49, 0x49, 0x36,
0x46, 0x49, 0x49, 0x29, 0x1E,
0x00, 0x00, 0x14, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41,
0x14, 0x14, 0x14, 0x14, 0x14,
0x00, 0x41, 0x22, 0x14, 0x08,
0x02, 0x01, 0x59, 0x09, 0x06,
0x3E, 0x41, 0x5D, 0x59, 0x4E,
0x7C, 0x12, 0x11, 0x12, 0x7C,
0x7F, 0x49, 0x49, 0x49, 0x36,
0x3E, 0x41, 0x41, 0x41, 0x22,
0x7F, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x49, 0x49, 0x49, 0x41,
0x7F, 0x09, 0x09, 0x09, 0x01,
0x3E, 0x41, 0x41, 0x51, 0x73,
0x7F, 0x08, 0x08, 0x08, 0x7F,
0x00, 0x41, 0x7F, 0x41, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01,
0x7F, 0x08, 0x14, 0x22, 0x41,
0x7F, 0x40, 0x40, 0x40, 0x40,
0x7F, 0x02, 0x1C, 0x02, 0x7F,
0x7F, 0x04, 0x08, 0x10, 0x7F,
0x3E, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x09, 0x09, 0x09, 0x06,
0x3E, 0x41, 0x51, 0x21, 0x5E,
0x7F, 0x09, 0x19, 0x29, 0x46,
0x26, 0x49, 0x49, 0x49, 0x32,
0x03, 0x01, 0x7F, 0x01, 0x03,
0x3F, 0x40, 0x40, 0x40, 0x3F,
0x1F, 0x20, 0x40, 0x20, 0x1F,
0x3F, 0x40, 0x38, 0x40, 0x3F,
0x63, 0x14, 0x08, 0x14, 0x63,
0x03, 0x04, 0x78, 0x04, 0x03,
0x61, 0x59, 0x49, 0x4D, 0x43,
0x00, 0x7F, 0x41, 0x41, 0x41,
0x02, 0x04, 0x08, 0x10, 0x20,
0x00, 0x41, 0x41, 0x41, 0x7F,
0x04, 0x02, 0x01, 0x02, 0x04,
0x40, 0x40, 0x40, 0x40, 0x40,
0x00, 0x03, 0x07, 0x08, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40,
0x7F, 0x28, 0x44, 0x44, 0x38,
0x38, 0x44, 0x44, 0x44, 0x28,
0x38, 0x44, 0x44, 0x28, 0x7F,
0x38, 0x54, 0x54, 0x54, 0x18,
0x00, 0x08, 0x7E, 0x09, 0x02,
0x18, 0xA4, 0xA4, 0x9C, 0x78,
0x7F, 0x08, 0x04, 0x04, 0x78,
0x00, 0x44, 0x7D, 0x40, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78,
0x7C, 0x08, 0x04, 0x04, 0x78,
0x38, 0x44, 0x44, 0x44, 0x38,
0xFC, 0x18, 0x24, 0x24, 0x18,
0x18, 0x24, 0x24, 0x18, 0xFC,
0x7C, 0x08, 0x04, 0x04, 0x08,
0x48, 0x54, 0x54, 0x54, 0x24,
0x04, 0x04, 0x3F, 0x44, 0x24,
0x3C, 0x40, 0x40, 0x20, 0x7C,
0x1C, 0x20, 0x40, 0x20, 0x1C,
0x3C, 0x40, 0x30, 0x40, 0x3C,
0x44, 0x28, 0x10, 0x28, 0x44,
0x4C, 0x90, 0x90, 0x90, 0x7C,
0x44, 0x64, 0x54, 0x4C, 0x44,
0x00, 0x08, 0x36, 0x41, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02,
0x3C, 0x26, 0x23, 0x26, 0x3C,
0x1E, 0xA1, 0xA1, 0x61, 0x12,
0x3A, 0x40, 0x40, 0x20, 0x7A,
0x38, 0x54, 0x54, 0x55, 0x59,
0x21, 0x55, 0x55, 0x79, 0x41,
0x21, 0x54, 0x54, 0x78, 0x41,
0x21, 0x55, 0x54, 0x78, 0x40,
0x20, 0x54, 0x55, 0x79, 0x40,
0x0C, 0x1E, 0x52, 0x72, 0x12,
0x39, 0x55, 0x55, 0x55, 0x59,
0x39, 0x54, 0x54, 0x54, 0x59,
0x39, 0x55, 0x54, 0x54, 0x58,
0x00, 0x00, 0x45, 0x7C, 0x41,
0x00, 0x02, 0x45, 0x7D, 0x42,
0x00, 0x01, 0x45, 0x7C, 0x40,
0xF0, 0x29, 0x24, 0x29, 0xF0,
0xF0, 0x28, 0x25, 0x28, 0xF0,
0x7C, 0x54, 0x55, 0x45, 0x00,
0x20, 0x54, 0x54, 0x7C, 0x54,
0x7C, 0x0A, 0x09, 0x7F, 0x49,
0x32, 0x49, 0x49, 0x49, 0x32,
0x32, 0x48, 0x48, 0x48, 0x32,
0x32, 0x4A, 0x48, 0x48, 0x30,
0x3A, 0x41, 0x41, 0x21, 0x7A,
0x3A, 0x42, 0x40, 0x20, 0x78,
0x00, 0x9D, 0xA0, 0xA0, 0x7D,
0x39, 0x44, 0x44, 0x44, 0x39,
0x3D, 0x40, 0x40, 0x40, 0x3D,
0x3C, 0x24, 0xFF, 0x24, 0x24,
0x48, 0x7E, 0x49, 0x43, 0x66,
0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
0xFF, 0x09, 0x29, 0xF6, 0x20,
0xC0, 0x88, 0x7E, 0x09, 0x03,
0x20, 0x54, 0x54, 0x79, 0x41,
0x00, 0x00, 0x44, 0x7D, 0x41,
0x30, 0x48, 0x48, 0x4A, 0x32,
0x38, 0x40, 0x40, 0x22, 0x7A,
0x00, 0x7A, 0x0A, 0x0A, 0x72,
0x7D, 0x0D, 0x19, 0x31, 0x7D,
0x26, 0x29, 0x29, 0x2F, 0x28,
0x26, 0x29, 0x29, 0x29, 0x26,
0x30, 0x48, 0x4D, 0x40, 0x20,
0x38, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x38,
0x2F, 0x10, 0xC8, 0xAC, 0xBA,
0x2F, 0x10, 0x28, 0x34, 0xFA,
0x00, 0x00, 0x7B, 0x00, 0x00,
0x08, 0x14, 0x2A, 0x14, 0x22,
0x22, 0x14, 0x2A, 0x14, 0x08,
0xAA, 0x00, 0x55, 0x00, 0xAA,
0xAA, 0x55, 0xAA, 0x55, 0xAA,
0x00, 0x00, 0x00, 0xFF, 0x00,
0x10, 0x10, 0x10, 0xFF, 0x00,
0x14, 0x14, 0x14, 0xFF, 0x00,
0x10, 0x10, 0xFF, 0x00, 0xFF,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x14, 0x14, 0x14, 0xFC, 0x00,
0x14, 0x14, 0xF7, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x14, 0x14, 0xF4, 0x04, 0xFC,
0x14, 0x14, 0x17, 0x10, 0x1F,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0x1F, 0x00,
0x10, 0x10, 0x10, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x10,
0x10, 0x10, 0x10, 0x1F, 0x10,
0x10, 0x10, 0x10, 0xF0, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0xFF, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x14,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x1F, 0x10, 0x17,
0x00, 0x00, 0xFC, 0x04, 0xF4,
0x14, 0x14, 0x17, 0x10, 0x17,
0x14, 0x14, 0xF4, 0x04, 0xF4,
0x00, 0x00, 0xFF, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0xF7, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x17, 0x14,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0xF4, 0x14,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x00, 0x00, 0x1F, 0x10, 0x1F,
0x00, 0x00, 0x00, 0x1F, 0x14,
0x00, 0x00, 0x00, 0xFC, 0x14,
0x00, 0x00, 0xF0, 0x10, 0xF0,
0x10, 0x10, 0xFF, 0x10, 0xFF,
0x14, 0x14, 0x14, 0xFF, 0x14,
0x10, 0x10, 0x10, 0x1F, 0x00,
0x00, 0x00, 0x00, 0xF0, 0x10,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x38, 0x44, 0x44, 0x38, 0x44,
0x7C, 0x2A, 0x2A, 0x3E, 0x14,
0x7E, 0x02, 0x02, 0x06, 0x06,
0x02, 0x7E, 0x02, 0x7E, 0x02,
0x63, 0x55, 0x49, 0x41, 0x63,
0x38, 0x44, 0x44, 0x3C, 0x04,
0x40, 0x7E, 0x20, 0x1E, 0x20,
0x06, 0x02, 0x7E, 0x02, 0x02,
0x99, 0xA5, 0xE7, 0xA5, 0x99,
0x1C, 0x2A, 0x49, 0x2A, 0x1C,
0x4C, 0x72, 0x01, 0x72, 0x4C,
0x30, 0x4A, 0x4D, 0x4D, 0x30,
0x30, 0x48, 0x78, 0x48, 0x30,
0xBC, 0x62, 0x5A, 0x46, 0x3D,
0x3E, 0x49, 0x49, 0x49, 0x00,
0x7E, 0x01, 0x01, 0x01, 0x7E,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x44, 0x44, 0x5F, 0x44, 0x44,
0x40, 0x51, 0x4A, 0x44, 0x40,
0x40, 0x44, 0x4A, 0x51, 0x40,
0x00, 0x00, 0xFF, 0x01, 0x03,
0xE0, 0x80, 0xFF, 0x00, 0x00,
0x08, 0x08, 0x6B, 0x6B, 0x08,
0x36, 0x12, 0x36, 0x24, 0x36,
0x06, 0x0F, 0x09, 0x0F, 0x06,
0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x00, 0x10, 0x10, 0x00,
0x30, 0x40, 0xFF, 0x01, 0x01,
0x00, 0x1F, 0x01, 0x01, 0x1E,
0x00, 0x19, 0x1D, 0x17, 0x12,
0x00, 0x3C, 0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00,
};
#endif