From 7c18941836946de9edf444158b7a40ef75fcb7e9 Mon Sep 17 00:00:00 2001 From: "Collin J. Doering" Date: Sun, 25 Oct 2015 00:27:51 -0400 Subject: [PATCH] Add boiler plate code for remaining ANSI escapes Added function declarations and empty/implementation incomplete definitions in lcdLib.h and lcdLib.c respectively for remaining ANSI escape sequences; namely: - scrollUp - scrollDown - eraseDisplay - eraseInline Prematurely edited the parsing of any ASCII escape which causes the screen to be cleared (Eg. '\n' on the last line), to use the new (but yet to be implemented) scrolling functions; thus after these functions have been filled in and tested, the ANSI escape support will be complete. Additionally, escapes that are not supported are passed over without printing any characters. The two cases that are handled in this commit are DSR and SGR. The parsing for DSR which when received, normally prints the current location of the cursor to standard output in the form "\e[n;mR", where n is the row and m is the column, is left unsupported but may be supported in the future (thus comments have been left indicating condition where a valid parse occurs). The SGR ANSI escape sequence can vary in length and thus needs to be completely consumed from the input before processing the next character. This is taken care of correctly in this commit, and has been tested. In a previous commit, forgot to add the declarations of the following utility functions to the lcdLib.h header file: - blinkCursorOff - blinkCursorOn - displayOff - displayOn There are still a few functions that will be needed for reading data from the LCD that have not been declared/defined. These functions are required for efficiently scrolling the screen up and down. They also will be needed to finish the last remaining piece of this library which, after completion of ANSI escapes and associated functions, leaves support for custom characters. Namely writing characters to CGRAM and displaying custom characters (from CGRAM) using ASCII codes 0-7 (or 0-3 if 5x10 font is used). Signed-off-by: Collin J. Doering --- lcdLib.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++---- lcdLib.h | 48 ++++++++++++++++++++++ 2 files changed, 163 insertions(+), 8 deletions(-) diff --git a/lcdLib.c b/lcdLib.c index 8023b08..26649c4 100644 --- a/lcdLib.c +++ b/lcdLib.c @@ -202,10 +202,13 @@ void writeCharToLCD(char c) { switch (c) { case '\n': // Line feed if (currentLineNum == LCD_NUMBER_OF_LINES - 1) { - clearDisplay(); - } else { - writeLCDInstr(INSTR_DDRAM_ADDR | lineBeginnings[++currentLineNum]); + scrollUp(1); + currentLineChars = 0; + writeLCDInstr(INSTR_DDRAM_ADDR | lineBeginnings[currentLineNum]); + } else { + currentLineChars = 0; + writeLCDInstr(INSTR_DDRAM_ADDR | lineBeginnings[++currentLineNum]); } break; case '\a': // Alarm @@ -231,14 +234,20 @@ void writeCharToLCD(char c) { case '\f': // Form feed clearDisplay(); break; - default: + default: // Printable character if (currentLineChars == LCD_CHARACTERS_PER_LINE - 1 && currentLineNum == LCD_NUMBER_OF_LINES - 1) { - clearDisplay(); + loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions + writeCharToLCD_(c); + + scrollUp(1); + + currentLineChars = 0; + writeLCDInstr(INSTR_DDRAM_ADDR | lineBeginnings[currentLineNum]); } else if (currentLineChars == LCD_CHARACTERS_PER_LINE - 1) { loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions writeCharToLCD_(c); - currentLineChars = 0; + currentLineChars = 0; writeLCDInstr(INSTR_DDRAM_ADDR | lineBeginnings[++currentLineNum]); } else { loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions @@ -251,8 +260,9 @@ void writeCharToLCD(char c) { /* Given a character string, and a uint8_t pointer, reads the character string until a non-numerical ASCII character, returning the integer representation of the number read. At - the end of the functions execution, the found_num uint8_t pointer will indicate how many - digits were read. + the end of the functions execution, the found_num uint8_t* will be updated to indicate how + many digits were read. The new_loc char** will be updated with the new parsing position in + the string. */ uint8_t readASCIINumber(char* str, uint8_t* found_num, char** new_loc) { uint8_t nums[3]; @@ -362,6 +372,51 @@ void writeStringToLCD(char* str) { num0 = fnd0 ? num0 : 1; moveCursorToColumn(num0); break; + case 'J': // ED - Erase display + num0 = fnd0 ? num0 : 1; + eraseDisplay(num0); + break; + case 'K': // EL - Erase in line + num0 = fnd0 ? num0 : 1; + eraseInline(num0); + break; + case 'S': // SU - Scroll up + num0 = fnd0 ? num0 : 1; + scrollUp(num0); + break; + case 'T': // SD Scroll down + num0 = fnd0 ? num0 : 1; + scrollDown(num0); + break; + case 'm': // SGR - Select graphic rendition (single optional argument) + break; + case ';': // SGR - Select graphic rendition (multiple arguments) + if (fnd0) { + while (fnd0) { + readASCIINumber(++str, &fnd0, &str); + if (fnd0) { + if (*str == 'm') { + break; // Valid SGR + } else if (*str == ';') { + continue; // More SGR parameters yet + } else { + break; // Invalid escape + } + } else { + // Invalid escape; expected SGR parameter + } + } + } else { + // Invalid escape; expected first SGR parameter but none given + } + break; + case 'n': // DSR - Device status report + if (fnd0 && num0 == 6) { + // Valid DSR + } else { + // Invalid DSR + } + break; default: // Invalid control character writeCharToLCD(*str); break; @@ -486,6 +541,58 @@ void moveCursorToColumn(uint8_t n) { } // else index out of range (off screen column) } +void eraseDisplay(uint8_t n) { + switch (n) { + case 0: // Clear from cursor to end of screen + case 1: // Clear from cursor to beginning of screen + case 2: // Clear entire screen + clearDisplay(); + break; + default: // Invalid argument; do nothing + break; + } +} + +void eraseInline(uint8_t n) { + char pos_x = currentLineChars; + + // BUG: when cursor is on the last character of the last line, writing currentLineChars + // number of spaces will currently clear the screen due to the way writeCharToLCD handles + // text wrapping. Specifically after the last character (bottom right) of the screen is + // written the screen is automatically cleared. + switch (n) { + case 0: // Clear from cursor to end of line + for (uint8_t i = 0; i < (LCD_CHARACTERS_PER_LINE - currentLineChars); i++) + writeCharToLCD(' '); + + // Move cursor back one char and line so its in its original position + setCursorPosition(pos_x, currentLineNum); + break; + case 1: // Clear from cursor to beginning of line + writeCharToLCD('\r'); + for (uint8_t i = 0; i < pos_x; i++) + writeCharToLCD(' '); + moveCursorToColumn(pos_x + 1); + + break; + case 2: // Clear entire line + writeCharToLCD('\r'); + for (uint8_t i = 0; i < LCD_CHARACTERS_PER_LINE; i++) + writeCharToLCD(' '); + + // Move cursor back one line so its in its original position + setCursorPosition(pos_x + 1, currentLineNum); + default: // Invalid argument; do nothing + break; + } +} + +void scrollUp(uint8_t n) { +} + +void scrollDown(uint8_t n) { +} + void saveCursorPosition() { saveCursorLineNum = currentLineNum; saveCursorLineChars = currentLineChars; diff --git a/lcdLib.h b/lcdLib.h index 4cd228e..62b0ee1 100644 --- a/lcdLib.h +++ b/lcdLib.h @@ -207,6 +207,32 @@ void moveCursorPreviousLine(uint8_t n); */ void moveCursorToColumn(uint8_t n); +/** + Scroll whole page up by n lines. New lines are added at the bottom. + */ +void scrollUp(uint8_t n); + +/** + Scroll whole page down by n lines. New lines are added at the top. + */ +void scrollDown(uint8_t n); + +/** + Clears part or all of screen dependent on the value of n: + 0 or missing: clear from cursor to end of screen + 1: clear from cursor to end of screen + 2: clear entire screen + */ +void eraseDisplay(uint8_t n); + +/** + Erases part of a line dependent on the value of n: + 0 or missing: clear from cursor to end of the line + 1: clear from cursor to beginning of the line + 2: clear entire line + */ +void eraseInline(uint8_t n); + /** Hides the cursor */ @@ -219,6 +245,28 @@ void showCursor(void); //----------------------------------------------------------------------------------------------- +/** + Turns the cursor blink off. + */ +void blinkCursorOff(void); + +/** + Turns the cursor blink on. + */ +void blinkCursorOn(void); + +/** + Turns the display off. + */ +void displayOff(void); + +/** + Turns the display on. + */ +void displayOn(void); + +//----------------------------------------------------------------------------------------------- + /* UNIMPLEMENTED */