From f710bae7e5d7bfc005e980254bee4b6cf060c94f Mon Sep 17 00:00:00 2001 From: kraus Date: Mon, 14 Aug 2023 18:12:25 +0200 Subject: [PATCH] issue #2191 --- .../I2CLCDBoard/I2CLCDBoard.ino | 176 ++++++++++++++++-- 1 file changed, 157 insertions(+), 19 deletions(-) diff --git a/sys/arduino/u8g2_page_buffer/I2CLCDBoard/I2CLCDBoard.ino b/sys/arduino/u8g2_page_buffer/I2CLCDBoard/I2CLCDBoard.ino index 0e7757c2..717c332a 100644 --- a/sys/arduino/u8g2_page_buffer/I2CLCDBoard/I2CLCDBoard.ino +++ b/sys/arduino/u8g2_page_buffer/I2CLCDBoard/I2CLCDBoard.ino @@ -1,7 +1,9 @@ /* I2CLCDBoard.ino - + + https://github.com/olikraus/u8g2/issues/2191 + Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) Copyright (c) 2023, olikraus@gmail.com @@ -30,7 +32,8 @@ 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. - + + */ #include @@ -74,11 +77,11 @@ /* - set a bit in the internal register and in the i2c control gpio - only update operation will be u8x8_set_ctrl_bit(u8x8, 0, 1); - typically the second argument will be one of the I2C_LCD_xxx macros + Set a bit in the internal register and in the i2c control gpio + The call "u8x8_set_ctrl_bit(u8x8, 0, 1);" will just refresh the gpio lines + Typically the second argument will be one of the I2C_LCD_xxx macros - reusing the "i2c_started" member variable, which is not used by the i2c lcd board software (i2c_started is only used by sw emulated i2c) + Reusing the "i2c_started" member variable, which is not used by the i2c lcd board software (i2c_started is only used by sw emulated i2c) */ void u8x8_set_ctrl_bit(u8x8_t *u8x8, uint8_t bit, uint8_t is_set) U8X8_NOINLINE; void u8x8_set_ctrl_bit(u8x8_t *u8x8, uint8_t bit, uint8_t is_set) @@ -198,17 +201,12 @@ uint8_t u8x8_byte_i2c_lcd_gfx_board_sed1520_6800(u8x8_t *u8x8, uint8_t msg, uint data++; arg_int--; - - // Assumption: u8x8_set_ctrl_bit() will be slow enough, so that no extra delay is required - //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns); u8x8_set_ctrl_bit(u8x8, enable_pin, 0); //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 200); //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); u8x8_set_ctrl_bit(u8x8, enable_pin, 1); - - } break; @@ -249,6 +247,70 @@ uint8_t u8x8_byte_i2c_lcd_gfx_board_sed1520_6800(u8x8_t *u8x8, uint8_t msg, uint } +/* + This is an example byte level procedure for a ST7920 display board. + This procedure will put the ST7920 in parallel mode. + The ST7920 must be connected to J3 of the I2C GFX Board. + See also: https://github.com/olikraus/u8g2/issues/2191 +*/ +uint8_t u8x8_byte_i2c_lcd_gfx_board_st7920(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) +{ + /* usually only the following two varibables need to be modified */ + uint8_t read_write = I2C_LCD_RW; /* Must be permanently 0 for the ST7920 to use the write mode */ + uint8_t enable_strobe = I2C_LCD_E; /* Used to latch in data for the ST7920 */ + uint8_t psb_select = I2C_LCD_CS; /* CS is connected to PSB at J3, so CS must be permanently 1 for parallel mode */ + uint8_t *data; + + switch(msg) + { + case U8X8_MSG_BYTE_SEND: + data = (uint8_t *)arg_ptr; + while( arg_int > 0 ) + { + Wire.beginTransmission(I2C_LCD_DATA_ADR); + Wire.write(*data); + Wire.endTransmission(); + + data++; + arg_int--; + + // Assumption: u8x8_set_ctrl_bit() will be slow enough, so that no extra delay is required + //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns); + u8x8_set_ctrl_bit(u8x8, enable_strobe, 1); // in 8080 mode, the RW signal is the /WR signal + //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); + u8x8_set_ctrl_bit(u8x8, enable_strobe, 0); // in 8080 mode, the RW signal is the /WR signal + } + break; + + case U8X8_MSG_BYTE_INIT: + Wire.begin(); + Wire.setClock(400000); // Assumption: PCF8574A supports fast I2C mode + + /* ensure that the enable signal is low (ST7920 datasheet) */ + u8x8_set_ctrl_bit(u8x8, enable_strobe, 0); // ST7920: Generate low-high-low pulse for data transfer, so start with 0 + u8x8_set_ctrl_bit(u8x8, read_write, 0); // ST7920: must be permanently low for write mode + u8x8_set_ctrl_bit(u8x8, psb_select, 1); // ST7920: This is actually connected to PSB on J1, so make this permanently 1 for parallel mode + u8x8_set_ctrl_bit(u8x8, I2C_LCD_CD, 0); // ST7920: Command Mode + break; + case U8X8_MSG_BYTE_SET_DC: + u8x8_set_ctrl_bit(u8x8, I2C_LCD_CD, arg_int); // command/data data/command + break; + case U8X8_MSG_BYTE_START_TRANSFER: + //u8x8_set_ctrl_bit(u8x8, chip_select, u8x8->display_info->chip_enable_level); // command/data data/command + //u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL); + break; + case U8X8_MSG_BYTE_END_TRANSFER: + //u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL); + //u8x8_set_ctrl_bit(u8x8, chip_select, u8x8->display_info->chip_disable_level); // command/data data/command + break; + default: + return 0; + } + return 1; +} + + + U8G2 u8g2; // create a plain U8g2 object void setup(void) @@ -261,13 +323,14 @@ void setup(void) Just replace the function name accordingly. Note: - For T6963 / LC7981 displays, use the "u8x8_byte_i2c_lcd_gfx_board_t6963_8080" callback function. + For T6963 / LC7981 / ST7920 displays, use the "u8x8_byte_i2c_lcd_gfx_board_t6963_8080" callback function. For SBN1661 / SED1520 use the "u8x8_byte_i2c_lcd_gfx_board_sed1520_6800" callback function. */ - u8g2_Setup_t6963_240x128_2(u8g2.getU8g2(), U8G2_R0, u8x8_byte_i2c_lcd_gfx_board_t6963_8080, u8x8_gpio_and_delay_i2c_lcd_gfx_board); - //u8g2_Setup_t6963_128x128_2(u8g2.getU8g2(), U8G2_R0, u8x8_byte_i2c_lcd_gfx_board_t6963_8080, u8x8_gpio_and_delay_i2c_lcd_gfx_board); - //u8g2_Setup_sed1520_122x32_2(u8g2.getU8g2(), U8G2_R0, u8x8_byte_i2c_lcd_gfx_board_sed1520_6800, u8x8_gpio_and_delay_i2c_lcd_gfx_board); + //u8g2_Setup_t6963_240x128_2(u8g2.getU8g2(), U8G2_R0, u8x8_byte_i2c_lcd_gfx_board_t6963_8080, u8x8_gpio_and_delay_i2c_lcd_gfx_board); // J4 + //u8g2_Setup_t6963_128x128_2(u8g2.getU8g2(), U8G2_R0, u8x8_byte_i2c_lcd_gfx_board_t6963_8080, u8x8_gpio_and_delay_i2c_lcd_gfx_board); // J2 + //u8g2_Setup_sed1520_122x32_2(u8g2.getU8g2(), U8G2_R0, u8x8_byte_i2c_lcd_gfx_board_sed1520_6800, u8x8_gpio_and_delay_i2c_lcd_gfx_board); // J5 + u8g2_Setup_st7920_128x64_2(u8g2.getU8g2(), U8G2_R0, u8x8_byte_i2c_lcd_gfx_board_st7920, u8x8_gpio_and_delay_i2c_lcd_gfx_board); // J3 /* After providing the callback function, start the communication with the display by using u8g2.begin() @@ -275,6 +338,76 @@ void setup(void) u8g2.begin(); } + +void drawLogo(void) +{ + uint8_t mdy = 0; + if ( u8g2.getDisplayHeight() < 59 ) + mdy = 5; + + + u8g2.setFontMode(1); // Transparent + u8g2.setDrawColor(1); +#ifdef MINI_LOGO + + u8g2.setFontDirection(0); + u8g2.setFont(u8g2_font_inb16_mf); + u8g2.drawStr(0, 22, "U"); + + u8g2.setFontDirection(1); + u8g2.setFont(u8g2_font_inb19_mn); + u8g2.drawStr(14,8,"8"); + + u8g2.setFontDirection(0); + u8g2.setFont(u8g2_font_inb16_mf); + u8g2.drawStr(36,22,"g"); + u8g2.drawStr(48,22,"\xb2"); + + u8g2.drawHLine(2, 25, 34); + u8g2.drawHLine(3, 26, 34); + u8g2.drawVLine(32, 22, 12); + u8g2.drawVLine(33, 23, 12); +#else + + u8g2.setFontDirection(0); + u8g2.setFont(u8g2_font_inb24_mf); + u8g2.drawStr(0, 30-mdy, "U"); + + u8g2.setFontDirection(1); + u8g2.setFont(u8g2_font_inb30_mn); + u8g2.drawStr(21,8-mdy,"8"); + + u8g2.setFontDirection(0); + u8g2.setFont(u8g2_font_inb24_mf); + u8g2.drawStr(51,30-mdy,"g"); + u8g2.drawStr(67,30-mdy,"\xb2"); + + u8g2.drawHLine(2, 35-mdy, 47); + u8g2.drawHLine(3, 36-mdy, 47); + u8g2.drawVLine(45, 32-mdy, 12); + u8g2.drawVLine(46, 33-mdy, 12); + +#endif + +} + +void drawURL(void) +{ +#ifndef MINI_LOGO + u8g2.setFont(u8g2_font_4x6_tr); + if ( u8g2.getDisplayHeight() < 59 ) + { + u8g2.drawStr(89,20-5,"github.com"); + u8g2.drawStr(73,29-5,"/olikraus/u8g2"); + } + else + { + u8g2.drawStr(1,54,"github.com/olikraus/u8g2"); + } +#endif +} + + uint8_t x = 0; long t = 0; long tt = 0; @@ -285,11 +418,16 @@ void loop(void) u8g2.firstPage(); do { - u8g2.setFont(u8g2_font_ncenB18_tr); - u8g2.drawStr(x*2,19,"Hello World!"); - u8g2.setFont(u8g2_font_ncenB12_tr); - u8g2.setCursor(x*2, 32); + u8g2.drawFrame(0,0,u8g2.getDisplayWidth(),u8g2.getDisplayHeight() ); + drawLogo(); + drawURL(); + + //u8g2.setFont(u8g2_font_ncenB18_tr); + //u8g2.drawStr(x*2,19,"Hello World!"); + u8g2.setFont(u8g2_font_4x6_tr); + u8g2.setCursor(x*2, 62); u8g2.print(tt, DEC); + } while ( u8g2.nextPage() ); x++; x &= 15;