summaryrefslogtreecommitdiff
path: root/nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c')
-rw-r--r--nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c255
1 files changed, 142 insertions, 113 deletions
diff --git a/nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c b/nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c
index 50697c587..bf564cf96 100644
--- a/nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c
+++ b/nuttx/configs/pcblogic-pic32mx/src/pic32mx_lcd1602.c
@@ -116,7 +116,17 @@
# undef CONFIG_DEBUG_LCD
#endif
-/* Pin configuratin *********************************************************/
+/* The ever-present MIN/MAX macros ******************************************/
+
+#ifndef MIN
+# define MIN(a,b) (a < b ? a : b)
+#endif
+
+#ifndef MAX
+# define MAX(a,b) (a > b ? a : b)
+#endif
+
+/* Pin configuration ********************************************************/
/* RB15, RS -- High values selects data */
#define GPIO_LCD_RS (GPIO_OUTPUT|GPIO_VALUE_ZERO|GPIO_PORTB|GPIO_PIN15)
@@ -166,8 +176,11 @@ struct lcd1602_2
#if defined(CONFIG_DEBUG_LCD) && defined(CONFIG_DEBUG_VERBOSE)
static void lcd_dumpstate(FAR const char *msg);
+static void lcd_dumpstream(FAR const char *msg,
+ FAR const struct lcd_instream_s *stream);
#else
# define lcd_dumpstate(msg)
+# define lcd_dumpstream(msg, stream)
#endif
/* Internal functions */
@@ -253,6 +266,21 @@ static void lcd_dumpstate(FAR const char *msg)
#endif
/****************************************************************************
+ * Name: lcd_dumpstate
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_LCD) && defined(CONFIG_DEBUG_VERBOSE)
+static void lcd_dumpstream(FAR const char *msg,
+ FAR const struct lcd_instream_s *stream)
+{
+ lcdvdbg("%s:\n", msg);
+ lcdvdbg(" nget: %d nbytes: %d\n",
+ stream->stream.nget, stream->nbytes);
+ lib_dumpbuffer("STREAM", stream->buffer, stream->nbytes);
+}
+#endif
+
+/****************************************************************************
* Name: lcd_getstream
*
* Description:
@@ -418,61 +446,86 @@ static void lcd_action(enum slcdcode_e code, uint8_t count)
case SLCDCODE_BACKDEL: /* Backspace (backward delete) N characters */
{
- /* If we are at the home position, then ignore the action */
+ int tmp;
+
+ /* If we are at the home position or if the count is zero, then ignore the action */
- if (g_lcd1602.curcol < 1)
+ if (g_lcd1602.curcol < 1 || count < 1)
{
break;
}
- /* Otherwise, BACKDEL is like moving the cursor back one then doing a
+ /* Otherwise, BACKDEL is like moving the cursor back N characters then doing a
* forward deletion. Decrement the cursor position and fall through.
*/
- g_lcd1602.curcol--;
- }
+ tmp = (int)g_lcd1602.curcol - count;
+ if (tmp < 0)
+ {
+ tmp = 0;
+ count = g_lcd1602.curcol;
+ }
- case SLCDCODE_FWDDEL: /* DELete (forward delete) N characters moving text */
- {
- uint8_t ch;
- int i;
+ /* Save the updated cursor positions */
- /* Move all characters after the current cursor position left by one */
-
- for (i = g_lcd1602.curcol + 1; i < LCD_NCOLUMNS - 1; i++)
- {
- ch = lcd_readch(g_lcd1602.currow, i);
- lcd_writech(ch, g_lcd1602.currow, i - 1);
- }
-
- /* Erase the last character on the display */
+ g_lcd1602.curcol = tmp;
+ }
- lcd_writech(' ', g_lcd1602.currow, LCD_NCOLUMNS - 1);
- }
+ case SLCDCODE_FWDDEL: /* DELete (forward delete) N characters moving text */
+ if (count > 0)
+ {
+ int nchars;
+ int nmove;
+ int i;
+
+ /* How many characters are to the right of the cursor position
+ * (including the one at the cursor position)? Then get the
+ * number of characters to move.
+ */
+
+ nchars = LCD_NCOLUMNS - g_lcd1602.curcol;
+ nmove = MIN(nchars, count) - 1;
+
+ /* Move all characters after the current cursor position left by 'nmove' characters */
+
+ for (i = g_lcd1602.curcol + nmove; i < LCD_NCOLUMNS - 1; i++)
+ {
+ uint8_t ch = lcd_readch(g_lcd1602.currow, i);
+ lcd_writech(ch, g_lcd1602.currow, i - nmove);
+ }
+
+ /* Erase the last 'nmove' characters on the display */
+
+ for (i = LCD_NCOLUMNS - nmove; i < LCD_NCOLUMNS; i++)
+ {
+ lcd_writech(' ', i, 0);
+ }
+ }
break;
case SLCDCODE_ERASE: /* Erase N characters from the cursor position */
- {
- int last;
- int i;
-
- /* Get the last position to clear and make sure that the last
- * position is on the SLCD.
- */
-
- last = g_lcd1602.curcol + count - 1;
- if (last >= LCD_NCOLUMNS)
- {
- last = LCD_NCOLUMNS - 1;
- }
-
- /* Erase N characters after the current cursor position left by one */
-
- for (i = g_lcd1602.curcol; i < last; i++)
- {
- lcd_writech(' ', g_lcd1602.currow, i);
- }
- }
+ if (count > 0)
+ {
+ int last;
+ int i;
+
+ /* Get the last position to clear and make sure that the last
+ * position is on the SLCD.
+ */
+
+ last = g_lcd1602.curcol + count - 1;
+ if (last >= LCD_NCOLUMNS)
+ {
+ last = LCD_NCOLUMNS - 1;
+ }
+
+ /* Erase N characters after the current cursor position left by one */
+
+ for (i = g_lcd1602.curcol; i < last; i++)
+ {
+ lcd_writech(' ', g_lcd1602.currow, i);
+ }
+ }
break;
case SLCDCODE_CLEAR: /* Home the cursor and erase the entire display */
@@ -518,45 +571,69 @@ static void lcd_action(enum slcdcode_e code, uint8_t count)
case SLCDCODE_LEFT: /* Cursor left by N characters */
{
+ int tmp = (int)g_lcd1602.curcol - count;
+
/* Don't permit movement past the beginning of the SLCD */
- if (g_lcd1602.curcol > 0)
+ if (tmp < 0)
{
- g_lcd1602.curcol--;
+ tmp = 0;
}
+
+ /* Save the new cursor position */
+
+ g_lcd1602.curcol = (uint8_t)tmp;
}
break;
case SLCDCODE_RIGHT: /* Cursor right by N characters */
{
+ int tmp = (int)g_lcd1602.curcol + count;
+
/* Don't permit movement past the end of the SLCD */
- if (g_lcd1602.curcol < (LCD_NCOLUMNS - 1))
+ if (tmp >= LCD_NCOLUMNS)
{
- g_lcd1602.curcol++;
+ tmp = LCD_NCOLUMNS - 1;
}
+
+ /* Save the new cursor position */
+
+ g_lcd1602.curcol = (uint8_t)tmp;
}
break;
case SLCDCODE_UP: /* Cursor up by N lines */
{
+ int tmp = (int)g_lcd1602.currow - count;
+
/* Don't permit movement past the top of the SLCD */
- if (g_lcd1602.currow > 0)
+ if (tmp < 0)
{
- g_lcd1602.currow--;
+ tmp = 0;
}
+
+ /* Save the new cursor position */
+
+ g_lcd1602.currow = (uint8_t)tmp;
}
break;
case SLCDCODE_DOWN: /* Cursor down by N lines */
{
+ int tmp = (int)g_lcd1602.currow + count;
+
/* Don't permit movement past the bottom of the SLCD */
- if (g_lcd1602.currow < (LCD_NCOLUMNS - 1))
+ if (tmp >= LCD_NROWS)
{
- g_lcd1602.currow++;
+ tmp = LCD_NROWS - 1;
}
+
+ /* Save the new cursor position */
+
+ g_lcd1602.currow = (uint8_t)tmp;
}
break;
@@ -627,8 +704,6 @@ static ssize_t lcd_write(FAR struct file *filp, FAR const char *buffer,
enum slcdret_e result;
uint8_t ch;
uint8_t count;
- uint8_t prev = ' ';
- bool valid = false;
/* Initialize the stream for use with the SLCD CODEC */
@@ -637,33 +712,11 @@ static ssize_t lcd_write(FAR struct file *filp, FAR const char *buffer,
instream.buffer = buffer;
instream.nbytes = len;
- /* Prime the pump */
-
- memset(&state, 0, sizeof(struct slcdstate_s));
- result = slcd_decode(&instream.stream, &state, &prev, &count);
-
- lcdvdbg("slcd_decode returned result=%d char=%d count=%d\n",
- result, prev, count);
-
- switch (result)
- {
- case SLCDRET_CHAR:
- valid = true;
- break;
-
- case SLCDRET_SPEC:
- {
- lcd_action((enum slcdcode_e)prev, count);
- prev = ' ';
- }
- break;
-
- case SLCDRET_EOF:
- return 0;
- }
+ lcd_dumpstream("BEFORE WRITE", &instream);
/* Now decode and process every byte in the input buffer */
+ memset(&state, 0, sizeof(struct slcdstate_s));
while ((result = slcd_decode(&instream.stream, &state, &ch, &count)) != SLCDRET_EOF)
{
lcdvdbg("slcd_decode returned result=%d char=%d count=%d\n",
@@ -679,37 +732,25 @@ static ssize_t lcd_write(FAR struct file *filp, FAR const char *buffer,
if (ch == ASCII_BS)
{
+ /* Perform the backward deletion */
+
lcd_action(SLCDCODE_BACKDEL, 1);
}
else if (ch == ASCII_CR)
{
- lcd_action(SLCDCODE_HOME, 0);
- }
- }
-
- /* Handle characters decoreated with a period or a colon */
+ /* Perform the carriage return */
- else if (ch == '.')
- {
- /* Write the previous character with the decimal point appended */
-
- lcd_appendch(prev);
- prev = ' ';
- valid = false;
- }
- else if (ch == ':')
- {
- /* Write the previous character with the colon appended */
-
- lcd_appendch(prev);
- prev = ' ';
- valid = false;
+ g_lcd1602.curcol = 0;
+ lcd_action(SLCDCODE_DOWN, 1);
+ }
}
/* Handle ASCII_DEL */
else if (ch == ASCII_DEL)
{
+ /* Perform the forward deletion */
+
lcd_action(SLCDCODE_FWDDEL, 1);
}
@@ -717,34 +758,22 @@ static ssize_t lcd_write(FAR struct file *filp, FAR const char *buffer,
else if (ch < 128)
{
- /* Write the previous character if it valid */
-
- if (valid)
- {
- lcd_appendch(prev);
- }
-
- /* There is now a valid output character */
+ /* Write the character if it valid */
- prev = ch;
- valid = true;
+ lcd_appendch(ch);
}
}
else /* (result == SLCDRET_SPEC) */ /* A special SLCD action was returned */
{
+ /* Then Perform the action */
+
lcd_action((enum slcdcode_e)ch, count);
}
}
- /* Handle any unfinished output */
-
- if (valid)
- {
- lcd_appendch(prev);
- }
-
/* Assume that the entire input buffer was processed */
+ lcd_dumpstream("AFTER WRITE", &instream);
return (ssize_t)len;
}