![]() | ![]() |
1. Connecting the console
2. Boot without disk
3. Compile in LEDE
4. Port management (via LuCI and console)
5. Connection to the I2C bus
6. Connecting the PCF8574 port extender
7. Initializing HD44780 via i2cset
8. Character device for writing data to the I2C bus
9. Adding HD44780 driver to the kernel
10. Adding processing of necessary VT100 commands to HD44780 driver
11. Adding a display with some VT100 commands to LCD4Linux
12. Adding a character generator programming command to the HD44780 driver
13. Optimization of data transmission on the I2C bus
RS - P0
R / W - P1
E - P2
BL - P3
D4 - P4
D5 - P5
D6 - P6
D7 - P7
root@lede: i2cdetect 0 WARNING! This program can confuse your I2C bus, cause data loss and worse! I will probe file /dev/i2c-0. I will probe address range 0x03-0x77. Continue? [Y/n] y 0 1 2 3 4 5 6 7 8 9 abcdef 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
insmod i2c-dev insmod i2c-gpio-custom bus0=0,$sda_gpio,$scl_gpio
root@lede: echo 24c00 0x27 > /sys/bus/i2c/devices/i2c-0/new_device root@lede: echo 24c00 0x27 > [ 33.335472] at24 0-0027: 16 byte 24c00 EEPROM, writable, 1 bytes/write [ 33.342102] i2c i2c-0: new_device: Instantiated device 24c00 at 0x27
root@lede: echo "1111" > /sys/bus/i2c/devices/i2c-0/0-0027/eeprom
0x4e-0x00-0x31 0x4e-0x01-0x31 0x4e-0x02-0x31 0x4e-0x03-0x31 0x4e-0x04-0x0a
//if (at24->chip.flags & AT24_FLAG_ADDR16) // msg.buf[i++] = offset >> 8; //msg.buf[i++] = offset;
root@lede: echo 24c00 0x27 > /sys/bus/i2c/devices/i2c-0/new_device [ 2708.782356] at24 0-0027: 16 byte 24c00 EEPROM, writable, 1 bytes/write [ 2708.788891] i2c i2c-0: new_device: Instantiated device 24c00 at 0x27 root@lede: echo "1111" > /sys/bus/i2c/devices/i2c-0/0-0027/eeprom
#!/bin/sh i2c_adres=0x27 i2c_dev=/sys/bus/i2c/devices/i2c-0/0-0027/eeprom led=8 ansi=0 to_octal () { hh3=$(($hh / 64)) hh1=$(($hh - $hh3 * 64)) hh2=$(($hh1 / 8)) hh1=$(($hh1 - $hh2 * 8)) } write_CMD () { : $((hb = $c & 240)) : $((lb = ($c << 4) & 240 )) hh=$((4 + $hb + $led)) to_octal echo -e -n \\$hh3$hh2$hh1 >> $i2c_dev hh=$((0 + $hb + $led)) to_octal echo -e -n \\$hh3$hh2$hh1 >> $i2c_dev hh=$((4 + $lb + $led)) to_octal echo -e -n \\$hh3$hh2$hh1 >> $i2c_dev hh=$((0 + $lb + $led)) to_octal echo -e -n \\$hh3$hh2$hh1 >> $i2c_dev } print_LCD () { : $((hb = $c & 240)) : $((lb = ($c << 4) & 240 )) hh=$((5 + $hb + $led)) to_octal echo -e -n \\$hh3$hh2$hh1 >> $i2c_dev hh=$((1 + $hb + $led)) to_octal echo -e -n \\$hh3$hh2$hh1 >> $i2c_dev hh=$((5 + $lb + $led)) to_octal echo -e -n \\$hh3$hh2$hh1 >> $i2c_dev hh=$((1 + $lb + $led)) to_octal echo -e -n \\$hh3$hh2$hh1 >> $i2c_dev } ########## init LCD ##################### init_LCD () { if [[ ! -w $i2c_dev ]] then echo 24c00 0x27 > /sys/bus/i2c/devices/i2c-0/new_device sleep 0.5 fi sleep 0.5 c=3 write_CMD c=3 write_CMD c=2 write_CMD c=40 #28 write_CMD c=44 #2C write_CMD c=44 #2C write_CMD c=12 #0C write_CMD c=1 write_CMD sleep 0.2 c=6 write_CMD c=2 write_CMD } ############################### init_LCD c=0x80 # stroka - 1 write_CMD for i in `seq 32 63`; do if [ "$i" == 48 ]; then c=0xC0 # stroka - 2 write_CMD fi c=$(($i + $ansi)) print_LCD done sleep 3 c=0x80 # stroka - 1 write_CMD for i in `seq 64 95`; do if [ "$i" == 80 ]; then c=0xC0 # stroka - 2 write_CMD fi c=$(($i + $ansi)) print_LCD done sleep 3 c=0x80 # stroka - 1 write_CMD for i in `seq 96 127`; do if [ "$i" == 112 ]; then c=0xC0 # stroka - 2 write_CMD fi c=$(($i + $ansi)) print_LCD done
Display HD44780-I2C { Driver 'HD44780' Model 'generic' Bus 'i2c' Port '/dev/i2c-0' Device '0x27' Bits '4' Size '16x2' asc255bug 0 Icons 1 Wire { RW 'DB1' RS 'DB0' ENABLE 'DB2' GPO 'GND' } }
root@lede: /usr/bin/lcd4linux -v -F LCD4Linux 0.11.0-SVN-1193 starting HD44780: $Rev: 1202 $ HD44780: using model 'generic' HD44780: using I2C bus HD44780: using 1 Controller(s) HD44780: using 4 bit mode udelay: using gettimeofday() delay loop Segmentation fault
ls -l -rw-r--r-- 1 root root 18092 Feb 21 2016 LICENSE -rw-r--r-- 1 root root 60 Nov 9 06:17 Makefile -rw-r--r-- 1 root root 1945 Feb 21 2016 README.md -rw-r--r-- 1 root root 10316 Nov 16 04:33 hd44780-dev.c -rw-r--r-- 1 root root 7756 Feb 21 2016 hd44780-i2c.c -rw-r--r-- 1 root root 1122 Nov 16 03:28 hd44780.h -rw-r--r-- 1 root root 235 Feb 21 2016 make.sh
obj-m := hd44780.o hd44780-y := hd44780-i2c.o hd44780-dev.o
include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=hd44780 PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define KernelPackage/hd44780 SUBMENU:=Other modules TITLE:=I2C HD44780 driver FILES:=$(PKG_BUILD_DIR)/hd44780.ko AUTOLOAD:=$(call AutoLoad,70,hd44780) KCONFIG:= endef define Package/hd44780/description Big comments.... ... endef MAKE_OPTS:= \ ARCH="$(LINUX_KARCH)" \ CROSS_COMPILE="$(TARGET_CROSS)" \ SUBDIRS="$(PKG_BUILD_DIR)" \ EXTRA_CFLAGS="$(EXTRA_CFLAGS)" define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef define Build/Compile $(MAKE) -C "$(LINUX_DIR)" \ $(MAKE_OPTS) \ modules endef $(eval $(call KernelPackage,hd44780))
make menuconfig
root@lede: insmod hd44780 root@lede: lsmod |grep 44780 hd44780 5450 0
root@lede: echo hd44780 0x27 > /sys/bus/i2c/devices/i2c-0/new_device [ 9463.913178] i2c i2c-0: new_device: Instantiated device hd44780 at 0x27
root@lede: echo -n 123 > /dev/lcd0
root@lede: echo -n 0 > /sys/class/hd44780/lcd0/cursor_blink
root@lede: echo -n -e '\x1b'[2J > /dev/lcd0 root@lede: echo -n -e '\x1b'[H > /dev/lcd0
#!/bin/sh echo hd44780 0x27 > /sys/bus/i2c/devices/i2c-0/new_device echo -n 16x2 > /sys/class/hd44780/lcd0/geometry echo -n 0 > /sys/class/hd44780/lcd0/cursor_display echo -n 0 > /sys/class/hd44780/lcd0/cursor_blink echo -n -e '\x1b'[2JHello! > /dev/lcd0 exit 0
static void hd44780_handle_esc_seq_char(struct hd44780 *lcd, char ch) { int prev_row, prev_col; lcd->esc_seq_buf.buf[lcd->esc_seq_buf.length++] = ch; if (!strcmp(lcd->esc_seq_buf.buf, "[2J")) { prev_row = lcd->pos.row; prev_col = lcd->pos.col; hd44780_clear_display(lcd); hd44780_write_instruction(lcd, HD44780_DDRAM_ADDR | (lcd->geometry->start_addrs[prev_row] + prev_col)); hd44780_leave_esc_seq(lcd); } else if (!strcmp(lcd->esc_seq_buf.buf, "[H")) { hd44780_write_instruction(lcd, HD44780_RETURN_HOME); lcd->pos.row = 0; lcd->pos.col = 0; hd44780_leave_esc_seq(lcd); } else if (lcd->esc_seq_buf.length == ESC_SEQ_BUF_SIZE) { hd44780_flush_esc_seq(lcd); } }
static void hd44780_handle_esc_seq_char(struct hd44780 *lcd, char ch) { int prev_row, prev_col; struct hd44780_geometry *geo = lcd->geometry; lcd->esc_seq_buf.buf[lcd->esc_seq_buf.length++] = ch; if (!strcmp(lcd->esc_seq_buf.buf, "[2J")) { prev_row = lcd->pos.row; prev_col = lcd->pos.col; hd44780_clear_display(lcd); hd44780_write_instruction(lcd, HD44780_DDRAM_ADDR | (lcd->geometry->start_addrs[prev_row] + prev_col)); hd44780_leave_esc_seq(lcd); } else if (!strcmp(lcd->esc_seq_buf.buf, "[H")) { hd44780_write_instruction(lcd, HD44780_RETURN_HOME); lcd->pos.row = 0; lcd->pos.col = 0; hd44780_leave_esc_seq(lcd); } else if ((lcd->esc_seq_buf.buf[0]=='[') && (lcd->esc_seq_buf.buf[4]=='H') && // Esc[ Line ; Column H (lcd->esc_seq_buf.buf[2]==';' ) && (lcd->esc_seq_buf.length == 5)) { lcd->pos.row = lcd->esc_seq_buf.buf[1] % geo->rows; lcd->pos.col = lcd->esc_seq_buf.buf[3] % geo->cols; hd44780_write_instruction(lcd, HD44780_DDRAM_ADDR | (geo->start_addrs[lcd->pos.row] + lcd->pos.col)); hd44780_leave_esc_seq(lcd); } else if (lcd->esc_seq_buf.length == ESC_SEQ_BUF_SIZE) { hd44780_flush_esc_seq(lcd); } }
#define ESC_SEQ_BUF_SIZE 4
root@debian:/apm82181-lede-master# make package/hd44780/compile make[1] package/hd44780/compile make[2] -C package/hd44780 compile
root@lede:/ echo -n -e '\x1b[1;6H' > /dev/lcd0
if test "$VT100" = "yes"; then TEXT="yes" I2C="yes" DRIVERS="$DRIVERS drv_vt100.o" AC_DEFINE(WITH_VT100,1,[vt100 driver]) fi
static int drv_vt100_open(const char *section) { char *s; int f = -1; s = cfg_get(section, "Port", NULL); if (s == NULL || *s == '\0' || strlen(s) > 80) { error("%s: no '%s.Port' entry from %s", Name, section, cfg_source()); return -1; } strcpy(Port, s); f = open(Port, O_WRONLY); if (f == -1) { error("open(%s) failed: %s", Port, strerror(errno)); return -1; } close (f); return 0; }
static void drv_vt100_send(const char *data, const unsigned int len) { unsigned int i; int f; f = open(Port, O_WRONLY); write (f, data, len); close (f); }
static void drv_vt100_clear(void) { char cmd[4]; cmd[0] = 0x1B; // ESC cmd[1] = '['; // [ cmd[2] = '2'; // 2 cmd[3] = 'J'; // J drv_vt100_send(cmd, 4); cmd[2] = 'H'; // H drv_vt100_send(cmd, 3); }
static void drv_vt100_write(const int row, const int col, const char *data, int len) { char cmd[6]; cmd[0] = 0x1B; // ESC cmd[1] = '['; // [ cmd[2] = row & 0xff; // Line cmd[3] = ';'; // ; cmd[4] = col & 0xff; // Column cmd[5] = 'H'; // H drv_vt100_send(cmd, 6); }
diff -Naur ./1 ./2 > 180-vt100.patch
diff -Naur ./vt100/Makefile.am ./vt100-f/Makefile.am --- ./vt100/Makefile.am 2016-11-28 11:01:56.000000000 +0000 +++ ./vt100-f/Makefile.am 2016-11-14 07:33:41.000000000 +0000 @@ -125,6 +125,7 @@ drv_USBHUB.c \ drv_USBLCD.c \ drv_vnc.c \ +drv_vt100.c \ drv_WincorNixdorf.c \ drv_X11.c \ \ diff -Naur ./vt100/drivers.m4 ./vt100-f/drivers.m4 --- ./vt100/drivers.m4 2016-11-14 11:54:41.000000000 +0000 +++ ./vt100-f/drivers.m4 2016-11-14 07:37:00.000000000 +0000 @@ -39,7 +39,7 @@ [ Newhaven, Noritake, NULL, Pertelian, PHAnderson,] [ PICGraphic, picoLCD, picoLCDGraphic, PNG, PPM, RouterBoard,] [ Sample, SamsungSPF, serdisplib, ShuttleVFD, SimpleLCD, st2205, T6963,] - [ TeakLCM, TEW673GRU, Trefon, ULA200, USBHUB, USBLCD, VNC, WincorNixdorf, X11], + [ TeakLCM, TEW673GRU, Trefon, ULA200, USBHUB, USBLCD, VNC, vt100, WincorNixdorf, X11], drivers=$withval, drivers=all ) @@ -114,6 +114,7 @@ USBHUB="yes" USBLCD="yes" VNC="yes" + VT100="yes" WINCORNIXDORF="yes" X11="yes" ;; @@ -279,6 +280,9 @@ VNC) VNC=$val ;; + vt100) + VT100=$val + ;; WincorNixdorf) WINCORNIXDORF=$val ;; @@ -869,6 +873,13 @@ fi fi +if test "$VT100" = "yes"; then + TEXT="yes" + I2C="yes" + DRIVERS="$DRIVERS drv_vt100.o" + AC_DEFINE(WITH_VT100,1,[vt100 driver]) +fi + if test "$WINCORNIXDORF" = "yes"; then TEXT="yes" SERIAL="yes"
Variables { tick 500 tack 100 minute 60000 } Display VT100 { Driver 'vt100' Size '16x2' Port '/dev/lcd0' } Widget Test { class 'Text' expression '1234567890123456' width 16 } Layout Test { Row01.Col1 'Test' Row02.Col1 'Test' } Display 'VT100' Layout 'Test'
root@lede:/# /usr/bin/lcd4linux -v -F LCD4Linux 0.11.0-SVN-1193 starting vt100: $Rev: 001 $ initializing layout 'Test' Creating new timer group (1000 ms) widget 'Test': Class 'text', Parent '<root>', Layer 1, Row 0, Col 0 (to 0,16) widget 'Test': Class 'text', Parent 'Test', Layer 1, Row 1, Col 0 (to 1,16)
static void hd44780_handle_esc_seq_char(struct hd44780 *lcd, char ch) { int prev_row, prev_col; struct hd44780_geometry *geo = lcd->geometry; if (lcd->is_in_set_char == 0) { lcd->esc_seq_buf.buf[lcd->esc_seq_buf.length++] = ch; if (!strcmp(lcd->esc_seq_buf.buf, "[2J")) { prev_row = lcd->pos.row; prev_col = lcd->pos.col; hd44780_clear_display(lcd); hd44780_write_instruction(lcd, HD44780_DDRAM_ADDR | (lcd->geometry->start_addrs[prev_row] + prev_col)); hd44780_leave_esc_seq(lcd); } else if (!strcmp(lcd->esc_seq_buf.buf, "[H")) { hd44780_write_instruction(lcd, HD44780_RETURN_HOME); lcd->pos.row = 0; lcd->pos.col = 0; hd44780_leave_esc_seq(lcd); } else if ((lcd->esc_seq_buf.buf[0]=='[') && (lcd->esc_seq_buf.buf[4]=='H') && // Esc[ Line ; Column H (lcd->esc_seq_buf.buf[2]==';' ) && (lcd->esc_seq_buf.length == 5)) { lcd->pos.row = lcd->esc_seq_buf.buf[1] % geo->rows; lcd->pos.col = lcd->esc_seq_buf.buf[3] % geo->cols; hd44780_write_instruction(lcd, HD44780_DDRAM_ADDR | (geo->start_addrs[lcd->pos.row] + lcd->pos.col)); hd44780_leave_esc_seq(lcd); } else if (!strcmp(lcd->esc_seq_buf.buf, "(S")) { // Esc(S code matrix(8) lcd->is_in_set_char = 1; } else if (lcd->esc_seq_buf.length == ESC_SEQ_BUF_SIZE) { hd44780_flush_esc_seq(lcd); } } else if (lcd->is_in_set_char == 1) { // start set CGRAM code hd44780_write_instruction(lcd, HD44780_CGRAM_ADDR | 8 * (ch & 0x07)); lcd->is_in_set_char++; } else { hd44780_write_data(lcd, ch & 0x1f); // set 8 bytes CGRAM code lcd->is_in_set_char++; if (lcd->is_in_set_char == 10){ // go to DDRAM mode hd44780_write_instruction(lcd, HD44780_DDRAM_ADDR | (geo->start_addrs[lcd->pos.row] + lcd->pos.col)); hd44780_leave_esc_seq(lcd); } } }
void hd44780_write(struct hd44780 *lcd, const char *buf, size_t count) ... case '\e': lcd->is_in_esc_seq = true; lcd->is_in_set_char = 0; break; default: hd44780_write_char(lcd, ch); ...
struct hd44780 { struct cdev cdev; struct device *device; struct i2c_client *i2c_client; struct hd44780_geometry *geometry; struct { int row; int col; } pos; char buf[BUF_SIZE]; struct { char buf[ESC_SEQ_BUF_SIZE]; int length; } esc_seq_buf; bool is_in_esc_seq; int is_in_set_char; bool backlight; bool cursor_blink; bool cursor_display; bool dirty; struct mutex lock; struct list_head list; };
static void drv_vt100_defchar(const int ascii, const unsigned char *matrix) { char cmd[12]; int i; /* call the 'define character' function */ cmd[0] = 0x1B; // ESC cmd[1] = '('; // ( cmd[2] = 'S'; // S cmd[3] = ascii & 0x07; // code /* send bitmap to the display */ for (i = 0; i < 8; i++) { cmd[i + 4] = (*matrix++) & 0x1f; } drv_vt100_send(cmd, 12); }
Variables { tick 500 tack 100 minute 60000 } Display VT100 { Driver 'vt100' Size '16x2' Port '/dev/lcd0' Icons 1 } Widget RAM { class 'Text' expression meminfo('MemFree')/1024 postfix ' MB RAM' width 11 precision 0 align 'R' update tick } Widget Busy { class 'Text' expression proc_stat::cpu('busy', 500) prefix 'Busy' postfix '%' width 9 precision 1 align 'R' update tick } Widget Uptime { class 'Text' expression uptime('%d days %H:%M:%S') width 20 align 'R' prefix 'Up ' update 1000 } Widget Uptime { class 'Text' expression 'Up '.uptime('%d %H:%M:%S') width 16 align 'L' update 1000 } # Icons Widget Timer { class 'Icon' speed 83 Bitmap { Row1 '.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|' Row2 '.***.|.*+*.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.+++.|.+*+.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|' Row3 '*****|**+**|**++*|**+++|**++.|**++.|**+++|**+++|**+++|**+++|**+++|+++++|+++++|++*++|++**+|++***|++**.|++**.|++***|++***|++***|++***|++***|*****|' Row4 '*****|**+**|**+**|**+**|**+++|**+++|**+++|**+++|**+++|**+++|+++++|+++++|+++++|++*++|++*++|++*++|++***|++***|++***|++***|++***|++***|*****|*****|' Row5 '*****|*****|*****|*****|*****|***++|***++|**+++|*++++|+++++|+++++|+++++|+++++|+++++|+++++|+++++|+++++|+++**|+++**|++***|+****|*****|*****|*****|' Row6 '.***.|.***.|.***.|.***.|.***.|.***.|.**+.|.*++.|.+++.|.+++.|.+++.|.+++.|.+++.|.+++.|.+++.|.+++.|.+++.|.+++.|.++*.|.+**.|.***.|.***.|.***.|.***.|' Row7 '.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|' Row8 '.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|' } } Layout L16x2 { Row1 { Col1 'Uptime' col16 'Timer' } Row2 { Col1 'Busy' Col11 'RAM' } } Display 'VT100' Layout 'L16x2'
root@lede: /usr/bin/lcd4linux -v -F LCD4Linux 0.11.0-SVN-1193 starting vt100: $Rev: 001 $ vt100: reserving 1 of 8 user-defined characters for icons initializing layout 'L16x2' Creating new timer group (1000 ms) widget 'Uptime': Class 'text', Parent '<root>', Layer 1, Row 0, Col 0 (to 0,16) Creating new timer group (83 ms) widget 'Timer': Class 'icon', Parent '<root>', Layer 1, Row 0, Col 15 (to 1,16) Creating new timer group (500 ms) widget 'Busy': Class 'text', Parent '<root>', Layer 1, Row 1, Col 0 (to 1,9) widget 'RAM': Class 'text', Parent '<root>', Layer 1, Row 1, Col 10 (to 1,21)
--- a/lcd4linux.conf.sample 2016-11-15 09:47:46.000000000 +0000 +++ af/lcd4linux.conf.sample 2016-11-18 03:18:22.000000000 +0000 @@ -567,7 +567,14 @@ HttpPort '5800' } - +Display VT100 { + Driver 'vt100' + Size '16x2' + Port '/dev/lcd0' + Icons 1 +} + + Display FutabaVFD { Driver 'FutabaVFD' Port '/dev/parport0' @@ -674,7 +681,7 @@ Widget RAM { class 'Text' - expression meminfo('MemTotal')/1024 + expression meminfo('MemFree')/1024 postfix ' MB RAM' width 11 precision 0 @@ -828,6 +835,14 @@ update 1000 } +Widget Uptime { + class 'Text' + expression 'Up '.uptime('%d %H:%M:%S') + width 16 + align 'L' + update 1000 +} + Widget mpris_TrackPosition_bar { class 'Bar' expression mpris_dbus::method_PositionGet('org.kde.amarok') @@ -1015,7 +1030,7 @@ Widget Timer { class 'Icon' - speed 50 + speed 83 Bitmap { Row1 '.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|.....|' Row2 '.***.|.*+*.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.*++.|.+++.|.+*+.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|.+**.|' @@ -1225,6 +1240,17 @@ } } +Layout L16x2-2 { + Row1 { + Col1 'Uptime' + col16 'Timer' + } + Row2 { + Col1 'Busy' + Col11 'RAM' + } +} + Layout L20x2 { Row1 { Col1 'CPUinfo' @@ -1323,7 +1349,7 @@ -Display 'ACool' +#Display 'ACool' #Display 'SerDispLib' #Display 'LCD-Linux' #Display 'LCD2041' @@ -1354,7 +1380,7 @@ #Display 'IRLCD' #Display 'USBLCD' #Display 'BWCT' -#Display 'Image' +Display 'Image' #Display 'TeakLCD' #Display 'Trefon' #Display 'LCD2USB' @@ -1363,15 +1389,17 @@ #Display 'ctinclud' #Display 'picoLCD' #Display 'VNC' +Display 'VT100' #Display 'FutabaVFD' #Display 'GLCD2USB' -#Layout 'Default' -Layout 'TestLayer' +Layout 'Default' +#Layout 'TestLayer' #Layout 'TestImage' #Layout 'L8x2' #Layout 'L16x1' #Layout 'L16x2' +Layout 'L16x2-2' #Layout 'L20x2' #Layout 'L40x2' #Layout 'Test'
static void pcf8574_raw_write(struct hd44780 *lcd, u8 data) { i2c_smbus_write_byte(lcd->i2c_client, data); } static void hd44780_write_nibble(struct hd44780 *lcd, dest_reg reg, u8 data) { data = (data << 4) & 0xF0; if (reg == DR) data |= RS; data = data | (RW & 0x00); if (lcd->backlight) data |= BL; pcf8574_raw_write(lcd, data); pcf8574_raw_write(lcd, data | E); pcf8574_raw_write(lcd, data); } static void hd44780_write_data(struct hd44780 *lcd, u8 data) { u8 h = (data >> 4) & 0x0F; u8 l = data & 0x0F; hd44780_write_nibble(lcd, DR, h); hd44780_write_nibble(lcd, DR, l); udelay(37 + 4); }
static void hd44780_write_data(struct hd44780 *lcd, u8 data) { u8 h = (data >> 4) & 0x0F; u8 l = data & 0x0F; u8 buf[5]; h = (h << 4) & 0xF0; l = (l << 4) & 0xF0; h |= RS; l |= RS; h = h | (RW & 0x00); l = l | (RW & 0x00); if (lcd->backlight){ h |= BL; l |= BL; } buf[0] = h | E; buf[1] = h; buf[2] = l; buf[3] = l | E; buf[4] = l; i2c_smbus_write_i2c_block_data(lcd->i2c_client, h, 5, (const u8 *)(&buf[0])); udelay(37 + 4); }
setenv addmisc 'setenv bootargs ${bootargs} i2c-ibm_iic.iic_force_fast=1'
root@lede: dmesg | grep i2c [ 0.000000] Kernel command line: root=/dev_nfs rw nfsroot=192.168.1.10:/nfs/debian_ppc/rootfs ip=dhcp console=ttyS0,115200 i2c-ibm_iic.iic_force_fast=1 [ 4.770923] i2c /dev entries driver [ 4.774742] ibm-iic 4ef600700.i2c: using fast (400 kHz) mode [ 10.456041] i2c i2c-0: new_device: Instantiated device hd44780 at 0x27
IIC0: i2c@ef600700 { compatible = "ibm,iic"; reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; interrupts = <0x2 0x4>; fast-mode; #address-cells = <1>; #size-cells = <0>; };
root@lede: dmesg | grep i2c [ 4.774585] i2c /dev entries driver [ 4.778396] ibm-iic 4ef600700.i2c: using fast (400 kHz) mode [ 10.464396] i2c i2c-0: new_device: Instantiated device hd44780 at 0x27 root@lede: ls -al /proc/device-tree/plb/opb/i2c@ef600700 -r--r--r-- 1 root root 4 Nov 18 04:13 #address-cells -r--r--r-- 1 root root 4 Nov 18 04:13 #size-cells drwxr-xr-x 2 root root 0 Nov 18 04:13 . drwxr-xr-x 12 root root 0 Nov 18 04:13 .. -r--r--r-- 1 root root 8 Nov 18 04:13 compatible -r--r--r-- 1 root root 0 Nov 18 04:13 fast-mode -r--r--r-- 1 root root 4 Nov 18 04:13 interrupt-parent -r--r--r-- 1 root root 8 Nov 18 04:13 interrupts -r--r--r-- 1 root root 4 Nov 18 04:13 name -r--r--r-- 1 root root 8 Nov 18 04:13 reg
Source: https://habr.com/ru/post/316100/
All Articles