kopia lustrzana https://github.com/Max-Plastix/tbeam-helium-mapper
Autodetect SSD1306 vs SH1106 OLED type
rodzic
b90680746b
commit
2749d67de6
|
@ -169,11 +169,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#endif
|
||||
|
||||
#define RED_LED 4 // GPIO4 on T-Beam v1.1
|
||||
// -----------------------------------------------------------------------------
|
||||
// OLED
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define SSD1306_ADDRESS 0x3C
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GPS
|
||||
|
|
|
@ -99,8 +99,9 @@ float min_dist_moved = MIN_DIST;
|
|||
AXP20X_Class axp;
|
||||
bool pmu_irq = false; // true when PMU IRQ pending
|
||||
|
||||
bool ssd1306_found = false;
|
||||
bool oled_found = false;
|
||||
bool axp192_found = false;
|
||||
uint8_t oled_addr = 0; // i2c address of OLED controller
|
||||
|
||||
bool packetQueued;
|
||||
bool isJoined = false;
|
||||
|
@ -498,7 +499,7 @@ void lora_msg_callback(uint8_t message) {
|
|||
void scanI2Cdevice(void) {
|
||||
byte err, addr;
|
||||
int nDevices = 0;
|
||||
for (addr = 1; addr < 127; addr++) {
|
||||
for (addr = 1; addr < 0x7F; addr++) {
|
||||
Wire.beginTransmission(addr);
|
||||
err = Wire.endTransmission();
|
||||
if (err == 0) {
|
||||
|
@ -511,9 +512,10 @@ void scanI2Cdevice(void) {
|
|||
#endif
|
||||
nDevices++;
|
||||
|
||||
if (addr == SSD1306_ADDRESS) {
|
||||
ssd1306_found = true;
|
||||
Serial.println("SSD1306 OLED display");
|
||||
if (addr == 0x3C || addr == 0x78 || addr == 0x7E) {
|
||||
oled_addr = addr;
|
||||
oled_found = true;
|
||||
Serial.printf("OLED at %02X\n", oled_addr);
|
||||
}
|
||||
if (addr == AXP192_SLAVE_ADDRESS) {
|
||||
axp192_found = true;
|
||||
|
@ -720,11 +722,11 @@ void setup() {
|
|||
// Don't init display if we don't have one or we are waking headless due to a
|
||||
// timer event
|
||||
if (0 && wakeCause == ESP_SLEEP_WAKEUP_TIMER)
|
||||
ssd1306_found = false; // forget we even have the hardware
|
||||
oled_found = false; // forget we even have the hardware
|
||||
|
||||
// This creates the display object, so if we don't call it.. all screen ops are do-nothing.
|
||||
if (ssd1306_found)
|
||||
screen_setup();
|
||||
if (oled_found)
|
||||
screen_setup(oled_addr);
|
||||
is_screen_on = true;
|
||||
|
||||
// GPS power on, so it has time to setttle.
|
||||
|
@ -794,7 +796,7 @@ void low_power_sleep(uint32_t seconds) {
|
|||
if (axp192_found) {
|
||||
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS power
|
||||
// axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); // OLED power
|
||||
// if (ssd1306_found)
|
||||
// if (oled_found)
|
||||
// screen_setup();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <Wire.h>
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
#include "SH1106Wire.h"
|
||||
#include "SSD1306Wire.h"
|
||||
#include "configuration.h"
|
||||
#include "credentials.h"
|
||||
|
@ -34,9 +35,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#define SCREEN_HEADER_HEIGHT 24
|
||||
|
||||
SSD1306Wire *display;
|
||||
OLEDDisplay *display;
|
||||
uint8_t _screen_line = SCREEN_HEADER_HEIGHT - 1;
|
||||
|
||||
enum display_types { DISPLAY_UNKNOWN, DISPLAY_SSD1306, DISPLAY_SH1106 };
|
||||
enum display_types display_type = DISPLAY_UNKNOWN;
|
||||
|
||||
void screen_show_logo() {
|
||||
if (!display)
|
||||
return;
|
||||
|
@ -99,9 +103,77 @@ void screen_update() {
|
|||
display->display();
|
||||
}
|
||||
|
||||
void screen_setup() {
|
||||
/*
|
||||
* The SSD1306 and SH1106 controllers are almost the same, but different.
|
||||
* Most importantly here, the SH1106 allows reading from the frame buffer, while the SSD1306 does not.
|
||||
* We exploit this by writing two bytes and reading them back. A mismatch probably means SSD1306.
|
||||
* Probably.
|
||||
*/
|
||||
enum display_types display_get_type(uint8_t id) {
|
||||
uint8_t err;
|
||||
uint8_t b1, b2;
|
||||
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
Wire.setClock(7000000);
|
||||
|
||||
Wire.beginTransmission(id);
|
||||
uint8_t a[] = {0, 0, 0x10, 0xB0};
|
||||
Wire.write(a, sizeof(a));
|
||||
if ((err = Wire.endTransmission(false)) != 0) {
|
||||
Serial.printf("err=%d EndTransmission=%d(%s)", err, Wire.lastError(), Wire.getErrorText(Wire.lastError()));
|
||||
return DISPLAY_UNKNOWN;
|
||||
}
|
||||
|
||||
Wire.beginTransmission(id);
|
||||
uint8_t b[] = {0x40, 'M', 'P'};
|
||||
Wire.write(b, sizeof(b));
|
||||
if ((err = Wire.endTransmission(false)) != 0) {
|
||||
Serial.printf("err=%d EndTransmission=%d(%s)", err, Wire.lastError(), Wire.getErrorText(Wire.lastError()));
|
||||
return DISPLAY_UNKNOWN;
|
||||
}
|
||||
|
||||
Wire.beginTransmission(id);
|
||||
uint8_t c[] = {0, 0, 0x10};
|
||||
Wire.write(c, sizeof(c));
|
||||
if ((err = Wire.endTransmission(false)) != 0) {
|
||||
Serial.printf("err=%d EndTransmission=%d(%s)", err, Wire.lastError(), Wire.getErrorText(Wire.lastError()));
|
||||
return DISPLAY_UNKNOWN;
|
||||
}
|
||||
|
||||
Wire.beginTransmission(id);
|
||||
Wire.write(0x40);
|
||||
if ((err = Wire.endTransmission(false)) != 0) {
|
||||
Serial.printf("err=%d EndTransmission=%d(%s)", err, Wire.lastError(), Wire.getErrorText(Wire.lastError()));
|
||||
return DISPLAY_UNKNOWN;
|
||||
}
|
||||
|
||||
err = Wire.requestFrom((int)id, (int)3, (int)1);
|
||||
if (err != 3) {
|
||||
return DISPLAY_UNKNOWN;
|
||||
}
|
||||
Wire.read(); // Discard
|
||||
b1 = Wire.read();
|
||||
b2 = Wire.read();
|
||||
Wire.endTransmission();
|
||||
|
||||
if (b1 == 'M' && b2 == 'P')
|
||||
return DISPLAY_SH1106;
|
||||
else
|
||||
return DISPLAY_SSD1306;
|
||||
}
|
||||
|
||||
void screen_setup(uint8_t addr) {
|
||||
/* Attempt to determine which kind of display we're dealing with */
|
||||
if (display_type == DISPLAY_UNKNOWN)
|
||||
display_type = display_get_type(addr);
|
||||
|
||||
// Display instance
|
||||
display = new SSD1306Wire(SSD1306_ADDRESS, I2C_SDA, I2C_SCL);
|
||||
if (display_type == DISPLAY_SSD1306)
|
||||
display = new SSD1306Wire(addr, I2C_SDA, I2C_SCL);
|
||||
else if (display_type == DISPLAY_SH1106)
|
||||
display = new SH1106Wire(addr, I2C_SDA, I2C_SCL);
|
||||
else
|
||||
return;
|
||||
display->init();
|
||||
display->flipScreenVertically();
|
||||
display->setFont(Custom_ArialMT_Plain_10);
|
||||
|
|
|
@ -16,5 +16,5 @@ void screen_off(void);
|
|||
void screen_on(void);
|
||||
|
||||
void screen_show_logo(void);
|
||||
void screen_setup(void);
|
||||
void screen_setup(uint8_t addr);
|
||||
void screen_end(void);
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"initializer_list": "cpp"
|
||||
"initializer_list": "cpp",
|
||||
"*.tcc": "cpp"
|
||||
}
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue