32 Screen::Screen(
bool i2cChannel)
37 digitalWrite(SDA0, HIGH);
38 digitalWrite(SCL0, HIGH);
43 digitalWrite(SDA1, HIGH);
44 digitalWrite(SCL1, HIGH);
68 _SFR_MEM8(this->twcr) = (1 << TWEN0)| (1 << TWINT0) | (1 << TWSTO0);
74 _SFR_MEM8(this->twsr) = 0;
75 _SFR_MEM8(this->twcr) = 0;
78 _SFR_MEM8(this->twbr) = 72;
80 _SFR_MEM8(this->twsr) &= 0xFC;
82 _SFR_MEM8(this->twcr) = _BV(TWEN0);
84 SSD1306_SEND_CMD(SSD1306_DISPLAY_OFF);
85 SSD1306_SEND_CMD(SSD1306_SET_DISPLAY_CLOCK_DIV_RATIO);
86 SSD1306_SEND_CMD(0x80);
87 SSD1306_SEND_CMD(SSD1306_SET_MULTIPLEX_RATIO);
88 SSD1306_SEND_CMD(H64_MULTIPLEX_RATIO);
89 SSD1306_SEND_CMD(SSD1306_SET_DISPLAY_OFFSET);
90 SSD1306_SEND_CMD(0x0);
91 SSD1306_SEND_CMD(SSD1306_SET_START_LINE | 0x0);
92 SSD1306_SEND_CMD(SSD1306_CHARGE_PUMP);
93 SSD1306_SEND_CMD(0x14);
94 SSD1306_SEND_CMD(SSD1306_MEMORY_ADDR_MODE);
95 SSD1306_SEND_CMD(0x00);
96 SSD1306_SEND_CMD(SSD1306_SET_SEGMENT_REMAP | 0x1);
97 SSD1306_SEND_CMD(SSD1306_COM_SCAN_DIR_DEC);
98 SSD1306_SEND_CMD(SSD1306_SET_COM_PINS);
99 SSD1306_SEND_CMD(H64_COM_PINS);
100 SSD1306_SEND_CMD(SSD1306_SET_CONTRAST_CONTROL);
101 SSD1306_SEND_CMD(0xCF);
102 SSD1306_SEND_CMD(SSD1306_SET_PRECHARGE_PERIOD);
103 SSD1306_SEND_CMD(0xF1);
104 SSD1306_SEND_CMD(SSD1306_SET_VCOM_DESELECT);
105 SSD1306_SEND_CMD(0x40);
106 SSD1306_SEND_CMD(SSD1306_DISPLAY_ALL_ON_RESUME);
107 SSD1306_SEND_CMD(SSD1306_NORMAL_DISPLAY);
108 SSD1306_SEND_CMD(SSD1306_DISPLAY_ON);
113 void* Screen::operator
new(
size_t size)
115 void *
object = malloc(size);
119 bool Screen::waitForAck()
121 int32_t time = millis();
123 while ((_SFR_MEM8(this->twcr) & (1 << TWINT0)) == 0)
125 if(millis() - time > 10)
133 void Screen::clrScreen()
141 SSD1306_SEND_CMD(SSD1306_SET_COLUMN_ADDR);
143 SSD1306_SEND_CMD(127);
145 SSD1306_SEND_CMD(SSD1306_SET_PAGE_ADDR);
150 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWEA0) | (1 << TWINT0) | (1 << TWSTA0);
151 if(this->waitForAck()){this->busFailure = 1;
return;}
152 _SFR_MEM8(this->twdr) = SSD1306_ADDR<<1;
153 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
154 if(this->waitForAck()){this->busFailure = 1;
return;}
155 _SFR_MEM8(this->twdr) = SSD1306_DATA_CONTINUE;
156 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
157 if(this->waitForAck()){this->busFailure = 1;
return;}
159 for (uint16_t b=0; b < 128*8; b++)
161 _SFR_MEM8(this->twdr) = 0x00;
162 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
163 if(this->waitForAck()){this->busFailure = 1;
return;}
166 _SFR_MEM8(this->twcr) = (1 << TWEN0)| (1 << TWINT0) | (1 << TWSTO0);
170 void Screen::drawImage(
const uint8_t *image, uint8_t x, uint8_t y, uint8_t width, uint8_t height,
bool invert)
180 SSD1306_SEND_CMD(SSD1306_SET_COLUMN_ADDR);
182 SSD1306_SEND_CMD(x+width-1);
184 SSD1306_SEND_CMD(SSD1306_SET_PAGE_ADDR);
185 SSD1306_SEND_CMD(y/8);
186 SSD1306_SEND_CMD(y/8 + height/8 - 1);
189 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWEA0) | (1 << TWINT0) | (1 << TWSTA0);
190 if(this->waitForAck()){this->busFailure = 1;
return;}
191 _SFR_MEM8(this->twdr) = SSD1306_ADDR<<1;
192 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
193 if(this->waitForAck()){this->busFailure = 1;
return;}
194 _SFR_MEM8(this->twdr) = SSD1306_DATA_CONTINUE;
195 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
196 if(this->waitForAck()){this->busFailure = 1;
return;}
197 for(i = (width*(height/8))-1; i > 0; i--)
199 pattern = pgm_read_byte(&(image[i]));
206 _SFR_MEM8(this->twdr) = pattern;
208 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
209 if(this->waitForAck()){this->busFailure = 1;
return;}
212 _SFR_MEM8(this->twcr) = (1 << TWEN0)| (1 << TWINT0) | (1 << TWSTO0);
216 void Screen::printString(
const uint8_t *
string, uint8_t x, uint8_t y,
bool invert)
223 const uint8_t *usedFont = font;
224 uint16_t i, j, len, k;
225 uint8_t pattern, width, height, rows = pgm_read_byte(&(usedFont[0])), offset = pgm_read_byte(&(usedFont[2]));
226 uint8_t patternOffset, runs;
228 len = strlen(
string);
239 SSD1306_SEND_CMD(SSD1306_SET_COLUMN_ADDR);
241 SSD1306_SEND_CMD(x+width-1);
243 SSD1306_SEND_CMD(SSD1306_SET_PAGE_ADDR);
244 SSD1306_SEND_CMD(y/8);
245 SSD1306_SEND_CMD(y/8+height+runs-1);
248 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWEA0) | (1 << TWINT0) | (1 << TWSTA0);
249 if(this->waitForAck()){this->busFailure = 1;
return;}
250 _SFR_MEM8(this->twdr) = SSD1306_ADDR<<1;
251 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
252 if(this->waitForAck()){this->busFailure = 1;
return;}
253 _SFR_MEM8(this->twdr) = SSD1306_DATA_CONTINUE;
254 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
255 if(this->waitForAck()){this->busFailure = 1;
return;}
257 for(i = 0; i < len; i++)
259 for(j = 0; j < rows; j++)
261 pattern = pgm_read_byte(&(usedFont[((
string[i]-offset)*rows) + 4 + j]));
268 _SFR_MEM8(this->twdr) = pattern;
270 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
271 if(this->waitForAck()){this->busFailure = 1;
return;}
276 _SFR_MEM8(this->twcr) = (1 << TWEN0)| (1 << TWINT0) | (1 << TWSTO0);
280 void Screen::drawRect(
int x1,
int y1,
int x2,
int y2,
bool color)
291 if(y2 < y1 || x2 < x1)
295 if(x1 < 0 || x2 > 127 || y1 < 0 || y2 > 63)
301 SSD1306_SEND_CMD(SSD1306_SET_COLUMN_ADDR);
302 SSD1306_SEND_CMD(x1);
303 SSD1306_SEND_CMD(x2);
305 SSD1306_SEND_CMD(SSD1306_SET_PAGE_ADDR);
306 SSD1306_SEND_CMD(y1/8);
307 SSD1306_SEND_CMD(y2/8);
310 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWEA0) | (1 << TWINT0) | (1 << TWSTA0);
311 if(this->waitForAck()){this->busFailure = 1;
return;}
312 _SFR_MEM8(this->twdr) = SSD1306_ADDR<<1;
313 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
314 if(this->waitForAck()){this->busFailure = 1;
return;}
315 _SFR_MEM8(this->twdr) = SSD1306_DATA_CONTINUE;
316 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
317 if(this->waitForAck()){this->busFailure = 1;
return;}
328 for(b = y1%8; b > 0; b--)
337 for(b = 7 - y2%8; b > 0; b--)
344 for (b=0; b < (x2 - x1)+1; b++)
346 _SFR_MEM8(this->twdr) = pattern;
348 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
349 if(this->waitForAck()){this->busFailure = 1;
return;}
354 if((y2/8 - y1/8) > 1)
364 for (b=0; b < (((y2/8) - (y1/8)) - 1) * ((x2 - x1) + 1); b++)
366 _SFR_MEM8(this->twdr) = pattern;
368 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
369 if(this->waitForAck()){this->busFailure = 1;
return;}
382 for(b = y2%8 + 1; b > 0; b--)
387 for (b=0; b < (x2 - x1)+1; b++)
389 _SFR_MEM8(this->twdr) = pattern;
391 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
392 if(this->waitForAck()){this->busFailure = 1;
return;}
397 _SFR_MEM8(this->twcr) = (1 << TWEN0)| (1 << TWINT0) | (1 << TWSTO0);
402 void Screen::cmd(uint8_t cmd)
410 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWEA0) | (1 << TWINT0) | (1 << TWSTA0);
411 if(this->waitForAck()){this->busFailure = 1;
return;}
412 _SFR_MEM8(this->twdr) = SSD1306_ADDR<<1;
413 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
414 if(this->waitForAck()){this->busFailure = 1;
return;}
416 _SFR_MEM8(this->twdr) = SSD1306_COMMAND;
417 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
418 if(this->waitForAck()){this->busFailure = 1;
return;}
419 _SFR_MEM8(this->twdr) = cmd;
420 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWEA0);
421 if(this->waitForAck()){this->busFailure = 1;
return;}
423 _SFR_MEM8(this->twcr) = (1 << TWEN0) | (1 << TWINT0) | (1 << TWSTO0);