diff --git a/README.md b/README.md index cd3873f..ad0f922 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,11 @@ Work is in progress... --- ## Version history +#### v0.9.710 +- rewritten ILI9225 display driver: now it supports framebuffer like the others and is more stable 👍🏻 +- fixed clock update bug when changing timezone in settings +- bug/warnings fixes + #### v0.9.702 - fixed compilation error for Nokia5110 displays diff --git a/yoRadio/src/Adafruit_ILI9225/Adafruit_ILI9225.cpp b/yoRadio/src/Adafruit_ILI9225/Adafruit_ILI9225.cpp new file mode 100644 index 0000000..e61c688 --- /dev/null +++ b/yoRadio/src/Adafruit_ILI9225/Adafruit_ILI9225.cpp @@ -0,0 +1,272 @@ +#include "../core/options.h" +#if DSP_MODEL==DSP_ILI9225 + +#include "Adafruit_ILI9225.h" + +#define SPI_DEFAULT_FREQ 24000000 + +/**************************************************************************/ +/*! + @brief Instantiate Adafruit ILI9225 driver with software SPI + @param cs Chip select pin # + @param dc Data/Command pin # + @param mosi SPI MOSI pin # + @param sclk SPI Clock pin # + @param rst Reset pin # (optional, pass -1 if unused) + @param miso SPI MISO pin # (optional, pass -1 if unused) +*/ +/**************************************************************************/ +Adafruit_ILI9225::Adafruit_ILI9225(int8_t cs, int8_t dc, int8_t mosi, + int8_t sclk, int8_t rst, int8_t miso) + : Adafruit_SPITFT(ILI9225_TFTWIDTH, ILI9225_TFTHEIGHT, cs, dc, mosi, sclk, + rst, miso) {} + +/**************************************************************************/ +/*! + @brief Instantiate Adafruit ILI9225 driver with hardware SPI using the + default SPI peripheral. + @param cs Chip select pin # (OK to pass -1 if CS tied to GND). + @param dc Data/Command pin # (required). + @param rst Reset pin # (optional, pass -1 if unused). +*/ +/**************************************************************************/ +Adafruit_ILI9225::Adafruit_ILI9225(int8_t cs, int8_t dc, int8_t rst) + : Adafruit_SPITFT(ILI9225_TFTWIDTH, ILI9225_TFTHEIGHT, cs, dc, rst) {} + +/**************************************************************************/ +/*! + @brief Instantiate Adafruit ILI9225 driver with hardware SPI using + a specific SPI peripheral (not necessarily default). + @param spiClass Pointer to SPI peripheral (e.g. &SPI or &SPI1). + @param dc Data/Command pin # (required). + @param cs Chip select pin # (optional, pass -1 if unused and + CS is tied to GND). + @param rst Reset pin # (optional, pass -1 if unused). +*/ +/**************************************************************************/ +Adafruit_ILI9225::Adafruit_ILI9225(SPIClass *spiClass, int8_t dc, int8_t cs, + int8_t rst) + : Adafruit_SPITFT(ILI9225_TFTWIDTH, ILI9225_TFTHEIGHT, spiClass, cs, dc, + rst) {} + +/**************************************************************************/ +/*! + @brief Instantiate Adafruit ILI9225 driver using parallel interface. + @param busWidth If tft16 (enumeration in Adafruit_SPITFT.h), is a + 16-bit interface, else 8-bit. + @param d0 Data pin 0 (MUST be a byte- or word-aligned LSB of a + PORT register -- pins 1-n are extrapolated from this). + @param wr Write strobe pin # (required). + @param dc Data/Command pin # (required). + @param cs Chip select pin # (optional, pass -1 if unused and CS + is tied to GND). + @param rst Reset pin # (optional, pass -1 if unused). + @param rd Read strobe pin # (optional, pass -1 if unused). +*/ +/**************************************************************************/ +Adafruit_ILI9225::Adafruit_ILI9225(tftBusWidth busWidth, int8_t d0, int8_t wr, + int8_t dc, int8_t cs, int8_t rst, int8_t rd) + : Adafruit_SPITFT(ILI9225_TFTWIDTH, ILI9225_TFTHEIGHT, busWidth, d0, wr, dc, + cs, rst, rd) {} + +static const uint8_t PROGMEM initcmd[] = { + ILI9225_POWER_CTRL1, 0x00, 0x00, + ILI9225_POWER_CTRL2, 0x00, 0x00, + ILI9225_POWER_CTRL3, 0x00, 0x00, + ILI9225_POWER_CTRL4, 0x00, 0x00, + ILI9225_POWER_CTRL5, 0x00, 0x00, + ILI9225_DELAY, 40, + ILI9225_POWER_CTRL2, 0x00, 0x18, + ILI9225_POWER_CTRL3, 0x61, 0x21, + ILI9225_POWER_CTRL4, 0x00, 0x6F, + ILI9225_POWER_CTRL5, 0x49, 0x5F, + ILI9225_POWER_CTRL1, 0x08, 0x00, + ILI9225_DELAY, 10, + ILI9225_POWER_CTRL2, 0x10, 0x3B, + ILI9225_DELAY, 50, + ILI9225_DRIVER_OUTPUT_CTRL, 0x01, 0x1C, + ILI9225_LCD_AC_DRIVING_CTRL, 0x01, 0x00, + ILI9225_ENTRY_MODE, 0x10, 0x38, + ILI9225_DISP_CTRL1, 0x00, 0x00, + ILI9225_BLANK_PERIOD_CTRL1, 0x08, 0x08, + ILI9225_FRAME_CYCLE_CTRL, 0x11, 0x00, + ILI9225_INTERFACE_CTRL, 0x00, 0x00, + ILI9225_OSC_CTRL, 0x0D, 0x01, + ILI9225_VCI_RECYCLING, 0x00, 0x20, + ILI9225_RAM_ADDR_SET1, 0x00, 0x00, + ILI9225_RAM_ADDR_SET2, 0x00, 0x00, + ILI9225_GATE_SCAN_CTRL, 0x00, 0x00, + ILI9225_VERTICAL_SCROLL_CTRL1, 0x00, 0xDB, + ILI9225_VERTICAL_SCROLL_CTRL2, 0x00, 0x00, + ILI9225_VERTICAL_SCROLL_CTRL3, 0x00, 0x00, + ILI9225_PARTIAL_DRIVING_POS1, 0x00, 0xDB, + ILI9225_PARTIAL_DRIVING_POS2, 0x00, 0x00, + ILI9225_HORIZONTAL_WINDOW_ADDR1, 0x00, 0xAF, + ILI9225_HORIZONTAL_WINDOW_ADDR2, 0x00, 0x00, + ILI9225_VERTICAL_WINDOW_ADDR1, 0x00, 0xDB, + ILI9225_VERTICAL_WINDOW_ADDR2, 0x00, 0x00, + ILI9225_GAMMA_CTRL1, 0x00, 0x00, + ILI9225_GAMMA_CTRL2, 0x08, 0x08, + ILI9225_GAMMA_CTRL3, 0x08, 0x0A, + ILI9225_GAMMA_CTRL4, 0x00, 0x0A, + ILI9225_GAMMA_CTRL5, 0x0A, 0x08, + ILI9225_GAMMA_CTRL6, 0x08, 0x08, + ILI9225_GAMMA_CTRL7, 0x00, 0x00, + ILI9225_GAMMA_CTRL8, 0x0A, 0x00, + ILI9225_GAMMA_CTRL9, 0x07, 0x10, + ILI9225_GAMMA_CTRL10, 0x07, 0x10, + ILI9225_DISP_CTRL1, 0x00, 0x12, + ILI9225_DELAY, 50, + ILI9225_DISP_CTRL1, 0x10, 0x17, + 0x00 // the end +}; + +/**************************************************************************/ +/*! + @brief Initialize ILI9225 chip + Connects to the ILI9225 over SPI and sends initialization procedure commands + @param freq Desired SPI clock frequency +*/ +/**************************************************************************/ +void Adafruit_ILI9225::begin(uint32_t freq) { + + if (!freq) + freq = SPI_DEFAULT_FREQ; + initSPI(freq); + SPI_CS_HIGH(); + uint8_t cmd; + const uint8_t *addr = initcmd; + + while ((cmd = pgm_read_byte(addr++)) > 0) { + if (cmd == ILI9225_DELAY) { + delay(pgm_read_byte(addr++)); + } else { + uint8_t hi = pgm_read_byte(addr++); + uint8_t lo = pgm_read_byte(addr++); + uint8_t data[2] = { hi, lo }; + sendCommand(cmd, data, 2); + } + } + _width = ILI9225_TFTWIDTH; + _height = ILI9225_TFTHEIGHT; +} + +/**************************************************************************/ +/*! + @brief Set origin of (0,0) and orientation of TFT display + @param m The index for rotation, from 0-3 inclusive +*/ +/**************************************************************************/ +void Adafruit_ILI9225::setRotation(uint8_t m) { + rotation = m % 4; // can't be higher than 3 + switch (rotation) { + case 0: + _width = ILI9225_TFTWIDTH; + _height = ILI9225_TFTHEIGHT; + _entry = 0x1030; + break; + case 1: + _width = ILI9225_TFTHEIGHT; + _height = ILI9225_TFTWIDTH; + _entry = 0x1028; + break; + case 2: + _width = ILI9225_TFTWIDTH; + _height = ILI9225_TFTHEIGHT; + _entry = 0x1000; + break; + case 3: + _width = ILI9225_TFTHEIGHT; + _height = ILI9225_TFTWIDTH; + _entry = 0x1038; + break; + } +} + +void Adafruit_ILI9225::_swap(uint16_t &a, uint16_t &b) { + uint16_t w = a; + a = b; + b = w; +} + +void Adafruit_ILI9225::_orientCoordinates(uint16_t &x1, uint16_t &y1) { + switch (rotation) { + case 0: + break; + case 1: + y1 = _height - y1 - 1; + _swap(x1, y1); + break; + case 2: + x1 = _width - x1 - 1; + y1 = _height - y1 - 1; + break; + case 3: + x1 = _width - x1 - 1; + _swap(x1, y1); + break; + } +} + +void Adafruit_ILI9225::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { + uint16_t x0=x, x1=x + w - 1, y0=y, y1=y + h - 1; + x0 = min( x0, (uint16_t) (_width-1) ); + x1 = min( x1, (uint16_t) (_width-1) ); + y0 = min( y0, (uint16_t) (_height-1) ); + y1 = min( y1, (uint16_t) (_height-1) ); + _orientCoordinates(x0, y0); + _orientCoordinates(x1, y1); + + if (x1 0 ) mode = modeTab[rotation-1][mode]; + _writeRegister(ILI9225_ENTRY_MODE, 0x1000 | ( mode<<3) ); + _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1,x1); + _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2,x0); + _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1,y1); + _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2,y0); + switch ( mode>>1 ) { + case 0: + _writeRegister(ILI9225_RAM_ADDR_SET1,x1); + _writeRegister(ILI9225_RAM_ADDR_SET2,y1); + break; + case 1: + _writeRegister(ILI9225_RAM_ADDR_SET1,x0); + _writeRegister(ILI9225_RAM_ADDR_SET2,y1); + break; + case 2: + _writeRegister(ILI9225_RAM_ADDR_SET1,x1); + _writeRegister(ILI9225_RAM_ADDR_SET2,y0); + break; + case 3: + _writeRegister(ILI9225_RAM_ADDR_SET1,x0); + _writeRegister(ILI9225_RAM_ADDR_SET2,y0); + break; + } + writeCommand(ILI9225_GRAM_DATA_REG); +} + +void Adafruit_ILI9225::invertDisplay(bool invert) { + _invertmode = invert?0x1013:0x1017; + startWrite(); + _writeRegister(ILI9225_DISP_CTRL1, _invertmode); + endWrite(); +} + +void Adafruit_ILI9225::setDisplay(bool flag) { + startWrite(); + if (flag) { + _writeRegister(ILI9225_POWER_CTRL1, 0x0000); + delay(50); + _writeRegister(ILI9225_DISP_CTRL1, _invertmode); + } else { + _writeRegister(ILI9225_DISP_CTRL1, 0x0000); + delay(50); + _writeRegister(ILI9225_POWER_CTRL1, 0x0003); + } + endWrite(); +} + +#endif diff --git a/yoRadio/src/Adafruit_ILI9225/Adafruit_ILI9225.h b/yoRadio/src/Adafruit_ILI9225/Adafruit_ILI9225.h new file mode 100644 index 0000000..37dafe3 --- /dev/null +++ b/yoRadio/src/Adafruit_ILI9225/Adafruit_ILI9225.h @@ -0,0 +1,109 @@ +#ifndef _ADAFRUIT_ILI9225H_ +#define _ADAFRUIT_ILI9225H_ + +#include "Adafruit_GFX.h" +#include "Arduino.h" +#include "Print.h" +#include +#include +/******************************/ +#define ILI9225_DELAY (0xDEu) +#define ILI9225_DRIVER_OUTPUT_CTRL (0x01u) // Driver Output Control +#define ILI9225_LCD_AC_DRIVING_CTRL (0x02u) // LCD AC Driving Control +#define ILI9225_ENTRY_MODE (0x03u) // Entry Mode +#define ILI9225_DISP_CTRL1 (0x07u) // Display Control 1 +#define ILI9225_BLANK_PERIOD_CTRL1 (0x08u) // Blank Period Control +#define ILI9225_FRAME_CYCLE_CTRL (0x0Bu) // Frame Cycle Control +#define ILI9225_INTERFACE_CTRL (0x0Cu) // Interface Control +#define ILI9225_OSC_CTRL (0x0Fu) // Osc Control +#define ILI9225_POWER_CTRL1 (0x10u) // Power Control 1 +#define ILI9225_POWER_CTRL2 (0x11u) // Power Control 2 +#define ILI9225_POWER_CTRL3 (0x12u) // Power Control 3 +#define ILI9225_POWER_CTRL4 (0x13u) // Power Control 4 +#define ILI9225_POWER_CTRL5 (0x14u) // Power Control 5 +#define ILI9225_VCI_RECYCLING (0x15u) // VCI Recycling +#define ILI9225_RAM_ADDR_SET1 (0x20u) // Horizontal GRAM Address Set +#define ILI9225_RAM_ADDR_SET2 (0x21u) // Vertical GRAM Address Set +#define ILI9225_GRAM_DATA_REG (0x22u) // GRAM Data Register +#define ILI9225_GATE_SCAN_CTRL (0x30u) // Gate Scan Control Register +#define ILI9225_VERTICAL_SCROLL_CTRL1 (0x31u) // Vertical Scroll Control 1 Register +#define ILI9225_VERTICAL_SCROLL_CTRL2 (0x32u) // Vertical Scroll Control 2 Register +#define ILI9225_VERTICAL_SCROLL_CTRL3 (0x33u) // Vertical Scroll Control 3 Register +#define ILI9225_PARTIAL_DRIVING_POS1 (0x34u) // Partial Driving Position 1 Register +#define ILI9225_PARTIAL_DRIVING_POS2 (0x35u) // Partial Driving Position 2 Register +#define ILI9225_HORIZONTAL_WINDOW_ADDR1 (0x36u) // Horizontal Address Start Position +#define ILI9225_HORIZONTAL_WINDOW_ADDR2 (0x37u) // Horizontal Address End Position +#define ILI9225_VERTICAL_WINDOW_ADDR1 (0x38u) // Vertical Address Start Position +#define ILI9225_VERTICAL_WINDOW_ADDR2 (0x39u) // Vertical Address End Position +#define ILI9225_GAMMA_CTRL1 (0x50u) // Gamma Control 1 +#define ILI9225_GAMMA_CTRL2 (0x51u) // Gamma Control 2 +#define ILI9225_GAMMA_CTRL3 (0x52u) // Gamma Control 3 +#define ILI9225_GAMMA_CTRL4 (0x53u) // Gamma Control 4 +#define ILI9225_GAMMA_CTRL5 (0x54u) // Gamma Control 5 +#define ILI9225_GAMMA_CTRL6 (0x55u) // Gamma Control 6 +#define ILI9225_GAMMA_CTRL7 (0x56u) // Gamma Control 7 +#define ILI9225_GAMMA_CTRL8 (0x57u) // Gamma Control 8 +#define ILI9225_GAMMA_CTRL9 (0x58u) // Gamma Control 9 +#define ILI9225_GAMMA_CTRL10 (0x59u) // Gamma Control 10 + +#define ILI9225C_INVOFF 0x20 +#define ILI9225C_INVON 0x21 +/********************************************/ +#define ILI9225_TFTWIDTH 176 ///< ILI9225 max TFT width +#define ILI9225_TFTHEIGHT 220 ///< ILI9225 max TFT height +// Color definitions +#define ILI9225_BLACK 0x0000 ///< 0, 0, 0 +#define ILI9225_NAVY 0x000F ///< 0, 0, 123 +#define ILI9225_DARKGREEN 0x03E0 ///< 0, 125, 0 +#define ILI9225_DARKCYAN 0x03EF ///< 0, 125, 123 +#define ILI9225_MAROON 0x7800 ///< 123, 0, 0 +#define ILI9225_PURPLE 0x780F ///< 123, 0, 123 +#define ILI9225_OLIVE 0x7BE0 ///< 123, 125, 0 +#define ILI9225_LIGHTGREY 0xC618 ///< 198, 195, 198 +#define ILI9225_DARKGREY 0x7BEF ///< 123, 125, 123 +#define ILI9225_BLUE 0x001F ///< 0, 0, 255 +#define ILI9225_GREEN 0x07E0 ///< 0, 255, 0 +#define ILI9225_CYAN 0x07FF ///< 0, 255, 255 +#define ILI9225_RED 0xF800 ///< 255, 0, 0 +#define ILI9225_MAGENTA 0xF81F ///< 255, 0, 255 +#define ILI9225_YELLOW 0xFFE0 ///< 255, 255, 0 +#define ILI9225_WHITE 0xFFFF ///< 255, 255, 255 +#define ILI9225_ORANGE 0xFD20 ///< 255, 165, 0 +#define ILI9225_GREENYELLOW 0xAFE5 ///< 173, 255, 41 +#define ILI9225_PINK 0xFC18 ///< 255, 130, 198 + +enum autoIncMode_t { R2L_BottomUp, BottomUp_R2L, L2R_BottomUp, BottomUp_L2R, R2L_TopDown, TopDown_R2L, L2R_TopDown, TopDown_L2R }; + +/**************************************************************************/ +/*! +@brief Class to manage hardware interface with ILI9225 chipset (also seems to +work with ILI9340) +*/ +/**************************************************************************/ + +class Adafruit_ILI9225 : public Adafruit_SPITFT { +public: + Adafruit_ILI9225(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK, int8_t _RST = -1, int8_t _MISO = -1); + Adafruit_ILI9225(int8_t _CS, int8_t _DC, int8_t _RST = -1); + Adafruit_ILI9225(SPIClass *spiClass, int8_t dc, int8_t cs = -1, int8_t rst = -1); + Adafruit_ILI9225(tftBusWidth busWidth, int8_t d0, int8_t wr, int8_t dc, int8_t cs = -1, int8_t rst = -1, int8_t rd = -1); + void begin(uint32_t freq = 0); + void setRotation(uint8_t r); + void invertDisplay(bool i); + void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h); + void setDisplay(bool flag); +private: + // Corresponding modes if orientation changed: + const autoIncMode_t modeTab [3][8] = { + // { R2L_BottomUp, BottomUp_R2L, L2R_BottomUp, BottomUp_L2R, R2L_TopDown, TopDown_R2L, L2R_TopDown, TopDown_L2R }// + /* 90° */ { BottomUp_L2R, L2R_BottomUp, TopDown_L2R, L2R_TopDown, BottomUp_R2L, R2L_BottomUp, TopDown_R2L, R2L_TopDown }, + /*180° */ { L2R_TopDown , TopDown_L2R, R2L_TopDown, TopDown_R2L, L2R_BottomUp, BottomUp_L2R, R2L_BottomUp, BottomUp_R2L}, + /*270° */ { TopDown_R2L , R2L_TopDown, BottomUp_R2L, R2L_BottomUp, TopDown_L2R, L2R_TopDown, BottomUp_L2R, L2R_BottomUp} + }; + uint16_t _entry, _invertmode; + void _writeRegister(uint16_t reg, uint16_t data) { writeCommand(reg); SPI_WRITE16(data); } + void _orientCoordinates(uint16_t &x1, uint16_t &y1); + void _swap(uint16_t &a, uint16_t &b); +}; + +#endif // _ADAFRUIT_ILI9225H diff --git a/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.cpp b/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.cpp deleted file mode 100644 index 14b32eb..0000000 --- a/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.cpp +++ /dev/null @@ -1,1483 +0,0 @@ -#include "../core/options.h" -#if DSP_MODEL==DSP_ILI9225 -#include "TFT_22_ILI9225Fix.h" - -//#define DEBUG -#ifdef DEBUG - #define DB_PRINT( ... ) { char dbgbuf[60]; sprintf( dbgbuf, __VA_ARGS__ ) ; Serial.println( dbgbuf ); } -#else - #define DB_PRINT( ... ) ; -#endif - -#ifndef ARDUINO_STM32_FEATHER - #include "pins_arduino.h" - #ifndef RASPI - #include "wiring_private.h" - #endif -#endif -#include -#ifdef __AVR__ - #include -#elif defined(ESP8266) || defined(ESP32) - #include -#endif - -// Many (but maybe not all) non-AVR board installs define macros -// for compatibility with existing PROGMEM-reading AVR code. -// Do our own checks and defines here for good measure... - -#ifndef pgm_read_byte - #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) -#endif -#ifndef pgm_read_word - #define pgm_read_word(addr) (*(const unsigned short *)(addr)) -#endif -#ifndef pgm_read_dword - #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) -#endif - -// Pointers are a peculiar case...typically 16-bit on AVR boards, -// 32 bits elsewhere. Try to accommodate both... - -#if !defined(__INT_MAX__) || (__INT_MAX__ > 0xFFFF) - #define pgm_read_pointer(addr) ((void *)pgm_read_dword(addr)) -#else - #define pgm_read_pointer(addr) ((void *)pgm_read_word(addr)) -#endif - -// Control pins - -#ifdef USE_FAST_PINIO - #define SPI_DC_HIGH() *dcport |= dcpinmask - #define SPI_DC_LOW() *dcport &= ~dcpinmask - #define SPI_CS_HIGH() *csport |= cspinmask - #define SPI_CS_LOW() *csport &= ~cspinmask -#else - #define SPI_DC_HIGH() digitalWrite(_rs, HIGH) - #define SPI_DC_LOW() digitalWrite(_rs, LOW) - #define SPI_CS_HIGH() digitalWrite(_cs, HIGH) - #define SPI_CS_LOW() digitalWrite(_cs, LOW) -#endif - -// Software SPI Macros - -#ifdef USE_FAST_PINIO - #define SSPI_MOSI_HIGH() *mosiport |= mosipinmask - #define SSPI_MOSI_LOW() *mosiport &= ~mosipinmask - #define SSPI_SCK_HIGH() *clkport |= clkpinmask - #define SSPI_SCK_LOW() *clkport &= ~clkpinmask -#else - #define SSPI_MOSI_HIGH() digitalWrite(_sdi, HIGH) - #define SSPI_MOSI_LOW() digitalWrite(_sdi, LOW) - #define SSPI_SCK_HIGH() digitalWrite(_clk, HIGH) - #define SSPI_SCK_LOW() digitalWrite(_clk, LOW) -#endif - -#define SSPI_BEGIN_TRANSACTION() -#define SSPI_END_TRANSACTION() -#define SSPI_WRITE(v) _spiWrite(v) -#define SSPI_WRITE16(s) SSPI_WRITE((s) >> 8); SSPI_WRITE(s) -#define SSPI_WRITE32(l) SSPI_WRITE((l) >> 24); SSPI_WRITE((l) >> 16); SSPI_WRITE((l) >> 8); SSPI_WRITE(l) -#define SSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ SSPI_WRITE(((uint8_t*)(c))[i+1]); SSPI_WRITE(((uint8_t*)(c))[i]); } - -// Hardware SPI Macros -#ifndef ESP32 - #ifdef SPI_CHANNEL - extern SPIClass SPI_CHANNEL; - #define SPI_OBJECT SPI_CHANNEL - #else - #define SPI_OBJECT SPI - #endif -#else - #define SPI_OBJECT _spi -#endif - -#if defined (__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1) - #define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV2); -#elif defined (__arm__) - #define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(11); -#elif defined(ESP8266) || defined(ESP32) - #define HSPI_SET_CLOCK() SPI_OBJECT.setFrequency(SPI_DEFAULT_FREQ); -#elif defined(RASPI) - #define HSPI_SET_CLOCK() SPI_OBJECT.setClock(SPI_DEFAULT_FREQ); -#elif defined(ARDUINO_ARCH_STM32F1) - #define HSPI_SET_CLOCK() SPI_OBJECT.setClock(SPI_DEFAULT_FREQ); -#else - #define HSPI_SET_CLOCK() -#endif - -#ifdef SPI_HAS_TRANSACTION - #define HSPI_BEGIN_TRANSACTION() SPI_OBJECT.beginTransaction(SPISettings(SPI_DEFAULT_FREQ, MSBFIRST, SPI_MODE0)) - #define HSPI_END_TRANSACTION() SPI_OBJECT.endTransaction() -#else - #define HSPI_BEGIN_TRANSACTION() HSPI_SET_CLOCK(); SPI_OBJECT.setBitOrder(MSBFIRST); SPI_OBJECT.setDataMode(SPI_MODE0) - #define HSPI_END_TRANSACTION() -#endif - -#ifdef ESP32 - #define SPI_HAS_WRITE_PIXELS -#endif -#if defined(ESP8266) || defined(ESP32) - // Optimized SPI (ESP8266 and ESP32) - #define HSPI_READ() SPI_OBJECT.transfer(0) - #define HSPI_WRITE(b) SPI_OBJECT.write(b) - #define HSPI_WRITE16(s) SPI_OBJECT.write16(s) - #define HSPI_WRITE32(l) SPI_OBJECT.write32(l) - #ifdef SPI_HAS_WRITE_PIXELS - #define SPI_MAX_PIXELS_AT_ONCE 32 - #define HSPI_WRITE_PIXELS(c,l) SPI_OBJECT.writePixels(c,l) - #else - #define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<((l)/2); i++){ HSPI_WRITE16(((uint16_t*)(c))[i]); } - #endif -#elif defined ( __STM32F1__ ) - #define HSPI_WRITE(b) SPI_OBJECT.write(b) - #define HSPI_WRITE16(s) SPI_OBJECT.write16(s) - -#else - // Standard Byte-by-Byte SPI - - #if defined(__AVR_ATmega4809__) - static inline uint8_t _avr_spi_read(void) __attribute__((always_inline)); - static inline uint8_t _avr_spi_read(void) { - uint8_t r = 0; - SPI0_DATA = r; - while(!(SPI0_INTFLAGS & _BV(SPI_IF_bp))); - r = SPI0_DATA; - return r; - } - #define HSPI_WRITE(b) {SPI0_DATA = (b); while(!(SPI0_INTFLAGS & _BV(SPI_IF_bp)));} - // #define HSPI_READ() _avr_spi_read() - #elif defined (__AVR__) || defined(TEENSYDUINO) - static inline uint8_t _avr_spi_read(void) __attribute__((always_inline)); - static inline uint8_t _avr_spi_read(void) { - uint8_t r = 0; - SPDR = r; - while(!(SPSR & _BV(SPIF))); - r = SPDR; - return r; - } - #define HSPI_WRITE(b) {SPDR = (b); while(!(SPSR & _BV(SPIF)));} - // #define HSPI_READ() _avr_spi_read() - #else - #define HSPI_WRITE(b) SPI_OBJECT.transfer((uint8_t)(b)) - // #define HSPI_READ() HSPI_WRITE(0) - #endif - // #define HSPI_WRITE16(s) HSPI_WRITE((s) >> 8); HSPI_WRITE(s) - // #define HSPI_WRITE32(l) HSPI_WRITE((l) >> 24); HSPI_WRITE((l) >> 16); HSPI_WRITE((l) >> 8); HSPI_WRITE(l) - // #define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ HSPI_WRITE(((uint8_t*)(c))[i+1]); HSPI_WRITE(((uint8_t*)(c))[i]); } -#endif - -// Final SPI Macros - -#if defined (ARDUINO_ARCH_ARC32) - #define SPI_DEFAULT_FREQ 16000000 -#elif defined (__AVR__) || defined(TEENSYDUINO) - #define SPI_DEFAULT_FREQ 8000000 -#elif defined(ESP8266) || defined(ESP32) - //#define SPI_DEFAULT_FREQ 40000000 - #define SPI_DEFAULT_FREQ 24000000 -#elif defined(RASPI) - #define SPI_DEFAULT_FREQ 80000000 -#elif defined(ARDUINO_ARCH_STM32F1) - #define SPI_DEFAULT_FREQ 18000000 - //#define SPI_DEFAULT_FREQ 36000000 -#else - #define SPI_DEFAULT_FREQ 24000000 -#endif - -#define SPI_BEGIN() if(_clk < 0){SPI_OBJECT.begin();} -#define SPI_BEGIN_TRANSACTION() if(_clk < 0){HSPI_BEGIN_TRANSACTION();} -#define SPI_END_TRANSACTION() if(_clk < 0){HSPI_END_TRANSACTION();} -// #define SPI_WRITE16(s) if(_clk < 0){HSPI_WRITE16(s);}else{SSPI_WRITE16(s);} -// #define SPI_WRITE32(l) if(_clk < 0){HSPI_WRITE32(l);}else{SSPI_WRITE32(l);} -// #define SPI_WRITE_PIXELS(c,l) if(_clk < 0){HSPI_WRITE_PIXELS(c,l);}else{SSPI_WRITE_PIXELS(c,l);} - - -// Constructor when using software SPI. All output pins are configurable. -TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t sdi, int8_t clk, int8_t led) { - _rst = rst; - _rs = rs; - _cs = cs; - _sdi = sdi; - _clk = clk; - _led = led; - _brightness = 255; // Set to maximum brightness - hwSPI = false; - writeFunctionLevel = 0; - gfxFont = NULL; -} - - -// Constructor when using software SPI. All output pins are configurable. Adds backlight brightness 0-255 -TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t sdi, int8_t clk, int8_t led, uint8_t brightness) { - _rst = rst; - _rs = rs; - _cs = cs; - _sdi = sdi; - _clk = clk; - _led = led; - _brightness = brightness; - hwSPI = false; - writeFunctionLevel = 0; - gfxFont = NULL; -} - - -// Constructor when using hardware SPI. Faster, but must use SPI pins -// specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.) -TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t led) { - _rst = rst; - _rs = rs; - _cs = cs; - _sdi = _clk = -1; - _led = led; - _brightness = 255; // Set to maximum brightness - hwSPI = true; - writeFunctionLevel = 0; - gfxFont = NULL; -} - - -// Constructor when using hardware SPI. Faster, but must use SPI pins -// specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.) -// Adds backlight brightness 0-255 -TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t led, uint8_t brightness) { - _rst = rst; - _rs = rs; - _cs = cs; - _sdi = _clk = -1; - _led = led; - _brightness = brightness; - hwSPI = true; - writeFunctionLevel = 0; - gfxFont = NULL; -} - -#ifdef ESP32 -void TFT_22_ILI9225::begin(SPIClass &spi) -#else -void TFT_22_ILI9225::begin() -#endif -{ -#ifdef ESP32 - _spi = spi; -#endif - // Set up reset pin - if (_rst > 0) { - pinMode(_rst, OUTPUT); - digitalWrite(_rst, LOW); - } - // Set up backlight pin, turn off initially - if (_led > 0) { - pinMode(_led, OUTPUT); - setBacklight(false); - } - - // Control pins - pinMode(_rs, OUTPUT); - digitalWrite(_rs, LOW); - pinMode(_cs, OUTPUT); - digitalWrite(_cs, HIGH); - -#ifdef USE_FAST_PINIO - csport = portOutputRegister(digitalPinToPort(_cs)); - cspinmask = digitalPinToBitMask(_cs); - dcport = portOutputRegister(digitalPinToPort(_rs)); - dcpinmask = digitalPinToBitMask(_rs); -#endif - - // Software SPI - if (_clk >= 0) { - pinMode(_sdi, OUTPUT); - digitalWrite(_sdi, LOW); - pinMode(_clk, OUTPUT); - digitalWrite(_clk, HIGH); -#ifdef USE_FAST_PINIO - clkport = portOutputRegister(digitalPinToPort(_clk)); - clkpinmask = digitalPinToBitMask(_clk); - mosiport = portOutputRegister(digitalPinToPort(_sdi)); - mosipinmask = digitalPinToBitMask(_sdi); - SSPI_SCK_LOW(); - SSPI_MOSI_LOW(); - } else { - clkport = 0; - clkpinmask = 0; - mosiport = 0; - mosipinmask = 0; -#endif - } - - // Hardware SPI - SPI_BEGIN(); - - // Initialization Code - if (_rst > 0) { - digitalWrite(_rst, HIGH); // Pull the reset pin high to release the ILI9225C from the reset status - delay(1); - digitalWrite(_rst, LOW); // Pull the reset pin low to reset ILI9225 - delay(10); - digitalWrite(_rst, HIGH); // Pull the reset pin high to release the ILI9225C from the reset status - delay(50); - } - - /* Start Initial Sequence */ - - /* Set SS bit and direction output from S528 to S1 */ - startWrite(); - _writeRegister(ILI9225_POWER_CTRL1, 0x0000); // Set SAP,DSTB,STB - _writeRegister(ILI9225_POWER_CTRL2, 0x0000); // Set APON,PON,AON,VCI1EN,VC - _writeRegister(ILI9225_POWER_CTRL3, 0x0000); // Set BT,DC1,DC2,DC3 - _writeRegister(ILI9225_POWER_CTRL4, 0x0000); // Set GVDD - _writeRegister(ILI9225_POWER_CTRL5, 0x0000); // Set VCOMH/VCOML voltage - endWrite(); - delay(40); - - // Power-on sequence - startWrite(); - _writeRegister(ILI9225_POWER_CTRL2, 0x0018); // Set APON,PON,AON,VCI1EN,VC - _writeRegister(ILI9225_POWER_CTRL3, 0x6121); // Set BT,DC1,DC2,DC3 - _writeRegister(ILI9225_POWER_CTRL4, 0x006F); // Set GVDD /*007F 0088 */ - _writeRegister(ILI9225_POWER_CTRL5, 0x495F); // Set VCOMH/VCOML voltage - _writeRegister(ILI9225_POWER_CTRL1, 0x0800); // Set SAP,DSTB,STB - endWrite(); - delay(10); - startWrite(); - _writeRegister(ILI9225_POWER_CTRL2, 0x103B); // Set APON,PON,AON,VCI1EN,VC - endWrite(); - delay(50); - - startWrite(); - _writeRegister(ILI9225_DRIVER_OUTPUT_CTRL, 0x011C); // set the display line number and display direction - _writeRegister(ILI9225_LCD_AC_DRIVING_CTRL, 0x0100); // set 1 line inversion - _writeRegister(ILI9225_ENTRY_MODE, 0x1038); // set GRAM write direction and BGR=1. - _writeRegister(ILI9225_DISP_CTRL1, 0x0000); // Display off - _writeRegister(ILI9225_BLANK_PERIOD_CTRL1, 0x0808); // set the back porch and front porch - _writeRegister(ILI9225_FRAME_CYCLE_CTRL, 0x1100); // set the clocks number per line - _writeRegister(ILI9225_INTERFACE_CTRL, 0x0000); // CPU interface - _writeRegister(ILI9225_OSC_CTRL, 0x0D01); // Set Osc /*0e01*/ - _writeRegister(ILI9225_VCI_RECYCLING, 0x0020); // Set VCI recycling - _writeRegister(ILI9225_RAM_ADDR_SET1, 0x0000); // RAM Address - _writeRegister(ILI9225_RAM_ADDR_SET2, 0x0000); // RAM Address - - /* Set GRAM area */ - _writeRegister(ILI9225_GATE_SCAN_CTRL, 0x0000); - _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL1, 0x00DB); - _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL2, 0x0000); - _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL3, 0x0000); - _writeRegister(ILI9225_PARTIAL_DRIVING_POS1, 0x00DB); - _writeRegister(ILI9225_PARTIAL_DRIVING_POS2, 0x0000); - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1, 0x00AF); - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2, 0x0000); - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1, 0x00DB); - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2, 0x0000); - - /* Set GAMMA curve */ - _writeRegister(ILI9225_GAMMA_CTRL1, 0x0000); - _writeRegister(ILI9225_GAMMA_CTRL2, 0x0808); - _writeRegister(ILI9225_GAMMA_CTRL3, 0x080A); - _writeRegister(ILI9225_GAMMA_CTRL4, 0x000A); - _writeRegister(ILI9225_GAMMA_CTRL5, 0x0A08); - _writeRegister(ILI9225_GAMMA_CTRL6, 0x0808); - _writeRegister(ILI9225_GAMMA_CTRL7, 0x0000); - _writeRegister(ILI9225_GAMMA_CTRL8, 0x0A00); - _writeRegister(ILI9225_GAMMA_CTRL9, 0x0710); - _writeRegister(ILI9225_GAMMA_CTRL10, 0x0710); - - _writeRegister(ILI9225_DISP_CTRL1, 0x0012); - endWrite(); - delay(50); - startWrite(); - _writeRegister(ILI9225_DISP_CTRL1, 0x1017); - endWrite(); - - // Turn on backlight - setBacklight(true); - setOrientation(0); - - // Initialize variables - setBackgroundColor( COLOR_BLACK ); - - clear(); -} - - -void TFT_22_ILI9225::_spiWrite(uint8_t b) { - if (_clk < 0) { - HSPI_WRITE(b); - return; - } - // Fast SPI bitbang swiped from LPD8806 library - for (uint8_t bit = 0x80; bit; bit >>= 1) { - if ((b) & bit) { - SSPI_MOSI_HIGH(); - } else { - SSPI_MOSI_LOW(); - } - SSPI_SCK_HIGH(); - SSPI_SCK_LOW(); - } -} - - -void TFT_22_ILI9225::_spiWrite16(uint16_t s) { - // Attempt to use HSPI_WRITE16 if available -#ifdef HSPI_WRITE16 - if (_clk < 0) { - HSPI_WRITE16(s); - return; - } -#endif - // Fallback to SSPI_WRITE16 if HSPI_WRITE16 not available - SSPI_WRITE16(s); -} - - -void TFT_22_ILI9225::_spiWriteCommand(uint8_t c) { - SPI_DC_LOW(); - SPI_CS_LOW(); - _spiWrite(c); - SPI_CS_HIGH(); -} - - -void TFT_22_ILI9225::_spiWriteData(uint8_t c) { - SPI_DC_HIGH(); - SPI_CS_LOW(); - _spiWrite(c); - SPI_CS_HIGH(); -} - - -void TFT_22_ILI9225::_orientCoordinates(uint16_t &x1, uint16_t &y1) { - - switch (_orientation) { - case 0: // ok - break; - case 1: // ok - y1 = _maxY - y1 - 1; - _swap(x1, y1); - break; - case 2: // ok - x1 = _maxX - x1 - 1; - y1 = _maxY - y1 - 1; - break; - case 3: // ok - x1 = _maxX - x1 - 1; - _swap(x1, y1); - break; - } -} - - -void TFT_22_ILI9225::_setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { - _setWindow( x0, y0, x1, y1, TopDown_L2R ); // default for drawing characters -} - - -void TFT_22_ILI9225::_setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, autoIncMode_t mode) { - DB_PRINT( "setWindows( x0=%d, y0=%d, x1=%d, y1=%d, mode=%d", x0,y0,x1,y1,mode ); - - // clip to TFT-Dimensions - x0 = min( x0, (uint16_t) (_maxX-1) ); - x1 = min( x1, (uint16_t) (_maxX-1) ); - y0 = min( y0, (uint16_t) (_maxY-1) ); - y1 = min( y1, (uint16_t) (_maxY-1) ); - _orientCoordinates(x0, y0); - _orientCoordinates(x1, y1); - - if (x1 0 ) mode = modeTab[_orientation-1][mode]; - _writeRegister(ILI9225_ENTRY_MODE, 0x1000 | ( mode<<3) ); - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1,x1); - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2,x0); - - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1,y1); - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2,y0); - DB_PRINT( "gedreht: x0=%d, y0=%d, x1=%d, y1=%d, mode=%d", x0,y0,x1,y1,mode ); - // starting position within window and increment/decrement direction - switch ( mode>>1 ) { - case 0: - _writeRegister(ILI9225_RAM_ADDR_SET1,x1); - _writeRegister(ILI9225_RAM_ADDR_SET2,y1); - break; - case 1: - _writeRegister(ILI9225_RAM_ADDR_SET1,x0); - _writeRegister(ILI9225_RAM_ADDR_SET2,y1); - break; - case 2: - _writeRegister(ILI9225_RAM_ADDR_SET1,x1); - _writeRegister(ILI9225_RAM_ADDR_SET2,y0); - break; - case 3: - _writeRegister(ILI9225_RAM_ADDR_SET1,x0); - _writeRegister(ILI9225_RAM_ADDR_SET2,y0); - break; - } - _writeCommand16( ILI9225_GRAM_DATA_REG ); - - //_writeRegister(ILI9225_RAM_ADDR_SET1,x0); - //_writeRegister(ILI9225_RAM_ADDR_SET2,y0); - - //_writeCommand(0x00, 0x22); - - endWrite(); -} - - -void TFT_22_ILI9225::_resetWindow() { - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1, 0x00AF); - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2, 0x0000); - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1, 0x00DB); - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2, 0x0000); - -} - - -void TFT_22_ILI9225::clear(uint16_t withColor) { - uint8_t old = _orientation; - setOrientation(0); - fillRectangle(0, 0, _maxX - 1, _maxY - 1, withColor); - setOrientation(old); - delay(10); -} - - -void TFT_22_ILI9225::invertDisplay(boolean flag) { - startWrite(); - _writeCommand16(flag ? ILI9225C_INVON : ILI9225C_INVOFF); - //_writeCommand(0x00, flag ? ILI9225C_INVON : ILI9225C_INVOFF); - endWrite(); -} - - -void TFT_22_ILI9225::setBacklight(boolean flag) { - blState = flag; -#ifndef ESP32 - if (_led) analogWrite(_led, blState ? _brightness : 0); -#endif -} - - -void TFT_22_ILI9225::setBacklightBrightness(uint8_t brightness) { - _brightness = brightness; - setBacklight(blState); -} - - -void TFT_22_ILI9225::setDisplay(boolean flag) { - if (flag) { - startWrite(); - _writeRegister(0x00ff, 0x0000); - _writeRegister(ILI9225_POWER_CTRL1, 0x0000); - endWrite(); - delay(50); - startWrite(); - _writeRegister(ILI9225_DISP_CTRL1, 0x1017); - endWrite(); - delay(200); - } else { - startWrite(); - _writeRegister(0x00ff, 0x0000); - _writeRegister(ILI9225_DISP_CTRL1, 0x0000); - endWrite(); - delay(50); - startWrite(); - _writeRegister(ILI9225_POWER_CTRL1, 0x0003); - endWrite(); - delay(200); - } -} - - -void TFT_22_ILI9225::setOrientation(uint8_t orientation) { - - _orientation = orientation % 4; - - switch (_orientation) { - case 0: - _maxX = ILI9225_LCD_WIDTH; - _maxY = ILI9225_LCD_HEIGHT; - break; - case 1: - _maxX = ILI9225_LCD_HEIGHT; - _maxY = ILI9225_LCD_WIDTH; - break; - case 2: - _maxX = ILI9225_LCD_WIDTH; - _maxY = ILI9225_LCD_HEIGHT; - break; - case 3: - _maxX = ILI9225_LCD_HEIGHT; - _maxY = ILI9225_LCD_WIDTH; - break; - } -} - - -uint8_t TFT_22_ILI9225::getOrientation() { - return _orientation; -} - - -void TFT_22_ILI9225::drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { - startWrite(); - drawLine(x1, y1, x1, y2, color); - drawLine(x1, y1, x2, y1, color); - drawLine(x1, y2, x2, y2, color); - drawLine(x2, y1, x2, y2, color); - endWrite(); -} - - -void TFT_22_ILI9225::fillRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { - - _setWindow(x1, y1, x2, y2); - - startWrite(); - for (uint16_t t=(y2 - y1 + 1) * (x2 - x1 + 1); t > 0; t--) - _writeData16(color); - endWrite(); - _resetWindow(); -} - - -void TFT_22_ILI9225::drawCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color) { - - int16_t f = 1 - r; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * r; - int16_t x = 0; - int16_t y = r; - - startWrite(); - - drawPixel(x0, y0 + r, color); - drawPixel(x0, y0- r, color); - drawPixel(x0 + r, y0, color); - drawPixel(x0 - r, y0, color); - - while (x < y) { - if (f >= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - drawPixel(x0 + x, y0 + y, color); - drawPixel(x0 - x, y0 + y, color); - drawPixel(x0 + x, y0 - y, color); - drawPixel(x0 - x, y0 - y, color); - drawPixel(x0 + y, y0 + x, color); - drawPixel(x0 - y, y0 + x, color); - drawPixel(x0 + y, y0 - x, color); - drawPixel(x0 - y, y0 - x, color); - } - endWrite(); -} - - -void TFT_22_ILI9225::fillCircle(uint8_t x0, uint8_t y0, uint8_t radius, uint16_t color) { - - int16_t f = 1 - radius; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * radius; - int16_t x = 0; - int16_t y = radius; - - startWrite(); - while (x < y) { - if (f >= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - drawLine(x0 + x, y0 + y, x0 - x, y0 + y, color); // bottom - drawLine(x0 + x, y0 - y, x0 - x, y0 - y, color); // top - drawLine(x0 + y, y0 - x, x0 + y, y0 + x, color); // right - drawLine(x0 - y, y0 - x, x0 - y, y0 + x, color); // left - } - endWrite(); - fillRectangle(x0-x, y0-y, x0+x, y0+y, color); -} - - -void TFT_22_ILI9225::drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { - - // Classic Bresenham algorithm - int16_t steep = abs((int16_t)(y2 - y1)) > abs((int16_t)(x2 - x1)); - - int16_t dx, dy; - - if (steep) { - _swap(x1, y1); - _swap(x2, y2); - } - - if (x1 > x2) { - _swap(x1, x2); - _swap(y1, y2); - } - - dx = x2 - x1; - dy = abs((int16_t)(y2 - y1)); - - int16_t err = dx / 2; - int16_t ystep; - - if (y1 < y2) ystep = 1; - else ystep = -1; - - startWrite(); - for (; x1<=x2; x1++) { - if (steep) drawPixel(y1, x1, color); - else drawPixel(x1, y1, color); - - err -= dy; - if (err < 0) { - y1 += ystep; - err += dx; - } - } - endWrite(); -} - - -void TFT_22_ILI9225::drawPixel(uint16_t x1, uint16_t y1, uint16_t color) { - - if((x1 >= _maxX) || (y1 >= _maxY)) return; - - // _setWindow(x1, y1, x1+1, y1+1); - // _orientCoordinates(x1, y1); - // startWrite(); - // //_writeData(color >> 8, color); - // _writeData16(color); - // endWrite(); - - _orientCoordinates(x1, y1); - startWrite(); - _writeRegister(ILI9225_RAM_ADDR_SET1,x1); - _writeRegister(ILI9225_RAM_ADDR_SET2,y1); - _writeRegister(ILI9225_GRAM_DATA_REG,color); - - endWrite(); -} - - -uint16_t TFT_22_ILI9225::maxX() { - return _maxX; -} - - -uint16_t TFT_22_ILI9225::maxY() { - return _maxY; -} - - -uint16_t TFT_22_ILI9225::setColor(uint8_t red8, uint8_t green8, uint8_t blue8) { - // rgb16 = red5 green6 blue5 - return (red8 >> 3) << 11 | (green8 >> 2) << 5 | (blue8 >> 3); -} - - -void TFT_22_ILI9225::splitColor(uint16_t rgb, uint8_t &red, uint8_t &green, uint8_t &blue) { - // rgb16 = red5 green6 blue5 - red = (rgb & 0b1111100000000000) >> 11 << 3; - green = (rgb & 0b0000011111100000) >> 5 << 2; - blue = (rgb & 0b0000000000011111) << 3; -} - - -void TFT_22_ILI9225::_swap(uint16_t &a, uint16_t &b) { - uint16_t w = a; - a = b; - b = w; -} - - -// Utilities - -void TFT_22_ILI9225::_writeCommand16(uint16_t command) { - SPI_DC_LOW(); - SPI_CS_LOW(); - if ( _clk < 0 ) { -# ifdef HSPI_WRITE16 - HSPI_WRITE16(command); -#else - HSPI_WRITE(command >> 8); - HSPI_WRITE(0x00ff & command); -#endif - } else { - // Fast SPI bitbang swiped from LPD8806 library - for (uint16_t bit = 0x8000; bit; bit >>= 1) { - if ((command) & bit) { - SSPI_MOSI_HIGH(); - } else { - SSPI_MOSI_LOW(); - } - SSPI_SCK_HIGH(); - SSPI_SCK_LOW(); - } - } - SPI_CS_HIGH(); -} - - -void TFT_22_ILI9225::_writeData16(uint16_t data) { - SPI_DC_HIGH(); - SPI_CS_LOW(); - if (_clk < 0) { -# ifdef HSPI_WRITE16 - HSPI_WRITE16(data); -#else - HSPI_WRITE(data >> 8); - HSPI_WRITE(0x00ff & data); -#endif - } else { - // Fast SPI bitbang swiped from LPD8806 library - for (uint16_t bit = 0x8000; bit; bit >>= 1) { - if((data) & bit) { - SSPI_MOSI_HIGH(); - } else { - SSPI_MOSI_LOW(); - } - SSPI_SCK_HIGH(); - SSPI_SCK_LOW(); - } - } - SPI_CS_HIGH(); -} - - -/* -void TFT_22_ILI9225::_writeData(uint8_t HI, uint8_t LO) { - _spiWriteData(HI); - _spiWriteData(LO); -} - -void TFT_22_ILI9225::_writeCommand(uint8_t HI, uint8_t LO) { - _spiWriteCommand(HI); - _spiWriteCommand(LO); -} -*/ - - -void TFT_22_ILI9225::_writeRegister(uint16_t reg, uint16_t data) { - _writeCommand16(reg); - _writeData16(data); -} - - -void TFT_22_ILI9225::drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color) { - startWrite(); - drawLine(x1, y1, x2, y2, color); - drawLine(x2, y2, x3, y3, color); - drawLine(x3, y3, x1, y1, color); - endWrite(); -} - - -void TFT_22_ILI9225::fillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color) { - - uint16_t a, b, y, last; - - // Sort coordinates by Y order (y3 >= y2 >= y1) - if (y1 > y2) { - _swap(y1, y2); _swap(x1, x2); - } - if (y2 > y3) { - _swap(y3, y2); _swap(x3, x2); - } - if (y1 > y2) { - _swap(y1, y2); _swap(x1, x2); - } - - startWrite(); - if (y1 == y3) { // Handle awkward all-on-same-line case as its own thing - a = b = x1; - if (x2 < a) a = x2; - else if (x2 > b) b = x2; - if (x3 < a) a = x3; - else if (x3 > b) b = x3; - drawLine(a, y1, b, y1, color); - return; - } - - int16_t dx11 = x2 - x1, - dy11 = y2 - y1, - dx12 = x3 - x1, - dy12 = y3 - y1, - dx22 = x3 - x2, - dy22 = y3 - y2; - int32_t sa = 0, - sb = 0; - - // For upper part of triangle, find scanline crossings for segments - // 0-1 and 0-2. If y2=y3 (flat-bottomed triangle), the scanline y2 - // is included here (and second loop will be skipped, avoiding a /0 - // error there), otherwise scanline y2 is skipped here and handled - // in the second loop...which also avoids a /0 error here if y1=y2 - // (flat-topped triangle). - if (y2 == y3) last = y2; // Include y2 scanline - else last = y2 - 1; // Skip it - - for (y = y1; y <= last; y++) { - a = x1 + sa / dy11; - b = x1 + sb / dy12; - sa += dx11; - sb += dx12; - // longhand: - // a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); - // b = x1 + (x3 - x1) * (y - y1) / (y3 - y1); - if (a > b) _swap(a,b); - drawLine(a, y, b, y, color); - } - - // For lower part of triangle, find scanline crossings for segments - // 0-2 and 1-2. This loop is skipped if y2=y3. - sa = dx22 * (y - y2); - sb = dx12 * (y - y1); - for (; y<=y3; y++) { - a = x2 + sa / dy22; - b = x1 + sb / dy12; - sa += dx22; - sb += dx12; - // longhand: - // a = x2 + (x3 - x2) * (y - y2) / (y3 - y2); - // b = x1 + (x3 - x1) * (y - y1) / (y3 - y1); - if (a > b) _swap(a,b); - drawLine(a, y, b, y, color); - } - endWrite(); -} - - -void TFT_22_ILI9225::setBackgroundColor(uint16_t color) { - _bgColor = color; -} - - -void TFT_22_ILI9225::setFont(uint8_t* font, bool monoSp) { - - cfont.font = font; - cfont.width = readFontByte(0); - cfont.height = readFontByte(1); - cfont.offset = readFontByte(2); - cfont.numchars = readFontByte(3); - cfont.nbrows = cfont.height / 8; - cfont.monoSp = monoSp; - - if (cfont.height % 8) cfont.nbrows++; // Set number of bytes used by height of font in multiples of 8 -} - - -_currentFont TFT_22_ILI9225::getFont() { - return cfont; -} - - -uint16_t TFT_22_ILI9225::drawText(uint16_t x, uint16_t y, STRING s, uint16_t color) { - - uint16_t currx = x; - - // Print every character in string -#ifdef USE_STRING_CLASS - for (uint8_t k = 0; k < s.length(); k++) { - currx += drawChar(currx, y, s.charAt(k), color) + 1; - } -#else - for (uint8_t k = 0; k < strlen(s); k++) { - currx += drawChar(currx, y, s[k], color) + 1; - } -#endif - return currx; -} - - -uint16_t TFT_22_ILI9225::getTextWidth( STRING s ) { - - uint16_t width = 0; - // Count every character in string ( +1 for spacing ) -#ifdef USE_STRING_CLASS - for (uint8_t k = 0; k < s.length(); k++) { - width += getCharWidth(s.charAt(k) ) + 1; - } -#else - for (uint8_t k = 0; k < strlen(s); k++) { - width += getCharWidth(s[k]) + 1; - } -#endif - return width; -} - - -uint16_t TFT_22_ILI9225::drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t color) { - - uint8_t charData, charWidth; - uint8_t h, i, j; - uint16_t charOffset; - bool fastMode; - - charOffset = (cfont.width * cfont.nbrows) + 1; // bytes used by each character - charOffset = (charOffset * (ch - cfont.offset)) + FONT_HEADER_SIZE; // char offset (add 4 for font header) - if ( cfont.monoSp ) charWidth = cfont.width; // monospaced: get char width from font - else charWidth = readFontByte(charOffset); // get chracter width from 1st byte - charOffset++; // increment pointer to first character data byte - - startWrite(); - - // use autoincrement/decrement feature, if character fits completely on screen - fastMode = ( (x+charWidth+1) < _maxX && (y+cfont.height-1) < _maxY ); - - if ( fastMode ) _setWindow( x,y,x+charWidth+1, y+cfont.height-1 ); // set character Window - - for (i = 0; i <= charWidth; i++) { // each font "column" (+1 blank column for spacing) - h = 0; // keep track of char height - for (j = 0; j < cfont.nbrows; j++) { // each column byte - if (i == charWidth) charData = (uint8_t)0x0; // Insert blank column - else charData = readFontByte(charOffset); - charOffset++; - - // Process every row in font character - for (uint8_t k = 0; k < 8; k++) { - if (h >= cfont.height ) break; // No need to process excess bits - if (fastMode ) _writeData16( bitRead(charData, k)?color:_bgColor ); - else drawPixel( x + i, y + (j * 8) + k, bitRead(charData, k)?color:_bgColor ); - h++; - } - } - } - endWrite(); - _resetWindow(); - return charWidth; -} - - -uint16_t TFT_22_ILI9225::getCharWidth(uint16_t ch) { - uint16_t charOffset; - charOffset = (cfont.width * cfont.nbrows) + 1; // bytes used by each character - charOffset = (charOffset * (ch - cfont.offset)) + FONT_HEADER_SIZE; // char offset (add 4 for font header) - - return readFontByte(charOffset); // get font width from 1st byte -} - - -// Draw a 1-bit image (bitmap) at the specified (x,y) position from the -// provided bitmap buffer (must be PROGMEM memory) using the specified -// foreground color (unset bits are transparent). -void TFT_22_ILI9225::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { - _drawBitmap( x, y, bitmap, w, h, color, 0, true, true, false ); -} - -// Draw a 1-bit image (bitmap) at the specified (x,y) position from the -// provided bitmap buffer (must be PROGMEM memory) using the specified -// foreground (for set bits) and background (for clear bits) colors. -void TFT_22_ILI9225::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) { - _drawBitmap( x, y, bitmap, w, h, color, bg, false, true, false ); -} - - -// drawBitmap() variant for RAM-resident (not PROGMEM) bitmaps. -void TFT_22_ILI9225::drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { - _drawBitmap( x, y, bitmap, w, h, color, 0, true, false, false ); -} - - -// drawBitmap() variant w/background for RAM-resident (not PROGMEM) bitmaps. -void TFT_22_ILI9225::drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) { - _drawBitmap( x, y, bitmap, w, h, color, bg, false, false, false ); -} - - -//Draw XBitMap Files (*.xbm), exported from GIMP, -//Usage: Export from GIMP to *.xbm, rename *.xbm to *.c and open in editor. -//C Array can be directly used with this function -void TFT_22_ILI9225::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { - _drawBitmap( x, y, bitmap, w, h, color, 0, true, true, true ); -} - - -void TFT_22_ILI9225::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) { - _drawBitmap( x, y, bitmap, w, h, color, bg, false, true, true ); -} - - -// internal function for drawing bitmaps with/without transparent bg, or from ram or progmem -void TFT_22_ILI9225::_drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg, bool transparent, bool progmem,bool Xbit) { - bool noAutoInc = false; // Flag set when transparent pixel was 'written' - int16_t i, j, byteWidth = (w + 7) / 8; - int16_t wx0, wy0, wx1, wy1, wh; // Window-position and size - // int16_t ww; - uint8_t byte, maskBit; - byte = 0; - maskBit = Xbit? 0x01:0x80; - // adjust window hight/width to displaydimensions - DB_PRINT( "DrawBitmap.. maxX=%d, maxY=%d", _maxX,_maxY ); - wx0 = x < 0 ? 0 : x; - wy0 = y < 0 ? 0 : y; - wx1 = (x + w > _maxX ?_maxX : x + w ) - 1; - wy1 = (y + h > _maxY ?_maxY : y + h ) - 1; - wh = wy1 - wy0 + 1; - // ww = wx1 - wx0 + 1; - _setWindow(wx0, wy0, wx1, wy1, L2R_TopDown); - startWrite(); - for (j = y>=0?0:-y; j < (y>=0?0:-y)+wh; j++) { - for (i = 0; i < w; i++ ) { - if (i & 7) { - if ( Xbit ) byte >>=1; else byte <<= 1; - } - else { - if ( progmem ) byte = pgm_read_byte(bitmap + j * byteWidth + i / 8); - else byte = bitmap[j * byteWidth + i / 8]; - } - if ( x+i >= wx0 && x+i <= wx1 ) { - // write only if pixel is within window - if (byte & maskBit) { - if (noAutoInc) { - //there was a transparent area, set pixelkoordinates again - drawPixel(x + i, y + j, color); - noAutoInc = false; - } - else { - _writeData16(color); - } - } - else { - if (transparent) noAutoInc = true; // no autoincrement in transparent area! - else _writeData16( bg); - } - } - } - } - endWrite(); - _resetWindow(); -} - -//High speed color bitmap -void TFT_22_ILI9225::drawBitmap(uint16_t x1, uint16_t y1, const uint16_t** bitmap, int16_t w, int16_t h) { - startWrite(); - _setWindow(x1, y1, x1+w-1, y1+h-1, L2R_TopDown); - SPI_DC_HIGH(); - SPI_CS_LOW(); - for (uint16_t y = 0; y < h; y++) { -#ifdef HSPI_WRITE_PIXELS - if (_clk < 0) { - HSPI_WRITE_PIXELS(bitmap[y], w * sizeof(uint16_t)); - continue; - } -#endif - for (uint16_t x = 0; x < w; x++) { - _spiWrite16(bitmap[y][x]); - } - } - SPI_CS_HIGH(); - endWrite(); - _resetWindow(); -} - - -//High speed color bitmap -void TFT_22_ILI9225::drawBitmap(uint16_t x1, uint16_t y1, uint16_t** bitmap, int16_t w, int16_t h) { - startWrite(); - _setWindow(x1, y1, x1+w-1, y1+h-1, L2R_TopDown); - SPI_DC_HIGH(); - SPI_CS_LOW(); - for (uint16_t y = 0; y < h; y++) { -#ifdef HSPI_WRITE_PIXELS - if (_clk < 0) { - HSPI_WRITE_PIXELS(bitmap[y], w * sizeof(uint16_t)); - continue; - } -#endif - for (uint16_t x = 0; x < w; x++) { - _spiWrite16(bitmap[y][x]); - } - } - SPI_CS_HIGH(); - endWrite(); - _resetWindow(); -} - - -//1-D array High speed color bitmap -void TFT_22_ILI9225::drawBitmap(uint16_t x1, uint16_t y1, const uint16_t* bitmap, int16_t w, int16_t h) { - startWrite(); - _setWindow(x1, y1, x1+w-1, y1+h-1, L2R_TopDown); - SPI_DC_HIGH(); - SPI_CS_LOW(); -#ifdef HSPI_WRITE_PIXELS - if (_clk < 0) { - HSPI_WRITE_PIXELS(bitmap, w * h * sizeof(uint16_t)); - } else -#endif - for (uint16_t i = 0; i < h * w; ++i) { - _spiWrite16(bitmap[i]); - } - SPI_CS_HIGH(); - endWrite(); - _resetWindow(); -} - - -//1-D array High speed color bitmap -void TFT_22_ILI9225::drawBitmap(uint16_t x1, uint16_t y1, uint16_t* bitmap, int16_t w, int16_t h) { - startWrite(); - _setWindow(x1, y1, x1+w-1, y1+h-1, L2R_TopDown); - SPI_DC_HIGH(); - SPI_CS_LOW(); -#ifdef HSPI_WRITE_PIXELS - if (_clk < 0) { - HSPI_WRITE_PIXELS(bitmap, w * h * sizeof(uint16_t)); - } else -#endif - for (uint16_t i = 0; i < h * w; ++i) { - _spiWrite16(bitmap[i]); - } - SPI_CS_HIGH(); - endWrite(); - _resetWindow(); -} - - -void TFT_22_ILI9225::startWrite(void) { - if (writeFunctionLevel++ == 0) { - SPI_BEGIN_TRANSACTION(); - SPI_CS_LOW(); - } -} - - -void TFT_22_ILI9225::endWrite(void) { - if (--writeFunctionLevel == 0) { - SPI_CS_HIGH(); - SPI_END_TRANSACTION(); - } -} - - -// TEXT- AND CHARACTER-HANDLING FUNCTIONS ---------------------------------- - -void TFT_22_ILI9225::setGFXFont(const GFXfont *f) { - gfxFont = (GFXfont *)f; -} - - -// Draw a string -void TFT_22_ILI9225::drawGFXText(int16_t x, int16_t y, STRING s, uint16_t color) { - - int16_t currx = x; - - if(gfxFont) { - // Print every character in string -#ifdef USE_STRING_CLASS - for (uint8_t k = 0; k < s.length(); k++) { - currx += drawGFXChar(currx, y, s.charAt(k), color) + 1; - } -#else - for (uint8_t k = 0; k < strlen(s); k++) { - currx += drawGFXChar(currx, y, s[k], color) + 1; - } -#endif - } -} - - -// Draw a character -uint16_t TFT_22_ILI9225::drawGFXChar(int16_t x, int16_t y, unsigned char c, uint16_t color) { - - c -= (uint8_t)pgm_read_byte(&gfxFont->first); - GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]); - uint8_t *bitmap = (uint8_t *)pgm_read_pointer(&gfxFont->bitmap); - - uint16_t bo = pgm_read_word(&glyph->bitmapOffset); - uint8_t w = pgm_read_byte(&glyph->width), - h = pgm_read_byte(&glyph->height), - xa = pgm_read_byte(&glyph->xAdvance); - int8_t xo = pgm_read_byte(&glyph->xOffset), - yo = pgm_read_byte(&glyph->yOffset); - uint8_t xx, yy, bits = 0, bit = 0; - // Add character clipping here one day - - startWrite(); - _setWindow( x-1,y+2,x+w+xo+1, y+yo-2 ); // set character Window - for(yy=0; yyfirst), - last = pgm_read_byte(&gfxFont->last); - // Char present in this font? - if((c >= first) && (c <= last)) { - GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c - first]); - *gw = pgm_read_byte(&glyph->width); - *gh = pgm_read_byte(&glyph->height); - *xa = pgm_read_byte(&glyph->xAdvance); - // int8_t xo = pgm_read_byte(&glyph->xOffset), - // yo = pgm_read_byte(&glyph->yOffset); - } -} - -void TFT_22_ILI9225::getGFXTextExtent(STRING str, int16_t x, int16_t y, int16_t *w, int16_t *h) { - *w = *h = 0; -#ifdef USE_STRING_CLASS - for (uint8_t k = 0; k < str.length(); k++) { - uint8_t c = str.charAt(k); -#else - for (uint8_t k = 0; k < strlen(str); k++) { - uint8_t c = str[k]; -#endif - int16_t gw, gh, xa; - getGFXCharExtent(c, &gw, &gh, &xa); - if(gh > *h) { - *h = gh; - } - *w += xa; - } -} - -GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) { - uint32_t bytes = w * h * 2; - if ((buffer = (uint16_t *)malloc(bytes))) { - memset(buffer, 0, bytes); - _width = WIDTH = w; - _height = HEIGHT = h; - } -} - -GFXcanvas16::~GFXcanvas16(void) { - if (buffer) - free(buffer); -} - -void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) { - if (buffer) { - if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) - return; - buffer[x + y * WIDTH] = color; - } -} - -uint16_t GFXcanvas16::getPixel(int16_t x, int16_t y) const { - return getRawPixel(x, y); -} - -uint16_t GFXcanvas16::getRawPixel(int16_t x, int16_t y) const { - if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT)) - return 0; - if (buffer) { - return buffer[x + y * WIDTH]; - } - return 0; -} - -void GFXcanvas16::fillScreen(uint16_t color) { - if (buffer) { - uint8_t hi = color >> 8, lo = color & 0xFF; - if (hi == lo) { - memset(buffer, lo, WIDTH * HEIGHT * 2); - } else { - uint32_t i, pixels = WIDTH * HEIGHT; - for (i = 0; i < pixels; i++) - buffer[i] = color; - } - } -} - -void GFXcanvas16::byteSwap(void) { - if (buffer) { - uint32_t i, pixels = WIDTH * HEIGHT; - for (i = 0; i < pixels; i++) - buffer[i] = __builtin_bswap16(buffer[i]); - } -} - -void GFXcanvas16::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { - if (h < 0) { - h *= -1; - y -= h - 1; - if (y < 0) { - h += y; - y = 0; - } - } - if ((x < 0) || (x >= width()) || (y >= height()) || ((y + h - 1) < 0)) { - return; - } - if (y < 0) { - h += y; - y = 0; - } - if (y + h > height()) { - h = height() - y; - } - drawFastRawVLine(x, y, h, color); -} - -void GFXcanvas16::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { - if (w < 0) { - w *= -1; - x -= w - 1; - if (x < 0) { - w += x; - x = 0; - } - } - if ((y < 0) || (y >= height()) || (x >= width()) || ((x + w - 1) < 0)) { - return; - } - if (x < 0) { - w += x; - x = 0; - } - if (x + w >= width()) { - w = width() - x; - } - drawFastRawHLine(x, y, w, color); -} - -void GFXcanvas16::drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { - uint16_t *buffer_ptr = buffer + y * WIDTH + x; - for (int16_t i = 0; i < h; i++) { - (*buffer_ptr) = color; - buffer_ptr += WIDTH; - } -} - -void GFXcanvas16::drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { - uint32_t buffer_index = y * WIDTH + x; - for (uint32_t i = buffer_index; i < buffer_index + w; i++) { - buffer[i] = color; - } -} - -void GFXcanvas16::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { - for (int16_t i = x; i < x + w; i++) { - drawFastVLine(i, y, h, color); - } -} - -#endif // DSP_MODEL==DSP_ILI9225 diff --git a/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.h b/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.h deleted file mode 100644 index 75e6178..0000000 --- a/yoRadio/src/ILI9225Fix/TFT_22_ILI9225Fix.h +++ /dev/null @@ -1,502 +0,0 @@ -#ifndef TFT_22_ILI9225FIX_h -#define TFT_22_ILI9225FIX_h - -#ifdef __STM32F1__ -#define ARDUINO_STM32_FEATHER -#define PROGMEM -// if 'SPI_CHANNEL' is not defined, 'SPI' is used, only valid for STM32F1 -//#define SPI_CHANNEL SPI_2 -#endif - -//#define USE_STRING_CLASS - -#ifdef USE_STRING_CLASS - #define STRING String -#else - #define STRING const char * -#endif - -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif -#include - -//#include "gfxfont.h" -typedef struct { // Data stored PER GLYPH - uint16_t bitmapOffset; // Pointer into GFXfont->bitmap - uint8_t width, height; // Bitmap dimensions in pixels - uint8_t xAdvance; // Distance to advance cursor (x axis) - int8_t xOffset, yOffset; // Dist from cursor pos to UL corner -} GFXglyph; - -typedef struct { // Data stored for FONT AS A WHOLE: - uint8_t *bitmap; // Glyph bitmaps, concatenated - GFXglyph *glyph; // Glyph array - uint8_t first, last; // ASCII extents - uint8_t yAdvance; // Newline distance (y axis) -} GFXfont; - -#if defined(ARDUINO_STM32_FEATHER) || defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) || defined(STM32F1) -typedef volatile uint32_t RwReg; -#endif -#if defined(ARDUINO_FEATHER52) -typedef volatile uint32_t RwReg; -#endif - -/* ILI9225 screen size */ -#define ILI9225_LCD_WIDTH 176 -#define ILI9225_LCD_HEIGHT 220 - -/* ILI9225 LCD Registers */ -#define ILI9225_DRIVER_OUTPUT_CTRL (0x01u) // Driver Output Control -#define ILI9225_LCD_AC_DRIVING_CTRL (0x02u) // LCD AC Driving Control -#define ILI9225_ENTRY_MODE (0x03u) // Entry Mode -#define ILI9225_DISP_CTRL1 (0x07u) // Display Control 1 -#define ILI9225_BLANK_PERIOD_CTRL1 (0x08u) // Blank Period Control -#define ILI9225_FRAME_CYCLE_CTRL (0x0Bu) // Frame Cycle Control -#define ILI9225_INTERFACE_CTRL (0x0Cu) // Interface Control -#define ILI9225_OSC_CTRL (0x0Fu) // Osc Control -#define ILI9225_POWER_CTRL1 (0x10u) // Power Control 1 -#define ILI9225_POWER_CTRL2 (0x11u) // Power Control 2 -#define ILI9225_POWER_CTRL3 (0x12u) // Power Control 3 -#define ILI9225_POWER_CTRL4 (0x13u) // Power Control 4 -#define ILI9225_POWER_CTRL5 (0x14u) // Power Control 5 -#define ILI9225_VCI_RECYCLING (0x15u) // VCI Recycling -#define ILI9225_RAM_ADDR_SET1 (0x20u) // Horizontal GRAM Address Set -#define ILI9225_RAM_ADDR_SET2 (0x21u) // Vertical GRAM Address Set -#define ILI9225_GRAM_DATA_REG (0x22u) // GRAM Data Register -#define ILI9225_GATE_SCAN_CTRL (0x30u) // Gate Scan Control Register -#define ILI9225_VERTICAL_SCROLL_CTRL1 (0x31u) // Vertical Scroll Control 1 Register -#define ILI9225_VERTICAL_SCROLL_CTRL2 (0x32u) // Vertical Scroll Control 2 Register -#define ILI9225_VERTICAL_SCROLL_CTRL3 (0x33u) // Vertical Scroll Control 3 Register -#define ILI9225_PARTIAL_DRIVING_POS1 (0x34u) // Partial Driving Position 1 Register -#define ILI9225_PARTIAL_DRIVING_POS2 (0x35u) // Partial Driving Position 2 Register -#define ILI9225_HORIZONTAL_WINDOW_ADDR1 (0x36u) // Horizontal Address Start Position -#define ILI9225_HORIZONTAL_WINDOW_ADDR2 (0x37u) // Horizontal Address End Position -#define ILI9225_VERTICAL_WINDOW_ADDR1 (0x38u) // Vertical Address Start Position -#define ILI9225_VERTICAL_WINDOW_ADDR2 (0x39u) // Vertical Address End Position -#define ILI9225_GAMMA_CTRL1 (0x50u) // Gamma Control 1 -#define ILI9225_GAMMA_CTRL2 (0x51u) // Gamma Control 2 -#define ILI9225_GAMMA_CTRL3 (0x52u) // Gamma Control 3 -#define ILI9225_GAMMA_CTRL4 (0x53u) // Gamma Control 4 -#define ILI9225_GAMMA_CTRL5 (0x54u) // Gamma Control 5 -#define ILI9225_GAMMA_CTRL6 (0x55u) // Gamma Control 6 -#define ILI9225_GAMMA_CTRL7 (0x56u) // Gamma Control 7 -#define ILI9225_GAMMA_CTRL8 (0x57u) // Gamma Control 8 -#define ILI9225_GAMMA_CTRL9 (0x58u) // Gamma Control 9 -#define ILI9225_GAMMA_CTRL10 (0x59u) // Gamma Control 10 - -#define ILI9225C_INVOFF 0x20 -#define ILI9225C_INVON 0x21 - -// autoincrement modes (register ILI9225_ENTRY_MODE, bit 5..3 ) -enum autoIncMode_t { R2L_BottomUp, BottomUp_R2L, L2R_BottomUp, BottomUp_L2R, R2L_TopDown, TopDown_R2L, L2R_TopDown, TopDown_L2R }; - -/* RGB 16-bit color table definition (RG565) */ -#define COLOR_BLACK 0x0000 /* 0, 0, 0 */ -#define COLOR_WHITE 0xFFFF /* 255, 255, 255 */ -#define COLOR_BLUE 0x001F /* 0, 0, 255 */ -#define COLOR_GREEN 0x07E0 /* 0, 255, 0 */ -#define COLOR_RED 0xF800 /* 255, 0, 0 */ -#define COLOR_NAVY 0x000F /* 0, 0, 128 */ -#define COLOR_DARKBLUE 0x0011 /* 0, 0, 139 */ -#define COLOR_DARKGREEN 0x03E0 /* 0, 128, 0 */ -#define COLOR_DARKCYAN 0x03EF /* 0, 128, 128 */ -#define COLOR_CYAN 0x07FF /* 0, 255, 255 */ -#define COLOR_TURQUOISE 0x471A /* 64, 224, 208 */ -#define COLOR_INDIGO 0x4810 /* 75, 0, 130 */ -#define COLOR_DARKRED 0x8000 /* 128, 0, 0 */ -#define COLOR_OLIVE 0x7BE0 /* 128, 128, 0 */ -#define COLOR_GRAY 0x8410 /* 128, 128, 128 */ -#define COLOR_GREY 0x8410 /* 128, 128, 128 */ -#define COLOR_SKYBLUE 0x867D /* 135, 206, 235 */ -#define COLOR_BLUEVIOLET 0x895C /* 138, 43, 226 */ -#define COLOR_LIGHTGREEN 0x9772 /* 144, 238, 144 */ -#define COLOR_DARKVIOLET 0x901A /* 148, 0, 211 */ -#define COLOR_YELLOWGREEN 0x9E66 /* 154, 205, 50 */ -#define COLOR_BROWN 0xA145 /* 165, 42, 42 */ -#define COLOR_DARKGRAY 0x7BEF /* 128, 128, 128 */ -#define COLOR_DARKGREY 0x7BEF /* 128, 128, 128 */ -#define COLOR_SIENNA 0xA285 /* 160, 82, 45 */ -#define COLOR_LIGHTBLUE 0xAEDC /* 172, 216, 230 */ -#define COLOR_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ -#define COLOR_SILVER 0xC618 /* 192, 192, 192 */ -#define COLOR_LIGHTGRAY 0xC618 /* 192, 192, 192 */ -#define COLOR_LIGHTGREY 0xC618 /* 192, 192, 192 */ -#define COLOR_LIGHTCYAN 0xE7FF /* 224, 255, 255 */ -#define COLOR_VIOLET 0xEC1D /* 238, 130, 238 */ -#define COLOR_AZUR 0xF7FF /* 240, 255, 255 */ -#define COLOR_BEIGE 0xF7BB /* 245, 245, 220 */ -#define COLOR_MAGENTA 0xF81F /* 255, 0, 255 */ -#define COLOR_TOMATO 0xFB08 /* 255, 99, 71 */ -#define COLOR_GOLD 0xFEA0 /* 255, 215, 0 */ -#define COLOR_ORANGE 0xFD20 /* 255, 165, 0 */ -#define COLOR_SNOW 0xFFDF /* 255, 250, 250 */ -#define COLOR_YELLOW 0xFFE0 /* 255, 255, 0 */ - - -/* Font defines */ -#define FONT_HEADER_SIZE 4 // 1: pixel width of 1 font character, 2: pixel height, -#define readFontByte(x) pgm_read_byte(&cfont.font[x]) - -/*extern uint8_t Terminal6x8[]; -extern uint8_t Terminal11x16[]; -extern uint8_t Terminal12x16[]; -extern uint8_t Trebuchet_MS16x21[];*/ - -struct _currentFont -{ - uint8_t* font; - uint8_t width; - uint8_t height; - uint8_t offset; - uint8_t numchars; - uint8_t nbrows; - bool monoSp; -}; -#define MONOSPACE 1 - -#if defined (ARDUINO_STM32_FEATHER) || defined(ESP32) - #undef USE_FAST_PINIO -#elif defined (__AVR__) || defined(TEENSYDUINO) || defined(ESP8266) || defined(__arm__) - #define USE_FAST_PINIO -#endif - -/// Main and core class -class TFT_22_ILI9225 { - - public: - - TFT_22_ILI9225(int8_t RST, int8_t RS, int8_t CS, int8_t SDI, int8_t CLK, int8_t LED); - TFT_22_ILI9225(int8_t RST, int8_t RS, int8_t CS, int8_t LED); - TFT_22_ILI9225(int8_t RST, int8_t RS, int8_t CS, int8_t SDI, int8_t CLK, int8_t LED, uint8_t brightness); - TFT_22_ILI9225(int8_t RST, int8_t RS, int8_t CS, int8_t LED, uint8_t brightness); - - /// Initialization -#ifndef ESP32 - void begin(void); -#else - void begin(SPIClass &spi=SPI); -#endif - - /// Clear the screen - void clear(uint16_t withColor = COLOR_BLACK); - - /// Invert screen - /// @param flag true to invert, false for normal screen - void invertDisplay(boolean flag); - - /// Switch backlight on or off - /// @param flag true=on, false=off - void setBacklight(boolean flag); - - /// Set backlight brightness - /// @param brightness sets backlight brightness 0-255 - void setBacklightBrightness(uint8_t brightness); - - /// Switch display on or off - /// @param flag true=on, false=off - void setDisplay(boolean flag); - - /// Set orientation - /// @param orientation orientation, 0=portrait, 1=right rotated landscape, 2=reverse portrait, 3=left rotated landscape - void setOrientation(uint8_t orientation); - - /// Get orientation - /// @return orientation orientation, 0=portrait, 1=right rotated landscape, 2=reverse portrait, 3=left rotated landscape - uint8_t getOrientation(void); - - /// Font size, x-axis - /// @return horizontal size of current font, in pixels - // uint8_t fontX(void); - - /// Font size, y-axis - /// @return vertical size of current font, in pixels - // uint8_t fontY(void); - - /// Screen size, x-axis - /// @return horizontal size of the screen, in pixels - /// @note 240 means 240 pixels and thus 0..239 coordinates (decimal) - uint16_t maxX(void); - /// Screen size, y-axis - /// @return vertical size of the screen, in pixels - /// @note 220 means 220 pixels and thus 0..219 coordinates (decimal) - uint16_t maxY(void); - /// Draw circle - /// @param x0 center, point coordinate, x-axis - /// @param y0 center, point coordinate, y-axis - /// @param radius radius - /// @param color 16-bit color - void drawCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t color); - - /// Draw solid circle - /// @param x0 center, point coordinate, x-axis - /// @param y0 center, point coordinate, y-axis - /// @param radius radius - /// @param color 16-bit color - void fillCircle(uint8_t x0, uint8_t y0, uint8_t radius, uint16_t color); - - /// Set background color - /// @param color background color, default=black - void setBackgroundColor(uint16_t color = COLOR_BLACK); - - /// Draw line, rectangle coordinates - /// @param x1 start point coordinate, x-axis - /// @param y1 start point coordinate, y-axis - /// @param x2 end point coordinate, x-axis - /// @param y2 end point coordinate, y-axis - /// @param color 16-bit color - void drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); - - /// Draw rectangle, rectangle coordinates - /// @param x1 top left coordinate, x-axis - /// @param y1 top left coordinate, y-axis - /// @param x2 bottom right coordinate, x-axis - /// @param y2 bottom right coordinate, y-axis - /// @param color 16-bit color - void drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); - - /// Draw solid rectangle, rectangle coordinates - /// @param x1 top left coordinate, x-axis - /// @param y1 top left coordinate, y-axis - /// @param x2 bottom right coordinate, x-axis - /// @param y2 bottom right coordinate, y-axis - /// @param color 16-bit color - void fillRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); - - /// Draw pixel - /// @param x1 point coordinate, x-axis - /// @param y1 point coordinate, y-axis - /// @param color 16-bit color - void drawPixel(uint16_t x1, uint16_t y1, uint16_t color); - - /// Draw ASCII Text (pixel coordinates) - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param s text string - /// @param color 16-bit color, default=white - /// @return x-position behind text - uint16_t drawText(uint16_t x, uint16_t y, STRING s, uint16_t color = COLOR_WHITE); - - /// width of an ASCII Text (pixel ) - /// @param s text string - uint16_t getTextWidth( STRING s ) ; - - /// Calculate 16-bit color from 8-bit Red-Green-Blue components - /// @param red red component, 0x00..0xff - /// @param green green component, 0x00..0xff - /// @param blue blue component, 0x00..0xff - /// @return 16-bit color - uint16_t setColor(uint8_t red, uint8_t green, uint8_t blue); - - /// Calculate 8-bit Red-Green-Blue components from 16-bit color - /// @param rgb 16-bit color - /// @param red red component, 0x00..0xff - /// @param green green component, 0x00..0xff - /// @param blue blue component, 0x00..0xff - void splitColor(uint16_t rgb, uint8_t &red, uint8_t &green, uint8_t &blue); - - /// Draw triangle, triangle coordinates - /// @param x1 corner 1 coordinate, x-axis - /// @param y1 corner 1 coordinate, y-axis - /// @param x2 corner 2 coordinate, x-axis - /// @param y2 corner 2 coordinate, y-axis - /// @param x3 corner 3 coordinate, x-axis - /// @param y3 corner 3 coordinate, y-axis - /// @param color 16-bit color - void drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color); - - /// Draw solid triangle, triangle coordinates - /// @param x1 corner 1 coordinate, x-axis - /// @param y1 corner 1 coordinate, y-axis - /// @param x2 corner 2 coordinate, x-axis - /// @param y2 corner 2 coordinate, y-axis - /// @param x3 corner 3 coordinate, x-axis - /// @param y3 corner 3 coordinate, y-axis - /// @param color 16-bit color - void fillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color); - - /// Set current font - /// @param font Font name - void setFont(uint8_t* font, bool monoSp=false ); // default = proportional - - /// Get current font - _currentFont getFont(); - - /// Draw single character (pixel coordinates) - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param ch ASCII character - /// @param color 16-bit color, default=white - /// @return width of character in display pixels - virtual uint16_t drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t color = COLOR_WHITE); - - /// width of an ASCII character (pixel ) - /// @param ch ASCII character - uint16_t getCharWidth( uint16_t ch ) ; - - /// Draw bitmap - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param bitmap - /// @param w width - /// @param h height - /// @param color 16-bit color, default=white - /// @param bg 16-bit color, background - void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color); - void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg); - void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color); - void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg); - - void drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color); - void drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg); - - /// Draw bitmap - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param bitmap, 2D 16bit color bitmap - /// @param w width - /// @param h height - void drawBitmap(uint16_t x, uint16_t y, const uint16_t** bitmap, int16_t w, int16_t h); - void drawBitmap(uint16_t x, uint16_t y, uint16_t** bitmap, int16_t w, int16_t h); - - /// Draw bitmap - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param bitmap, 1D 16bit color bitmap - /// @param w width - /// @param h height - void drawBitmap(uint16_t x, uint16_t y, const uint16_t* bitmap, int16_t w, int16_t h); - void drawBitmap(uint16_t x, uint16_t y, uint16_t* bitmap, int16_t w, int16_t h); - - /// Set current GFX font - /// @param f GFX font name defined in include file - void setGFXFont(const GFXfont *f = NULL); - - /// Draw a string with the current GFX font - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param s string to print - /// @param color 16-bit color - void drawGFXText(int16_t x, int16_t y, STRING s, uint16_t color); - - /// Get the width & height of a text string with the current GFX font - /// @param str string to analyze - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param w width in pixels of string - /// @param h height in pixels of string - void getGFXTextExtent(STRING str, int16_t x, int16_t y, int16_t *w, int16_t *h); - - /// Draw a single character with the current GFX font - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param c character to draw - /// @param color 16-bit color - /// @return width of character in display pixels - uint16_t drawGFXChar(int16_t x, int16_t y, unsigned char c, uint16_t color); - - virtual void startWrite(void); - virtual void endWrite(void); - - private: - - void _spiWrite(uint8_t v); - void _spiWrite16(uint16_t v); - void _spiWriteCommand(uint8_t c); - void _spiWriteData(uint8_t d); - - void _swap(uint16_t &a, uint16_t &b); - void _setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); - void _setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, autoIncMode_t mode); - void _resetWindow(); - void _drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, - uint16_t color, uint16_t bg, bool transparent, bool progmem, bool Xbit ); - void _orientCoordinates(uint16_t &x1, uint16_t &y1); - void _writeRegister(uint16_t reg, uint16_t data); - void _writeData(uint8_t HI, uint8_t LO); - void _writeData16(uint16_t HILO); - void _writeCommand(uint8_t HI, uint8_t LO); - void _writeCommand16(uint16_t HILO); - uint16_t _maxX, _maxY, _bgColor; - -#if defined (__AVR__) || defined(TEENSYDUINO) - int8_t _rst, _rs, _cs, _sdi, _clk, _led; - #ifdef USE_FAST_PINIO - volatile uint8_t *mosiport, *clkport, *dcport, *rsport, *csport; - uint8_t mosipinmask, clkpinmask, cspinmask, dcpinmask; - #endif -#elif defined (__arm__) - int32_t _rst, _rs, _cs, _sdi, _clk, _led; - #ifdef USE_FAST_PINIO - volatile RwReg *mosiport, *clkport, *dcport, *rsport, *csport; - uint32_t mosipinmask, clkpinmask, cspinmask, dcpinmask; - #endif -#elif defined (ESP8266) || defined (ESP32) - int8_t _rst, _rs, _cs, _sdi, _clk, _led; - #ifdef USE_FAST_PINIO - volatile uint32_t *mosiport, *clkport, *dcport, *rsport, *csport; - uint32_t mosipinmask, clkpinmask, cspinmask, dcpinmask; - #endif -#else - int8_t _rst, _rs, _cs, _sdi, _clk, _led; -#endif - uint8_t _orientation, _brightness; - - // Corresponding modes if orientation changed: - const autoIncMode_t modeTab [3][8] = { - // { R2L_BottomUp, BottomUp_R2L, L2R_BottomUp, BottomUp_L2R, R2L_TopDown, TopDown_R2L, L2R_TopDown, TopDown_L2R }// - /* 90° */ { BottomUp_L2R, L2R_BottomUp, TopDown_L2R, L2R_TopDown, BottomUp_R2L, R2L_BottomUp, TopDown_R2L, R2L_TopDown }, - /*180° */ { L2R_TopDown , TopDown_L2R, R2L_TopDown, TopDown_R2L, L2R_BottomUp, BottomUp_L2R, R2L_BottomUp, BottomUp_R2L}, - /*270° */ { TopDown_R2L , R2L_TopDown, BottomUp_R2L, R2L_BottomUp, TopDown_L2R, L2R_TopDown, BottomUp_L2R, L2R_BottomUp} - }; - - - bool hwSPI, blState; - - //_currentFont cfont; - -#ifdef ESP32 - SPIClass _spi; -#endif - - protected: - - uint32_t writeFunctionLevel; - - void getGFXCharExtent(uint8_t c, int16_t *gw, int16_t *gh, int16_t *xa); - - GFXfont *gfxFont; - - _currentFont cfont; -}; - -class GFXcanvas16 { -public: - GFXcanvas16(uint16_t w, uint16_t h); - ~GFXcanvas16(void); - void drawPixel(int16_t x, int16_t y, uint16_t color); - void fillScreen(uint16_t color); - void byteSwap(void); - void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - uint16_t getPixel(int16_t x, int16_t y) const; - uint16_t *getBuffer(void) const { return buffer; } - int16_t width(void) const { return _width; }; - int16_t height(void) const { return _height; } - void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); -protected: - uint16_t getRawPixel(int16_t x, int16_t y) const; - void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - int16_t WIDTH; - int16_t HEIGHT; - int16_t _width; - int16_t _height; - -private: - uint16_t *buffer; -}; -#endif diff --git a/yoRadio/src/IRremoteESP8266/IRrecv.cpp b/yoRadio/src/IRremoteESP8266/IRrecv.cpp index 5501d3c..eedfc2a 100644 --- a/yoRadio/src/IRremoteESP8266/IRrecv.cpp +++ b/yoRadio/src/IRremoteESP8266/IRrecv.cpp @@ -217,7 +217,8 @@ static void USE_IRAM_ATTR gpio_intr() { else params.rawbuf[rawlen] = (now - start) / kRawTick; } - params.rawlen++; + rawlen++; + params.rawlen = rawlen; start = now; diff --git a/yoRadio/src/audioI2S/Audio.cpp b/yoRadio/src/audioI2S/Audio.cpp index 6cde1bc..413ab3b 100644 --- a/yoRadio/src/audioI2S/Audio.cpp +++ b/yoRadio/src/audioI2S/Audio.cpp @@ -28,6 +28,10 @@ fs::SDFATFS SD_SDFAT; #if defined(ESP_ARDUINO_3) #include "soc/io_mux_reg.h" #endif +#ifdef ESP_ARDUINO_3 +#define dma_buf_count dma_desc_num +#define dma_buf_len dma_frame_num +#endif //--------------------------------------------------------------------------------------------------------------------- AudioBuffer::AudioBuffer(size_t maxBlockSize) { // if maxBlockSize isn't set use defaultspace (1600 bytes) is enough for aac and mp3 player @@ -323,7 +327,7 @@ void Audio::setDefaults() { } playI2Sremains(); - AUDIO_INFO("buffers freed, free Heap: %u bytes", ESP.getFreeHeap()); + AUDIO_INFO("buffers freed, free Heap: %lu bytes", ESP.getFreeHeap()); m_f_chunked = false; // Assume not chunked m_f_firstmetabyte = false; @@ -513,7 +517,7 @@ bool Audio::connecttohost(const char* host, const char* user, const char* pwd) { if(res){ uint32_t dt = millis() - t; strcpy(m_lastHost, l_host); - AUDIO_INFO("%s has been established in %u ms, free Heap: %u bytes", + AUDIO_INFO("%s has been established in %lu ms, free Heap: %lu bytes", m_f_ssl?"SSL":"Connection", dt, ESP.getFreeHeap()); m_f_running = true; } @@ -1292,7 +1296,7 @@ int Audio::read_WAV_Header(uint8_t* data, size_t len) { AUDIO_INFO("FormatCode: %u", fc); // AUDIO_INFO("Channel: %u", nic); // AUDIO_INFO("SampleRate: %u", sr); - AUDIO_INFO("DataRate: %u", dr); + AUDIO_INFO("DataRate: %lu", dr); AUDIO_INFO("DataBlockSize: %u", dbs); AUDIO_INFO("BitsPerSample: %u", bps); @@ -1388,7 +1392,7 @@ int Audio::read_FLAC_Header(uint8_t *data, size_t len) { m_controlCounter = FLAC_MAGIC; if(getDatamode() == AUDIO_LOCALFILE){ m_contentlength = getFileSize(); - AUDIO_INFO("Content-Length: %u", m_contentlength); + AUDIO_INFO("Content-Length: %lu", m_contentlength); } return 0; } @@ -1453,7 +1457,7 @@ int Audio::read_FLAC_Header(uint8_t *data, size_t len) { vTaskDelay(2); uint32_t nextval = bigEndian(data + 13, 3); m_flacSampleRate = nextval >> 4; - AUDIO_INFO("FLAC sampleRate: %u", m_flacSampleRate); + AUDIO_INFO("FLAC sampleRate: %lu", m_flacSampleRate); vTaskDelay(2); m_flacNumChannels = ((nextval & 0x06) >> 1) + 1; AUDIO_INFO("FLAC numChannels: %u", m_flacNumChannels); @@ -1469,13 +1473,13 @@ int Audio::read_FLAC_Header(uint8_t *data, size_t len) { AUDIO_INFO("FLAC bitsPerSample: %u", m_flacBitsPerSample); m_flacTotalSamplesInStream = bigEndian(data + 17, 4); if(m_flacTotalSamplesInStream){ - AUDIO_INFO("total samples in stream: %u", m_flacTotalSamplesInStream); + AUDIO_INFO("total samples in stream: %lu", m_flacTotalSamplesInStream); } else{ AUDIO_INFO("total samples in stream: N/A"); } if(bps != 0 && m_flacTotalSamplesInStream) { - AUDIO_INFO("audio file duration: %u seconds", m_flacTotalSamplesInStream / m_flacSampleRate); + AUDIO_INFO("audio file duration: %lu seconds", m_flacTotalSamplesInStream / m_flacSampleRate); } m_controlCounter = FLAC_MBH; // METADATA_BLOCK_HEADER retvalue = l + 3; @@ -1565,7 +1569,7 @@ int Audio::read_ID3_Header(uint8_t *data, size_t len) { if(getDatamode() == AUDIO_LOCALFILE){ ID3version = 0; m_contentlength = getFileSize(); - AUDIO_INFO("Content-Length: %u", m_contentlength); + AUDIO_INFO("Content-Length: %lu", m_contentlength); } m_controlCounter ++; APIC_seen = false; @@ -1941,10 +1945,10 @@ int Audio::read_M4A_Header(uint8_t *data, size_t len) { if(streamType!= 5) { log_e("Streamtype is not audio!"); } uint32_t maxBr = bigEndian(pos + 26, 4); // max bitrate - AUDIO_INFO("max bitrate: %i", maxBr); + AUDIO_INFO("max bitrate: %lu", maxBr); uint32_t avrBr = bigEndian(pos + 30, 4); // avg bitrate - AUDIO_INFO("avr bitrate: %i", avrBr); + AUDIO_INFO("avr bitrate: %lu", avrBr); uint16_t ASC = bigEndian(pos + 39, 2); @@ -1962,7 +1966,7 @@ int Audio::read_M4A_Header(uint8_t *data, size_t len) { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 }; uint8_t sRate = (ASC & 0x0600) >> 7; // next 4 bits Sampling Frequencies - AUDIO_INFO("Sampling Frequency: %u",samplingFrequencies[sRate]); + AUDIO_INFO("Sampling Frequency: %lu",samplingFrequencies[sRate]); uint8_t chConfig = (ASC & 0x78) >> 3; // next 4 bits if(chConfig == 0) AUDIO_INFO("Channel Configurations: AOT Specifc Config"); @@ -2048,7 +2052,7 @@ int Audio::read_M4A_Header(uint8_t *data, size_t len) { m_audioDataStart = headerSize; // m_contentlength = headerSize + m_audioDataSize; // after this mdat atom there may be other atoms if(getDatamode() == AUDIO_LOCALFILE){ - AUDIO_INFO("Content-Length: %u", m_contentlength); + AUDIO_INFO("Content-Length: %lu", m_contentlength); if(audio_progress) audio_progress(m_audioDataStart, m_audioDataSize); } m_controlCounter = M4A_OKAY; // that's all @@ -2086,7 +2090,7 @@ int Audio::read_OGG_Header(uint8_t *data, size_t len){ m_controlCounter = OGG_MAGIC; if(getDatamode() == AUDIO_LOCALFILE){ m_contentlength = getFileSize(); - AUDIO_INFO("Content-Length: %u", m_contentlength); + AUDIO_INFO("Content-Length: %lu", m_contentlength); } return 0; } @@ -2211,7 +2215,7 @@ int Audio::read_OGG_Header(uint8_t *data, size_t len){ uint32_t nextval = bigEndian(data + i, 3); i += 3; m_flacSampleRate = nextval >> 4; - AUDIO_INFO("FLAC sampleRate: %u", m_flacSampleRate); + AUDIO_INFO("FLAC sampleRate: %lu", m_flacSampleRate); vTaskDelay(2); m_flacNumChannels = ((nextval & 0x06) >> 1) + 1; AUDIO_INFO("FLAC numChannels: %u", m_flacNumChannels); @@ -2235,13 +2239,13 @@ int Audio::read_OGG_Header(uint8_t *data, size_t len){ m_flacTotalSamplesInStream = bigEndian(data + i, 4); i++; if(m_flacTotalSamplesInStream) { - AUDIO_INFO("total samples in stream: %u", m_flacTotalSamplesInStream); + AUDIO_INFO("total samples in stream: %lu", m_flacTotalSamplesInStream); } else { AUDIO_INFO("total samples in stream: N/A"); } if(bps != 0 && m_flacTotalSamplesInStream) { - AUDIO_INFO("audio file duration: %u seconds", m_flacTotalSamplesInStream / m_flacSampleRate); + AUDIO_INFO("audio file duration: %lu seconds", m_flacTotalSamplesInStream / m_flacSampleRate); } m_controlCounter = OGG_MAGIC; retvalue = pageLen; @@ -2255,7 +2259,7 @@ int Audio::read_OGG_Header(uint8_t *data, size_t len){ } if(!FLACDecoder_AllocateBuffers()) {m_f_running = false; stopSong(); return -1;} InBuff.changeMaxBlockSize(m_frameSizeFLAC); - AUDIO_INFO("FLACDecoder has been initialized, free Heap: %u bytes", ESP.getFreeHeap()); + AUDIO_INFO("FLACDecoder has been initialized, free Heap: %lu bytes", ESP.getFreeHeap()); m_controlCounter = OGG_OKAY; // 100 eofHeader = true; @@ -3079,7 +3083,7 @@ void Audio::processLocalFile() { playI2Sremains(); if(m_f_loop && f_stream){ //eof - AUDIO_INFO("loop from: %u to: %u", getFilePos(), m_audioDataStart); //TEST loop + AUDIO_INFO("loop from: %lu to: %lu", getFilePos(), m_audioDataStart); //TEST loop setFilePos(m_audioDataStart); if(m_codec == CODEC_FLAC) FLACDecoderReset(); /* @@ -3780,7 +3784,7 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque int32_t br = atoi(c_bitRate); // Found bitrate tag, read the bitrate in Kbit br = br * 1000; setBitrate(br); - sprintf(chbuf, "%d", getBitRate()); + sprintf(chbuf, "%lu", getBitRate()); if(audio_bitrate) audio_bitrate(chbuf); } @@ -3805,7 +3809,7 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque int32_t i_cl = atoi(c_cl); m_contentlength = i_cl; m_streamType = ST_WEBFILE; // Stream comes from a fileserver - if(m_f_Log) AUDIO_INFO("content-length: %i", m_contentlength); + if(m_f_Log) AUDIO_INFO("content-length: %lu", m_contentlength); } else if(startsWith(rhl, "icy-description:")) { @@ -3870,20 +3874,20 @@ bool Audio:: initializeDecoder(){ switch(m_codec){ case CODEC_MP3: if(!MP3Decoder_AllocateBuffers()) goto exit; - AUDIO_INFO("MP3Decoder has been initialized, free Heap: %u bytes", ESP.getFreeHeap()); + AUDIO_INFO("MP3Decoder has been initialized, free Heap: %lu bytes", ESP.getFreeHeap()); InBuff.changeMaxBlockSize(m_frameSizeMP3); break; case CODEC_AAC: if(!AACDecoder_IsInit()){ if(!AACDecoder_AllocateBuffers()) goto exit; - AUDIO_INFO("AACDecoder has been initialized, free Heap: %u bytes", ESP.getFreeHeap()); + AUDIO_INFO("AACDecoder has been initialized, free Heap: %lu bytes", ESP.getFreeHeap()); InBuff.changeMaxBlockSize(m_frameSizeAAC); } break; case CODEC_M4A: if(!AACDecoder_IsInit()){ if(!AACDecoder_AllocateBuffers()) goto exit; - AUDIO_INFO("AACDecoder has been initialized, free Heap: %u bytes", ESP.getFreeHeap()); + AUDIO_INFO("AACDecoder has been initialized, free Heap: %lu bytes", ESP.getFreeHeap()); InBuff.changeMaxBlockSize(m_frameSizeAAC); } break; @@ -3894,7 +3898,7 @@ bool Audio:: initializeDecoder(){ } if(!FLACDecoder_AllocateBuffers()) goto exit; InBuff.changeMaxBlockSize(m_frameSizeFLAC); - AUDIO_INFO("FLACDecoder has been initialized, free Heap: %u bytes", ESP.getFreeHeap()); + AUDIO_INFO("FLACDecoder has been initialized, free Heap: %lu bytes", ESP.getFreeHeap()); break; case CODEC_WAV: InBuff.changeMaxBlockSize(m_frameSizeWav); @@ -3912,7 +3916,7 @@ bool Audio:: initializeDecoder(){ return true; exit: - AUDIO_ERROR("Not enough free memory to initialize the decoder: %u bytes free", ESP.getFreeHeap()); + AUDIO_ERROR("Not enough free memory to initialize the decoder: %lu bytes free", ESP.getFreeHeap()); stopSong(); return false; } @@ -4101,7 +4105,7 @@ void Audio::showstreamtitle(const char* ml) { if(m_streamTitleHash != hash){ m_streamTitleHash = hash; - AUDIO_INFO("%s", sTit); + if(audio_info) audio_info(sTit); uint8_t pos = 12; // remove "StreamTitle=" if(sTit[pos] == '\'') pos++; // remove leading \' if(sTit[strlen(sTit) - 1] == '\'') sTit[strlen(sTit) -1] = '\0'; // remove trailing \' @@ -4121,7 +4125,7 @@ void Audio::showstreamtitle(const char* ml) { while(i < strlen(sUrl)){hash += sUrl[i] * i+1; i++;} if(m_streamTitleHash != hash){ m_streamTitleHash = hash; - AUDIO_INFO("%s", sUrl); + if(audio_info) audio_info(sUrl); } if(sUrl) {free(sUrl); sUrl = NULL;} } @@ -4134,7 +4138,7 @@ void Audio::showstreamtitle(const char* ml) { uint16_t len = idx2 - idx1; char *sAdv; sAdv = strndup(ml + idx1, len + 1); sAdv[len] = '\0'; - AUDIO_INFO("%s", sAdv); + if(audio_info) audio_info(sAdv); uint8_t pos = 21; // remove "StreamTitle=" if(sAdv[pos] == '\'') pos++; // remove leading \' if(sAdv[strlen(sAdv) - 1] == '\'') sAdv[strlen(sAdv) -1] = '\0'; // remove trailing \' @@ -4148,9 +4152,9 @@ void Audio::showCodecParams(){ // print Codec Parameter (mp3, aac) in audio_info() AUDIO_INFO("Channels: %i", getChannels()); - AUDIO_INFO("SampleRate: %i", getSampleRate()); + AUDIO_INFO("SampleRate: %lu", getSampleRate()); AUDIO_INFO("BitsPerSample: %i", getBitsPerSample()); - if(getBitRate()) {AUDIO_INFO("BitRate: %i", getBitRate());} + if(getBitRate()) {AUDIO_INFO("BitRate: %lu", getBitRate());} else {AUDIO_INFO("BitRate: N/A");} if(m_codec == CODEC_AAC || m_codec == CODEC_M4A){ @@ -4216,7 +4220,7 @@ int Audio::findNextSync(uint8_t* data, size_t len){ } if (nextSync == 0){ if(audio_info && swnf>0){ - sprintf(chbuf, "syncword not found %i times", swnf); + sprintf(chbuf, "syncword not found %lu times", swnf); audio_info(chbuf); swnf = 0; } diff --git a/yoRadio/src/audioI2S/AudioEx.h b/yoRadio/src/audioI2S/AudioEx.h index 8fa3522..50b4b95 100644 --- a/yoRadio/src/audioI2S/AudioEx.h +++ b/yoRadio/src/audioI2S/AudioEx.h @@ -20,7 +20,11 @@ #include #include #include +//TODO +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcpp" #include +#pragma GCC diagnostic pop #ifdef SDFATFS_USED #include // https://github.com/greiman/SdFat @@ -91,8 +95,8 @@ extern __attribute__((weak)) void audio_process_extern(int16_t* buff, uint16_t l extern __attribute__((weak)) void audio_progress(uint32_t startpos, uint32_t endpos); extern __attribute__((weak)) void audio_error(const char*); -#define AUDIO_INFO(...) {char buff[512 + 64]; sprintf(buff,__VA_ARGS__); if(audio_info) audio_info(buff);} -#define AUDIO_ERROR(...) {char buff[512 + 64]; sprintf(buff,__VA_ARGS__); if(audio_error) audio_error(buff);} +#define AUDIO_INFO(...) {char buff[512 + 64]; snprintf(buff, sizeof(buff),__VA_ARGS__); if(audio_info) audio_info(buff);} +#define AUDIO_ERROR(...) {char buff[512 + 64]; snprintf(buff, sizeof(buff),__VA_ARGS__); if(audio_error) audio_error(buff);} //---------------------------------------------------------------------------------------------------------------------- class AudioBuffer { diff --git a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp index 0b90a75..9c5a226 100644 --- a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp +++ b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp @@ -1351,7 +1351,7 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque int32_t br = atoi(c_bitRate); // Found bitrate tag, read the bitrate in Kbit br = br * 1000; m_bitrate= br; - sprintf(chbuf, "%d", br); + sprintf(chbuf, "%ld", br); if(audio_bitrate) audio_bitrate(chbuf); } @@ -1376,7 +1376,7 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque int32_t i_cl = atoi(c_cl); m_contentlength = i_cl; m_streamType = ST_WEBFILE; // Stream comes from a fileserver - if(m_f_Log) AUDIO_INFO("content-length: %i", m_contentlength); + if(m_f_Log) AUDIO_INFO("content-length: %lu", m_contentlength); } else if(startsWith(rhl, "icy-description:")) { @@ -1610,8 +1610,11 @@ uint32_t Audio::stop_mp3client(){ int v=read_register(SCI_VOL); m_f_webstream=false; write_register(SCI_VOL, 0); // Mute while stopping - - _client->flush(); // Flush stream client + #ifdef ESP_ARDUINO_3 + _client->clear(); // Flush stream client + #else + _client->flush(); + #endif _client->stop(); // Stop stream client write_register(SCI_VOL, v); return pos; @@ -1864,7 +1867,7 @@ bool Audio::connecttohost(const char* host, const char* user, const char* pwd) { if(res){ uint32_t dt = millis() - t; strcpy(m_lastHost, l_host); - AUDIO_INFO("%s has been established in %u ms, free Heap: %u bytes", + AUDIO_INFO("%s has been established in %lu ms, free Heap: %lu bytes", m_f_ssl?"SSL":"Connection", dt, ESP.getFreeHeap()); m_f_running = true; } @@ -2100,7 +2103,7 @@ bool Audio::connecttospeech(const char* speech, const char* lang){ return false; } clientsecure.print(resp); - sprintf(chbuf, "SSL has been established, free Heap: %u bytes", ESP.getFreeHeap()); + sprintf(chbuf, "SSL has been established, free Heap: %lu bytes", ESP.getFreeHeap()); if(audio_info) audio_info(chbuf); m_f_webstream = true; @@ -2191,7 +2194,7 @@ int Audio::read_MP3_Header(uint8_t *data, size_t len) { if(m_f_localfile){ m_contentlength = getFileSize(); ID3version = 0; - sprintf(chbuf, "Content-Length: %u", m_contentlength); + sprintf(chbuf, "Content-Length: %lu", m_contentlength); if(audio_info) audio_info(chbuf); } m_controlCounter ++; @@ -2571,7 +2574,7 @@ uint32_t Audio::getAudioCurrentTime(){ } m_localBitrateSend = prev_bitrate==m_avr_bitrate; if(m_avr_bitrate==0) return 0; - sprintf(brbuf, "%d", m_avr_bitrate); + sprintf(brbuf, "%lu", m_avr_bitrate); if(audio_bitrate && !m_localBitrateSend) audio_bitrate(brbuf); m_localBitrateSend = true; m_audioFileDuration = 8 * ((float)m_audioDataSize / (m_avr_bitrate)); @@ -2584,7 +2587,7 @@ uint32_t Audio::getAudioCurrentTime(){ m_avr_bitrate = SCIStatus * 8; m_localBitrateSend = prev_bitrate==m_avr_bitrate; if(m_avr_bitrate==0) return 0; - sprintf(brbuf, "%d", m_avr_bitrate); + sprintf(brbuf, "%lu", m_avr_bitrate); if(audio_bitrate && !m_localBitrateSend) audio_bitrate(brbuf); m_localBitrateSend = true; m_audioFileDuration = 8 * ((float)m_audioDataSize / (m_avr_bitrate)); diff --git a/yoRadio/src/core/audiohandlers.h b/yoRadio/src/core/audiohandlers.h index 6d9a0c5..ca6087c 100644 --- a/yoRadio/src/core/audiohandlers.h +++ b/yoRadio/src/core/audiohandlers.h @@ -84,8 +84,8 @@ void audio_id3album(const char *info){ if(strlen(config.station.title)==0){ config.setTitle(info); }else{ - char tmp[BUFLEN]; - snprintf(tmp, BUFLEN, "%s - %s", config.station.title, info); + char tmp[BUFLEN+3]; + snprintf(tmp, BUFLEN+3, "%s - %s", config.station.title, info); config.setTitle(tmp); } } diff --git a/yoRadio/src/core/config.cpp b/yoRadio/src/core/config.cpp index 1469524..ad36921 100644 --- a/yoRadio/src/core/config.cpp +++ b/yoRadio/src/core/config.cpp @@ -221,6 +221,9 @@ bool Config::spiffsCleanup(){ } void Config::waitConnection(){ +#if I2S_DOUT==255 + return; +#endif while(!player.connproc) vTaskDelay(50); vTaskDelay(500); } @@ -1022,7 +1025,7 @@ void Config::bootInfo() { for(int i=0; i<17; i=i+8) { chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; } - BOOTLOG("chip:\t\tmodel: %s | rev: %d | id: %d | cores: %d | psram: %d", ESP.getChipModel(), ESP.getChipRevision(), chipId, ESP.getChipCores(), ESP.getPsramSize()); + BOOTLOG("chip:\t\tmodel: %s | rev: %d | id: %lu | cores: %d | psram: %lu", ESP.getChipModel(), ESP.getChipRevision(), chipId, ESP.getChipCores(), ESP.getPsramSize()); BOOTLOG("display:\t%d", DSP_MODEL); if(VS1053_CS==255) { BOOTLOG("audio:\t\t%s (%d, %d, %d)", "I2S", I2S_DOUT, I2S_BCLK, I2S_LRC); diff --git a/yoRadio/src/core/display.cpp b/yoRadio/src/core/display.cpp index 5180a2c..4dcfd25 100644 --- a/yoRadio/src/core/display.cpp +++ b/yoRadio/src/core/display.cpp @@ -457,9 +457,9 @@ void Display::loop() { if(pm_result) switch (request.type){ case NEWMODE: _swichMode((displayMode_e)request.payload); break; - case CLOSEPLAYLIST: player.sendCommand({PR_PLAY, request.payload}); + case CLOSEPLAYLIST: player.sendCommand({PR_PLAY, request.payload}); break; case CLOCK: - if(_mode==PLAYER || _mode==SCREENSAVER) _time(); + if(_mode==PLAYER || _mode==SCREENSAVER) _time(request.payload==1); /*#ifdef USE_NEXTION if(_mode==TIMEZONE) nextion.localTime(network.timeinfo); if(_mode==INFO) nextion.rssi(); @@ -623,7 +623,7 @@ void Display::_time(bool redraw) { //_clock->moveTo({clockConf.left, ft, 0}); _clock->moveTo({lt, ft, 0}); } - _clock->draw(); + _clock->draw(redraw); /*#ifdef USE_NEXTION nextion.printClock(network.timeinfo); #endif*/ diff --git a/yoRadio/src/core/mqtt.cpp b/yoRadio/src/core/mqtt.cpp index 83377c1..276c3fe 100644 --- a/yoRadio/src/core/mqtt.cpp +++ b/yoRadio/src/core/mqtt.cpp @@ -8,7 +8,7 @@ AsyncMqttClient mqttClient; TimerHandle_t mqttReconnectTimer; -char topic[100], status[BUFLEN+50]; +char topic[100], status[BUFLEN*2]; void connectToMqtt() { //config.waitConnection(); @@ -44,7 +44,8 @@ void mqttPublishStatus() { char title[BUFLEN/2]; config.escapeQuotes(config.station.name, name, sizeof(name)-10); config.escapeQuotes(config.station.title, title, sizeof(title)-10); - sprintf(status, "{\"status\": %d, \"station\": %d, \"name\": \"%s\", \"title\": \"%s\", \"on\": %d}", player.status()==PLAYING?1:0, config.lastStation(), name, title, config.store.dspon); + sprintf(status, "{\"status\": %d, \"station\": %d, \"name\": \"%s\", \"title\": \"%s\", \"on\": %d}", + player.status()==PLAYING?1:0, config.lastStation(), name, title, config.store.dspon); mqttClient.publish(topic, 0, true, status); } } diff --git a/yoRadio/src/core/options.h b/yoRadio/src/core/options.h index da7d1e3..71ec15f 100644 --- a/yoRadio/src/core/options.h +++ b/yoRadio/src/core/options.h @@ -2,7 +2,7 @@ #define options_h #pragma once -#define YOVERSION "0.9.702" +#define YOVERSION "0.9.710" /******************************************************* DO NOT EDIT THIS FILE. diff --git a/yoRadio/src/core/telnet.cpp b/yoRadio/src/core/telnet.cpp index 056f8ef..c520bfa 100644 --- a/yoRadio/src/core/telnet.cpp +++ b/yoRadio/src/core/telnet.cpp @@ -49,7 +49,11 @@ void Telnet::toggle() { } void Telnet::emptyClientStream(WiFiClient client) { + #ifdef ESP_ARDUINO_3 + client.clear(); + #else client.flush(); + #endif delay(50); while (client.available()) { client.read(); @@ -80,7 +84,7 @@ void Telnet::loop() { return; } uint8_t i; - if(config.store.telnet) + if(config.store.telnet){ if (WiFi.status() == WL_CONNECTED) { if (server.hasClient()) { for (i = 0; i < MAX_TLN_CLIENTS; i++) { @@ -88,7 +92,11 @@ void Telnet::loop() { if (clients[i]) { clients[i].stop(); } + #ifdef ESP_ARDUINO_3 + clients[i] = server.accept(); + #else clients[i] = server.available(); + #endif if (!clients[i]) Serial.println("available broken"); on_connect(config.ipToStr(clients[i].remoteIP()), i); clients[i].setNoDelay(true); @@ -97,7 +105,11 @@ void Telnet::loop() { } } if (i >= MAX_TLN_CLIENTS) { + #ifdef ESP_ARDUINO_3 + server.accept().stop(); + #else server.available().stop(); + #endif } } for (i = 0; i < MAX_TLN_CLIENTS; i++) { @@ -115,6 +127,7 @@ void Telnet::loop() { } delay(1000); } + } handleSerial(); } @@ -446,12 +459,16 @@ void Telnet::on_input(const char* str, uint8_t clientId) { printf(clientId, "##WIFI.STATION#\n> "); return; } - if (sscanf(str, "wifi.con(\"%[^\"]\",\"%[^\"]\")", config.tmpBuf, config.tmpBuf2) == 2 || sscanf(str, "wifi.con(%[^,],%[^)])", config.tmpBuf, config.tmpBuf2) == 2 || sscanf(str, "wifi.con(%[^ ] %[^)])", config.tmpBuf, config.tmpBuf2) == 2 || sscanf(str, "wifi %[^ ] %s", config.tmpBuf, config.tmpBuf2) == 2) { - snprintf(cmBuf, sizeof(cmBuf), "New SSID: \"%s\" with PASS: \"%s\" for next boot\n> ", config.tmpBuf, config.tmpBuf2); + char ssidbuf[50], passbuff[50]; + if (sscanf(str, "wifi.con(\"%[^\"]\",\"%[^\"]\")", ssidbuf, passbuff) == 2 || + sscanf(str, "wifi.con(%[^,],%[^)])", ssidbuf, passbuff) == 2 || + sscanf(str, "wifi.con(%[^ ] %[^)])", ssidbuf, passbuff) == 2 || + sscanf(str, "wifi %[^ ] %s", ssidbuf, passbuff) == 2) { + snprintf(cmBuf, sizeof(cmBuf), "New SSID: \"%s\" with PASS: \"%s\" for next boot\n> ", ssidbuf, passbuff); printf(clientId, cmBuf); printf(clientId, "...REBOOTING...\n> "); memset(cmBuf, 0, sizeof(cmBuf)); - snprintf(cmBuf, sizeof(cmBuf), "%s\t%s", config.tmpBuf, config.tmpBuf2); + snprintf(cmBuf, sizeof(cmBuf), "%s\t%s", ssidbuf, passbuff); config.saveWifiFromNextion(cmBuf); return; } diff --git a/yoRadio/src/core/timekeeper.cpp b/yoRadio/src/core/timekeeper.cpp index aadaa16..3593b16 100644 --- a/yoRadio/src/core/timekeeper.cpp +++ b/yoRadio/src/core/timekeeper.cpp @@ -239,7 +239,7 @@ void TimeKeeper::timeTask(){ tsFailCnt = 0; forceTimeSync = false; mktime(&network.timeinfo); - display.putRequest(CLOCK); + display.putRequest(CLOCK, 1); network.requestTimeSync(true); #if RTCSUPPORTED if (config.isRTCFound()) rtc.setTime(&network.timeinfo); diff --git a/yoRadio/src/displays/conf/displayILI9225conf.h b/yoRadio/src/displays/conf/displayILI9225conf.h index 649f44d..20d7e9e 100644 --- a/yoRadio/src/displays/conf/displayILI9225conf.h +++ b/yoRadio/src/displays/conf/displayILI9225conf.h @@ -14,24 +14,23 @@ #define MAX_WIDTH DSP_WIDTH-TFT_FRAMEWDT*2 #if BITRATE_FULL - #define TITLE_FIX 28 + #define TITLE_FIX 44 #else #define TITLE_FIX 0 #endif #define bootLogoTop 28 -//#define DSP_QUEUE_TICKS 5 /* SROLLS */ /* {{ left, top, fontsize, align }, buffsize, uppercase, width, scrolldelay, scrolldelta, scrolltime } */ -const ScrollConfig metaConf PROGMEM = {{ TFT_FRAMEWDT, TFT_FRAMEWDT, 2, WA_LEFT }, 140, true, DSP_WIDTH+10, 5000, 4, 30 }; -const ScrollConfig title1Conf PROGMEM = {{ TFT_FRAMEWDT, 28, 1, WA_LEFT }, 140, true, MAX_WIDTH-TITLE_FIX, 5000, 3, 25 }; -const ScrollConfig title2Conf PROGMEM = {{ TFT_FRAMEWDT, 40, 1, WA_LEFT }, 140, true, MAX_WIDTH-TITLE_FIX, 5000, 3, 25 }; -const ScrollConfig playlistConf PROGMEM = {{ TFT_FRAMEWDT, 80, 2, WA_LEFT }, 140, true, DSP_WIDTH+10, 1000, 4, 30 }; +const ScrollConfig metaConf PROGMEM = {{ TFT_FRAMEWDT, TFT_FRAMEWDT+1, 2, WA_LEFT }, 140, true, MAX_WIDTH, 5000, 4, 30 }; +const ScrollConfig title1Conf PROGMEM = {{ TFT_FRAMEWDT, 31, 2, WA_LEFT }, 140, true, MAX_WIDTH-TITLE_FIX, 5000, 3, 25 }; +const ScrollConfig title2Conf PROGMEM = {{ TFT_FRAMEWDT, 51, 2, WA_LEFT }, 140, true, MAX_WIDTH-TITLE_FIX, 5000, 3, 25 }; +const ScrollConfig playlistConf PROGMEM = {{ TFT_FRAMEWDT, 80, 2, WA_LEFT }, 140, true, MAX_WIDTH, 1000, 4, 30 }; const ScrollConfig apTitleConf PROGMEM = {{ TFT_FRAMEWDT, TFT_FRAMEWDT, 2, WA_CENTER }, 140, false, MAX_WIDTH, 0, 4, 30 }; -const ScrollConfig apSettConf PROGMEM = {{ TFT_FRAMEWDT, DSP_HEIGHT-TFT_FRAMEWDT-16, 2, WA_LEFT }, 140, false, DSP_WIDTH+10, 0, 3, 25 }; -const ScrollConfig weatherConf PROGMEM = {{ TFT_FRAMEWDT, 56, 2, WA_LEFT }, 140, true, DSP_WIDTH+10, 0, 4, 30 }; +const ScrollConfig apSettConf PROGMEM = {{ TFT_FRAMEWDT, DSP_HEIGHT-TFT_FRAMEWDT-16, 2, WA_LEFT }, 140, false, MAX_WIDTH, 0, 3, 25 }; +const ScrollConfig weatherConf PROGMEM = {{ TFT_FRAMEWDT, 146, 1, WA_LEFT }, 140, true, MAX_WIDTH, 0, 4, 30 }; /* BACKGROUNDS */ /* {{ left, top, fontsize, align }, width, height, outlined } */ -const FillConfig metaBGConf PROGMEM = {{ 0, 0, 0, WA_LEFT }, DSP_WIDTH, 22, false }; +const FillConfig metaBGConf PROGMEM = {{ 0, 0, 0, WA_LEFT }, DSP_WIDTH, 24, false }; const FillConfig metaBGConfInv PROGMEM = {{ 0, 22, 0, WA_LEFT }, DSP_WIDTH, 1, false }; const FillConfig volbarConf PROGMEM = {{ TFT_FRAMEWDT, DSP_HEIGHT-TFT_FRAMEWDT-4, 0, WA_LEFT }, MAX_WIDTH, 4, true }; const FillConfig playlBGConf PROGMEM = {{ 0, 76, 0, WA_LEFT }, DSP_WIDTH, 22, false }; @@ -48,15 +47,15 @@ const WidgetConfig apNameConf PROGMEM = { TFT_FRAMEWDT, 38, 2, WA_CENTER }; const WidgetConfig apName2Conf PROGMEM = { TFT_FRAMEWDT, 62, 2, WA_CENTER }; const WidgetConfig apPassConf PROGMEM = { TFT_FRAMEWDT, 102, 2, WA_CENTER }; const WidgetConfig apPass2Conf PROGMEM = { TFT_FRAMEWDT, 126, 2, WA_CENTER }; -const WidgetConfig clockConf PROGMEM = { TFT_FRAMEWDT*3, 130, 0, WA_RIGHT }; -const WidgetConfig vuConf PROGMEM = { TFT_FRAMEWDT, 58, 1, WA_LEFT }; +const WidgetConfig clockConf PROGMEM = { TFT_FRAMEWDT*3, 122, 0, WA_RIGHT }; +const WidgetConfig vuConf PROGMEM = { TFT_FRAMEWDT, 76, 1, WA_LEFT }; const WidgetConfig bootWdtConf PROGMEM = { 0, 130, 1, WA_CENTER }; const ProgressConfig bootPrgConf PROGMEM = { 90, 14, 4 }; -const BitrateConfig fullbitrateConf PROGMEM = {{DSP_WIDTH-TFT_FRAMEWDT-21, 25, 1, WA_LEFT}, 22 }; +const BitrateConfig fullbitrateConf PROGMEM = {{DSP_WIDTH-TFT_FRAMEWDT-40, 27, 2, WA_LEFT}, 40 }; /* BANDS */ /* { onebandwidth, onebandheight, bandsHspace, bandsVspace, numofbands, fadespeed } */ -const VUBandsConfig bandsConf PROGMEM = { 19, 90, 2, 2, 10, 2 }; +const VUBandsConfig bandsConf PROGMEM = { 19, 80, 2, 2, 10, 2 }; /* STRINGS */ const char numtxtFmt[] PROGMEM = "%d"; const char rssiFmt[] PROGMEM = "WiFi %d"; @@ -65,8 +64,8 @@ const char voltxtFmt[] PROGMEM = "\023\025%d"; const char bitrateFmt[] PROGMEM = "%d kBs"; /* MOVES */ /* { left, top, width } */ -const MoveConfig clockMove PROGMEM = { TFT_FRAMEWDT*2, 130, 0 }; -const MoveConfig weatherMove PROGMEM = { TFT_FRAMEWDT, 64, DSP_WIDTH+10 }; -const MoveConfig weatherMoveVU PROGMEM = { TFT_FRAMEWDT+46, 58, DSP_WIDTH+10-46 }; +const MoveConfig clockMove PROGMEM = { TFT_FRAMEWDT*2, 122, -1 }; +const MoveConfig weatherMove PROGMEM = { TFT_FRAMEWDT, 146, MAX_WIDTH }; +const MoveConfig weatherMoveVU PROGMEM = { TFT_FRAMEWDT+46, 146, MAX_WIDTH-46 }; #endif diff --git a/yoRadio/src/displays/conf/displayLCD2004conf.h b/yoRadio/src/displays/conf/displayLCD2004conf.h index e71b592..8eea1d5 100644 --- a/yoRadio/src/displays/conf/displayLCD2004conf.h +++ b/yoRadio/src/displays/conf/displayLCD2004conf.h @@ -21,8 +21,8 @@ #define META_MOVE /* SROLLS */ /* {{ left, top, fontsize, align }, buffsize, uppercase, width, scrolldelay, scrolldelta, scrolltime } */ -#define SDELTA 2 -#define STIME 300 +#define SDELTA 3 +#define STIME 500 const ScrollConfig metaConf PROGMEM = {{ 0, 0, 1, WA_LEFT }, 140, true, MAX_WIDTH-6, 2000, SDELTA, STIME }; const ScrollConfig title1Conf PROGMEM = {{ 0, 1, 1, WA_LEFT }, 140, true, MAX_WIDTH-4, 2000, SDELTA, STIME }; const ScrollConfig title2Conf PROGMEM = {{ 0, 2, 1, WA_LEFT }, 140, true, MAX_WIDTH, 2000, SDELTA, STIME }; diff --git a/yoRadio/src/displays/displayILI9225.cpp b/yoRadio/src/displays/displayILI9225.cpp index 14750f4..8e97776 100644 --- a/yoRadio/src/displays/displayILI9225.cpp +++ b/yoRadio/src/displays/displayILI9225.cpp @@ -4,90 +4,25 @@ #include #include "../core/config.h" -extern unsigned char yofont5x7[]; -extern unsigned char yofont10x14[]; - -DspCore::DspCore(): TFT_22_ILI9225(TFT_RST, TFT_DC, TFT_CS, 0) {} - -void DspCore::setTextSize(uint8_t s){ - if(s==2){ - setFont(yofont10x14, true); - }else{ - setFont(yofont5x7, true); - } -} - -void DspCore::setTextColor(uint16_t fg, uint16_t bg){ - _bgcolor=bg; - setBackgroundColor(_bgcolor); - _fgcolor=fg; -} - -void DspCore::setCursor(int16_t x, int16_t y){ - _cursorx=x; - _cursory=y; -} - -uint16_t DspCore::print(const char* s){ - - if(_gFont){ - drawGFXText(_cursorx, _cursory, s, _fgcolor); - return 0; - }else{ - _cursorx=drawText(_cursorx, _cursory, s, _fgcolor); - return _cursorx; - } -} - -void DspCore::setFont(uint8_t* font, bool monoSp) { - _gFont = false; - TFT_22_ILI9225::setFont(font, monoSp); -} - -void DspCore::setFont(const GFXfont *f) { - if (f) { - _gFont = true; - setGFXFont(f); - } else { - setFont(yofont5x7, false); - } -} - -void DspCore::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { - if(y<0){ - h=h+y; - y=0; - } - fillRectangle(x, y, x+w, y+h, color); -} - -void DspCore::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){ - drawRectangle(x, y, x+w, y+h, color); -} - -void DspCore::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color){ - drawLine(x, y, x, y+h, color); -} - -void DspCore::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color){ - drawLine(x, y, x+w, y, color); -} - -void DspCore::initDisplay() { #if DSP_HSPI - begin(SPI2); +DspCore::DspCore(): Adafruit_ILI9225(&SPI2, TFT_DC, TFT_CS, TFT_RST) {} #else - begin(); +DspCore::DspCore(): Adafruit_ILI9225(TFT_CS, TFT_DC, TFT_RST) {} #endif + +void DspCore::initDisplay() { + begin(); invert(); + cp437(true); flip(); - setTextSize(1); + setTextWrap(false); } -void DspCore::clearDsp(bool black){ clear(black?0x0000:config.theme.background); } -void DspCore::flip(){ setOrientation(config.store.flipscreen?3:1); } +void DspCore::clearDsp(bool black){ fillScreen(black?0:config.theme.background); } +void DspCore::flip(){ setRotation(config.store.flipscreen?1:3); } void DspCore::invert(){ invertDisplay(config.store.invertdisplay); } void DspCore::sleep(void){ setDisplay(false); } void DspCore::wake(void){ setDisplay(true); } + #endif diff --git a/yoRadio/src/displays/displayILI9225.h b/yoRadio/src/displays/displayILI9225.h index ffb23da..756b5fc 100644 --- a/yoRadio/src/displays/displayILI9225.h +++ b/yoRadio/src/displays/displayILI9225.h @@ -3,12 +3,12 @@ #include "../core/options.h" //================================================== #include "Arduino.h" -#include "../ILI9225Fix/TFT_22_ILI9225Fix.h" +#include "../Adafruit_ILI9225/Adafruit_ILI9225.h" #include "fonts/bootlogo99x64.h" #include "fonts/dsfont35.h" typedef GFXcanvas16 Canvas; -typedef TFT_22_ILI9225 yoDisplay; +typedef Adafruit_ILI9225 yoDisplay; #include "tools/commongfx.h" diff --git a/yoRadio/src/displays/dspcore.h b/yoRadio/src/displays/dspcore.h index a755079..bc798e7 100644 --- a/yoRadio/src/displays/dspcore.h +++ b/yoRadio/src/displays/dspcore.h @@ -74,6 +74,7 @@ #elif DSP_MODEL==DSP_ILI9225 // https://k210.org/images/content/uploads/yoradio/ILI9225.jpg #define TIME_SIZE 35 + #define PSFBUFFER #include "displayILI9225.h" #elif DSP_MODEL==DSP_ST7796 // https://k210.org/images/content/uploads/yoradio/ST7796.jpg diff --git a/yoRadio/src/displays/tools/commongfx.h b/yoRadio/src/displays/tools/commongfx.h index bc24bf4..2c0e094 100644 --- a/yoRadio/src/displays/tools/commongfx.h +++ b/yoRadio/src/displays/tools/commongfx.h @@ -2,7 +2,6 @@ #define common_gfx_h #include "../widgets/widgetsconfig.h" // displayXXXDDDDconf.h #include "utf8Rus.h" -#define ADAFRUIT_CLIPPING !defined(DSP_LCD) && DSP_MODEL!=DSP_ILI9225 typedef struct clipArea { uint16_t left; @@ -64,31 +63,7 @@ class DspCore: public yoDisplay { void setScrollId(void * scrollid) { _scrollid = scrollid; } void * getScrollId() { return _scrollid; } uint16_t textWidth(const char *txt); - #if DSP_MODEL==DSP_ILI9225 - uint16_t width(void) { return (int16_t)maxX(); } - uint16_t height(void) { return (int16_t)maxY(); } - inline void drawRGBBitmap(int16_t x, int16_t y, const uint16_t *bitmap, int16_t w, int16_t h){ drawBitmap(x, y, bitmap, w, h); } - uint16_t print(const char* s); - void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - void setFont(const GFXfont *f = NULL); - void setFont(uint8_t* font, bool monoSp=false ); - void setTextColor(uint16_t fg, uint16_t bg); - void setCursor(int16_t x, int16_t y); - void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - inline uint16_t drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t color = COLOR_WHITE){ - if(_clipping){ - if ((x < _cliparea.left) || (x >= _cliparea.left+_cliparea.width) || (y < _cliparea.top) || (y > _cliparea.top + _cliparea.height)) { - return cfont.width; - } - } - uint16_t ret=TFT_22_ILI9225::drawChar(x, y, ch, color); - return ret; - } - void setTextSize(uint8_t s); - #endif - #if ADAFRUIT_CLIPPING + #if !defined(DSP_LCD) inline void writePixel(int16_t x, int16_t y, uint16_t color) { if(_clipping){ if ((x < _cliparea.left) || (x > _cliparea.left+_cliparea.width) || (y < _cliparea.top) || (y > _cliparea.top + _cliparea.height)) return; @@ -122,11 +97,6 @@ class DspCore: public yoDisplay { #ifdef PSFBUFFER psFrameBuffer* _fb=nullptr; #endif - #if DSP_MODEL==DSP_ILI9225 - uint16_t _bgcolor, _fgcolor; - int16_t _cursorx, _cursory; - bool _gFont/*, _started*/; - #endif }; extern DspCore dsp; diff --git a/yoRadio/src/displays/widgets/widgets.cpp b/yoRadio/src/displays/widgets/widgets.cpp index 94896d2..93928c5 100644 --- a/yoRadio/src/displays/widgets/widgets.cpp +++ b/yoRadio/src/displays/widgets/widgets.cpp @@ -234,11 +234,16 @@ void ScrollWidget::_draw() { uint16_t _newx = fbl - _x; const char* _cursor = _text + _newx / _charWidth; uint16_t hiddenChars = _cursor - _text; + uint8_t addChars = _fb->ready()?2:1; if (hiddenChars < strlen(_text)) { - snprintf(_window, _width / _charWidth + 1, "%s%s%s", _cursor, _sep, _text); + //TODO + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-truncation=" + snprintf(_window, _width / _charWidth + addChars, "%s%s%s", _cursor, _sep, _text); + #pragma GCC diagnostic pop } else { const char* _scursor = _sep + (_cursor - (_text + strlen(_text))); - snprintf(_window, _width / _charWidth + 1, "%s%s", _scursor, _text); + snprintf(_window, _width / _charWidth + addChars, "%s%s", _scursor, _text); } if(_fb->ready()){ #ifdef PSFBUFFER @@ -420,26 +425,18 @@ void VuWidget::_draw(){ #else _canvas->fillRect(0, 0, _bands.width-(_bands.width-measL), _bands.width, _bgcolor); _canvas->fillRect(_bands.width * 2 + _bands.space - measR, 0, measR, _bands.width, _bgcolor); - #if DSP_MODEL!=DSP_ILI9225 dsp.startWrite(); dsp.setAddrWindow(_config.left, _config.top, _bands.width * 2 + _bands.space, _bands.height); dsp.writePixels((uint16_t*)_canvas->getBuffer(), (_bands.width * 2 + _bands.space)*_bands.height); dsp.endWrite(); - #else - dsp.drawRGBBitmap(_config.left, _config.top, _canvas->getBuffer(), _bands.width * 2 + _bands.space, _bands.height); - #endif #endif }else{ _canvas->fillRect(0, 0, _bands.width, measL, _bgcolor); _canvas->fillRect(_bands.width + _bands.space, 0, _bands.width, measR, _bgcolor); - #if DSP_MODEL!=DSP_ILI9225 dsp.startWrite(); dsp.setAddrWindow(_config.left, _config.top, _bands.width * 2 + _bands.space, _bands.height); dsp.writePixels((uint16_t*)_canvas->getBuffer(), (_bands.width * 2 + _bands.space)*_bands.height); dsp.endWrite(); - #else - dsp.drawRGBBitmap(_config.left, _config.top, _canvas->getBuffer(), _bands.width * 2 + _bands.space, _bands.height); - #endif } } @@ -499,11 +496,11 @@ void VuWidget::_clear(){ } uint16_t _textWidth(const char *txt){ uint16_t w = 0, l=strlen(txt); for(uint16_t c=0;cready()) return *_fb; - #endif - return dsp; - } + +Adafruit_GFX& ClockWidget::getRealDsp(){ +#ifdef PSFBUFFER + if (_fb && _fb->ready()) return *_fb; #endif + return dsp; +} + void ClockWidget::_printClock(bool force){ auto& gfx = getRealDsp(); gfx.setTextSize(Clock_GFXfontPtr==nullptr?TIME_SIZE:1); @@ -770,9 +763,9 @@ void ClockWidget::_clearClock(){ #endif } -void ClockWidget::draw(){ +void ClockWidget::draw(bool force){ if(!_active) return; - _printClock(_getTime()); + _printClock(_getTime() || force); } void ClockWidget::_draw(){ diff --git a/yoRadio/src/displays/widgets/widgets.h b/yoRadio/src/displays/widgets/widgets.h index eef58fb..db675c7 100644 --- a/yoRadio/src/displays/widgets/widgets.h +++ b/yoRadio/src/displays/widgets/widgets.h @@ -205,18 +205,14 @@ class ClockWidget: public Widget { public: using Widget::init; void init(WidgetConfig wconf, uint16_t fgcolor, uint16_t bgcolor); - void draw(); + void draw(bool force=false); uint8_t textsize(){ return _config.textsize; } void clear(){ _clearClock(); } inline uint16_t dateSize(){ return _space+ _dateheight; } inline uint16_t clockWidth(){ return _clockwidth; } private: #ifndef DSP_LCD - #if DSP_MODEL==DSP_ILI9225 - auto &getRealDsp(); - #else Adafruit_GFX &getRealDsp(); - #endif #endif protected: char _timebuffer[20]="00:00"; diff --git a/yoRadio/src/yoEncoder/yoEncoder.h b/yoRadio/src/yoEncoder/yoEncoder.h index ad9e081..37e16f9 100644 --- a/yoRadio/src/yoEncoder/yoEncoder.h +++ b/yoRadio/src/yoEncoder/yoEncoder.h @@ -51,7 +51,7 @@ public: uint8_t encoderSteps, bool internalPullup = true); void setBoundaries(long minValue = -100, long maxValue = 100, bool circleValues = false); - void IRAM_ATTR readEncoder_ISR(); + void readEncoder_ISR(); void setup(void (*ISR_callback)(void)); void begin();