diff --git a/cppsrc/U8g2lib.h b/cppsrc/U8g2lib.h index 94f6223b..95827043 100644 --- a/cppsrc/U8g2lib.h +++ b/cppsrc/U8g2lib.h @@ -110,7 +110,7 @@ class U8G2 : public Print uint8_t getMenuEvent(void) { return u8x8_GetMenuEvent(u8g2_GetU8x8(&u8g2)); } void initDisplay(void) { - u8g2_InitDisplay(&u8g2); } + u8g2_InitDisplay(&u8g2, u8g2_parent_class); } void clearDisplay(void) { u8g2_ClearDisplay(&u8g2); } @@ -121,6 +121,9 @@ class U8G2 : public Print void setFlipMode(uint8_t mode) { u8g2_SetFlipMode(&u8g2, mode); } + void setGrey(uint8_t value) { + u8g2_SetGrey(&u8g2, value); } + void setContrast(uint8_t value) { u8g2_SetContrast(&u8g2, value); } @@ -135,6 +138,7 @@ class U8G2 : public Print #ifndef U8G2_USE_DYNAMIC_ALLOC initDisplay(); clearDisplay(); + setFlipMode(0); setPowerSave(0); return 1; #else @@ -251,6 +255,7 @@ class U8G2 : public Print void setFont(const uint8_t *font) {u8g2_SetFont(&u8g2, font); } void setFontMode(uint8_t is_transparent) {u8g2_SetFontMode(&u8g2, is_transparent); } void setFontDirection(uint8_t dir) {u8g2_SetFontDirection(&u8g2, dir); } + void setFontScroll(int8_t x, int8_t y, uint8_t gap=0) {u8g2_SetFontScroll(&u8g2, x, y, gap); } int8_t getAscent(void) { return u8g2_GetAscent(&u8g2); } int8_t getDescent(void) { return u8g2_GetDescent(&u8g2); } @@ -7952,6 +7957,186 @@ class U8G2_SSD1329_128X96_NONAME_F_8080 : public U8G2 { u8x8_SetPin_8Bit_8080(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); } }; +class U8G2_SSD1362_256X64_1_4W_SW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_1_4W_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_1(&u8g2, rotation, u8x8_byte_arduino_4wire_sw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_SW_SPI(getU8x8(), clock, data, cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_1_4W_HW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_1_4W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_1(&u8g2, rotation, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_HW_SPI(getU8x8(), cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_1_2ND_4W_HW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_1_2ND_4W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_1(&u8g2, rotation, u8x8_byte_arduino_2nd_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_HW_SPI(getU8x8(), cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_1_3W_SW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_1_3W_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_1(&u8g2, rotation, u8x8_byte_arduino_3wire_sw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_3Wire_SW_SPI(getU8x8(), clock, data, cs, reset); + } +}; +class U8G2_SSD1362_256X64_1_3W_HW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_1_3W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_1(&u8g2, rotation, u8x8_byte_arduino_3wire_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_3Wire_HW_SPI(getU8x8(), cs, reset); + } +}; +class U8G2_SSD1362_256X64_1_6800 : public U8G2 { + public: U8G2_SSD1362_256X64_1_6800(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_1(&u8g2, rotation, u8x8_byte_8bit_6800mode, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_8Bit_6800(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_1_8080 : public U8G2 { + public: U8G2_SSD1362_256X64_1_8080(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_1(&u8g2, rotation, u8x8_byte_arduino_8bit_8080mode, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_8Bit_8080(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_2_4W_SW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_2_4W_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_2(&u8g2, rotation, u8x8_byte_arduino_4wire_sw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_SW_SPI(getU8x8(), clock, data, cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_2_4W_HW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_2_4W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_2(&u8g2, rotation, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_HW_SPI(getU8x8(), cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_2_2ND_4W_HW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_2_2ND_4W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_2(&u8g2, rotation, u8x8_byte_arduino_2nd_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_HW_SPI(getU8x8(), cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_2_3W_SW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_2_3W_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_2(&u8g2, rotation, u8x8_byte_arduino_3wire_sw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_3Wire_SW_SPI(getU8x8(), clock, data, cs, reset); + } +}; +class U8G2_SSD1362_256X64_2_3W_HW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_2_3W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_2(&u8g2, rotation, u8x8_byte_arduino_3wire_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_3Wire_HW_SPI(getU8x8(), cs, reset); + } +}; +class U8G2_SSD1362_256X64_2_6800 : public U8G2 { + public: U8G2_SSD1362_256X64_2_6800(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_2(&u8g2, rotation, u8x8_byte_8bit_6800mode, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_8Bit_6800(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_2_8080 : public U8G2 { + public: U8G2_SSD1362_256X64_2_8080(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_2(&u8g2, rotation, u8x8_byte_arduino_8bit_8080mode, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_8Bit_8080(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_F_4W_SW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_F_4W_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_f(&u8g2, rotation, u8x8_byte_arduino_4wire_sw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_SW_SPI(getU8x8(), clock, data, cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_F_4W_HW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_F_4W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_f(&u8g2, rotation, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_HW_SPI(getU8x8(), cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_F_2ND_4W_HW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_F_2ND_4W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_f(&u8g2, rotation, u8x8_byte_arduino_2nd_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_HW_SPI(getU8x8(), cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_F_3W_SW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_F_3W_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_f(&u8g2, rotation, u8x8_byte_arduino_3wire_sw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_3Wire_SW_SPI(getU8x8(), clock, data, cs, reset); + } +}; +class U8G2_SSD1362_256X64_F_3W_HW_SPI : public U8G2 { + public: U8G2_SSD1362_256X64_F_3W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_f(&u8g2, rotation, u8x8_byte_arduino_3wire_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_3Wire_HW_SPI(getU8x8(), cs, reset); + } +}; +class U8G2_SSD1362_256X64_F_6800 : public U8G2 { + public: U8G2_SSD1362_256X64_F_6800(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_f(&u8g2, rotation, u8x8_byte_8bit_6800mode, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_8Bit_6800(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_F_8080 : public U8G2 { + public: U8G2_SSD1362_256X64_F_8080(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_256x64_f(&u8g2, rotation, u8x8_byte_arduino_8bit_8080mode, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_8Bit_8080(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); + } +}; +class U8G2_SSD1362_256X64_1_SW_I2C : public U8G2 { + public: U8G2_SSD1362_256X64_1_SW_I2C(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_i2c_256x64_1(&u8g2, rotation, u8x8_byte_arduino_sw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_SW_I2C(getU8x8(), clock, data, reset); + } +}; +class U8G2_SSD1362_256X64_1_HW_I2C : public U8G2 { + public: U8G2_SSD1362_256X64_1_HW_I2C(const u8g2_cb_t *rotation, uint8_t reset = U8X8_PIN_NONE, uint8_t clock = U8X8_PIN_NONE, uint8_t data = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_i2c_256x64_1(&u8g2, rotation, u8x8_byte_arduino_hw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_HW_I2C(getU8x8(), reset, clock, data); + } +}; +class U8G2_SSD1362_256X64_1_2ND_HW_I2C : public U8G2 { + public: U8G2_SSD1362_256X64_1_2ND_HW_I2C(const u8g2_cb_t *rotation, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_i2c_256x64_1(&u8g2, rotation, u8x8_byte_arduino_2nd_hw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_HW_I2C(getU8x8(), reset); + } +}; +class U8G2_SSD1362_256X64_2_SW_I2C : public U8G2 { + public: U8G2_SSD1362_256X64_2_SW_I2C(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_i2c_256x64_2(&u8g2, rotation, u8x8_byte_arduino_sw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_SW_I2C(getU8x8(), clock, data, reset); + } +}; +class U8G2_SSD1362_256X64_2_HW_I2C : public U8G2 { + public: U8G2_SSD1362_256X64_2_HW_I2C(const u8g2_cb_t *rotation, uint8_t reset = U8X8_PIN_NONE, uint8_t clock = U8X8_PIN_NONE, uint8_t data = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_i2c_256x64_2(&u8g2, rotation, u8x8_byte_arduino_hw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_HW_I2C(getU8x8(), reset, clock, data); + } +}; +class U8G2_SSD1362_256X64_2_2ND_HW_I2C : public U8G2 { + public: U8G2_SSD1362_256X64_2_2ND_HW_I2C(const u8g2_cb_t *rotation, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_i2c_256x64_2(&u8g2, rotation, u8x8_byte_arduino_2nd_hw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_HW_I2C(getU8x8(), reset); + } +}; +class U8G2_SSD1362_256X64_F_SW_I2C : public U8G2 { + public: U8G2_SSD1362_256X64_F_SW_I2C(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_i2c_256x64_f(&u8g2, rotation, u8x8_byte_arduino_sw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_SW_I2C(getU8x8(), clock, data, reset); + } +}; +class U8G2_SSD1362_256X64_F_HW_I2C : public U8G2 { + public: U8G2_SSD1362_256X64_F_HW_I2C(const u8g2_cb_t *rotation, uint8_t reset = U8X8_PIN_NONE, uint8_t clock = U8X8_PIN_NONE, uint8_t data = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_i2c_256x64_f(&u8g2, rotation, u8x8_byte_arduino_hw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_HW_I2C(getU8x8(), reset, clock, data); + } +}; +class U8G2_SSD1362_256X64_F_2ND_HW_I2C : public U8G2 { + public: U8G2_SSD1362_256X64_F_2ND_HW_I2C(const u8g2_cb_t *rotation, uint8_t reset = U8X8_PIN_NONE) : U8G2() { + u8g2_Setup_ssd1362_i2c_256x64_f(&u8g2, rotation, u8x8_byte_arduino_2nd_hw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_HW_I2C(getU8x8(), reset); + } +}; class U8G2_LD7032_60X32_1_4W_SW_SPI : public U8G2 { public: U8G2_LD7032_60X32_1_4W_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() { u8g2_Setup_ld7032_60x32_1(&u8g2, rotation, u8x8_byte_arduino_4wire_sw_spi, u8x8_gpio_and_delay_arduino); diff --git a/cppsrc/U8x8lib.h b/cppsrc/U8x8lib.h index aa9a6cbf..c49d6b0a 100644 --- a/cppsrc/U8x8lib.h +++ b/cppsrc/U8x8lib.h @@ -209,7 +209,7 @@ class U8X8 : public Print #endif void initDisplay(void) { - u8x8_InitDisplay(&u8x8); } + u8x8_InitDisplay(&u8x8, u8x8_parent_class); } void clearDisplay(void) { u8x8_ClearDisplay(&u8x8); } @@ -221,7 +221,7 @@ class U8X8 : public Print u8x8_SetPowerSave(&u8x8, is_enable); } bool begin(void) { - initDisplay(); clearDisplay(); setPowerSave(0); return 1; } + initDisplay(); clearDisplay(); setFlipMode(0); setPowerSave(0); return 1; } #ifdef U8X8_USE_PINS /* use U8X8_PIN_NONE if a pin is not required */ @@ -244,6 +244,9 @@ class U8X8 : public Print void clearLine(uint8_t line) { u8x8_ClearLine(&u8x8, line); } + void setGrey(uint8_t value) { + u8x8_SetGrey(&u8x8, value); } + void setContrast(uint8_t value) { u8x8_SetContrast(&u8x8, value); } @@ -2895,6 +2898,66 @@ class U8X8_SSD1329_128X96_NONAME_8080 : public U8X8 { u8x8_SetPin_8Bit_8080(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); } }; +class U8X8_SSD1362_256X64_4W_SW_SPI : public U8X8 { + public: U8X8_SSD1362_256X64_4W_SW_SPI(uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_001, u8x8_byte_arduino_4wire_sw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_SW_SPI(getU8x8(), clock, data, cs, dc, reset); + } +}; +class U8X8_SSD1362_256X64_4W_HW_SPI : public U8X8 { + public: U8X8_SSD1362_256X64_4W_HW_SPI(uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_001, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_HW_SPI(getU8x8(), cs, dc, reset); + } +}; +class U8X8_SSD1362_256X64_2ND_4W_HW_SPI : public U8X8 { + public: U8X8_SSD1362_256X64_2ND_4W_HW_SPI(uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_001, u8x8_byte_arduino_2nd_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_4Wire_HW_SPI(getU8x8(), cs, dc, reset); + } +}; +class U8X8_SSD1362_256X64_3W_SW_SPI : public U8X8 { + public: U8X8_SSD1362_256X64_3W_SW_SPI(uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_001, u8x8_byte_arduino_3wire_sw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_3Wire_SW_SPI(getU8x8(), clock, data, cs, reset); + } +}; +class U8X8_SSD1362_256X64_3W_HW_SPI : public U8X8 { + public: U8X8_SSD1362_256X64_3W_HW_SPI(uint8_t cs, uint8_t reset = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_001, u8x8_byte_arduino_3wire_hw_spi, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_3Wire_HW_SPI(getU8x8(), cs, reset); + } +}; +class U8X8_SSD1362_256X64_6800 : public U8X8 { + public: U8X8_SSD1362_256X64_6800(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_001, u8x8_byte_8bit_6800mode, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_8Bit_6800(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); + } +}; +class U8X8_SSD1362_256X64_8080 : public U8X8 { + public: U8X8_SSD1362_256X64_8080(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_001, u8x8_byte_arduino_8bit_8080mode, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_8Bit_8080(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, cs, dc, reset); + } +}; +class U8X8_SSD1362_256X64_SW_I2C : public U8X8 { + public: U8X8_SSD1362_256X64_SW_I2C(uint8_t clock, uint8_t data, uint8_t reset = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_ssd13xx_i2c, u8x8_byte_arduino_sw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_SW_I2C(getU8x8(), clock, data, reset); + } +}; +class U8X8_SSD1362_256X64_HW_I2C : public U8X8 { + public: U8X8_SSD1362_256X64_HW_I2C(uint8_t reset = U8X8_PIN_NONE, uint8_t clock = U8X8_PIN_NONE, uint8_t data = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_ssd13xx_i2c, u8x8_byte_arduino_hw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_HW_I2C(getU8x8(), reset, clock, data); + } +}; +class U8X8_SSD1362_256X64_2ND_HW_I2C : public U8X8 { + public: U8X8_SSD1362_256X64_2ND_HW_I2C(uint8_t reset = U8X8_PIN_NONE) : U8X8() { + u8x8_Setup(getU8x8(), u8x8_d_ssd1362_256x64, u8x8_cad_ssd13xx_i2c, u8x8_byte_arduino_2nd_hw_i2c, u8x8_gpio_and_delay_arduino); + u8x8_SetPin_HW_I2C(getU8x8(), reset); + } +}; class U8X8_LD7032_60X32_4W_SW_SPI : public U8X8 { public: U8X8_LD7032_60X32_4W_SW_SPI(uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8X8() { u8x8_Setup(getU8x8(), u8x8_d_ld7032_60x32, u8x8_cad_011, u8x8_byte_arduino_4wire_sw_spi, u8x8_gpio_and_delay_arduino); diff --git a/csrc/u8g2.h b/csrc/u8g2.h index 10fb75ae..fe669be4 100644 --- a/csrc/u8g2.h +++ b/csrc/u8g2.h @@ -116,6 +116,13 @@ */ #define U8G2_WITH_FONT_ROTATION +/* + The following macro enables scrolling for glyphs. + + Sept 2020: Disabling this macro will save up to ??? bytes on AVR +*/ +#define U8G2_WITH_FONT_SCROLLING + /* U8glib V2 contains support for unicode plane 0 (Basic Multilingual Plane, BMP). The following macro activates this support. Deactivation would save some ROM. @@ -242,6 +249,14 @@ struct _u8g2_font_decode_t u8g2_uint_t target_x; u8g2_uint_t target_y; +#ifdef U8G2_WITH_FONT_SCROLLING + int8_t target_x_offset; + int8_t target_y_offset; + int8_t target_delta; + int8_t scroll_x; + int8_t scroll_y; + uint8_t gap; /* gap in pixel scrolling rotation */ +#endif int8_t x; /* local coordinates, (0,0) is upper left */ int8_t y; @@ -371,9 +386,10 @@ struct u8g2_struct #define u8g2_SetupDisplay(u8g2, display_cb, cad_cb, byte_cb, gpio_and_delay_cb) \ u8x8_Setup(u8g2_GetU8x8(u8g2), (display_cb), (cad_cb), (byte_cb), (gpio_and_delay_cb)) -#define u8g2_InitDisplay(u8g2) u8x8_InitDisplay(u8g2_GetU8x8(u8g2)) +#define u8g2_InitDisplay(u8g2, class) u8x8_InitDisplay(u8g2_GetU8x8(u8g2), (class)) #define u8g2_SetPowerSave(u8g2, is_enable) u8x8_SetPowerSave(u8g2_GetU8x8(u8g2), (is_enable)) #define u8g2_SetFlipMode(u8g2, mode) u8x8_SetFlipMode(u8g2_GetU8x8(u8g2), (mode)) +#define u8g2_SetGrey(u8g2, value) u8x8_SetGrey(u8g2_GetU8x8(u8g2), (value)) #define u8g2_SetContrast(u8g2, value) u8x8_SetContrast(u8g2_GetU8x8(u8g2), (value)) //#define u8g2_ClearDisplay(u8g2) u8x8_ClearDisplay(u8g2_GetU8x8(u8g2)) obsolete, can not be used in all cases void u8g2_ClearDisplay(u8g2_t *u8g2); @@ -832,6 +848,12 @@ void u8g2_Setup_ssd1327_i2c_visionox_128x96_f(u8g2_t *u8g2, const u8g2_cb_t *rot void u8g2_Setup_ssd1329_128x96_noname_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); void u8g2_Setup_ssd1329_128x96_noname_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); void u8g2_Setup_ssd1329_128x96_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); +void u8g2_Setup_ssd1362_256x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); +void u8g2_Setup_ssd1362_256x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); +void u8g2_Setup_ssd1362_256x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); +void u8g2_Setup_ssd1362_i2c_256x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); +void u8g2_Setup_ssd1362_i2c_256x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); +void u8g2_Setup_ssd1362_i2c_256x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); void u8g2_Setup_ld7032_60x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); void u8g2_Setup_ld7032_60x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); void u8g2_Setup_ld7032_60x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); @@ -1344,6 +1366,7 @@ u8g2_uint_t u8g2_DrawGlyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t int8_t u8g2_GetStrX(u8g2_t *u8g2, const char *s); /* for u8g compatibility */ void u8g2_SetFontDirection(u8g2_t *u8g2, uint8_t dir); +void u8g2_SetFontScroll(u8g2_t *u8g2, int8_t x, int8_t y, uint8_t gap); u8g2_uint_t u8g2_DrawStr(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str); u8g2_uint_t u8g2_DrawUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str); u8g2_uint_t u8g2_DrawExtendedUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t to_left, u8g2_kerning_t *kerning, const char *str); diff --git a/csrc/u8g2_buffer.c b/csrc/u8g2_buffer.c index 9aee96d4..3185529c 100644 --- a/csrc/u8g2_buffer.c +++ b/csrc/u8g2_buffer.c @@ -162,7 +162,12 @@ void u8g2_UpdateDisplayArea(u8g2_t *u8g2, uint8_t tx, uint8_t ty, uint8_t tw, u page_size = u8g2->pixel_buf_width; /* 8*u8g2->u8g2_GetU8x8(u8g2)->display_info->tile_width */ ptr = u8g2_GetBufferPtr(u8g2); - ptr += tx*8; + + if(u8g2->ll_hvline == u8g2_ll_hvline_vertical_top_lsb){ + ptr += tx*8; /* 8 bytes across per tile, stacked vertically */ + }else{ + ptr += tx; /* 1 byte across per tile, stacked horizontally */ + } ptr += page_size*ty; while( th > 0 ) diff --git a/csrc/u8g2_d_setup.c b/csrc/u8g2_d_setup.c index 867137ee..9784b578 100644 --- a/csrc/u8g2_d_setup.c +++ b/csrc/u8g2_d_setup.c @@ -2307,6 +2307,62 @@ void u8g2_Setup_ssd1329_128x96_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, buf = u8g2_m_16_12_f(&tile_buf_height); u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation); } +/* ssd1362 */ +/* ssd1362 1 */ +void u8g2_Setup_ssd1362_256x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_ssd1362_256x64, u8x8_cad_001, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_32_8_1(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation); +} +/* ssd1362 2 */ +void u8g2_Setup_ssd1362_256x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_ssd1362_256x64, u8x8_cad_001, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_32_8_2(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation); +} +/* ssd1362 f */ +void u8g2_Setup_ssd1362_256x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_ssd1362_256x64, u8x8_cad_001, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_32_8_f(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation); +} +/* ssd1362 */ +/* ssd1362 1 */ +void u8g2_Setup_ssd1362_i2c_256x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_ssd1362_256x64, u8x8_cad_ssd13xx_i2c, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_32_8_1(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation); +} +/* ssd1362 2 */ +void u8g2_Setup_ssd1362_i2c_256x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_ssd1362_256x64, u8x8_cad_ssd13xx_i2c, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_32_8_2(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation); +} +/* ssd1362 f */ +void u8g2_Setup_ssd1362_i2c_256x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_ssd1362_256x64, u8x8_cad_ssd13xx_i2c, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_32_8_f(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation); +} /* ld7032 */ /* ld7032 1 */ void u8g2_Setup_ld7032_60x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) diff --git a/csrc/u8g2_font.c b/csrc/u8g2_font.c index 816667c6..eb122233 100644 --- a/csrc/u8g2_font.c +++ b/csrc/u8g2_font.c @@ -404,6 +404,25 @@ void u8g2_font_decode_len(u8g2_t *u8g2, uint8_t len, uint8_t is_foreground) /* get the local position */ lx = decode->x; ly = decode->y; + +#ifdef U8G2_WITH_FONT_SCROLLING + u8g2_int_t sx,sy; + uint8_t sh = decode->gap; /*scroll gap*/ + uint8_t sw = sh; + uint8_t srem; + sh += u8g2->font_ref_ascent; + sh -= u8g2->font_ref_descent; /*scroll box height=current font (all character) used height+scroll gap*/ + sw += decode->target_delta; /*scroll box width=current font (per character) used width+scroll gap*/ + ly += u8g2->font_ref_ascent; + ly -= decode->glyph_height; + ly -= decode->target_y_offset; /*offset so zero points to top edge of glyph*/ + sy = decode->scroll_y; + if( (sy!=0)&&(sh!=0) ){ + sy %= sh; /*scroll inbounds*/ + if(ly<-sy) /*(sy+ly<0)*/ + sy += sh; /*bring point up into scroll box*/ + } +#endif for(;;) { @@ -417,27 +436,54 @@ void u8g2_font_decode_len(u8g2_t *u8g2, uint8_t len, uint8_t is_foreground) if ( cnt < rem ) current = cnt; - /* now draw the line, but apply the rotation around the glyph target position */ //u8g2_font_decode_draw_pixel(u8g2, lx,ly,current, is_foreground); /* get target position */ x = decode->target_x; y = decode->target_y; - +#ifdef U8G2_WITH_FONT_SCROLLING + /* apply scrolling */ + sx = decode->scroll_x; + lx += decode->target_x_offset; /*offset so zero points to right edge of glyph*/ + if( (sx!=0)&&(sw!=0) ){ + sx %= sw; /*scroll inbounds*/ + if(lx<-sx){ /*(sx+lx<0)*/ + sx += sw; /*bring point up into scroll box*/ + }else if( (sx+lx)>=sw ) + sx -= sw; /*bring point down into scroll box*/ + } + lx +=sx; /*x position within scroll box*/ + srem = sw; + srem -= lx; /*pixels to right of scroll box*/ + if(current<=srem) + srem = 0; /*all draw line within scroll area*/ + /* otherwise srem = pixels to edge */ + if(lx > decode->target_delta){ + current = 0; /*start of line beyond right edge of font box*/ + }else if((lx+current) > decode->target_delta){ + current = decode->target_delta; /*shorten end of draw line to right edge of font box*/ + current -= lx; + } + if( (sy>0)&&(sh!=0) ) + if( (sy+ly)>=sh ) + sy -= sh; /*bring point down into scroll box*/ + ly +=sy; /*y position within scroll box*/ +#endif /* apply rotation */ #ifdef U8G2_WITH_FONT_ROTATION - x = u8g2_add_vector_x(x, lx, ly, decode->dir); y = u8g2_add_vector_y(y, lx, ly, decode->dir); - //u8g2_add_vector(&x, &y, lx, ly, decode->dir); - + #else x += lx; y += ly; #endif +#ifdef U8G2_WITH_FONT_SCROLLING + if( (ly < (u8g2->font_ref_ascent - u8g2->font_ref_descent)) && (lx < decode->target_delta) ){ /*dont draw if outside viewable font box*/ +#endif /* draw foreground and background (if required) */ if ( is_foreground ) { @@ -467,16 +513,38 @@ void u8g2_font_decode_len(u8g2_t *u8g2, uint8_t len, uint8_t is_foreground) #endif ); } - +#ifdef U8G2_WITH_FONT_SCROLLING + } + lx -=sx; + lx -= decode->target_x_offset; /*remove offset, restores back to zero points to left edge of font box*/ + ly -=sy; /*restore*/ + if(srem==0){ /*line drawn complet or to glyph right edge*/ + /* check, whether the end of the run length code has been reached */ + if ( cnt < rem ) + break; + cnt -= rem; + lx = 0; + ly++; + }else{ /*reached scroll box right edge, still more to draw*/ + cnt -= srem; + lx += srem; + } +#else /* check, whether the end of the run length code has been reached */ if ( cnt < rem ) break; cnt -= rem; lx = 0; ly++; +#endif } lx += cnt; +#ifdef U8G2_WITH_FONT_SCROLLING + ly -= u8g2->font_ref_ascent; + ly += decode->glyph_height; + ly += decode->target_y_offset; /*remove offset, restores back to zero points to ascent top edge of font box*/ +#endif decode->x = lx; decode->y = ly; @@ -533,17 +601,30 @@ int8_t u8g2_font_decode_glyph(u8g2_t *u8g2, const uint8_t *glyph_data) if ( decode->glyph_width > 0 ) { -#ifdef U8G2_WITH_FONT_ROTATION +#ifdef U8G2_WITH_FONT_SCROLLING + decode->target_x_offset = x; + decode->target_y_offset = y; + decode->target_delta = d; + #ifdef U8G2_WITH_FONT_ROTATION /*point to top left of font ascent box*/ + decode->target_x = u8g2_add_vector_x(decode->target_x, 0, -u8g2->font_ref_ascent, decode->dir); + decode->target_y = u8g2_add_vector_y(decode->target_y, 0, -u8g2->font_ref_ascent, decode->dir); + //u8g2_add_vector(&(decode->target_x), &(decode->target_y), 0, -u8g2->font_ref_ascent, decode->dir); + + #else +// decode->target_x += 0; + decode->target_y -= u8g2->font_ref_ascent; + #endif +#else + #ifdef U8G2_WITH_FONT_ROTATION /*point to top left of glyph box*/ decode->target_x = u8g2_add_vector_x(decode->target_x, x, -(h+y), decode->dir); decode->target_y = u8g2_add_vector_y(decode->target_y, x, -(h+y), decode->dir); - //u8g2_add_vector(&(decode->target_x), &(decode->target_y), x, -(h+y), decode->dir); -#else + #else decode->target_x += x; decode->target_y -= h+y; + #endif #endif - //u8g2_add_vector(&(decode->target_x), &(decode->target_y), x, -(h+y), decode->dir); #ifdef U8G2_WITH_INTERSECTION { @@ -1288,4 +1369,12 @@ void u8g2_SetFontDirection(u8g2_t *u8g2, uint8_t dir) #endif } +void u8g2_SetFontScroll(u8g2_t *u8g2, int8_t x, int8_t y, uint8_t gap) +{ +#ifdef U8G2_WITH_FONT_SCROLLING + u8g2->font_decode.scroll_x = x; + u8g2->font_decode.scroll_y = y; + u8g2->font_decode.gap = gap; +#endif +} diff --git a/csrc/u8g2_setup.c b/csrc/u8g2_setup.c index 0e71a707..016e5961 100644 --- a/csrc/u8g2_setup.c +++ b/csrc/u8g2_setup.c @@ -101,6 +101,12 @@ void u8g2_SetupBuffer(u8g2_t *u8g2, uint8_t *buf, uint8_t tile_buf_height, u8g2_ #ifdef U8G2_WITH_FONT_ROTATION u8g2->font_decode.dir = 0; #endif + +#ifdef U8G2_WITH_FONT_SCROLLING + u8g2->font_decode.scroll_x = 0; + u8g2->font_decode.scroll_y = 0; + u8g2->font_decode.gap = 0; +#endif } /* diff --git a/csrc/u8x8.h b/csrc/u8x8.h index 18f6ebc8..fae7ace6 100644 --- a/csrc/u8x8.h +++ b/csrc/u8x8.h @@ -88,6 +88,9 @@ /*==========================================*/ /* Global Defines */ +/* Undefine this to remove u8x8_SetContrast function */ +#define U8X8_WITH_SET_GREY + /* Undefine this to remove u8x8_SetContrast function */ #define U8X8_WITH_SET_CONTRAST @@ -103,6 +106,11 @@ /* Note: Not all display types support a mirror functon for the frame buffer */ /* 26 May 2016: Obsolete */ //#define U8X8_DEFAULT_FLIP_MODE 0 +/*==========================================*/ +/* Parent class of display controller */ + +#define u8x8_parent_class 0 +#define u8g2_parent_class 1 /*==========================================*/ /* Includes */ @@ -435,9 +443,9 @@ void u8x8_d_helper_display_init(u8x8_t *u8g2); /* Name: U8X8_MSG_DISPLAY_INIT - Args: None + Args: arg_int: 0: U8X8 parent class, 1: U8G2 parent class Tasks: - + 1) send display controller parent class arg_int 2) put interface into default state: execute u8x8_gpio_Init for port directions execute u8x8_cad_Init for default port levels @@ -457,6 +465,15 @@ void u8x8_d_helper_display_init(u8x8_t *u8g2); */ #define U8X8_MSG_DISPLAY_SET_POWER_SAVE 11 +/* + Name: U8X8_MSG_DISPLAY_SET_GREY + Args: arg_int: 0..255 grey value + Tasks: + Sets display controllers pixel grey level + thoughts:- May upgrade with u8x8.h structure pointer for levels(RGBW[]), interactions(I[]) and draw layers(display buff[]). Idea is draw layers of different levels and interaction(solid,transparent,xor,or,sum) between lower(back) to higher layers(front). Only active layers need updating by user program, but all are needed for display controller when refreshing display. Possible levels & interaction for both foreground and background. +*/ +#define U8X8_MSG_DISPLAY_SET_GREY 12 + /* Name: U8X8_MSG_DISPLAY_SET_FLIP_MODE Args: arg_int: 0: normal mode, 1: flipped HW screen (180 degree) @@ -550,10 +567,11 @@ void u8x8_SetupMemory(u8x8_t *u8x8); It will init the display, but keep display in power save mode. Usually this command must be followed by u8x8_SetPowerSave() */ -void u8x8_InitDisplay(u8x8_t *u8x8); +void u8x8_InitDisplay(u8x8_t *u8x8, uint8_t parent_class); /* wake up display from power save mode */ void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable); void u8x8_SetFlipMode(u8x8_t *u8x8, uint8_t mode); +void u8x8_SetGrey(u8x8_t *u8x8, uint8_t value); void u8x8_SetContrast(u8x8_t *u8x8, uint8_t value); void u8x8_ClearDisplayWithTile(u8x8_t *u8x8, const uint8_t *buf) U8X8_NOINLINE; void u8x8_ClearDisplay(u8x8_t *u8x8); // this does not work for u8g2 in some cases @@ -900,6 +918,7 @@ uint8_t u8x8_d_ssd1327_ws_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, vo uint8_t u8x8_d_ssd1327_visionox_128x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_ssd1326_er_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_ssd1329_128x96_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); +uint8_t u8x8_d_ssd1362_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_uc1601_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_uc1604_jlx19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_uc1608_erc24064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); diff --git a/csrc/u8x8_d_sh1122.c b/csrc/u8x8_d_sh1122.c index 52db4f26..0a895232 100644 --- a/csrc/u8x8_d_sh1122.c +++ b/csrc/u8x8_d_sh1122.c @@ -32,191 +32,121 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - Copied from sh1122 mostly because of the similar RAM architecture. - However: Commands are very different! + 256x64 pixel, 16 grey levels(two pixel per byte in CGRAM) */ #include "u8x8.h" +static uint8_t u8x8_d_sh1122_parent_class=0x00; /* 0=u8x8, 1=u8g2 */ +#ifdef U8X8_WITH_SET_GREY +static uint8_t u8x8_d_sh1122_grey_level=0xff; /* 2px 16 grey levels */ +#endif +/*=========================================================*/ +static uint8_t u8x8_d_sh1122_8px_byte_conversion(u8x8_t *u8x8, uint8_t pixel_byte, uint8_t *buf){ /* input: one byte 8px; output: four bytes 8px 4bit grey */ +#ifdef U8X8_WITH_SET_GREY + buf[0] = u8x8_d_sh1122_grey_level; + if( !(pixel_byte&128) ) buf[0] &= 0x0f; + if( !(pixel_byte&64) ) buf[0] &= 0xf0; + buf[1] = u8x8_d_sh1122_grey_level; + if( !(pixel_byte&32) ) buf[1] &= 0x0f; + if( !(pixel_byte&16) ) buf[1] &= 0xf0; + buf[2] = u8x8_d_sh1122_grey_level; + if( !(pixel_byte&8) ) buf[2] &= 0x0f; + if( !(pixel_byte&4) ) buf[2] &= 0xf0; + buf[3] = u8x8_d_sh1122_grey_level; + if( !(pixel_byte&2) ) buf[3] &= 0x0f; + if( !(pixel_byte&1) ) buf[3] &= 0xf0; +#else + buf[0] = 0xff; + if( !(pixel_byte&128) ) buf[0] &= 0x0f; + if( !(pixel_byte&64) ) buf[0] &= 0xf0; + buf[1] = 0xff; + if( !(pixel_byte&32) ) buf[1] &= 0x0f; + if( !(pixel_byte&16) ) buf[1] &= 0xf0; + buf[2] = 0xff; + if( !(pixel_byte&8) ) buf[2] &= 0x0f; + if( !(pixel_byte&4) ) buf[2] &= 0xf0; + buf[3] = 0xff; + if( !(pixel_byte&2) ) buf[3] &= 0x0f; + if( !(pixel_byte&1) ) buf[3] &= 0xf0; +#endif + return 4; +} - - -static const uint8_t u8x8_d_sh1122_powersave0_seq[] = { - U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ - U8X8_C(0x0af), /* sh1122: display on */ - U8X8_END_TRANSFER(), /* disable chip */ - U8X8_END() /* end of sequence */ -}; - -static const uint8_t u8x8_d_sh1122_powersave1_seq[] = { - U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ - U8X8_C(0x0ae), /* sh1122: display off */ - U8X8_END_TRANSFER(), /* disable chip */ - U8X8_END() /* end of sequence */ -}; - - - - -/* - input: - one tile (8 Bytes) - output: - Tile for SH1122 (32 Bytes) -*/ - -/* -static uint8_t u8x8_sh1122_to32_dest_buf[32]; - -static uint8_t *u8x8_sh1122_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr) -{ - uint8_t v; - uint8_t a,b; - uint8_t i, j; - uint8_t *dest; +uint8_t u8x8_d_sh1122_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr){ + uint8_t col, row, tile_rep, tile_cnt, i; + uint8_t *ptr; + uint8_t rbuf[(u8x8_d_sh1122_parent_class == u8x8_parent_class?8:0)]; /* 8 bytes for tile rotation when parent class is u8x8 */ + static uint8_t buf[4]; /* 4 bytes for a tile - 8px columns */ + + col = ((u8x8_tile_t *)arg_ptr)->x_pos; + col *= 8/2; /* 2px per column byte - 8px per tile = 4 columns(bytes) */ + col += u8x8->x_offset; + row = (((u8x8_tile_t *)arg_ptr)->y_pos); + row *= 8; /* 1px per row - 8px per tile = 8 rows */ + tile_cnt = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles to send to display */ + ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* buffer pointer to 1st tile to send to display */ - for( j = 0; j < 4; j++ ) - { - dest = u8x8_sh1122_to32_dest_buf; - dest += j; - a =*ptr; - ptr++; - b = *ptr; - ptr++; - for( i = 0; i < 8; i++ ) - { - v = 0; - if ( a&1 ) v |= 0xf0; - if ( b&1 ) v |= 0x0f; - *dest = v; - dest+=4; - a >>= 1; - b >>= 1; + if( u8x8_d_sh1122_parent_class == u8x8_parent_class ){ /*parent class u8x8, sends individual tiles, but it needs to rotated by 90 degrees */ + for( i = 0; i < 8; i++ ){ + rbuf[i] =((*(ptr) &(1<>i)<<7; + rbuf[i]+=((*(ptr+1)&(1<>i)<<6; + rbuf[i]+=((*(ptr+2)&(1<>i)<<5; + rbuf[i]+=((*(ptr+3)&(1<>i)<<4; + rbuf[i]+=((*(ptr+4)&(1<>i)<<3; + rbuf[i]+=((*(ptr+5)&(1<>i)<<2; + rbuf[i]+=((*(ptr+6)&(1<>i)<<1; + rbuf[i]+=((*(ptr+7)&(1<>i); } } - - return u8x8_sh1122_to32_dest_buf; -} -*/ + u8x8_cad_StartTransfer(u8x8); + for( i = 0; i < 8; i++ ) { + u8x8_cad_SendCmd(u8x8, col & 15 ); /* lower 4 bit*/ + u8x8_cad_SendCmd(u8x8, 0x10 | (col >> 4) ); /* higher 3 bit */ + u8x8_cad_SendCmd(u8x8, 0xb0 ); /* set row address */ + u8x8_cad_SendArg(u8x8, row); - -static uint8_t u8x8_write_byte_to_16gr_device(u8x8_t *u8x8, uint8_t b) -{ - static uint8_t buf[4]; - static uint8_t map[4] = { 0, 0x00f, 0x0f0, 0x0ff }; - buf [3] = map[b & 3]; - b>>=2; - buf [2] = map[b & 3]; - b>>=2; - buf [1] = map[b & 3]; - b>>=2; - buf [0] = map[b & 3]; - return u8x8_cad_SendData(u8x8, 4, buf); -} - -uint8_t u8x8_d_sh1122_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) -{ - uint8_t x; - uint8_t y, c, i; - uint8_t *ptr; - switch(msg) - { - /* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */ - /* - case U8X8_MSG_DISPLAY_SETUP_MEMORY: - break; - case U8X8_MSG_DISPLAY_INIT: - u8x8_d_helper_display_init(u8x8); - u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_init_seq); - break; - */ - case U8X8_MSG_DISPLAY_SET_POWER_SAVE: - if ( arg_int == 0 ) - u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_powersave0_seq); - else - u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_powersave1_seq); - break; -#ifdef U8X8_WITH_SET_CONTRAST - case U8X8_MSG_DISPLAY_SET_CONTRAST: - u8x8_cad_StartTransfer(u8x8); - u8x8_cad_SendCmd(u8x8, 0x081 ); - u8x8_cad_SendArg(u8x8, arg_int ); /* sh1122 has range from 0 to 255 */ - u8x8_cad_EndTransfer(u8x8); - break; -#endif - case U8X8_MSG_DISPLAY_DRAW_TILE: - u8x8_cad_StartTransfer(u8x8); - x = ((u8x8_tile_t *)arg_ptr)->x_pos; - x *= 2; // only every 4th col can be addressed - x += u8x8->x_offset; - - y = (((u8x8_tile_t *)arg_ptr)->y_pos); - y *= 8; - - - c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */ - ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */ - for( i = 0; i < 8; i++ ) - { - u8x8_cad_SendCmd(u8x8, 0x0b0 ); /* set row address */ - u8x8_cad_SendArg(u8x8, y); - u8x8_cad_SendCmd(u8x8, x & 15 ); /* lower 4 bit*/ - u8x8_cad_SendCmd(u8x8, 0x010 | (x >> 4) ); /* higher 3 bit */ - c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */ - - while ( c > 0 ) - { - u8x8_write_byte_to_16gr_device(u8x8, *ptr); - c--; - ptr++; - } - y++; + if( u8x8_d_sh1122_parent_class == u8g2_parent_class ){ /* parent class u8g2 */ + while ( tile_cnt > 0 ){ /* number of tiles to send; tile repeats=1 for u8g2*/ + u8x8_d_sh1122_8px_byte_conversion(u8x8, *ptr, buf); /* 1 byte mono to 4 byte grey */ + u8x8_cad_SendData(u8x8, 4, buf); + tile_cnt--; + ptr++; } + tile_cnt = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */ + ptr += u8x8->display_info->tile_width; + ptr -= tile_cnt; /* point to next row for draw area */ - - u8x8_cad_EndTransfer(u8x8); - break; - default: - return 0; + }else if( u8x8_d_sh1122_parent_class == u8x8_parent_class ){ /* parent class u8x8 */ + u8x8_d_sh1122_8px_byte_conversion(u8x8, rbuf[i], buf); /* 1 byte mono to 4 byte grey */ + tile_rep = arg_int; /* number of repeats of same tile to send to display */ + while (tile_rep>0) { /* number of repeats of same tile to send; number of tiles=1 in u8x8 */ +// tile_cnt = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */ +// while ( tile_cnt > 0 ){ + u8x8_cad_SendData(u8x8, 4, buf); +// tile_cnt--; +// } + tile_rep--; + } + } + row++; } - return 1; + u8x8_cad_EndTransfer(u8x8); } - /*=========================================================*/ - -static const uint8_t u8x8_d_sh1122_256x64_flip0_seq[] = { - U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ - U8X8_C(0x0a1), /* remap */ - U8X8_C(0x0c8), /* remap */ - U8X8_C(0x060), - U8X8_END_TRANSFER(), /* disable chip */ - U8X8_END() /* end of sequence */ -}; - -static const uint8_t u8x8_d_sh1122_256x64_flip1_seq[] = { - U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ - U8X8_C(0x0a0), /* remap */ - U8X8_C(0x0c0), /* remap */ - U8X8_C(0x040), - U8X8_END_TRANSFER(), /* disable chip */ - U8X8_END() /* end of sequence */ -}; - -static const u8x8_display_info_t u8x8_sh1122_256x64_display_info = -{ +static const u8x8_display_info_t u8x8_sh1122_256x64_display_info = { /* chip_enable_level = */ 0, /* chip_disable_level = */ 1, - - /* post_chip_enable_wait_ns = */ 20, + /* post_chip_enable_wait_ns = */ 40, /* pre_chip_disable_wait_ns = */ 10, /* reset_pulse_width_ms = */ 10, /* sh1122: 10 us */ - /* post_reset_wait_ms = */ 20, /* */ - /* sda_setup_time_ns = */ 125, /* sh1122: cycle time is 250ns, so use 250/2 */ - /* sck_pulse_width_ns = */ 125, /* sh1122: cycle time is 250ns, so use 250/2 */ + /* post_reset_wait_ms = */ 10, /* sh1122: 2us */ + /* sda_setup_time_ns = */ 150, /* sh1122: cycle time is 250ns, so use 300/2 */ + /* sck_pulse_width_ns = */ 150, /* sh1122: cycle time is 250ns, so use 300/2 */ /* sck_clock_hz = */ 40000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ /* spi_mode = */ 0, /* active high, rising edge */ /* i2c_bus_clock_100kHz = */ 4, - /* data_setup_time_ns = */ 10, + /* data_setup_time_ns = */ 40, /* write_pulse_width_ns = */ 150, /* sh1122: cycle time is 300ns, so use 300/2 = 150 */ /* tile_width = */ 32, /* 256 pixel, so we require 32 bytes for this */ /* tile_hight = */ 8, @@ -226,62 +156,131 @@ static const u8x8_display_info_t u8x8_sh1122_256x64_display_info = /* pixel_height = */ 64 }; - -static const uint8_t u8x8_d_sh1122_256x64_init_seq[] = { - - U8X8_DLY(1), - U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ - U8X8_DLY(1), - - U8X8_C(0xae), /* display off */ - U8X8_C(0x40), /* display start line */ - U8X8_C(0x0a0), /* remap */ - U8X8_C(0x0c0), /* remap */ - U8X8_CA(0x81, 0x80), /* set display contrast */ - U8X8_CA(0xa8, 0x3f), /* multiplex ratio 1/64 Duty (0x0F~0x3F) */ - U8X8_CA(0xad, 0x81), /* use buildin DC-DC with 0.6 * 500 kHz */ - - U8X8_CA(0xd5, 0x50), /* set display clock divide ratio (lower 4 bit)/oscillator frequency (upper 4 bit) */ - U8X8_CA(0xd3, 0x00), /* display offset, shift mapping ram counter */ - U8X8_CA(0xd9, 0x22), /* pre charge (lower 4 bit) and discharge(higher 4 bit) period */ - U8X8_CA(0xdb, 0x35), /* VCOM deselect level */ - U8X8_CA(0xdc, 0x35), /* Pre Charge output voltage */ - U8X8_C(0x030), /* discharge level */ - - U8X8_DLY(1), /* delay */ - - U8X8_END_TRANSFER(), /* disable chip */ - U8X8_END() /* end of sequence */ +static const uint8_t u8x8_d_sh1122_powersave0_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0xaf), /* display on - normal mode */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ }; +static const uint8_t u8x8_d_sh1122_powersave1_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0xae), /* display off - some commands only work when display off! */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; -uint8_t u8x8_d_sh1122_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) -{ - switch(msg) - { +static const uint8_t u8x8_d_sh1122_256x64_flip0_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0xa0), /* enable right rotation */ + U8X8_C(0xc0), /* normal COM scan */ + U8X8_C(0x40), /* 0x00 - display start line - RAM vertical shift */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + +static const uint8_t u8x8_d_sh1122_256x64_flip1_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0xa1), /* enable left rotation */ + U8X8_C(0xc8), /* reverse COM scan */ + U8X8_C(0x60), /* 0x20 - display start line - RAM vertical shift */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + +/* Midas MCOT256064DY-WM OLED 256x64 16 levels of grey */ +static const uint8_t u8x8_d_sh1122_256x64_init_seq[] = { + U8X8_DLY(1), + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_DLY(1), + + U8X8_C(0xae), /*POR 0xae; 0/1; display off - some commands only work when display off! */ +/// U8X8_C(0xaf), /* display on - normal mode */ + U8X8_C(0x00), /*POR 0x00; 0x0n 0..15 Nn=N*16+n=0..127; column RAM address */ + U8X8_C(0x10), /*POR 0x10; 0x1N 0..7 Nn=N*16+n=0..127; column RAM address */ + U8X8_CA(0xb0, 0x00), /*POR 0x00; 0..63; row RAM address */ + U8X8_CA(0xd3, 0x00), /*POR 0x00; 0..63; set display offset - COM vertical shift */ +#if(0) /* removed as setFlipMode(0) in .begin constructor(s), otherwise display flicks about when processor reset and using u8g2.beginSimple() for silent resets */ + U8X8_C(0x40), /*POR 0x40; 0..63; display start line - RAM vertical shift */ + U8X8_C(0xa0), /*POR 0xa0; 0/1; enable right rotation */ +/// U8X8_C(0xa1), /* enable left rotation */ + U8X8_C(0xc0), /*POR 0xc0; 0/8; normal COM scan */ +/// U8X8_C(0xc8), /* reverse COM scan */ +#endif +/// U8X8_CA(0x81, 0x38), + U8X8_CA(0x81, 0x80), /*POR 0x80; 0..255; set display contrast */ + U8X8_C(0xa4), /*POR 0xa4; 0/1; normal display */ +/// U8X8_C(0xa5), /* entire display ON */ + U8X8_C(0xa6), /*POR 0xa6; 0/1; normal display */ +/// U8X8_C(0xa7), /* enable inverse display */ + U8X8_CA(0xa8, 0x3f), /*POR 0x3f; 0..63; multiplex MUX ratio - active rows 1-64 */ +/// U8X8_CA(0xad, 0x81), /*POR 0x81; 0x8Nn=0b1000NNNn 0..7,0..1; enable builtin DC-DC & frequency - display needs to be off */ + U8X8_CA(0xad, 0x80), /* disable builtin DC-DC - display needs to be off */ +// U8X8_CA(0xad, 0x8N), /*0x0N N=0..7<<1; set builtin DC-DC frequency = (0.6+0.1*N)*500 kHz */ +// U8X8_CA(0xad, 0x8n), /*0x0n n=0/1; enable(1) builtin DC-DC */ + U8X8_CA(0xd5, 0x90), /* set display clock(fosc*1.2) & divide(dclk/1) */ +/// U8X8_CA(0xd5, 0x50), /*POR 0x50; 0xNn N=0..15,n=0..15; set display clock & divide */ +// U8X8_CA(0xd5, 0x0n), /*0x0n n=0..15; set display divide ratio = dclk/(1+n) */ +// U8X8_CA(0xd5, 0xN0), /*0xN0 N=0..15<<4; set display clock frequency = fosc*(0.75+0.05*N) */ + U8X8_CA(0xd9, 0x44), /* discharge(4*dclk) & precharge(12*dclk) period */ +/// U8X8_CA(0xd9, 0x22), /*POR 0x22; 0xNn N=0..15,n=0..15; discharge & precharge period */ +// U8X8_CA(0xd9, 0x0n), /*0x0n n=1..15; precharge period = n*dclk */ +// U8X8_CA(0xd9, 0xN0), /*0xN0 N=1..15<<4; discharge period = n*dclk */ + U8X8_CA(0xdb, 0x3b), /* VCOM level - deselect voltage(0.808485*VREF) */ +/// U8X8_CA(0xdb, 0x35), /*POR 0x35; n=0..255; VCOM level - deselect voltage; VCOM = β1*VREF = (0.43+n*0.006415)*VREF */ +// U8X8_CA(0xdc, 0x1a), /* VSEGM level - precharge voltage(0.59679*VREF) */ + U8X8_CA(0xdc, 0x35), /*POR 0x35; 0..255; VSEGM level - precharge voltage; VSEGM = β2*VREF = (0.43+n*0.006415)*VREF */ + U8X8_C(0x030), /*POR 0x30; n=0..15; VSL level - discharge voltage(0); VSL = n==0?0:(0.75+0.25*n) */ + + U8X8_DLY(1), /* delay */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; +/*=========================================================*/ +uint8_t u8x8_d_sh1122_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { + switch(msg) { case U8X8_MSG_DISPLAY_SETUP_MEMORY: u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1122_256x64_display_info); break; case U8X8_MSG_DISPLAY_INIT: + u8x8_d_sh1122_parent_class = arg_int; /* 0=u8x8, 1=u8g2 */ u8x8_d_helper_display_init(u8x8); u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_init_seq); break; case U8X8_MSG_DISPLAY_SET_FLIP_MODE: - if ( arg_int == 0 ) - { - u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_flip0_seq); - u8x8->x_offset = u8x8->display_info->default_x_offset; - } - else - { - u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_flip1_seq); - u8x8->x_offset = u8x8->display_info->flipmode_x_offset; + if ( arg_int == 0 ){ + u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_flip0_seq); + u8x8->x_offset = u8x8->display_info->default_x_offset; + }else{ + u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_flip1_seq); + u8x8->x_offset = u8x8->display_info->flipmode_x_offset; } break; - + case U8X8_MSG_DISPLAY_SET_POWER_SAVE: + if ( arg_int == 0 ) + u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_powersave0_seq); + else + u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_powersave1_seq); + break; +#ifdef U8X8_WITH_SET_CONTRAST + case U8X8_MSG_DISPLAY_SET_CONTRAST: + u8x8_cad_StartTransfer(u8x8); + u8x8_cad_SendCmd(u8x8, 0x81 ); + u8x8_cad_SendArg(u8x8, arg_int ); /* device's contrast range from 0 to 255 */ + u8x8_cad_EndTransfer(u8x8); + break; +#endif +#ifdef U8X8_WITH_SET_GREY + case U8X8_MSG_DISPLAY_SET_GREY: + u8x8_d_sh1122_grey_level = arg_int>>4; /* device's pixel grey level range from 0 to 15 */ + u8x8_d_sh1122_grey_level |= (u8x8_d_sh1122_grey_level<<4); /* 2 pixel mask */ + break; +#endif + case U8X8_MSG_DISPLAY_DRAW_TILE: + u8x8_d_sh1122_draw_tile(u8x8, arg_int, arg_ptr); + break; default: - return u8x8_d_sh1122_common(u8x8, msg, arg_int, arg_ptr); + return 0; } return 1; } - diff --git a/csrc/u8x8_d_ssd1362.c b/csrc/u8x8_d_ssd1362.c new file mode 100644 index 00000000..9886bf70 --- /dev/null +++ b/csrc/u8x8_d_ssd1362.c @@ -0,0 +1,298 @@ +/* + + u8x8_d_ssd1362.c + + Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) + + Copyright (c) 2016, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + 256x64 pixel, 16 grey levels(two pixel per byte in CGRAM) + +*/ +#include "u8x8.h" + +static uint8_t u8x8_d_ssd1362_parent_class=0x00; /* 0=u8x8, 1=u8g2 */ +#ifdef U8X8_WITH_SET_GREY +static uint8_t u8x8_d_ssd1362_grey_level=0xff; /* 2px 16 grey levels */ +#endif + +static uint8_t u8x8_d_ssd1362_8px_byte_conversion(u8x8_t *u8x8, uint8_t pixel_byte, uint8_t *buf){ /* input: one byte 8px; output: four bytes 8px 4bit grey */ +#ifdef U8X8_WITH_SET_GREY + buf[0] = u8x8_d_ssd1362_grey_level; + if( !(pixel_byte&128) ) buf[0] &= 0x0f; + if( !(pixel_byte&64) ) buf[0] &= 0xf0; + buf[1] = u8x8_d_ssd1362_grey_level; + if( !(pixel_byte&32) ) buf[1] &= 0x0f; + if( !(pixel_byte&16) ) buf[1] &= 0xf0; + buf[2] = u8x8_d_ssd1362_grey_level; + if( !(pixel_byte&8) ) buf[2] &= 0x0f; + if( !(pixel_byte&4) ) buf[2] &= 0xf0; + buf[3] = u8x8_d_ssd1362_grey_level; + if( !(pixel_byte&2) ) buf[3] &= 0x0f; + if( !(pixel_byte&1) ) buf[3] &= 0xf0; +#else + buf[0] = 0xff; + if( !(pixel_byte&128) ) buf[0] &= 0x0f; + if( !(pixel_byte&64) ) buf[0] &= 0xf0; + buf[1] = 0xff; + if( !(pixel_byte&32) ) buf[1] &= 0x0f; + if( !(pixel_byte&16) ) buf[1] &= 0xf0; + buf[2] = 0xff; + if( !(pixel_byte&8) ) buf[2] &= 0x0f; + if( !(pixel_byte&4) ) buf[2] &= 0xf0; + buf[3] = 0xff; + if( !(pixel_byte&2) ) buf[3] &= 0x0f; + if( !(pixel_byte&1) ) buf[3] &= 0xf0; +#endif + return 4; +} + +uint8_t u8x8_d_ssd1362_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr){ + uint8_t col, row, tile_rep, tile_cnt, i; + uint8_t *ptr; + uint8_t rbuf[(u8x8_d_ssd1362_parent_class == u8x8_parent_class?8:0)]; /* 8 bytes for tile rotation when parent class is u8x8 */ + static uint8_t buf[4]; /* 4 bytes for a tile - 8px columns */ + + col = ((u8x8_tile_t *)arg_ptr)->x_pos; + col *= 8/2; /* 2px per column byte - 8px per tile = 4 columns(bytes) */ + col += u8x8->x_offset; + row = (((u8x8_tile_t *)arg_ptr)->y_pos); + row *= 8; /* 1px per row - 8px per tile = 8 rows */ + tile_cnt = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles to send to display */ + ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* buffer pointer to 1st tile to send to display */ + + if( u8x8_d_ssd1362_parent_class == u8x8_parent_class ){ /*parent class u8x8, sends individual tiles, but it needs to rotated by 90 degrees */ + for( i = 0; i < 8; i++ ){ + rbuf[i] =((*(ptr) &(1<>i)<<7; + rbuf[i]+=((*(ptr+1)&(1<>i)<<6; + rbuf[i]+=((*(ptr+2)&(1<>i)<<5; + rbuf[i]+=((*(ptr+3)&(1<>i)<<4; + rbuf[i]+=((*(ptr+4)&(1<>i)<<3; + rbuf[i]+=((*(ptr+5)&(1<>i)<<2; + rbuf[i]+=((*(ptr+6)&(1<>i)<<1; + rbuf[i]+=((*(ptr+7)&(1<>i); + } + } + u8x8_cad_StartTransfer(u8x8); + for( i = 0; i < 8; i++ ) { + u8x8_cad_SendCmd(u8x8, 0x15 ); /* set column start, end address */ + u8x8_cad_SendCmd(u8x8, col ); + u8x8_cad_SendCmd(u8x8, 0x7f); + u8x8_cad_SendCmd(u8x8, 0x75 ); /* set row start,end address */ + u8x8_cad_SendArg(u8x8, row); + u8x8_cad_SendArg(u8x8, 0x3f); + + if( u8x8_d_ssd1362_parent_class == u8g2_parent_class ){ /* parent class u8g2 */ + while ( tile_cnt > 0 ){ /* number of tiles to send; tile repeats=1 for u8g2*/ + u8x8_d_ssd1362_8px_byte_conversion(u8x8, *ptr, buf); /* 1 byte mono to 4 byte grey */ + u8x8_cad_SendData(u8x8, 4, buf); + tile_cnt--; + ptr++; + } + tile_cnt = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */ + ptr += u8x8->display_info->tile_width; + ptr -= tile_cnt; /* point to next row for draw area */ + + }else if( u8x8_d_ssd1362_parent_class == u8x8_parent_class ){ /* parent class u8x8 */ + u8x8_d_ssd1362_8px_byte_conversion(u8x8, rbuf[i], buf); /* 1 byte mono to 4 byte grey */ + tile_rep = arg_int; /* number of repeats of same tile to send to display */ + while (tile_rep>0) { /* number of repeats of same tile to send; number of tiles=1 in u8x8 */ +// tile_cnt = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */ +// while ( tile_cnt > 0 ){ + u8x8_cad_SendData(u8x8, 4, buf); +// tile_cnt--; +// } + tile_rep--; + } + } + row++; + } + u8x8_cad_EndTransfer(u8x8); +} +/*=========================================================*/ +static const u8x8_display_info_t u8x8_ssd1362_256x64_display_info = { + /* chip_enable_level = */ 0, + /* chip_disable_level = */ 1, + /* post_chip_enable_wait_ns = */ 45, + /* pre_chip_disable_wait_ns = */ 20, + /* reset_pulse_width_ms = */ 10, /* ssd1362: 100us */ + /* post_reset_wait_ms = */ 10, /* ssd1362: 100us */ + /* sda_setup_time_ns = */ 50, /* ssd1362: cycle time is 100ns, so use 100/2 */ + /* sck_pulse_width_ns = */ 50, /* ssd1362: cycle time is 100ns, so use 100/2 */ + /* sck_clock_hz = */ 10000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ + /* spi_mode = */ 0, /* active high, rising edge */ + /* i2c_bus_clock_100kHz = */ 4, + /* data_setup_time_ns = */ 15, + /* write_pulse_width_ns = */ 150, /* ssd1362: cycle time is 300ns, so use 300/2 = 150 */ + /* tile_width = */ 32, /* 256 pixel, so we require 32 bytes for this */ + /* tile_hight = */ 8, + /* default_x_offset = */ 0, /* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */ + /* flipmode_x_offset = */ 0, + /* pixel_width = */ 256, + /* pixel_height = */ 64 +}; + +static const uint8_t u8x8_d_ssd1362_powersave0_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0x0af), /* display on - normal mode */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + +static const uint8_t u8x8_d_ssd1362_powersave1_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0x0ae), /* display off - sleep mode */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + +static const uint8_t u8x8_d_ssd1362_256x64_flip0_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_CA(0xa0,0xc3), /* remap normal */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + +static const uint8_t u8x8_d_ssd1362_256x64_flip1_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_CA(0xa0,0xd0), /* remap flipped */ +///or U8X8_CA(0xa0,0x52), /* remap flipped */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + +/* Raystar REX025664A-ZIF OLED 256x64 16 levels of grey */ +/* Midas MDOT256064G1V-WM OLED 256x64 16 levels of grey */ +static const uint8_t u8x8_d_ssd1362_256x64_init_seq[] = { + U8X8_DLY(1), + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_DLY(1), + + U8X8_CA(0xfd, 0x12), /*POR 0x12; 0/4; unlock command */ +/// U8X8_CA(0xfd, 0x16), /* lock command */ + U8X8_C(0xae), /*POR; 0/1; display off - sleep mode */ +/// U8X8_C(0xaf), /* display on - normal mode */ + U8X8_CAA(0x15, 0x00, 0x7f), /*POR 0x00,0x7f; 0..127,0..127; set column address range(0x15,start,end)*/ + U8X8_CAA(0x75, 0x00, 0x3f), /*POR 0x00,0x3f; 0..63,0..63; set row address range(0x75,start,end) */ + U8X8_CA(0x81, 0x80), /*POR 0x7f; 0..255; set display contrast */ +#if(0) /* removed as setFlipMode(0) in .begin constructor(s), otherwise display flicks about when processor reset and using u8g2.beginSimple() for silent resets */ +/// U8X8_CA(0xa0, 0x40), /*POR 0x40; 0bLS0C0VNA; set remap */ + U8X8_CA(0xa0, 0xc3), /* remap flip 0 */ +// U8X8_CA(0xa0, 0x01), /* A=0/1; enable column address remap */ +// U8X8_CA(0xa0, 0x02), /* N=0/2; enable nibble remap */ +// U8X8_CA(0xa0, 0x04), /* V=0/4; enable horizontal(0)/vertical(4) address increments */ +// U8X8_CA(0xa0, 0x10), /* C=0/16; enable COM remap */ +// U8X8_CA(0xa0, 0x40), /* S=0/64; enable SEG split odd even */ +// U8X8_CA(0xa0, 0x80), /* L=0/128; enable SEG left/right remap */ +#endif + U8X8_CA(0xa1, 0x00), /*POR 0x00; 0..63; display start line - RAM vertical shift */ + U8X8_CA(0xa2, 0x00), /*POR 0x00; 0..63; set display Offset - COM vertical shift */ + U8X8_C(0xa4), /*POR; normal display */ +/// U8X8_C(0xa5), /* all pixels fully ON display */ +/// U8X8_C(0xa6), /* all pixels OFF display */ +/// U8X8_C(0xa7), /* enable inverse display */ + U8X8_CA(0xa8, 0x3f), /*POR 0x3f; 3..63; set multiplex MUX Ratio - active rows 4-64 */ + U8X8_CA(0xab, 0x01), /*POR 0X01; 0/1; enable internal VDD regulator */ +/// U8X8_CA(0xab, 0x00), /* external VDD, disable internal VDD regulator */ +/// U8X8_CA(0xad, 0x8e), /*POR 0x8e; external IREF */ + U8X8_CA(0xad, 0x9e), /* enable internal IREF */ + U8X8_CA(0xb1, 0x22), /*POR 0x82; set phase length */ +// U8X8_CA(0xb1, 0x0n), /*0x0n n=1..15; phase1(discharge) period = 2*n*dclk */ +// U8X8_CA(0xb1, 0xN0), /*0xN0 N=1..15<<4; phase2(1st precharge) period = 2*N*dclk */ + U8X8_CA(0xb3, 0xa0), /*POR 0xa1; display clock & divider */ +// U8X8_CA(0xb3, 0x0n), /*0x0n n=0..8; display clock divider = dclk>>n */ +// U8X8_CA(0xb3, 0xN0), /*0xN0 N=0..15<<4; display clock frequency increase n */ + U8X8_CA(0xb6, 0x04), /*POR 0x04; 1..15; set phase3(2nd precharge) period = n*dclk */ + U8X8_C(0xb9), /* set linear grey LUT */ +/// U8X8_CAAA(0xb8, 12, 24, 36), /* custom grey LUT, 0140, GS1, GS2, GS3 */ +/// U8X8_A4(48, 60, 72, 84), /* GS4, GS5, GS6, GS7 */ +/// U8X8_A4(96, 108, 120, 132), /* GS8, GS9, GS10,GS11 */ +/// U8X8_A4(144, 156, 168, 180), /* GS12,GS13,GS14,GS15>140 */ + U8X8_CA(0xbc, 0x10), /*POR 0x04; n=0..31 set pre-charge voltage level = 0.1+0.0133*n*Vcc */ +/// U8X8_CA(0xbd, 0x00), /*POR 0x00; no external Vp capacitor */ + U8X8_CA(0xbd, 0x01), /* external Vp capacitor */ + U8X8_CA(0xbe, 0x07), /*POR 0x05; n=0..7; set COM level, deselect voltage = 0.72+0.02*n*Vcc */ + U8X8_CA(0x23, 0x00), /*POR 0x00; Disable fade mode */ +// U8X8_CA(0x23, 0x1x), /* enable fade in mode */ +// U8X8_CA(0x23, 0x2x), /* enable fade out mode */ +// U8X8_CA(0x23, 0x3x), /* enable continous fade out/in mode */ +// U8X8_CA(0x23, 0x0n), /* n=0..15 fade interval=8*(n+1) frames */ + + U8X8_DLY(1), /* delay */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; +/*=========================================================*/ +uint8_t u8x8_d_ssd1362_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { + switch(msg){ + case U8X8_MSG_DISPLAY_SETUP_MEMORY: + u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1362_256x64_display_info); + break; + case U8X8_MSG_DISPLAY_INIT: + u8x8_d_ssd1362_parent_class = arg_int; /* 0=u8x8, 1=u8g2 */ + u8x8_d_helper_display_init(u8x8); + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_256x64_init_seq); + break; + case U8X8_MSG_DISPLAY_SET_FLIP_MODE: + if ( arg_int == 0 ){ + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_256x64_flip0_seq); + u8x8->x_offset = u8x8->display_info->default_x_offset; + }else{ + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_256x64_flip1_seq); + u8x8->x_offset = u8x8->display_info->flipmode_x_offset; + } + break; + case U8X8_MSG_DISPLAY_SET_POWER_SAVE: + if ( arg_int == 0 ) + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_powersave0_seq); + else + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_powersave1_seq); + break; +#ifdef U8X8_WITH_SET_CONTRAST + case U8X8_MSG_DISPLAY_SET_CONTRAST: + u8x8_cad_StartTransfer(u8x8); + u8x8_cad_SendCmd(u8x8, 0x81 ); + u8x8_cad_SendArg(u8x8, arg_int ); /* device's contrast range from 0 to 255 */ + u8x8_cad_EndTransfer(u8x8); + break; +#endif +#ifdef U8X8_WITH_SET_GREY + case U8X8_MSG_DISPLAY_SET_GREY: + u8x8_d_ssd1362_grey_level = arg_int>>4; /* device's pixel grey level range from 0 to 15 */ + u8x8_d_ssd1362_grey_level |= (u8x8_d_ssd1362_grey_level<<4); /* 2 pixel mask */ + break; +#endif + case U8X8_MSG_DISPLAY_DRAW_TILE: + u8x8_d_ssd1362_draw_tile(u8x8, arg_int, arg_ptr); + break; + default: + return 0; + } + return 1; +} \ No newline at end of file diff --git a/csrc/u8x8_display.c b/csrc/u8x8_display.c index 4f4d4f7a..70d3ed43 100644 --- a/csrc/u8x8_display.c +++ b/csrc/u8x8_display.c @@ -95,7 +95,7 @@ void u8x8_SetupMemory(u8x8_t *u8x8) u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SETUP_MEMORY, 0, NULL); } -void u8x8_InitDisplay(u8x8_t *u8x8) +void u8x8_InitDisplay(u8x8_t *u8x8, uint8_t parent_class) { u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL); } @@ -107,7 +107,12 @@ void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable) void u8x8_SetFlipMode(u8x8_t *u8x8, uint8_t mode) { - u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_FLIP_MODE, mode, NULL); + u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, parent_class, NULL); +} + +void u8x8_SetGrey(u8x8_t *u8x8, uint8_t value) +{ + u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_GREY, value, NULL); } void u8x8_SetContrast(u8x8_t *u8x8, uint8_t value)