/*
  SSD1306 - Display monocromático OLED 128x64
  Autor: Tiago
  Compilador: MikroC PRO PIC
  Criado em: 26/12/2014 por Tiago
*/

/* Fundamental Command */
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_ENTIREDISPLAYON_RESUME 0xA4
#define SSD1306_ENTIREDISPLAYON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF

/* Scrolling Command */
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_ACTIVATE_SCROLL 0x2F
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3

/* Addressing Setting Command */
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR   0x22
#define SSD1306_PAGESTARTADDR 0xB0

/* Hardware Configuration (Panel resolution and layout related) Command */
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_SETMULTIPLEXRATIO 0xA8
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA

/* Timing and Driving Scheme Setting Command  */
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_NOP 0xE3

#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2

#define SSD1306_CL_WHITE 0
#define SSD1306_CL_BLACK 1

/* Rotinas */
void SSD1306_Init();
void SSD1306_Cmd( char wData );
void SSD1306_Data( char wData );
void SSD1306_Chr( char character, char color );
void SSD1306_Chr8( char row, char col, char wChar, char color );
void SSD1306_Chr16( char row, char col, char wChar, char color );
void SSD1306_Out8( char row, char col, char *texto, char color );
void SSD1306_Out16( char row, char col, char *texto, char color );
void SSD1306_Set_Cursor( char row, char col );
void SSD1306_Set_Contrast( char value );

#define SSD1306_Clear() SSD1306_Fill( 0 )

//https://bitbucket.org/tinusaur/ssd1306xled/src/d467de1d216d/ssd1306xled/?at=default
const code char SSD1306_Font8x16[][16] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,// ! 1
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// " 2
0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,// # 3
0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,// $ 4
0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,// % 5
0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,// & 6
0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ' 7
0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,// ( 8
0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,// ) 9
0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,// * 10
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,// + 11
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,// , 12
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,// - 13
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,// . 14
0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,// / 15
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,// 0 16
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// 1 17
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,// 2 18
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,// 3 19
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,// 4 20
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,// 5 21
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,// 6 22
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,// 7 23
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,// 8 24
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,// 9 25
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,// : 26
0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,// ; 27
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,// < 28
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,// = 29
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,// > 30
0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,// ? 31
0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,// @ 32
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,// A 33
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,// B 34
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,// C 35
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,// D 36
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,// E 37
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,// F 38
0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,// G 39
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,// H 40
0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// I 41
0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,// J 42
0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,// K 43
0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,// L 44
0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,// M 45
0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,// N 46
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,// O 47
0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,// P 48
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,// Q 49
0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,// R 50
0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,// S 51
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,// T 52
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,// U 53
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,// V 54
0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,// W 55
0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,// X 56
0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,// Y 57
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,// Z 58
0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,// [ 59
0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,// \ 60
0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,// ] 61
0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ^ 62
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,// _ 63
0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ` 64
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,// a 65
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,// b 66
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,// c 67
0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,// d 68
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,// e 69
0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// f 70
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,// g 71
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,// h 72
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// i 73
0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,// j 74
0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,// k 75
0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// l 76
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,// m 77
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,// n 78
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,// o 79
0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,// p 80
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,// q 81
0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,// r 82
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,// s 83
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,// t 84
0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,// u 85
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,// v 86
0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,// w 87
0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,// x 88
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,// y 89
0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,// z 90
0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,// { 91
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,// | 92
0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,// } 93
0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ~ 94
};

const code char SSD1306_Font8x8[][8] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00,
0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00,
0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00,
0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00,
0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00,
0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00,
0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00,
0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00,
0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00,
0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00,
0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,
0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00,
0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00,
0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00,
0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00,
0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00,
0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00,
0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00,
0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00,
0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00,
0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00,
0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00,
0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00,
0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00,
0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00,
0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00,
0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00,
0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00,
0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00,
0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00,
0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00,
0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00,
0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00,
0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00,
0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00,
0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00,
0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00,
0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00,
0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00,
0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00,
0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00,
0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00,
0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00,
0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00,
0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00,
0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00,
0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00,
0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00,
0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00,
0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00,
0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00,
0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00,
0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00,
0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00,
0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00,
0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00,
0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00,
0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00,
0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00,
0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00,
0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,
0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00,
0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00,
0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00,
0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00,
0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00,
0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00,
0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00,
0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00,
0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00,
0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00,
0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00,
0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00,
0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00,
0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00,
0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00,
0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00,
0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00,
0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00,
0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00,
0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00,
0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00,
0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00,
0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00,
0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00,
0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00,
0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00,
0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00,
0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00,
0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,
0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00,
0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00,
0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00
};

/* Envia um comando */
void SSD1306_Cmd( char wData )
{
   Soft_I2C_Start(); //Sinal de start
   Soft_I2C_Write( 0x78 ); //Envia o endereço do display
   Soft_I2C_Write( 0x00 ); //Control Byte 
   Soft_I2C_Write( wData ); //Comando
   Soft_I2C_Stop(); //Sinal de stop
}

/* Envia um dado */
void SSD1306_Data( char wData )
{
   Soft_I2C_Start(); //Sinal de start
   Soft_I2C_Write( 0x78 ); //Envia o endereço do display
   Soft_I2C_Write( 0b1100000 ); //Control Byte
   Soft_I2C_Write( wData ); //Dado
   Soft_I2C_Stop(); //Sinal de stop
}

/* Inicializa o display */
void SSD1306_Init()
{
   SSD1306_Cmd( SSD1306_DISPLAYOFF );             //Display Off
    
   /* MUITO IMPORTANTE!!! */
   SSD1306_Cmd( SSD1306_SETMULTIPLEXRATIO );      //Multiplex Ratio
   SSD1306_Cmd( 0x3F );          
    
   SSD1306_Cmd( SSD1306_SETDISPLAYOFFSET );       //Display Offset
   SSD1306_Cmd( 0x00 );
   SSD1306_Cmd( SSD1306_SETSTARTLINE );           //Display Start Line
   SSD1306_Cmd( SSD1306_SEGREMAP | 1 );        
   SSD1306_Cmd( SSD1306_COMSCANDEC );             //COM Output Scan Direction
   SSD1306_Cmd( SSD1306_SETCOMPINS );             //COM Pins Hardware Configuration
   SSD1306_Cmd( 0x12 );
   SSD1306_Cmd( SSD1306_SETCONTRAST );            //Contrast Control
   SSD1306_Cmd( 255 );          
   SSD1306_Cmd( SSD1306_ENTIREDISPLAYON_RESUME ); //Entire Display On/Off
   SSD1306_Cmd( SSD1306_NORMALDISPLAY );          //Normal/Inverse Display
   SSD1306_Cmd( SSD1306_SETDISPLAYCLOCKDIV ); //Display Clock Divide Ratio/Oscillator Frequency
   SSD1306_Cmd( 0x80 );
   
   SSD1306_Cmd( SSD1306_SETPRECHARGE );           //Pre-Charge Period
   SSD1306_Cmd( 0x25 );
   SSD1306_Cmd( SSD1306_SETVCOMDETECT );          //VCOMH Deselect Level
   SSD1306_Cmd( 0x20 );
 
   /* MUITO IMPORTANTE!!! */
   SSD1306_Cmd( SSD1306_PAGEADDR );        
   SSD1306_Cmd( 0 );        
   SSD1306_Cmd( 7 );  
   
   /* posicao inicial do cursor */
   SSD1306_Cmd( 0xB0 );
   SSD1306_Cmd( 0x10 );
   SSD1306_Cmd( 0x00 );
   SSD1306_Cmd( SSD1306_MEMORYMODE );
   SSD1306_Cmd( 2 ); 
    
   SSD1306_Cmd( SSD1306_CHARGEPUMP );             //Charge Pump
   SSD1306_Cmd( 0x14 );                           //Enable Charge Pump    
   SSD1306_Cmd( SSD1306_DISPLAYON );              //Display On
}

/* Define a posição do cursor */
void SSD1306_Set_Cursor( char row, char col )
{
   SSD1306_Cmd( SSD1306_PAGESTARTADDR | row ); //Define a posicao da linha
   SSD1306_Cmd( ( SSD1306_SETHIGHCOLUMN | ( col >> 4 ) ) ); //Define o nibble MSB da posição da coluna
   SSD1306_Cmd( ( 0x0f & col ) ); //Difne o nibble LSB da posição da coluna
}

/* Define o constraste do display */
void SSD1306_Set_Contrast( char value )
{
   SSD1306_Cmd( SSD1306_SETCONTRAST ); //Envia o comando para alterar o contraste
   SSD1306_Cmd( value ); //Define o novo valor do constraste
}

/* Escreve um caracter 8x8 na posição atual do cursor */
void SSD1306_Chr( char wChar, char color )
{
char i;
   wChar = wChar - 0x20;
   color = color ? 0x00 : 0xFF;
   for( i = 0; i < 8; i++ )
      SSD1306_Data( SSD1306_Font8x8[wChar][i] ^ color );
}

/* Escreve um caracter 8x8 na posição especificada */
void SSD1306_Chr8( char row, char col, char wChar, char color )
{
     SSD1306_Set_Cursor( row, col << 3 );
     SSD1306_Chr( wChar, color );
}

/* Escreve um caracter 8x16 na posição especificada */
void SSD1306_Chr16( char row, char col, char wChar, char color )
{
char i;
   col <<= 3;
   SSD1306_Set_Cursor( row++, col );
   wChar = wChar - 0x20;
   color = color ? 0x00 : 0xFF;
   for( i = 0; i < 8; i++ )
      SSD1306_Data( SSD1306_Font8x16[wChar][i] ^ color );
   SSD1306_Set_Cursor( row, col ); 
   for( i = 8; i < 16; i++ )
      SSD1306_Data( SSD1306_Font8x16[wChar][i] ^ color );
}

/* Escreve um texto com caracteres 8x8 na posição especificada */
void SSD1306_Out8( char row, char col, char *texto, char color )
{
   SSD1306_Set_Cursor( row, col << 3 );
   while( *texto )
      SSD1306_Chr( *texto++, color );
}

/* Escreve um texto com caracteres 8x16 na posição especificada */
void SSD1306_Out16( char row, char col, char *texto, char color )
{
   while( *texto )
      SSD1306_Chr16( row, col++, *texto++, color );
}

/* Desenha uma imagem */
void SSD1306_Image( const char *bmp, char color )
{
char x, y;
   color = color ? 0x00 : 0xFF;
   for( y = 0; y < 8; y++ )
   {
      SSD1306_Set_Cursor( y, 0 );
      Soft_I2C_Start();
      Soft_I2C_Write( 0x78 );
      Soft_I2C_Write( 0b1100000 );
      for( x = 0; x < 128; x++ )
         Soft_I2C_Write( *bmp++ ^ color );
      Soft_I2C_Stop();  
   } 
}

/* Preeche o display com o byte */
void SSD1306_Fill( char color )
{
char x, y;
   for( y = 0; y < 8; y++ )
   {
      SSD1306_Set_Cursor( y, 0 );
      Soft_I2C_Start();
      Soft_I2C_Write( 0x78 );
      Soft_I2C_Write( 0b1100000 );
      for( x = 0; x < 128; x++ )
         Soft_I2C_Write( color );
      Soft_I2C_Stop();  
   }
}