This commit is contained in:
kraus 2023-08-14 18:12:25 +02:00
parent 7c3517921a
commit f710bae7e5
1 changed files with 157 additions and 19 deletions

View File

@ -1,7 +1,9 @@
/* /*
I2CLCDBoard.ino I2CLCDBoard.ino
https://github.com/olikraus/u8g2/issues/2191
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2023, olikraus@gmail.com Copyright (c) 2023, olikraus@gmail.com
@ -30,7 +32,8 @@
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <Arduino.h> #include <Arduino.h>
@ -74,11 +77,11 @@
/* /*
set a bit in the internal register and in the i2c control gpio 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); 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 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) U8X8_NOINLINE;
void u8x8_set_ctrl_bit(u8x8_t *u8x8, uint8_t bit, uint8_t is_set) 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++; data++;
arg_int--; arg_int--;
// Assumption: u8x8_set_ctrl_bit() will be slow enough, so that no extra delay is required // 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_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
u8x8_set_ctrl_bit(u8x8, enable_pin, 0); 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, 200);
//u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
u8x8_set_ctrl_bit(u8x8, enable_pin, 1); u8x8_set_ctrl_bit(u8x8, enable_pin, 1);
} }
break; 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 U8G2 u8g2; // create a plain U8g2 object
void setup(void) void setup(void)
@ -261,13 +323,14 @@ void setup(void)
Just replace the function name accordingly. Just replace the function name accordingly.
Note: 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. 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_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); //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); //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() After providing the callback function, start the communication with the display by using u8g2.begin()
@ -275,6 +338,76 @@ void setup(void)
u8g2.begin(); 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; uint8_t x = 0;
long t = 0; long t = 0;
long tt = 0; long tt = 0;
@ -285,11 +418,16 @@ void loop(void)
u8g2.firstPage(); u8g2.firstPage();
do do
{ {
u8g2.setFont(u8g2_font_ncenB18_tr); u8g2.drawFrame(0,0,u8g2.getDisplayWidth(),u8g2.getDisplayHeight() );
u8g2.drawStr(x*2,19,"Hello World!"); drawLogo();
u8g2.setFont(u8g2_font_ncenB12_tr); drawURL();
u8g2.setCursor(x*2, 32);
//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); u8g2.print(tt, DEC);
} while ( u8g2.nextPage() ); } while ( u8g2.nextPage() );
x++; x++;
x &= 15; x &= 15;