summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/ChangeLog.txt3
-rw-r--r--apps/examples/slcd/slcd_main.c89
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/configs/pcblogic-pic32mx/README.txt9
-rw-r--r--nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c16
-rw-r--r--nuttx/libc/misc/lib_slcddecode.c36
-rw-r--r--nuttx/libc/misc/lib_slcdencode.c2
7 files changed, 111 insertions, 46 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index f064a61f6..910cd113e 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -562,4 +562,5 @@
Book. Contributed by Max Holtberg (2013-5-22).
* apps/examples/slcd: Add an example for testing alphanumeric,
segment LCDs (2013-5-24).
-
+ * apps/examples/slcd: Extend SLCD test to handle multi-line displays
+ (2013-5-26).
diff --git a/apps/examples/slcd/slcd_main.c b/apps/examples/slcd/slcd_main.c
index 0a0a5e0f2..b6168de56 100644
--- a/apps/examples/slcd/slcd_main.c
+++ b/apps/examples/slcd/slcd_main.c
@@ -54,8 +54,8 @@
* Pre-processor Definitions
****************************************************************************/
-#ifndef EXAMPLES_SLCD_DEVNAME
-# define EXAMPLES_SLCD_DEVNAME "/dev/slcd"
+#ifndef CONFIG_EXAMPLES_SLCD_DEVNAME
+# define CONFIG_EXAMPLES_SLCD_DEVNAME "/dev/slcd"
#endif
/****************************************************************************
@@ -64,13 +64,18 @@
/* All state information for this test is kept within the following structure
* in order create a namespace and to minimize the possibility of name
* collisions.
+ *
+ * NOTE: stream must be the first element of struct slcd_test_s to support
+ * casting between these two types.
*/
struct slcd_test_s
{
- struct lib_outstream_s stream; /* Stream to use for all output */
- struct slcd_geometry_s geo; /* Size of the SLCD (rows x columns) */
- int fd; /* File descriptor or the open SLCD device */
+ struct lib_outstream_s stream; /* Stream to use for all output */
+ struct slcd_geometry_s geo; /* Size of the SLCD (rows x columns) */
+ int fd; /* File descriptor or the open SLCD device */
+ bool initialized; /* TRUE: Initialized */
+ uint8_t currow; /* Next row to display */
/* The I/O buffer */
@@ -102,7 +107,7 @@ void slcd_dumpbuffer(FAR const char *msg, FAR const uint8_t *buffer, unsigned in
int j;
int k;
- printf("%s (%p):\n", msg, buffer);
+ printf("%s:\n", msg);
for (i = 0; i < buflen; i += 32)
{
printf("%04x: ", i);
@@ -256,43 +261,66 @@ int slcd_main(int argc, char *argv[])
{
str = argv[1];
}
-#endif
- /* Initialize the output stream */
+ /* Are we already initialized? */
+
+ if (!priv->initialized)
+#endif
+ {
+ /* Initialize the output stream */
- memset(priv, 0, sizeof(struct slcd_test_s));
- priv->stream.put = slcd_putc;
+ memset(priv, 0, sizeof(struct slcd_test_s));
+ priv->stream.put = slcd_putc;
#ifdef CONFIG_STDIO_LINEBUFFER
- priv->stream.flush = slcd_flush;
+ priv->stream.flush = slcd_flush;
#endif
- /* Open the SLCD device */
+ /* Open the SLCD device */
- printf("Opening %s for read/write access\n", EXAMPLES_SLCD_DEVNAME);
+ printf("Opening %s for read/write access\n", CONFIG_EXAMPLES_SLCD_DEVNAME);
- priv->fd = open(EXAMPLES_SLCD_DEVNAME, O_RDWR);
- if (priv->fd < 0)
- {
- printf("Failed to open %s: %d\n", EXAMPLES_SLCD_DEVNAME, errno);
- goto errout;
- }
+ priv->fd = open(CONFIG_EXAMPLES_SLCD_DEVNAME, O_RDWR);
+ if (priv->fd < 0)
+ {
+ printf("Failed to open %s: %d\n", CONFIG_EXAMPLES_SLCD_DEVNAME, errno);
+ goto errout;
+ }
- /* Get the geometry of the SCLD device */
+ /* Get the geometry of the SCLD device */
- ret = ioctl(priv->fd, SLCDIOC_GEOMETRY, (unsigned long)&priv->geo);
- if (ret < 0)
- {
- printf("ioctl(SLCDIOC_GEOMETRY) failed: %d\n", errno);
- goto errout_with_fd;
+ ret = ioctl(priv->fd, SLCDIOC_GEOMETRY, (unsigned long)&priv->geo);
+ if (ret < 0)
+ {
+ printf("ioctl(SLCDIOC_GEOMETRY) failed: %d\n", errno);
+ goto errout_with_fd;
+ }
+
+ printf("Geometry rows: %d columns: %d nbars: %d\n",
+ priv->geo.nrows, priv->geo.ncolumns, priv->geo.nbars);
+
+ /* Home the cursor and clear the display */
+
+ printf("Clear screen\n");
+ slcd_encode(SLCDCODE_CLEAR, 0, &priv->stream);
+ slcd_flush(&priv->stream);
+
+ priv->initialized = true;
}
- printf("Geometry rows: %d columns: %d nbars: %d\n",
- priv->geo.nrows, priv->geo.ncolumns, priv->geo.nbars);
+ /* Set the cursor to the beginning of the current row and erase to the end
+ * of the line.
+ */
+
+ slcd_encode(SLCDCODE_HOME, 0, &priv->stream);
+ slcd_encode(SLCDCODE_DOWN, priv->currow, &priv->stream);
+ slcd_encode(SLCDCODE_ERASEEOL, 0, &priv->stream);
- /* Home the cursor and clear the display */
+ /* Increment to the next row, wrapping back to first if necessary. */
- printf("Clear screen\n");
- slcd_encode(SLCDCODE_CLEAR, 0, &priv->stream);
+ if (++priv->currow >= priv->geo.nrows)
+ {
+ priv->currow = 0;
+ }
/* Say hello */
@@ -309,5 +337,6 @@ int slcd_main(int argc, char *argv[])
errout_with_fd:
close(priv->fd);
errout:
+ priv->initialized = false;
exit(EXIT_FAILURE);
}
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 6d7f6ae50..e02fa4f14 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -4803,3 +4803,5 @@
cursor position (2013-5-25).
* include/nuttx/lcd/slcd_ioctl.h: Moved ioctls commands and structures
from slcd_codec.h (2013-5-25)
+ * libc/misc/lib_slcdencode.c and lib_slcddecode.c: Several encoding
+ and decoding bug fixes (2013-5-26)
diff --git a/nuttx/configs/pcblogic-pic32mx/README.txt b/nuttx/configs/pcblogic-pic32mx/README.txt
index 22815ae0c..fa11750af 100644
--- a/nuttx/configs/pcblogic-pic32mx/README.txt
+++ b/nuttx/configs/pcblogic-pic32mx/README.txt
@@ -665,15 +665,12 @@ Configuration sub-directories
To enable LCD debug output:
- Device Drivers:
- CONFIG_LCD=y : (Needed to enable LCD debug)
-
Build Setup:
CONFIG_DEBUG=y : Enable debug features
CONFIG_DEBUG_VERBOSE=y : Enable LCD debug
NOTE: At this point in time, testing of the SLCD is very limited because
there is not much in apps/examples/slcd. Certainly there are more bugs
- to be found. There are also many segment-encoded glyphs in stm32_lcd.c
- But there is a basically functional driver with a working test setup
- that can be extended if you want a fully functional SLCD driver.
+ to be found. But there is a basically functional driver with a working
+ test setup that can be extended if you want a fully functional LCD1602
+ driver.
diff --git a/nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c b/nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c
index 7740048a0..50697c587 100644
--- a/nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c
+++ b/nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c
@@ -73,6 +73,7 @@
#include <stdbool.h>
#include <string.h>
#include <semaphore.h>
+#include <ctype.h>
#include <poll.h>
#include <errno.h>
#include <debug.h>
@@ -122,7 +123,6 @@
/* LCD **********************************************************************/
-
#define LCD_NROWS 2
#define LCD_NCOLUMNS 16
#define LCD_NCHARS (LCD_NROWS * LCD_NCOLUMNS)
@@ -225,8 +225,9 @@ static struct lcd1602_2 g_lcd1602;
static void lcd_dumpstate(FAR const char *msg)
{
uint8_t buffer[LCD_NCOLUMNS];
- uint8_t row;
- uint8_t column;
+ uint8_t ch;
+ int row;
+ int column;
lcdvdbg("%s:\n", msg);
lcdvdbg(" currow: %d curcol: %d\n",
@@ -234,10 +235,11 @@ static void lcd_dumpstate(FAR const char *msg)
for (row = 0, column = 0; row < LCD_NROWS; )
{
- buffer[column] = lcd_readch(row, column);
+ ch = lcd_readch(row, column);
+ buffer[column] = isprint(ch) ? ch : '.';
if (++column >= LCD_NCOLUMNS)
{
- lcdvdbg(" %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
+ lcdvdbg(" [%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c]\n",
buffer[0], buffer[1], buffer[2], buffer[3],
buffer[4], buffer[5], buffer[6], buffer[7],
buffer[8], buffer[9], buffer[10], buffer[11],
@@ -551,9 +553,9 @@ static void lcd_action(enum slcdcode_e code, uint8_t count)
{
/* Don't permit movement past the bottom of the SLCD */
- if (g_lcd1602.curcol < (LCD_NCOLUMNS - 1))
+ if (g_lcd1602.currow < (LCD_NCOLUMNS - 1))
{
- g_lcd1602.curcol++;
+ g_lcd1602.currow++;
}
}
break;
diff --git a/nuttx/libc/misc/lib_slcddecode.c b/nuttx/libc/misc/lib_slcddecode.c
index 97fa951c8..79c549b39 100644
--- a/nuttx/libc/misc/lib_slcddecode.c
+++ b/nuttx/libc/misc/lib_slcddecode.c
@@ -52,6 +52,21 @@
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
+/* Configuration ************************************************************/
+/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose
+ * debug must also be enabled.
+ */
+
+#ifndef CONFIG_DEBUG
+# undef CONFIG_DEBUG_VERBOSE
+# undef CONFIG_DEBUG_LCD
+#endif
+
+#ifndef CONFIG_DEBUG_VERBOSE
+# undef CONFIG_DEBUG_LCD
+#endif
+
+/* Indices, counts, helper macros ******************************************/
#define NDX_ESC 0
#define NDX_BRACKET 1
@@ -74,6 +89,16 @@
#define IS_CODE(a) (((a) >= CODE_MIN) && ((a) <= CODE_MAX))
#define CODE_RETURN(a) (enum slcdcode_e)((a) - 'A')
+/* Debug ********************************************************************/
+
+#ifdef CONFIG_DEBUG_LCD
+# define lcddbg dbg
+# define lcdvdbg vdbg
+#else
+# define lcddbg(x...)
+# define lcdvdbg(x...)
+#endif
+
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -239,6 +264,7 @@ enum slcdret_e slcd_decode(FAR struct lib_instream_s *stream,
* return the following characters later.
*/
+ lcddbg("Parsing failed: ESC followed by %02x\n", ch);
return slcd_reget(state, pch, parg);
}
@@ -269,6 +295,8 @@ enum slcdret_e slcd_decode(FAR struct lib_instream_s *stream,
if (code < (int)FIRST_SLCDCODE || code > (int)LAST_SLCDCODE)
{
+ lcddbg("Parsing failed: ESC-L followed by %02x\n", ch);
+
/* Not a special command code.. put the character in the reget
* buffer.
*/
@@ -310,6 +338,9 @@ enum slcdret_e slcd_decode(FAR struct lib_instream_s *stream,
* following characters later.
*/
+ lcddbg("Parsing failed: ESC-L-%c followed by %02x\n",
+ state->buf[NDX_COUNTH], ch);
+
return slcd_reget(state, pch, parg);
}
@@ -342,7 +373,7 @@ enum slcdret_e slcd_decode(FAR struct lib_instream_s *stream,
*/
code = CODE_RETURN(ch);
- count = slcd_nibble(state->buf[NDX_COUNTH]) << 4;
+ count = slcd_nibble(state->buf[NDX_COUNTH]) << 4 |
slcd_nibble(state->buf[NDX_COUNTL]);
/* Verify the special CLCD action code */
@@ -353,6 +384,9 @@ enum slcdret_e slcd_decode(FAR struct lib_instream_s *stream,
* of the characters later.
*/
+ lcddbg("Parsing failed: ESC-L-%c-%c followed by %02x, count=%d\n",
+ state->buf[NDX_COUNTH], state->buf[NDX_COUNTL], ch, count);
+
return slcd_reget(state, pch, parg);
}
}
diff --git a/nuttx/libc/misc/lib_slcdencode.c b/nuttx/libc/misc/lib_slcdencode.c
index 148cb3a99..12454ca8e 100644
--- a/nuttx/libc/misc/lib_slcdencode.c
+++ b/nuttx/libc/misc/lib_slcdencode.c
@@ -70,7 +70,7 @@ static uint8_t slcd_nibble(uint8_t binary)
{
binary &= 0x0f;
- if (binary > 9)
+ if (binary <= 9)
{
return '0' + binary;
}