9
0
Fork 0

Extentions SCLD test; SCLD CODEC and LCD1602 driver bug fixes

This commit is contained in:
Gregory Nutt 2013-05-26 09:28:57 -06:00
parent f7102cb478
commit 5e23e42a0d
7 changed files with 112 additions and 47 deletions

View File

@ -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).

View File

@ -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,44 +261,67 @@ int slcd_main(int argc, char *argv[])
{
str = argv[1];
}
/* Are we already initialized? */
if (!priv->initialized)
#endif
{
/* Initialize the output stream */
/* 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 */
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;
}
/* Get the geometry of the SCLD device */
/* Set the cursor to the beginning of the current row and erase to the end
* of the line.
*/
ret = ioctl(priv->fd, SLCDIOC_GEOMETRY, (unsigned long)&priv->geo);
if (ret < 0)
slcd_encode(SLCDCODE_HOME, 0, &priv->stream);
slcd_encode(SLCDCODE_DOWN, priv->currow, &priv->stream);
slcd_encode(SLCDCODE_ERASEEOL, 0, &priv->stream);
/* Increment to the next row, wrapping back to first if necessary. */
if (++priv->currow >= priv->geo.nrows)
{
printf("ioctl(SLCDIOC_GEOMETRY) failed: %d\n", errno);
goto errout_with_fd;
priv->currow = 0;
}
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);
/* Say hello */
printf("Print [%s]\n", str);
@ -309,5 +337,6 @@ int slcd_main(int argc, char *argv[])
errout_with_fd:
close(priv->fd);
errout:
priv->initialized = false;
exit(EXIT_FAILURE);
}

View File

@ -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)

View File

@ -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.

View File

@ -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;

View File

@ -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);
}
}

View File

@ -70,7 +70,7 @@ static uint8_t slcd_nibble(uint8_t binary)
{
binary &= 0x0f;
if (binary > 9)
if (binary <= 9)
{
return '0' + binary;
}