Raspberry Pi driver:
- Correct check for mmap errors (closes #3604495). - Add 40x4 support (for displays with two controllers). - Update the documentation.
This commit is contained in:
@@ -2962,8 +2962,8 @@ software adjustable contrast and brightness (backlight).
|
||||
<sect3 id="hd44780-raspberrypi">
|
||||
<title>Raspberry Pi</title>
|
||||
|
||||
<para>This connection type supports a single LCD connected to the GPIO header P1
|
||||
on a Raspberry Pi.</para>
|
||||
<para>This connection type supports a LCD connected to the GPIO header P1 on
|
||||
a Raspberry Pi. Displays with one or two controllers are supported.</para>
|
||||
|
||||
<para>It supports a switchable backlight connected to pin P1-11 by default. Use
|
||||
the switch circuit as described in <xref linkend="hd44780-ftdi-backlight"/>.</para>
|
||||
@@ -3051,6 +3051,13 @@ the switch circuit as described in <xref linkend="hd44780-ftdi-backlight"/>.</pa
|
||||
<entry>RW</entry>
|
||||
<entry>5</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>GPIO22</entry>
|
||||
<entry>P1-15</entry>
|
||||
<entry></entry>
|
||||
<entry>EN2</entry>
|
||||
<entry>Second controller (optional)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>GPIO17</entry>
|
||||
<entry>P1-11</entry>
|
||||
@@ -3066,17 +3073,21 @@ the switch circuit as described in <xref linkend="hd44780-ftdi-backlight"/>.</pa
|
||||
bus. If you loaded the SPI driver you will need to assign them to a different
|
||||
GPIO, e.g. GPIO04 and GPIO22.</para>
|
||||
|
||||
<para>When using a display with two controllers the <literal>vspan</literal>
|
||||
option has to be configured as well (e.g. <literal>vspan=2,2</literal> for a
|
||||
40x4 display).</para>
|
||||
|
||||
<sect4 id="hd44780-raspberrypi-config">
|
||||
<title>Special Raspberry Pi configuration options</title>
|
||||
|
||||
<para>This connection driver can be configured to use other pins than the
|
||||
one described in <link linkend="hd44780-raspberrypi.pin-mapping">the table
|
||||
above</link>. Using the <literal> pin_<replaceable><name>
|
||||
above</link>. Using the <literal>pin_<replaceable><LCD pin name>
|
||||
</replaceable></literal> configuration option, any LCD pin can be assigned
|
||||
to any GPIO pin.</para>
|
||||
|
||||
<important>
|
||||
<para>The values for the <literal>pin_<replaceable><name>
|
||||
<para>The values for the <literal>pin_<replaceable><LCD pin name>
|
||||
</replaceable></literal> 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 <ulink url=
|
||||
|
||||
@@ -14,13 +14,12 @@
|
||||
* P1-24 (8) EN (6)
|
||||
* GND R/W (5)
|
||||
* P1-26 (7) RS (4)
|
||||
* P1-15 (22) EN2 (second controller, optional)
|
||||
* P1-11 (17) BL (backlight optional)
|
||||
*
|
||||
* Mappings can be set in the config file using the key-words:
|
||||
* pin_EN, pin_RS, pin_D7, pin_D6, pin_D5, pin_D4, pin_BL
|
||||
* pin_EN, pin_EN2, pin_RS, pin_D7, pin_D6, pin_D5, pin_D4, pin_BL
|
||||
* in the [HD44780] section.
|
||||
*
|
||||
* Only a single LCD is currently supported.
|
||||
*/
|
||||
|
||||
/*-
|
||||
@@ -38,13 +37,14 @@
|
||||
*/
|
||||
|
||||
/* Default GPIO pin assignment */
|
||||
#define RPI_DEF_D7 18
|
||||
#define RPI_DEF_D6 23
|
||||
#define RPI_DEF_D5 24
|
||||
#define RPI_DEF_D4 25
|
||||
#define RPI_DEF_RS 7
|
||||
#define RPI_DEF_EN 8
|
||||
#define RPI_DEF_BL 17
|
||||
#define RPI_DEF_D7 18
|
||||
#define RPI_DEF_D6 23
|
||||
#define RPI_DEF_D5 24
|
||||
#define RPI_DEF_D4 25
|
||||
#define RPI_DEF_RS 7
|
||||
#define RPI_DEF_EN 8
|
||||
#define RPI_DEF_EN2 22
|
||||
#define RPI_DEF_BL 17
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user