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:
mmdolze
2013-02-22 15:20:16 +00:00
parent 96502bcfdf
commit c23077b722
3 changed files with 63 additions and 24 deletions
+15 -4
View File
@@ -2962,8 +2962,8 @@ software adjustable contrast and brightness (backlight).
<sect3 id="hd44780-raspberrypi"> <sect3 id="hd44780-raspberrypi">
<title>Raspberry Pi</title> <title>Raspberry Pi</title>
<para>This connection type supports a single LCD connected to the GPIO header P1 <para>This connection type supports a LCD connected to the GPIO header P1 on
on a Raspberry Pi.</para> 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 <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> 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>RW</entry>
<entry>5</entry> <entry>5</entry>
</row> </row>
<row>
<entry>GPIO22</entry>
<entry>P1-15</entry>
<entry></entry>
<entry>EN2</entry>
<entry>Second controller (optional)</entry>
</row>
<row> <row>
<entry>GPIO17</entry> <entry>GPIO17</entry>
<entry>P1-11</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 bus. If you loaded the SPI driver you will need to assign them to a different
GPIO, e.g. GPIO04 and GPIO22.</para> 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"> <sect4 id="hd44780-raspberrypi-config">
<title>Special Raspberry Pi configuration options</title> <title>Special Raspberry Pi configuration options</title>
<para>This connection driver can be configured to use other pins than the <para>This connection driver can be configured to use other pins than the
one described in <link linkend="hd44780-raspberrypi.pin-mapping">the table one described in <link linkend="hd44780-raspberrypi.pin-mapping">the table
above</link>. Using the <literal> pin_<replaceable>&lt;name&gt; above</link>. Using the <literal>pin_<replaceable>&lt;LCD pin name&gt;
</replaceable></literal> configuration option, any LCD pin can be assigned </replaceable></literal> configuration option, any LCD pin can be assigned
to any GPIO pin.</para> to any GPIO pin.</para>
<important> <important>
<para>The values for the <literal>pin_<replaceable>&lt;name&gt; <para>The values for the <literal>pin_<replaceable>&lt;LCD pin name&gt;
</replaceable></literal> configuration option are the number part from the </replaceable></literal> configuration option are the number part from the
GPIO signal name, not the pin number from the header connector! To find 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= out which signal is routed to which connector pin refer to the <ulink url=
+36 -9
View File
@@ -14,13 +14,12 @@
* P1-24 (8) EN (6) * P1-24 (8) EN (6)
* GND R/W (5) * GND R/W (5)
* P1-26 (7) RS (4) * P1-26 (7) RS (4)
* P1-15 (22) EN2 (second controller, optional)
* P1-11 (17) BL (backlight optional) * P1-11 (17) BL (backlight optional)
* *
* Mappings can be set in the config file using the key-words: * 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. * in the [HD44780] section.
*
* Only a single LCD is currently supported.
*/ */
/*- /*-
@@ -44,6 +43,7 @@
#define RPI_DEF_D4 25 #define RPI_DEF_D4 25
#define RPI_DEF_RS 7 #define RPI_DEF_RS 7
#define RPI_DEF_EN 8 #define RPI_DEF_EN 8
#define RPI_DEF_EN2 22
#define RPI_DEF_BL 17 #define RPI_DEF_BL 17
#include <stdio.h> #include <stdio.h>
@@ -121,8 +121,8 @@ setup_io(Driver *drvthis)
mem_fd, mem_fd,
GPIO_BASE); GPIO_BASE);
if ((long) gpio_map < 0) { if (gpio_map == MAP_FAILED) {
report(RPT_ERR, "setup_io: mmap error %s", strerror(errno)); report(RPT_ERR, "setup_io: mmap failed: %s", strerror(errno));
close(mem_fd); close(mem_fd);
return -1; return -1;
} }
@@ -280,6 +280,8 @@ lcdrpi_HD44780_close(PrivateData *p)
INP_GPIO(p->rpi_gpio->d4); INP_GPIO(p->rpi_gpio->d4);
if (p->have_backlight) if (p->have_backlight)
INP_GPIO(p->backlight_bit); INP_GPIO(p->backlight_bit);
if (p->numDisplays > 1)
INP_GPIO(p->rpi_gpio->en2);
/* Unmap and free memory */ /* Unmap and free memory */
if (gpio_map != NULL) if (gpio_map != NULL)
@@ -336,6 +338,15 @@ hd_init_rpi(Driver *drvthis)
return -1; 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 */ if (p->have_backlight) { /* Backlight setup is optional */
p->backlight_bit = drvthis->config_get_int(drvthis->name, "pin_BL", 0, RPI_DEF_BL); 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); 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; 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 /* Setup the lcd in 4 bit mode: Send (FUNCSET | IF_8BIT) three times
* followed by (FUNCSET | IF_4BIT) using four nibbles. Timing is not * followed by (FUNCSET | IF_4BIT) using four nibbles. Timing is not
* exactly what is required by HD44780. */ * exactly what is required by HD44780. */
@@ -392,10 +407,6 @@ hd_init_rpi(Driver *drvthis)
void void
lcdrpi_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) 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 */ /* Safeguard: This should never happen */
if (gpio_map == NULL) { if (gpio_map == NULL) {
return; return;
@@ -422,9 +433,16 @@ lcdrpi_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char f
p->hd44780_functions->uPause(p, 50); p->hd44780_functions->uPause(p, 50);
/* Data is clocked on the falling edge of EN */ /* Data is clocked on the falling edge of EN */
if (displayID == 1 || displayID == 0)
SET_GPIO(p->rpi_gpio->en, 1); 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); p->hd44780_functions->uPause(p, 50);
if (displayID == 1 || displayID == 0)
SET_GPIO(p->rpi_gpio->en, 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); p->hd44780_functions->uPause(p, 50);
/* Do same for lower nibble */ /* 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->d5, 0);
SET_GPIO(p->rpi_gpio->d4, 0); SET_GPIO(p->rpi_gpio->d4, 0);
p->hd44780_functions->uPause(p, 50); p->hd44780_functions->uPause(p, 50);
SET_GPIO(p->rpi_gpio->d7, (ch & 0x08)); SET_GPIO(p->rpi_gpio->d7, (ch & 0x08));
SET_GPIO(p->rpi_gpio->d6, (ch & 0x04)); SET_GPIO(p->rpi_gpio->d6, (ch & 0x04));
SET_GPIO(p->rpi_gpio->d5, (ch & 0x02)); SET_GPIO(p->rpi_gpio->d5, (ch & 0x02));
SET_GPIO(p->rpi_gpio->d4, (ch & 0x01)); SET_GPIO(p->rpi_gpio->d4, (ch & 0x01));
p->hd44780_functions->uPause(p, 50); p->hd44780_functions->uPause(p, 50);
if (displayID == 1 || displayID == 0)
SET_GPIO(p->rpi_gpio->en, 1); 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); p->hd44780_functions->uPause(p, 50);
if (displayID == 1 || displayID == 0)
SET_GPIO(p->rpi_gpio->en, 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); p->hd44780_functions->uPause(p, 50);
} }
+1
View File
@@ -11,6 +11,7 @@ int hd_init_rpi(Driver *drvthis);
* stored here is used for mapping physical GPIO pins to BCM2835 gpio. */ * stored here is used for mapping physical GPIO pins to BCM2835 gpio. */
struct rpi_gpio_map { struct rpi_gpio_map {
int en; int en;
int en2;
int rs; int rs;
int d7; int d7;
int d6; int d6;