summaryrefslogtreecommitdiff
path: root/nuttx/configs/stm32ldiscovery
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-05-26 11:26:34 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-05-26 11:26:34 -0600
commit5049717590dea3c2bb216409887eff9ec4f2d535 (patch)
tree96c58ccbab729b3c51fe31ad3a728f00f819ae9b /nuttx/configs/stm32ldiscovery
parent5e23e42a0d5f7256bb284bdd8ffbe7b52eef0cef (diff)
downloadnuttx-5049717590dea3c2bb216409887eff9ec4f2d535.tar.gz
nuttx-5049717590dea3c2bb216409887eff9ec4f2d535.tar.bz2
nuttx-5049717590dea3c2bb216409887eff9ec4f2d535.zip
More SLCD-related fixes
Diffstat (limited to 'nuttx/configs/stm32ldiscovery')
-rw-r--r--nuttx/configs/stm32ldiscovery/src/stm32_lcd.c182
1 files changed, 138 insertions, 44 deletions
diff --git a/nuttx/configs/stm32ldiscovery/src/stm32_lcd.c b/nuttx/configs/stm32ldiscovery/src/stm32_lcd.c
index abc9a0644..d843fba7e 100644
--- a/nuttx/configs/stm32ldiscovery/src/stm32_lcd.c
+++ b/nuttx/configs/stm32ldiscovery/src/stm32_lcd.c
@@ -94,6 +94,8 @@
# undef CONFIG_DEBUG_LCD
#endif
+/* The ever-present MIN/MAX macros ******************************************/
+
#ifndef MIN
# define MIN(a,b) (a < b ? a : b)
#endif
@@ -896,59 +898,85 @@ static void slcd_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_slcdstate.curpos < 1)
+ if (g_slcdstate.curpos < 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_slcdstate.curpos--;
- }
-
- case SLCDCODE_FWDDEL: /* DELete (forward delete) N characters moving text */
- {
- int i;
-
- /* Move all characters after the current cursor position left by one */
+ tmp = (int)g_slcdstate.curpos - count;
+ if (tmp < 0)
+ {
+ tmp = 0;
+ count = g_slcdstate.curpos;
+ }
- for (i = g_slcdstate.curpos + 1; i < SLCD_NCHARS - 1; i++)
- {
- slcd_writech(g_slcdstate.buffer[i-1], i, g_slcdstate.options[i-1]);
- }
+ /* Save the updated cursor positions */
- /* Erase the last character on the display */
+ g_slcdstate.curpos = tmp;
+ }
- slcd_writech(' ', SLCD_NCHARS - 1, 0);
- }
+ 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 = SLCD_CHARS - g_slcdstate.curpos;
+ nmove = MIN(nchars, count) - 1;
+
+ /* Move all characters after the current cursor position left by 'nmove' characters */
+
+ for (i = g_slcdstate.curpos + nmove; i < SLCD_NCHARS - 1; i++)
+ {
+ slcd_writech(g_slcdstate.buffer[i-nmove], i, g_slcdstate.options[i-nmove]);
+ }
+
+ /* Erase the last 'nmove' characters on the display */
+
+ for (i = SLCD_NCHARS - nmove; i < SLCD_NCHARS; i++)
+ {
+ slcd_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_slcdstate.curpos + count - 1;
- if (last >= SLCD_NCHARS)
- {
- last = SLCD_NCHARS - 1;
- }
-
- /* Erase N characters after the current cursor position left by one */
-
- for (i = g_slcdstate.curpos; i < last; i++)
- {
- slcd_writech(' ', i, 0);
- }
- }
+ 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_slcdstate.curpos + count - 1;
+ if (last >= SLCD_NCHARS)
+ {
+ last = SLCD_NCHARS - 1;
+ }
+
+ /* Erase N characters after the current cursor position left by one */
+
+ for (i = g_slcdstate.curpos; i < last; i++)
+ {
+ slcd_writech(' ', i, 0);
+ }
+ }
break;
case SLCDCODE_CLEAR: /* Home the cursor and erase the entire display */
@@ -989,23 +1017,35 @@ static void slcd_action(enum slcdcode_e code, uint8_t count)
case SLCDCODE_LEFT: /* Cursor left by N characters */
{
+ int tmp = (int)g_slcdstate.curpos - count;
+
/* Don't permit movement past the beginning of the SLCD */
- if (g_slcdstate.curpos > 0)
+ if (tmp < 0)
{
- g_slcdstate.curpos--;
+ tmp = 0;
}
+
+ /* Save the new cursor position */
+
+ g_slcdstate.curpos = (uint8_t)tmp;
}
break;
case SLCDCODE_RIGHT: /* Cursor right by N characters */
{
+ int tmp = (int)g_slcdstate.curpos + count;
+
/* Don't permit movement past the end of the SLCD */
- if (g_slcdstate.curpos < (SLCD_NCHARS - 1))
+ if (tmp >= SLCD_NCHARS)
{
- g_slcdstate.curpos++;
+ tmp = SLCD_NCHARS - 1;
}
+
+ /* Save the new cursor position */
+
+ g_slcdstate.curpos = (uint8_t)tmp;
}
break;
@@ -1096,7 +1136,9 @@ static ssize_t slcd_write(FAR struct file *filp,
instream.buffer = buffer;
instream.nbytes = len;
- /* Prime the pump */
+ /* Prime the pump. This is messy, but necessary to handle decoration on a
+ * character based on any following period or colon.
+ */
memset(&state, 0, sizeof(struct slcdstate_s));
result = slcd_decode(&instream.stream, &state, &prev, &count);
@@ -1138,10 +1180,36 @@ static ssize_t slcd_write(FAR struct file *filp,
if (ch == ASCII_BS)
{
+ /* If there is a pending character, then output it now before
+ * performing the action.
+ */
+
+ if (valid)
+ {
+ slcd_appendch(prev, 0);
+ prev = ' ';
+ valid = false;
+ }
+
+ /* Then perform the backward deletion */
+
slcd_action(SLCDCODE_BACKDEL, 1);
}
else if (ch == ASCII_CR)
{
+ /* If there is a pending character, then output it now before
+ * performing the action.
+ */
+
+ if (valid)
+ {
+ slcd_appendch(prev, 0);
+ prev = ' ';
+ valid = false;
+ }
+
+ /* Then perform the carriage return */
+
slcd_action(SLCDCODE_HOME, 0);
}
}
@@ -1169,6 +1237,19 @@ static ssize_t slcd_write(FAR struct file *filp,
else if (ch == ASCII_DEL)
{
+ /* If there is a pending character, then output it now before
+ * performing the action.
+ */
+
+ if (valid)
+ {
+ slcd_appendch(prev, 0);
+ prev = ' ';
+ valid = false;
+ }
+
+ /* Then perform the foward deletion */
+
slcd_action(SLCDCODE_FWDDEL, 1);
}
@@ -1191,6 +1272,19 @@ static ssize_t slcd_write(FAR struct file *filp,
}
else /* (result == SLCDRET_SPEC) */ /* A special SLCD action was returned */
{
+ /* If there is a pending character, then output it now before
+ * performing the action.
+ */
+
+ if (valid)
+ {
+ slcd_appendch(prev, 0);
+ prev = ' ';
+ valid = false;
+ }
+
+ /* Then perform the action */
+
slcd_action((enum slcdcode_e)ch, count);
}
}