SPI display option for 4 Line Display usermod.
This commit is contained in:
		| @@ -31,6 +31,21 @@ | ||||
|   #ifndef FLD_PIN_SDA | ||||
|     #define FLD_PIN_SDA 21 | ||||
|   #endif | ||||
|   #ifndef FLD_PIN_CLOCKSPI | ||||
|     #define FLD_PIN_CLOCKSPI 18 | ||||
|   #endif | ||||
|    #ifndef FLD_PIN_DATASPI | ||||
|     #define FLD_PIN_DATASPI 23 | ||||
|   #endif    | ||||
|   #ifndef FLD_PIN_DC | ||||
|     #define FLD_PIN_DC 19 | ||||
|   #endif | ||||
|   #ifndef FLD_PIN_CS | ||||
|     #define FLD_PIN_CS 5 | ||||
|   #endif | ||||
|   #ifndef FLD_PIN_RESET | ||||
|     #define FLD_PIN_RESET 26 | ||||
|   #endif | ||||
| #else | ||||
|   #ifndef FLD_PIN_SCL | ||||
|     #define FLD_PIN_SCL 5 | ||||
| @@ -38,6 +53,21 @@ | ||||
|   #ifndef FLD_PIN_SDA | ||||
|     #define FLD_PIN_SDA 4 | ||||
|   #endif | ||||
|   #ifndef FLD_PIN_CLOCKSPI | ||||
|     #define FLD_PIN_CLOCKSPI 14 | ||||
|   #endif | ||||
|    #ifndef FLD_PIN_DATASPI | ||||
|     #define FLD_PIN_DATASPI 13 | ||||
|   #endif    | ||||
|   #ifndef FLD_PIN_DC | ||||
|     #define FLD_PIN_DC 12 | ||||
|   #endif | ||||
|     #ifndef FLD_PIN_CS | ||||
|     #define FLD_PIN_CS 15 | ||||
|   #endif | ||||
|   #ifndef FLD_PIN_RESET | ||||
|     #define FLD_PIN_RESET 16 | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| // When to time out to the clock or blank the screen | ||||
| @@ -64,11 +94,13 @@ typedef enum { | ||||
|  | ||||
| typedef enum { | ||||
|   NONE = 0, | ||||
|   SSD1306,    // U8X8_SSD1306_128X32_UNIVISION_HW_I2C | ||||
|   SH1106,     // U8X8_SH1106_128X64_WINSTAR_HW_I2C | ||||
|   SSD1306_64, // U8X8_SSD1306_128X64_NONAME_HW_I2C | ||||
|   SSD1305,    // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C | ||||
|   SSD1305_64  // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C | ||||
|   SSD1306,      // U8X8_SSD1306_128X32_UNIVISION_HW_I2C | ||||
|   SH1106,       // U8X8_SH1106_128X64_WINSTAR_HW_I2C | ||||
|   SSD1306_64,   // U8X8_SSD1306_128X64_NONAME_HW_I2C | ||||
|   SSD1305,      // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C | ||||
|   SSD1305_64,   // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C | ||||
|   SSD1306_SPI,  // U8X8_SSD1306_128X32_NONAME_HW_SPI | ||||
|   SSD1306_SPI64 // U8X8_SSD1306_128X64_NONAME_HW_SPI | ||||
| } DisplayType; | ||||
|  | ||||
| class FourLineDisplayUsermod : public Usermod { | ||||
| @@ -80,8 +112,13 @@ class FourLineDisplayUsermod : public Usermod { | ||||
|  | ||||
|     // HW interface & configuration | ||||
|     U8X8 *u8x8 = nullptr;           // pointer to U8X8 display object | ||||
|     int8_t sclPin=FLD_PIN_SCL, sdaPin=FLD_PIN_SDA;    // I2C pins for interfacing, get initialised in readFromConfig() | ||||
|     #ifndef FLD_SPI_DEFAULT | ||||
|     int8_t ioPin[5] = {FLD_PIN_SCL, FLD_PIN_SDA, -1, -1, -1};        // I2C pins: SCL, SDA | ||||
|     DisplayType type = SSD1306;     // display type | ||||
|     #else | ||||
|     int8_t ioPin[5] = {FLD_PIN_CLOCKSPI, FLD_PIN_DATASPI, FLD_PIN_CS, FLD_PIN_DC, FLD_PIN_RESET}; // SPI pins: CLK, MOSI, CS, DC, RST | ||||
|     DisplayType type = SSD1306_SPI; // display type | ||||
|     #endif | ||||
|     bool flip = false;              // flip display 180° | ||||
|     uint8_t contrast = 10;          // screen contrast | ||||
|     uint8_t lineHeight = 1;         // 1 row or 2 rows | ||||
| @@ -131,53 +168,74 @@ class FourLineDisplayUsermod : public Usermod { | ||||
|     // network here | ||||
|     void setup() { | ||||
|       if (type == NONE) return; | ||||
|       if (!pinManager.allocatePin(sclPin)) { sclPin = -1; type = NONE; return;} | ||||
|       if (!pinManager.allocatePin(sdaPin)) { pinManager.deallocatePin(sclPin); sclPin = sdaPin = -1; type = NONE; return; } | ||||
|       bool allocated = false; | ||||
|       byte i; | ||||
|       if (type == SSD1306_SPI || type == SSD1306_SPI64) { | ||||
|         for (i=0; i<5; i++) if (!pinManager.allocatePin(ioPin[i])) { allocated=true; break; } | ||||
|         if (i<5 && allocated) { for (byte i=0; i<5; i++) pinManager.deallocatePin(ioPin[i]); type=NONE; return; } | ||||
|       } else { | ||||
|         for (i=0; i<2; i++) if (!pinManager.allocatePin(ioPin[i])) { allocated=true; break; } | ||||
|         if (i<2 && allocated) { for (byte i=0; i<5; i++) pinManager.deallocatePin(ioPin[i]); type=NONE; return; } | ||||
|       } | ||||
|       DEBUG_PRINTLN(F("Allocating display.")); | ||||
|       switch (type) { | ||||
|         case SSD1306: | ||||
|           #ifdef ESP8266 | ||||
|           if (!(sclPin==5 && sdaPin==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset | ||||
|           if (!(ioPin[0]==5 && ioPin[1]==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset | ||||
|           else | ||||
|           #endif | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA | ||||
|           lineHeight = 1; | ||||
|           break; | ||||
|         case SH1106: | ||||
|           #ifdef ESP8266 | ||||
|           if (!(sclPin==5 && sdaPin==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset | ||||
|           if (!(ioPin[0]==5 && ioPin[1]==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset | ||||
|           else | ||||
|           #endif | ||||
|             u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA | ||||
|             u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA | ||||
|           lineHeight = 2; | ||||
|           break; | ||||
|         case SSD1306_64: | ||||
|           #ifdef ESP8266 | ||||
|           if (!(sclPin==5 && sdaPin==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset | ||||
|           if (!(ioPin[0]==5 && ioPin[1]==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset | ||||
|           else | ||||
|           #endif | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA | ||||
|           lineHeight = 2; | ||||
|           break; | ||||
|         case SSD1305: | ||||
|           #ifdef ESP8266 | ||||
|           if (!(sclPin==5 && sdaPin==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_NONAME_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset | ||||
|           if (!(ioPin[0]==5 && ioPin[1]==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset | ||||
|           else | ||||
|           #endif | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA | ||||
|           lineHeight = 1; | ||||
|           break; | ||||
|         case SSD1305_64: | ||||
|           #ifdef ESP8266 | ||||
|           if (!(sclPin==5 && sdaPin==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_SW_I2C(sclPin, sdaPin); // SCL, SDA, reset | ||||
|           if (!(ioPin[0]==5 && ioPin[1]==4)) | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset | ||||
|           else | ||||
|           #endif | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA | ||||
|           lineHeight = 2; | ||||
|           break; | ||||
|         case SSD1306_SPI: | ||||
|           if (!(ioPin[0]==FLD_PIN_CLOCKSPI && ioPin[1]==FLD_PIN_DATASPI)) // if not overridden these sould be HW accellerated | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]); | ||||
|           else | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset | ||||
|           lineHeight = 1; | ||||
|           break; | ||||
|         case SSD1306_SPI64: | ||||
|           if (!(ioPin[0]==FLD_PIN_CLOCKSPI && ioPin[1]==FLD_PIN_DATASPI)) // if not overridden these sould be HW accellerated | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]); | ||||
|           else | ||||
|             u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset | ||||
|           lineHeight = 2; | ||||
|           break; | ||||
|         default: | ||||
| @@ -605,10 +663,10 @@ class FourLineDisplayUsermod : public Usermod { | ||||
|      * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings! | ||||
|      */ | ||||
|     void addToConfig(JsonObject& root) { | ||||
|       JsonObject top    = root.createNestedObject(FPSTR(_name)); | ||||
|       JsonArray i2c_pin = top.createNestedArray("pin"); | ||||
|       i2c_pin.add(sclPin); | ||||
|       i2c_pin.add(sdaPin); | ||||
|       JsonObject top   = root.createNestedObject(FPSTR(_name)); | ||||
|       JsonArray io_pin = top.createNestedArray("pin"); | ||||
|       for (byte i=0; i<5; i++) io_pin.add(ioPin[i]); | ||||
|       top["help4PinTypes"]       = F("Clk,Data,CS,DC,RST"); // help for Settings page | ||||
|       top["type"]                = type; | ||||
|       top[FPSTR(_flip)]          = (bool) flip; | ||||
|       top[FPSTR(_contrast)]      = contrast; | ||||
| @@ -630,8 +688,7 @@ class FourLineDisplayUsermod : public Usermod { | ||||
|     bool readFromConfig(JsonObject& root) { | ||||
|       bool needsRedraw    = false; | ||||
|       DisplayType newType = type; | ||||
|       int8_t newScl       = sclPin; | ||||
|       int8_t newSda       = sdaPin; | ||||
|       int8_t newPin[5]; for (byte i=0; i<5; i++) newPin[i] = ioPin[i]; | ||||
|  | ||||
|       JsonObject top = root[FPSTR(_name)]; | ||||
|       if (top.isNull()) { | ||||
| @@ -640,9 +697,8 @@ class FourLineDisplayUsermod : public Usermod { | ||||
|         return false; | ||||
|       } | ||||
|  | ||||
|       newScl        = top["pin"][0] | newScl; | ||||
|       newSda        = top["pin"][1] | newSda; | ||||
|       newType       = top["type"] | newType; | ||||
|       for (byte i=0; i<5; i++) newPin[i] = top["pin"][i] | ioPin[i]; | ||||
|       flip          = top[FPSTR(_flip)] | flip; | ||||
|       contrast      = top[FPSTR(_contrast)] | contrast; | ||||
|       refreshRate   = (top[FPSTR(_refreshRate)] | refreshRate/1000) * 1000; | ||||
| @@ -653,20 +709,21 @@ class FourLineDisplayUsermod : public Usermod { | ||||
|       DEBUG_PRINT(FPSTR(_name)); | ||||
|       if (!initDone) { | ||||
|         // first run: reading from cfg.json | ||||
|         sclPin = newScl; | ||||
|         sdaPin = newSda; | ||||
|         for (byte i=0; i<5; i++) ioPin[i] = newPin[i]; | ||||
|         type = newType; | ||||
|         DEBUG_PRINTLN(F(" config loaded.")); | ||||
|       } else { | ||||
|         DEBUG_PRINTLN(F(" config (re)loaded.")); | ||||
|         // changing parameters from settings page | ||||
|         if (sclPin!=newScl || sdaPin!=newSda || type!=newType) { | ||||
|         bool pinsChanged = false; | ||||
|         for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; } | ||||
|         if (pinsChanged || type!=newType) { | ||||
|           if (type != NONE) delete (static_cast<U8X8*>(u8x8)); | ||||
|           pinManager.deallocatePin(sclPin); | ||||
|           pinManager.deallocatePin(sdaPin); | ||||
|           sclPin = newScl; | ||||
|           sdaPin = newSda; | ||||
|           if (newScl<0 || newSda<0) { | ||||
|           for (byte i=0; i<5; i++) { | ||||
|             if (ioPin[i]>=0) pinManager.deallocatePin(ioPin[i]); | ||||
|             ioPin[i] = newPin[i]; | ||||
|           } | ||||
|           if (ioPin[0]<0 || ioPin[1]<0) { // data & clock must be > -1 | ||||
|             type = NONE; | ||||
|             return true; | ||||
|           } else type = newType; | ||||
| @@ -678,7 +735,7 @@ class FourLineDisplayUsermod : public Usermod { | ||||
|         if (needsRedraw && !wakeDisplay()) redraw(true); | ||||
|       } | ||||
|       // use "return !top["newestParameter"].isNull();" when updating Usermod with new features | ||||
|       return true; | ||||
|       return !(top["pin"][2]).isNull(); | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Blaz Kristan
					Blaz Kristan