Skip to content

Commit 086e891

Browse files
committed
Merge pull request #40 from FWeinb/add-brzo-i2c-support
Add optional support for using brzo as i2c lib
2 parents f1f4248 + 24e44fc commit 086e891

File tree

2 files changed

+148
-86
lines changed

2 files changed

+148
-86
lines changed

SSD1306.cpp

Lines changed: 134 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,8 @@ bool SSD1306::init() {
5050
}
5151
#endif
5252

53-
Wire.begin(this->sda, this->sdc);
54-
55-
// Let's use ~700khz if ESP8266 is in 160Mhz mode
56-
// this will be limited to ~400khz if the ESP8266 in 80Mhz mode.
57-
Wire.setClock(700000);
58-
53+
reconnect();
5954
sendInitCommands();
60-
6155
resetDisplay();
6256

6357
return true;
@@ -72,14 +66,15 @@ void SSD1306::end() {
7266

7367
void SSD1306::resetDisplay(void) {
7468
clear();
75-
#ifdef SSD1306_DOUBLE_BUFFER
76-
memset(buffer_back, 1, DISPLAY_BUFFER_SIZE);
77-
#endif
7869
display();
7970
}
8071

8172
void SSD1306::reconnect() {
82-
Wire.begin(this->sda, this->sdc);
73+
#ifdef SSD1306_USE_BRZO
74+
brzo_i2c_setup(this->sda, this->sdc, 2000);
75+
#else
76+
Wire.begin(this->sda, this->sdc);
77+
#endif
8378
}
8479

8580
void SSD1306::setColor(SSD1306_COLOR color) {
@@ -518,100 +513,155 @@ void SSD1306::flipScreenVertically() {
518513

519514
void SSD1306::display(void) {
520515
#ifdef SSD1306_DOUBLE_BUFFER
521-
uint16_t minBoundY = 8;
522-
uint16_t maxBoundY = 0;
523-
524-
uint16_t minBoundX = 129;
525-
uint16_t maxBoundX = 0;
526-
527-
uint16_t x, y;
528-
529-
// Calculate the Y bounding box of changes
530-
// and copy buffer[pos] to buffer_back[pos];
531-
for (y = 0; y < 8; y++) {
532-
for (x = 0; x < DISPLAY_WIDTH; x++) {
533-
uint16_t pos = x + y * DISPLAY_WIDTH;
534-
if (buffer[pos] != buffer_back[pos]) {
535-
minBoundY = min(minBoundY, y);
536-
maxBoundY = max(maxBoundY, y);
537-
minBoundX = min(minBoundX, x);
538-
maxBoundX = max(maxBoundX, x);
539-
}
540-
buffer_back[pos] = buffer[pos];
516+
uint16_t minBoundY = ~0;
517+
uint16_t maxBoundY = 0;
518+
519+
uint16_t minBoundX = ~0;
520+
uint16_t maxBoundX = 0;
521+
522+
uint16_t x, y;
523+
524+
// Calculate the Y bounding box of changes
525+
// and copy buffer[pos] to buffer_back[pos];
526+
for (y = 0; y < 8; y++) {
527+
for (x = 0; x < DISPLAY_WIDTH; x++) {
528+
uint16_t pos = x + y * DISPLAY_WIDTH;
529+
if (buffer[pos] != buffer_back[pos]) {
530+
minBoundY = min(minBoundY, y);
531+
maxBoundY = max(maxBoundY, y);
532+
minBoundX = min(minBoundX, x);
533+
maxBoundX = max(maxBoundX, x);
534+
}
535+
buffer_back[pos] = buffer[pos];
536+
}
537+
yield();
541538
}
542-
yield();
543-
}
544539

545-
// If the minBoundY wasn't updated
546-
// we can savely assume that buffer_back[pos] == buffer[pos]
547-
// holdes true for all values of pos
548-
if (minBoundY == 8) return;
549-
550-
sendCommand(COLUMNADDR);
551-
sendCommand(minBoundX);
552-
sendCommand(maxBoundX);
553-
554-
sendCommand(PAGEADDR);
555-
sendCommand(minBoundY);
556-
sendCommand(maxBoundY);
557-
558-
byte k = 0;
559-
for (y = minBoundY; y <= maxBoundY; y++) {
560-
for (x = minBoundX; x <= maxBoundX; x++) {
561-
if (k == 0) {
562-
Wire.beginTransmission(this->i2cAddress);
563-
Wire.write(0x40);
540+
// If the minBoundY wasn't updated
541+
// we can savely assume that buffer_back[pos] == buffer[pos]
542+
// holdes true for all values of pos
543+
if (minBoundY == ~0) return;
544+
545+
sendCommand(COLUMNADDR);
546+
sendCommand(minBoundX);
547+
sendCommand(maxBoundX);
548+
549+
sendCommand(PAGEADDR);
550+
sendCommand(minBoundY);
551+
sendCommand(maxBoundY);
552+
553+
byte k = 0;
554+
#ifdef SSD1306_USE_BRZO
555+
uint8_t sendBuffer[17];
556+
sendBuffer[0] = 0x40;
557+
brzo_i2c_start_transaction(this->i2cAddress, BRZO_I2C_SPEED);
558+
for (y = minBoundY; y <= maxBoundY; y++) {
559+
for (x = minBoundX; x <= maxBoundX; x++) {
560+
k++;
561+
sendBuffer[k] = buffer[x + y * DISPLAY_WIDTH];
562+
if (k == 16) {
563+
brzo_i2c_write(sendBuffer, 17, true);
564+
k = 0;
565+
}
564566
}
565-
Wire.write(buffer[x + y * DISPLAY_WIDTH]);
566-
k++;
567-
if (k == 16) {
568-
Wire.endTransmission();
569-
k = 0;
567+
yield();
568+
}
569+
brzo_i2c_write(sendBuffer, k + 1, true);
570+
brzo_i2c_end_transaction();
571+
#else
572+
for (y = minBoundY; y <= maxBoundY; y++) {
573+
for (x = minBoundX; x <= maxBoundX; x++) {
574+
if (k == 0) {
575+
Wire.beginTransmission(this->i2cAddress);
576+
Wire.write(0x40);
577+
}
578+
Wire.write(buffer[x + y * DISPLAY_WIDTH]);
579+
k++;
580+
if (k == 16) {
581+
Wire.endTransmission();
582+
k = 0;
583+
}
570584
}
585+
yield();
571586
}
572-
yield();
573-
}
574587

575-
if (k != 0) {
576-
Wire.endTransmission();
577-
}
588+
if (k != 0) {
589+
Wire.endTransmission();
590+
}
591+
#endif
578592

579593
#else
580594
// No double buffering
581-
sendCommand(COLUMNADDR);
582-
sendCommand(0x0);
583-
sendCommand(0x7F);
584-
585-
sendCommand(PAGEADDR);
586-
sendCommand(0x0);
587-
sendCommand(0x7);
588-
589-
for (uint16_t i=0; i < DISPLAY_BUFFER_SIZE; i++) {
590-
Wire.beginTransmission(this->i2cAddress);
591-
Wire.write(0x40);
592-
for (uint8_t x = 0; x < 16; x++) {
593-
Wire.write(buffer[i]);
594-
i++;
595-
}
596-
i--;
597-
Wire.endTransmission();
598-
}
595+
sendCommand(COLUMNADDR);
596+
sendCommand(0x0);
597+
sendCommand(0x7F);
598+
599+
sendCommand(PAGEADDR);
600+
sendCommand(0x0);
601+
sendCommand(0x7);
602+
603+
#ifdef SSD1306_USE_BRZO
604+
uint8_t sendBuffer[17];
605+
sendBuffer[0] = 0x40;
606+
brzo_i2c_start_transaction(this->i2cAddress, BRZO_I2C_SPEED);
607+
for (uint16_t i=0; i<DISPLAY_BUFFER_SIZE; i++) {
608+
for (uint8_t x=1; x<17; x++) {
609+
sendBuffer[x] = buffer[i];
610+
i++;
611+
}
612+
i--;
613+
brzo_i2c_write(sendBuffer, 17, true);
614+
yield();
615+
}
616+
brzo_i2c_end_transaction();
617+
#else
618+
byte k = 0;
619+
for (y = minBoundY; y <= maxBoundY; y++) {
620+
for (x = minBoundX; x <= maxBoundX; x++) {
621+
if (k == 0) {
622+
Wire.beginTransmission(this->i2cAddress);
623+
Wire.write(0x40);
624+
}
625+
Wire.write(buffer[x + y * DISPLAY_WIDTH]);
626+
k++;
627+
if (k == 16) {
628+
Wire.endTransmission();
629+
k = 0;
630+
}
631+
}
632+
yield();
633+
}
634+
635+
if (k != 0) {
636+
Wire.endTransmission();
637+
}
638+
#endif
599639
#endif
600640
}
601641

602642

603643
void SSD1306::clear(void) {
604644
memset(buffer, 0, DISPLAY_BUFFER_SIZE);
645+
#ifdef SSD1306_DOUBLE_BUFFER
646+
memset(buffer_back, 1, DISPLAY_BUFFER_SIZE);
647+
#endif
605648
}
606649

607650

608651
// Private functions
609652

610653
void SSD1306::sendCommand(unsigned char com) {
611-
Wire.beginTransmission(this->i2cAddress); //begin transmitting
612-
Wire.write(0x80); //command mode
613-
Wire.write(com);
614-
Wire.endTransmission(); // stop transmitting
654+
#ifdef SSD1306_USE_BRZO
655+
uint8_t command[2] = {0x80 /* command mode */, com};
656+
brzo_i2c_start_transaction(this->i2cAddress, BRZO_I2C_SPEED);
657+
brzo_i2c_write(command, 2, true);
658+
brzo_i2c_end_transaction();
659+
#else
660+
Wire.beginTransmission(this->i2cAddress); //begin transmitting
661+
Wire.write(0x80); //command mode
662+
Wire.write(com);
663+
Wire.endTransmission(); // stop transmitting
664+
#endif
615665
}
616666

617667
void SSD1306::sendInitCommands(void) {

SSD1306.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,22 @@
2828
#pragma once
2929

3030
#include <Arduino.h>
31-
#include <Wire.h>
32-
3331
#include "SSD1306Fonts.h"
3432

33+
#ifdef SSD1306_USE_BRZO
34+
#include "brzo_i2c.h"
35+
// Brzo can handle 1Mhz in ESP8266 160Mhz mode
36+
// and 800KHz in 80Mhz mode
37+
#if F_CPU == 160000000L
38+
#define BRZO_I2C_SPEED 1000
39+
#else
40+
#define BRZO_I2C_SPEED 800
41+
#endif
42+
#else // Default use Wire
43+
#include <Wire.h>
44+
#endif
45+
46+
3547
//#define DEBUG_SSD1306(...) Serial.printf( __VA_ARGS__ )
3648

3749
#ifndef DEBUG_SSD1306

0 commit comments

Comments
 (0)