From c7bf6bf65a458cb30b892340b69de6c025d1cc22 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 23 May 2013 10:23:41 -0600 Subject: Add logic to encode/decode special SLCD actions --- nuttx/ChangeLog | 6 +- nuttx/include/nuttx/lcd/slcd_codec.h | 212 ++++++++++++++++++++ nuttx/libc/Kconfig | 35 +++- nuttx/libc/misc/Make.defs | 6 + nuttx/libc/misc/lib_kbddecode.c | 4 +- nuttx/libc/misc/lib_slcddecode.c | 366 +++++++++++++++++++++++++++++++++++ nuttx/libc/misc/lib_slcdencode.c | 203 +++++++++++++++++++ 7 files changed, 820 insertions(+), 12 deletions(-) create mode 100644 nuttx/include/nuttx/lcd/slcd_codec.h create mode 100644 nuttx/libc/misc/lib_slcddecode.c create mode 100644 nuttx/libc/misc/lib_slcdencode.c diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 54ea6a44c..93212d83e 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3819,8 +3819,8 @@ there is a issue of ARM9 systems with low vectors and large memories that will have to be addressed in the future. * libc/misc/lib_kbdencode.c and lib_kbddecode.c: Add logic to marshal - and serialized "out-of-band" keyboard commands intermixed with normal - ASCII data (not yet hooked into anything). + and serialize speical keyboard commands intermixed with normal ASCII + data (not yet hooked into anything). * drivers/usbhost/usbhost_hidkbd.c: If CONFIG_HIDKBD_ENCODED is defined, this driver will now use libc/misc/lib_kbdencode.c to encode special function keys. @@ -4779,3 +4779,5 @@ (2013-5-23) * fs/fs_poll.c: Actually, it should not ignore invlid descriptors, it should set the POLLNVAL event and return immediately (2013-5-23). + * libc/misc/lib_slcdencode.c and lib_slcddecode.c: Add logic to marshal + and serialized special SLCD intermixed with normal ASCII data (2013-5-23) diff --git a/nuttx/include/nuttx/lcd/slcd_codec.h b/nuttx/include/nuttx/lcd/slcd_codec.h new file mode 100644 index 000000000..a43796718 --- /dev/null +++ b/nuttx/include/nuttx/lcd/slcd_codec.h @@ -0,0 +1,212 @@ +/************************************************************************************ + * include/nuttx/input/slcd_codec.h + * Serialize and marshaling data and events for character-based, segment LCDs + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __INCLUDE_NUTTX_INPUT_SLCD_CODEC_H +#define __INCLUDE_NUTTX_INPUT_SLCD_CODEC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef CONFIG_LIB_SLCDCODEC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* These are the special SLCD commands recognized by the CODEC. NOTE: that + * some require a a count argument, N. + */ + +enum slcdcode_e +{ + SLCDCODE_NORMAL = 0, /* Not a special keycode */ + + /* Delete and Backspace keycodes (in case they may be different than the + * ASCII BKSP and DEL values. + */ + + SLCDCODE_FWDDEL, /* DELete (forward delete) N characters moving cursor */ + SLCDCODE_BACKDEL, /* Backspace (backward delete) N characters */ + SLCDCODE_ERASE, /* Erase N characters from the cursor position */ + SLCDCODE_ERASEEOL, /* Erase from the cursor position to the end of line */ + SLCDCODE_CLEAR, /* Home the cursor and erase the entire display */ + + /* Cursor movement */ + + SLCDCODE_HOME, /* Cursor home */ + SLCDCODE_END, /* Cursor end */ + SLCDCODE_LEFT, /* Cursor left by N characters */ + SLCDCODE_RIGHT, /* Cursor right by N characters */ + SLCDCODE_UP, /* Cursor up by N lines */ + SLCDCODE_DOWN, /* Cursor down by N lines */ + SLCDCODE_PAGEUP, /* Cursor up by N pages */ + SLCDCODE_PAGEDOWN, /* Cursor down by N pages */ + + /* Blinking */ + + SLCDCODE_BLINKSTART, /* Start blinking with current cursor position */ + SLCDCODE_BLINKEND, /* End blinking after the current cursor position */ + SLCDCODE_BLINKOFF /* Turn blinking off */ +}; + +#define FIRST_SLCDCODE SLCDCODE_FWDDEL +#define LAST_SLCDCODE SLCDCODE_BLINKOFF + +/* Values returned by slcd_decode() */ + +enum slcdret_e +{ + SLCDRET_CHAR = 0, /* A normal character was returned */ + SLCDRET_SPEC, /* A special SLCD action was returned */ + SLCDRET_EOF /* An EOF (or possibly an error) occurred */ +}; + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Working data needed by slcd_encode that must be provided and initialized + * by the caller. + */ + +struct slcdstate_s +{ + uint8_t nch; /* Number of characters in the buffer */ + uint8_t ndx; /* Index to next character in the buffer */ + uint8_t buf[5]; /* Buffer of ungotten data */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * The following functions are intended for use by "producer", application + * code to encode information into driver I/O buffers. + ****************************************************************************/ + +/**************************************************************************** + * Name: slcd_put + * + * Description: + * Put one byte of normal character data into the output data stream. + * + * Input Parameters: + * ch - The character to be added to the output stream. + * stream - An instance of lib_outstream_s to do the low-level put + * operation. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define slcd_put(ch, stream) (stream)->put((stream), (int)(ch)) + +/**************************************************************************** + * Name: slcd_encode + * + * Description: + * Encode one special action into the output data stream + * + * Input Parameters: + * code - The action to be taken + * count - The 8-bit unsigned count value N associated with some actions + * stream - An instance of lib_outstream_s to do the low-level put + * operation. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void slcd_encode(enum slcdcode_e code, uint8_t count, + FAR struct lib_outstream_s *stream); + +/**************************************************************************** + * The following functions are intended for use by "consumer" SLCD driver + * code to remove and decode information from the application provided + * buffer. + ****************************************************************************/ + +/**************************************************************************** + * Name: slcd_decode + * + * Description: + * Get one byte of data or special command from the application provided + * input buffer. + * + * Input Parameters: + * stream - An instance of lib_instream_s to do the low-level get + * operation. + * state - A user provided buffer to support parsing. This structure + * should be cleared the first time that slcd_decode is called. + * pch - The location to save the returned value. This may be + * either a normal, character code or a special command from enum + * slcdcode_e, depending on the return value from slcd_decode() + * parg - The location to save the count argument that accompanies some + * special actions + * + * Returned Value: + * + * See enum slcdret_e + * + ****************************************************************************/ + +enum slcdret_e slcd_decode(FAR struct lib_instream_s *stream, + FAR struct slcdstate_s *state, FAR uint8_t *pch, + FAR uint8_t *parg); + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_LIB_SLCDCODEC */ +#endif /* __INCLUDE_NUTTX_INPUT_SLCD_CODEC_H */ + diff --git a/nuttx/libc/Kconfig b/nuttx/libc/Kconfig index 09c332725..2173d1bd4 100644 --- a/nuttx/libc/Kconfig +++ b/nuttx/libc/Kconfig @@ -475,18 +475,37 @@ config LIB_KBDCODEC may have an (optional) encoding/decoding layer on the data returned by the character driver. A keyboard may return simple text data (alphabetic, numeric, and punctuaction) or control characters - (enter, control-C, etc.). We can think about this the normal - "in-band" keyboard data stream. However, in addition, most - keyboards support actions that cannot be represented as text data. - Such actions include things like cursor controls (home, up arrow, + (enter, control-C, etc.). However, in addition, most keyboards + support actions that cannot be represented as text data. Such + actions include things like cursor controls (home, up arrow, page down, etc.), editing functions (insert, delete, etc.), volume - controls, (mute, volume up, etc.) and other special functions. We - can think about this as special, "out-of-band" keyboard commands. - In this case, some special encoding may be required to multiplex - the in-band text data and out-of-band command streams. + controls, (mute, volume up, etc.) and other special functions. + Some special encoding may be required to multiplex these two classes + of data. This option enables the functions that implement the encoding and decoding of keyboard data. These are the interfaces prototyped in include/nuttx/input/kbd_codec.h. While not correctly a part of the C library, it is included here because the decoding side of this interface must be accessible by end user programs. + +config LIB_SLCDCODEC + bool "Segment LCD CODEC" + default n + ---help--- + In NuttX, a character-oriented, segment LCD (SLCD) driver is simply + a character device that may have an (optional) encoding/decoding + layer on the data provided to the SLCD driver. The application may + provide simple text data (alphabetic, numeric, and punctuaction) or + control characters (enter, control-C, etc.). However, in addition, + most SLCDs support actions that cannot be represented as text data. + Such actions include things like cursor controls (home, up arrow, + page down, etc.) and other special functions (e.g., blinking). Some + special encoding may be required to multiplex these two classes of + data. + + This option enables the functions that implement the encoding and + decoding of SLCD data. These are the interfaces prototyped in + include/nuttx/lcd/slcd_codec.h. While not correctly a part of the C + library, it is included here because the encoding side of this + interface must be accessible by end user programs. diff --git a/nuttx/libc/misc/Make.defs b/nuttx/libc/misc/Make.defs index 0d3c87d9d..02b3b2679 100644 --- a/nuttx/libc/misc/Make.defs +++ b/nuttx/libc/misc/Make.defs @@ -69,6 +69,12 @@ ifeq ($(CONFIG_LIB_KBDCODEC),y) CSRCS += lib_kbdencode.c lib_kbddecode.c endif +# SLCD driver encoder/decoder + +ifeq ($(CONFIG_LIB_SLCDCODEC),y) +CSRCS += lib_slcdencode.c lib_slcddecode.c +endif + # Add the misc directory to the build DEPPATH += --dep-path misc diff --git a/nuttx/libc/misc/lib_kbddecode.c b/nuttx/libc/misc/lib_kbddecode.c index 62554902c..4e7379832 100644 --- a/nuttx/libc/misc/lib_kbddecode.c +++ b/nuttx/libc/misc/lib_kbddecode.c @@ -74,8 +74,8 @@ * Name: kbd_reget * * Description: - * We have unused characters from the last, unsuccessful. Return one of - * these instead of the . + * We have unused characters from the last, unsuccessful decode attempt. + * Return one of these instead of the new character from the stream. * * Input Parameters: * stream - An instance of lib_instream_s to do the low-level get diff --git a/nuttx/libc/misc/lib_slcddecode.c b/nuttx/libc/misc/lib_slcddecode.c new file mode 100644 index 000000000..05e883f88 --- /dev/null +++ b/nuttx/libc/misc/lib_slcddecode.c @@ -0,0 +1,366 @@ +/**************************************************************************** + * libc/msic/lib_slcddecode.c + * Decoding side of the SLCD CODEC + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +#define NDX_ESC 0 +#define NDX_BRACKET 1 +#define NDX_CODE3 2 +#define NDX_COUNTH 2 +#define NDX_COUNTL 3 +#define NDX_CODE5 4 + +#define NCH_ESC 1 +#define NCH_BRACKET 2 +#define NCH_CODE3 3 +#define NCH_COUNTH 3 +#define NCH_COUNTL 4 +#define NCH_CODE5 5 + +#define IS_HEX(a) ((((a) >= '0') && ((a) <= '9')) || \ + (((a) >= 'a') && ((a) <= 'f'))) +#define CODE_MIN ('A' + FIRST_SLCDCODE) +#define CODE_MAX ('A' + LAST_SLCDCODE) +#define IS_CODE(a) (((a) >= CODE_MIN) && ((a) <= CODE_MAX)) +#define CODE_RETURN(a) (enum slcdcode_e)((a) - 'A') + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: slcd_nibble + * + * Description: + * Convert a ASCII hexadecimal character (using only lower case alphabetics + * into a binary nibble + * + * Input Parameters: + * ascii - The nibble characgter. + * + * Returned Value: + * The binary value of the nibble. + * + ****************************************************************************/ + +static uint8_t slcd_nibble(uint8_t ascii) +{ + if (ascii >= '0' && ascii <= '9') + { + return ascii - '0'; + } + else + { + return ascii - 'a'; + } +} + +/**************************************************************************** + * Name: slcd_reget + * + * Description: + * We have unused characters from the last, unsuccessful decode attempt. + * Return one of these instead of the new character from the stream. + * + * Input Parameters: + * stream - An instance of lib_instream_s to do the low-level get + * operation. + * pch - The location character to save the returned value. This may be + * either a normal, character code or a special command from enum + * slcd_keycode_e + * + * Returned Value: + * Always SLCDRET_CHAR + * + ****************************************************************************/ + +static enum slcdret_e slcd_reget(FAR struct slcdstate_s *state, + FAR uint8_t *pch, FAR uint8_t *parg) +{ + /* Return the next character */ + + *pch = state->buf[state->ndx]; + *parg = 0; + + /* Bump up the indices and return false (meaning a normal character) */ + + state->ndx++; + state->nch--; + return SLCDRET_CHAR; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: slcd_decode + * + * Description: + * Get one byte of data or special command from the application provided + * input buffer. + * + * Input Parameters: + * stream - An instance of lib_instream_s to do the low-level get + * operation. + * state - A user provided buffer to support parsing. This structure + * should be cleared the first time that slcd_decode is called. + * pch - The location to save the returned value. This may be + * either a normal, character code or a special command from enum + * slcdcode_e, depending on the return value from slcd_decode() + * parg - The location to save the count argument that accompanies some + * special actions + * + * Returned Value: + * + * false: Normal character + * true: Special SLCD action code with possible argument + * + ****************************************************************************/ + +enum slcdret_e slcd_decode(FAR struct lib_instream_s *stream, + FAR struct slcdstate_s *state, FAR uint8_t *pch, + FAR uint8_t *parg) + +{ + enum slcdcode_e code; + uint8_t count; + int ch; + + DEBUGASSERT(stream && state && pch && parg); + + /* Are their ungotten characters from the last, failed parse? */ + + if (state->nch > 0) + { + /* Yes, return the next ungotten character */ + + return slcd_reget(state, pch, parg); + } + + state->ndx = 0; + + /* No, ungotten characters. Get the next character from the buffer. */ + + ch = stream->get(stream); + if (ch == EOF) + { + /* End of file/stream (or perhaps an I/O error) */ + + return SLCDRET_EOF; + } + + /* Save the character (whatever it is) in case we fail parsing later */ + + state->buf[NDX_ESC] = (uint8_t)ch; + state->nch = NCH_ESC; + + /* Check for the beginning of an escape sequence */ + + if (ch != ASCII_ESC) + { + /* Not the beginning of an escape sequence. Return the character. */ + + return slcd_reget(state, pch, parg); + } + + /* Get the next character from the buffer */ + + ch = stream->get(stream); + if (ch == EOF) + { + /* End of file/stream. Return the escape character now. We will + * return the EOF indication next time. + */ + + return slcd_reget(state, pch, parg); + } + + /* Save the character (whatever it is) in case we fail parsing later */ + + state->buf[NDX_BRACKET] = ch; + state->nch = NCH_BRACKET; + + /* Check for ESC-[ */ + + if (ch != '[') + { + /* Not the beginning of an escape sequence. Return the ESC now, + * return the following characters later. + */ + + return slcd_reget(state, pch, parg); + } + + /* Get the next character from the buffer */ + + ch = stream->get(stream); + if (ch == EOF) + { + /* End of file/stream. Return the ESC now; return the following + * characters later. + */ + + return slcd_reget(state, pch, parg); + } + + /* If the next character is a hexidecimal value (with lower case + * alphabetic characters), then we are parsing a 5-byte sequence. + */ + + if (!IS_HEX(ch)) + { + /* Verify the special CLCD action code */ + + if (ch < (int)FIRST_SLCDCODE || ch > (int)LAST_SLCDCODE) + { + /* Not a special command code.. put the character in the reget + * buffer. + */ + + state->buf[NDX_CODE3] = (uint8_t)ch; + state->nch = NCH_CODE3; + + /* Return the ESC now and the next two characters later. */ + + return slcd_reget(state, pch, parg); + } + + /* Provide the return values */ + + code = CODE_RETURN(ch); + count = 0; + } + else + { + /* Save the first character of the two byte hexidecimal number */ + + state->buf[NDX_COUNTH] = (uint8_t)ch; + state->nch = NCH_COUNTH; + + /* Get the next character from the buffer */ + + ch = stream->get(stream); + if (ch == EOF) + { + /* End of file/stream. Return the ESC now; return the following + * characters later. + */ + + return slcd_reget(state, pch, parg); + } + + /* We expect the next character to be the second byte of hexidecimal + * count value. + */ + + if (!IS_HEX(ch)) + { + /* Not a 5-byte escape sequence. Return the ESC now; return the + * following characters later. + */ + + return slcd_reget(state, pch, parg); + } + + /* Save the second character of the two byte hexidecimal number */ + + state->buf[NDX_COUNTL] = (uint8_t)ch; + state->nch = NCH_COUNTL; + + /* Get the next character from the buffer */ + + ch = stream->get(stream); + if (ch == EOF) + { + /* End of file/stream. Return the ESC now; return the following + * characters later. + */ + + return slcd_reget(state, pch, parg); + } + + /* Verify the special CLCD action code */ + + if (ch < (int)FIRST_SLCDCODE || ch > (int)LAST_SLCDCODE) + { + /* Not a special command code.. put the character in the reget + * buffer. + */ + + state->buf[NDX_CODE5] = (uint8_t)ch; + state->nch = NCH_CODE5; + + /* Return the ESC now and the next two characters later. */ + + return slcd_reget(state, pch, parg); + } + + /* Provide the return values */ + + code = CODE_RETURN(ch); + count = slcd_nibble(state->buf[NDX_COUNTH]) << 4; + slcd_nibble(state->buf[NDX_COUNTL]); + } + + /* We have successfully parsed the the entire escape sequence. Return the + * CLCD value in pch, return the count in parg, and an indication that this + * is a special action. + */ + + *pch = code; + *parg = count; + state->nch = 0; + return SLCDRET_SPEC; +} + diff --git a/nuttx/libc/misc/lib_slcdencode.c b/nuttx/libc/misc/lib_slcdencode.c new file mode 100644 index 000000000..148cb3a99 --- /dev/null +++ b/nuttx/libc/misc/lib_slcdencode.c @@ -0,0 +1,203 @@ +/**************************************************************************** + * libc/msic/lib_slcdencode.c + * Encoding side of the SLCD CODEC + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: slcd_nibble + * + * Description: + * Convert a binary nibble to a hexadecimal character (using only lower + * case alphabetics). + * + * Input Parameters: + * binary - The nibble value. + * + * Returned Value: + * The ASCII hexadecimal character representing the nibble. + * + ****************************************************************************/ + +static uint8_t slcd_nibble(uint8_t binary) +{ + binary &= 0x0f; + + if (binary > 9) + { + return '0' + binary; + } + else + { + return 'a' + binary; + } +} + +/**************************************************************************** + * Name: slcd_put3 + * + * Description: + * Encode one special special 3-byte sequence command into the output + * stream. + * + * Input Parameters: + * slcdcode - The special action to be added to the output stream. + * stream - An instance of lib_outstream_s to do the low-level put + * operation. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void slcd_put3(uint8_t slcdcode, + FAR struct lib_outstream_s *stream) +{ + /* Put the 3-byte escape sequences into the output buffer */ + + stream->put(stream, ASCII_ESC); + stream->put(stream, '['); + stream->put(stream, 'A' + (int)slcdcode); +} + +/**************************************************************************** + * Name: slcd_putarg + * + * Description: + * Encode one special special 5-byte sequence command into the output + * stream. + * + * Input Parameters: + * slcdcode - The command to be added to the output stream. + * stream - An instance of lib_outstream_s to do the low-level put + * operation. + * terminator - Escape sequence terminating character. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void slcd_put5(uint8_t slcdcode, uint8_t count, + FAR struct lib_outstream_s *stream) +{ + /* The minimum value of the count argument is one */ + + if (count < 1) + { + count = 1; + } + + /* Put the 5-byte escape sequences into the output buffer */ + + stream->put(stream, ASCII_ESC); + stream->put(stream, '['); + stream->put(stream, slcd_nibble(count >> 4)); + stream->put(stream, slcd_nibble(count)); + stream->put(stream, 'A' + (int)slcdcode); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: slcd_encode + * + * Description: + * Encode one special action into the output data stream + * + * Input Parameters: + * code - The action to be taken + * count - The count value N associated with some actions + * stream - An instance of lib_outstream_s to do the low-level put + * operation. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void slcd_encode(enum slcdcode_e code, uint8_t count, + FAR struct lib_outstream_s *stream) +{ + switch (code) + { + /* Codes with no argument */ + + case SLCDCODE_ERASEEOL: /* Erase from the cursor position to the end of line */ + case SLCDCODE_CLEAR: /* Home the cursor and erase the entire display */ + case SLCDCODE_HOME: /* Cursor home */ + case SLCDCODE_END: /* Cursor end */ + case SLCDCODE_BLINKSTART: /* Start blinking with current cursor position */ + case SLCDCODE_BLINKEND: /* End blinking after the current cursor position */ + case SLCDCODE_BLINKOFF: /* Turn blinking off */ + slcd_put3(code, stream); /* Generate the 3-byte encoding */ + break; + + /* Codes with an 8-bit count argument */ + + case SLCDCODE_FWDDEL: /* DELete (forward delete) N characters moving cursor */ + case SLCDCODE_BACKDEL: /* Backspace (backward delete) N characters */ + case SLCDCODE_ERASE: /* Erase N characters from the cursor position */ + case SLCDCODE_LEFT: /* Cursor left by N characters */ + case SLCDCODE_RIGHT: /* Cursor right by N characters */ + case SLCDCODE_UP: /* Cursor up by N lines */ + case SLCDCODE_DOWN: /* Cursor down by N lines */ + case SLCDCODE_PAGEUP: /* Cursor up by N pages */ + case SLCDCODE_PAGEDOWN: /* Cursor down by N pages */ + slcd_put5(code, count, stream); /* Generate the 5-byte sequence */ + break; + + default: + case SLCDCODE_NORMAL: /* Not a special slcdcode */ + break; + } +} -- cgit v1.2.3