diff --git a/docs/lcdproc-user/drivers/hd44780.docbook b/docs/lcdproc-user/drivers/hd44780.docbook index 21b7535..7d07ab5 100644 --- a/docs/lcdproc-user/drivers/hd44780.docbook +++ b/docs/lcdproc-user/drivers/hd44780.docbook @@ -2962,8 +2962,8 @@ software adjustable contrast and brightness (backlight). Raspberry Pi -This connection type supports a single LCD connected to the GPIO header P1 -on a Raspberry Pi. +This connection type supports a LCD connected to the GPIO header P1 on +a Raspberry Pi. Displays with one or two controllers are supported. It supports a switchable backlight connected to pin P1-11 by default. Use the switch circuit as described in . @@ -3051,6 +3051,13 @@ the switch circuit as described in .RW 5 + + GPIO22 + P1-15 + + EN2 + Second controller (optional) + GPIO17 P1-11 @@ -3066,17 +3073,21 @@ the switch circuit as described in . +When using a display with two controllers the vspan +option has to be configured as well (e.g. vspan=2,2 for a +40x4 display). + Special Raspberry Pi configuration options This connection driver can be configured to use other pins than the one described in the table -above. Using the pin_<name> +above. Using the pin_<LCD pin name> configuration option, any LCD pin can be assigned to any GPIO pin. - The values for the pin_<name> + The values for the pin_<LCD pin name> configuration option are the number part from the GPIO signal name, not the pin number from the header connector! To find out which signal is routed to which connector pin refer to the #include @@ -121,8 +121,8 @@ setup_io(Driver *drvthis) mem_fd, GPIO_BASE); - if ((long) gpio_map < 0) { - report(RPT_ERR, "setup_io: mmap error %s", strerror(errno)); + if (gpio_map == MAP_FAILED) { + report(RPT_ERR, "setup_io: mmap failed: %s", strerror(errno)); close(mem_fd); return -1; } @@ -280,6 +280,8 @@ lcdrpi_HD44780_close(PrivateData *p) INP_GPIO(p->rpi_gpio->d4); if (p->have_backlight) INP_GPIO(p->backlight_bit); + if (p->numDisplays > 1) + INP_GPIO(p->rpi_gpio->en2); /* Unmap and free memory */ if (gpio_map != NULL) @@ -336,6 +338,15 @@ hd_init_rpi(Driver *drvthis) return -1; } + if (p->numDisplays > 1) { /* For displays with two controllers */ + p->rpi_gpio->en2 = drvthis->config_get_int(drvthis->name, "pin_EN2", 0, RPI_DEF_EN2); + debug(RPT_INFO, "hd_init_rpi: Pin EN2 mapped to GPIO%d", p->rpi_gpio->en2); + if (check_pin(drvthis, p->rpi_gpio->en2, allowed_gpio_pins, used_pins)) { + free(p->rpi_gpio); + return -1; + } + } + if (p->have_backlight) { /* Backlight setup is optional */ p->backlight_bit = drvthis->config_get_int(drvthis->name, "pin_BL", 0, RPI_DEF_BL); debug(RPT_INFO, "hd_init_rpi: Backlight mapped to GPIO%d", p->backlight_bit); @@ -368,6 +379,10 @@ hd_init_rpi(Driver *drvthis) p->hd44780_functions->backlight = lcdrpi_HD44780_backlight; } + if (p->numDisplays > 1) { + setup_gpio(drvthis, p->rpi_gpio->en2); + } + /* Setup the lcd in 4 bit mode: Send (FUNCSET | IF_8BIT) three times * followed by (FUNCSET | IF_4BIT) using four nibbles. Timing is not * exactly what is required by HD44780. */ @@ -392,10 +407,6 @@ hd_init_rpi(Driver *drvthis) void lcdrpi_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) { - /* Only one display is (currently) supported */ - if (displayID > 1) { - return; - } /* Safeguard: This should never happen */ if (gpio_map == NULL) { return; @@ -422,9 +433,16 @@ lcdrpi_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char f p->hd44780_functions->uPause(p, 50); /* Data is clocked on the falling edge of EN */ - SET_GPIO(p->rpi_gpio->en, 1); + if (displayID == 1 || displayID == 0) + SET_GPIO(p->rpi_gpio->en, 1); + if (displayID == 2 || (p->numDisplays > 1 && displayID == 0)) + SET_GPIO(p->rpi_gpio->en2, 1); p->hd44780_functions->uPause(p, 50); - SET_GPIO(p->rpi_gpio->en, 0); + + if (displayID == 1 || displayID == 0) + SET_GPIO(p->rpi_gpio->en, 0); + if (displayID == 2 || (p->numDisplays > 1 && displayID == 0)) + SET_GPIO(p->rpi_gpio->en2, 0); p->hd44780_functions->uPause(p, 50); /* Do same for lower nibble */ @@ -433,14 +451,23 @@ lcdrpi_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char f SET_GPIO(p->rpi_gpio->d5, 0); SET_GPIO(p->rpi_gpio->d4, 0); p->hd44780_functions->uPause(p, 50); + SET_GPIO(p->rpi_gpio->d7, (ch & 0x08)); SET_GPIO(p->rpi_gpio->d6, (ch & 0x04)); SET_GPIO(p->rpi_gpio->d5, (ch & 0x02)); SET_GPIO(p->rpi_gpio->d4, (ch & 0x01)); p->hd44780_functions->uPause(p, 50); - SET_GPIO(p->rpi_gpio->en, 1); + + if (displayID == 1 || displayID == 0) + SET_GPIO(p->rpi_gpio->en, 1); + if (displayID == 2 || (p->numDisplays > 1 && displayID == 0)) + SET_GPIO(p->rpi_gpio->en2, 1); p->hd44780_functions->uPause(p, 50); - SET_GPIO(p->rpi_gpio->en, 0); + + if (displayID == 1 || displayID == 0) + SET_GPIO(p->rpi_gpio->en, 0); + if (displayID == 2 || (p->numDisplays > 1 && displayID == 0)) + SET_GPIO(p->rpi_gpio->en2, 0); p->hd44780_functions->uPause(p, 50); } diff --git a/server/drivers/hd44780-rpi.h b/server/drivers/hd44780-rpi.h index 99847eb..8b01be7 100644 --- a/server/drivers/hd44780-rpi.h +++ b/server/drivers/hd44780-rpi.h @@ -11,6 +11,7 @@ int hd_init_rpi(Driver *drvthis); * stored here is used for mapping physical GPIO pins to BCM2835 gpio. */ struct rpi_gpio_map { int en; + int en2; int rs; int d7; int d6;