diff options
-rw-r--r-- | apps/ChangeLog.txt | 3 | ||||
-rw-r--r-- | apps/examples/slcd/slcd_main.c | 89 | ||||
-rw-r--r-- | nuttx/ChangeLog | 2 | ||||
-rw-r--r-- | nuttx/configs/pcblogic-pic32mx/README.txt | 9 | ||||
-rw-r--r-- | nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c | 16 | ||||
-rw-r--r-- | nuttx/libc/misc/lib_slcddecode.c | 36 | ||||
-rw-r--r-- | nuttx/libc/misc/lib_slcdencode.c | 2 |
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; } |