2015-09-29 06:48:09 +00:00
|
|
|
/**
|
|
|
|
* (C) Copyright Collin J. Doering 2015
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2015-10-19 08:58:03 +00:00
|
|
|
*/
|
2015-09-29 06:48:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* File: lcdLib.c
|
|
|
|
* Author: Collin J. Doering <collin.doering@rekahsoft.ca>
|
|
|
|
* Date: Sep 29, 2015
|
|
|
|
*/
|
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
// Includes -----------------------------------------------------------------------------------
|
|
|
|
#include <math.h>
|
|
|
|
#include <avr/io.h>
|
2015-09-29 06:48:09 +00:00
|
|
|
#include <util/delay.h>
|
|
|
|
|
|
|
|
#include "lcdLib.h"
|
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
//---------------------------------------------------------------------------------------------
|
|
|
|
// Static global variables
|
2015-10-06 07:05:56 +00:00
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
static volatile uint8_t currentLineNum;
|
|
|
|
static volatile uint8_t currentLineChars;
|
2015-10-24 04:42:54 +00:00
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
static volatile uint8_t saveCursorLineNum;
|
|
|
|
static volatile uint8_t saveCursorLineChars;
|
2015-10-24 07:45:32 +00:00
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
static volatile uint8_t lcdState;
|
2015-10-06 07:05:56 +00:00
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
static const uint8_t lineBeginnings[LCD_NUMBER_OF_LINES] = { LCD_LINE_BEGINNINGS };
|
2015-10-15 04:26:46 +00:00
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
//---------------------------------------------------------------------------------------------
|
|
|
|
// Static functions
|
|
|
|
|
|
|
|
/*
|
|
|
|
Bring LCD_ENABLE line high, wait for LCD_ENABLE_HIGH_DELAY; then bring LCD_ENABLE line low
|
|
|
|
and wait for LCD_ENABLE_LOW_DELAY.
|
|
|
|
|
|
|
|
Note: LCD_ENABLE, LCD_ENABLE_HIGH_DELAY, and LCD_ENABLE_LOW_DELAY must be defined in lcdLibConfig.h
|
|
|
|
*/
|
|
|
|
static void clkLCD(void) {
|
2015-10-01 07:04:33 +00:00
|
|
|
LCD_ENABLE_PORT |= (1 << LCD_ENABLE);
|
|
|
|
_delay_us(LCD_ENABLE_HIGH_DELAY);
|
|
|
|
LCD_ENABLE_PORT &= ~(1 << LCD_ENABLE);
|
|
|
|
_delay_us(LCD_ENABLE_LOW_DELAY);
|
2015-09-29 06:48:09 +00:00
|
|
|
}
|
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
/*
|
|
|
|
Wait until LCD_BF (busy flag) is cleared (low).
|
|
|
|
*/
|
|
|
|
static void loop_until_LCD_BF_clear(void) {
|
2015-10-06 07:34:39 +00:00
|
|
|
uint8_t bf;
|
|
|
|
|
2015-10-01 07:04:33 +00:00
|
|
|
LCD_RS_PORT &= ~(1 << LCD_RS); // RS=0
|
|
|
|
LCD_RW_PORT |= (1 << LCD_RW); // RW=1
|
|
|
|
|
|
|
|
// Set LCD_BF as input
|
2015-10-01 08:06:08 +00:00
|
|
|
LCD_DBUS7_DDR &= ~(1 << LCD_BF);
|
2015-09-29 06:48:09 +00:00
|
|
|
|
2015-09-30 08:46:49 +00:00
|
|
|
do {
|
2015-10-06 07:34:39 +00:00
|
|
|
bf = 0;
|
|
|
|
LCD_ENABLE_PORT |= (1 << LCD_ENABLE);
|
|
|
|
_delay_us(1); // 'delay data time' and 'enable pulse width'
|
|
|
|
|
|
|
|
bf |= (LCD_DBUS7_PIN & (1 << LCD_BF));
|
|
|
|
|
|
|
|
LCD_ENABLE_PORT &= ~(1 << LCD_ENABLE);
|
|
|
|
_delay_us(1); // 'address hold time', 'data hold time' and 'enable cycle width'
|
|
|
|
|
|
|
|
#ifdef FOUR_BIT_MODE
|
|
|
|
LCD_ENABLE_PORT |= (1 << LCD_ENABLE);
|
|
|
|
_delay_us(1); // 'delay data time' and 'enable pulse width'
|
|
|
|
LCD_ENABLE_PORT &= ~(1 << LCD_ENABLE);
|
|
|
|
_delay_us(1); // 'address hold time', 'data hold time' and 'enable cycle width'
|
|
|
|
#endif
|
|
|
|
} while (bf);
|
2015-10-01 07:04:33 +00:00
|
|
|
|
2015-10-01 07:43:07 +00:00
|
|
|
#if defined (FOUR_BIT_MODE) || defined (EIGHT_BIT_ARBITRARY_PIN_MODE)
|
2015-10-01 08:06:08 +00:00
|
|
|
LCD_DBUS7_DDR |= (1 << LCD_DBUS7);
|
|
|
|
LCD_DBUS6_DDR |= (1 << LCD_DBUS6);
|
|
|
|
LCD_DBUS5_DDR |= (1 << LCD_DBUS5);
|
|
|
|
LCD_DBUS4_DDR |= (1 << LCD_DBUS4);
|
2015-10-01 07:43:07 +00:00
|
|
|
#ifdef EIGHT_BIT_ARBITRARY_PIN_MODE
|
2015-10-01 08:06:08 +00:00
|
|
|
LCD_DBUS3_DDR |= (1 << LCD_DBUS3);
|
|
|
|
LCD_DBUS2_DDR |= (1 << LCD_DBUS2);
|
|
|
|
LCD_DBUS1_DDR |= (1 << LCD_DBUS1);
|
|
|
|
LCD_DBUS0_DDR |= (1 << LCD_DBUS0);
|
2015-10-01 07:43:07 +00:00
|
|
|
#endif
|
2015-10-01 07:04:33 +00:00
|
|
|
#else
|
2015-09-29 06:48:09 +00:00
|
|
|
LCD_DBUS_DDR = 0xff; // Reset all LCD_DBUS_PORT pins as outputs
|
2015-10-01 07:04:33 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
/*
|
|
|
|
Given a 8 bit integer, writes the four MSB's (one nibble) to the LCD data bus.
|
|
|
|
|
|
|
|
Note: this is only defined in FOUR_BIT_MODE
|
|
|
|
*/
|
2015-10-01 07:04:33 +00:00
|
|
|
#ifdef FOUR_BIT_MODE
|
2015-10-26 08:49:19 +00:00
|
|
|
static void writeLCDDBusNibble_(uint8_t b) {
|
2015-10-01 07:04:33 +00:00
|
|
|
// Reset data lines to zeros
|
|
|
|
LCD_DBUS7_PORT &= ~(1 << LCD_DBUS7);
|
|
|
|
LCD_DBUS6_PORT &= ~(1 << LCD_DBUS6);
|
|
|
|
LCD_DBUS5_PORT &= ~(1 << LCD_DBUS5);
|
|
|
|
LCD_DBUS4_PORT &= ~(1 << LCD_DBUS4);
|
|
|
|
|
|
|
|
// Write 1's where appropriate on data lines
|
|
|
|
if (b & (1 << 7)) LCD_DBUS7_PORT |= (1 << LCD_DBUS7);
|
|
|
|
if (b & (1 << 6)) LCD_DBUS6_PORT |= (1 << LCD_DBUS6);
|
|
|
|
if (b & (1 << 5)) LCD_DBUS5_PORT |= (1 << LCD_DBUS5);
|
|
|
|
if (b & (1 << 4)) LCD_DBUS4_PORT |= (1 << LCD_DBUS4);
|
|
|
|
|
|
|
|
// Pulse the enable line
|
|
|
|
clkLCD();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
/*
|
|
|
|
Given an 8 bit integer, writes it to the LCD data bus, regardless of its
|
|
|
|
configuration (default 8-bit mode, 8-bit arbitrary pin mode and 4-bit mode). In the default
|
|
|
|
8-bit mode and EIGHT_BIT_ARBITRARY_PIN_MODE, the given data is written in one cycle using the
|
|
|
|
writeLCDDBusByte_ function. In FOUR_BIT_MODE however, the given data is written in two cycles
|
|
|
|
using two successive calls to the writeLCDDBusNibble_ function.
|
|
|
|
|
|
|
|
This function does not ensure the LCD is ready to accept new data and thus needs to
|
|
|
|
be handled by the caller.
|
|
|
|
*/
|
|
|
|
static void writeLCDDBusByte_(uint8_t b) {
|
2015-10-01 07:43:07 +00:00
|
|
|
#ifdef FOUR_BIT_MODE
|
2015-10-25 07:54:54 +00:00
|
|
|
writeLCDDBusNibble_(b);
|
|
|
|
writeLCDDBusNibble_(b << 4);
|
2015-10-01 07:43:07 +00:00
|
|
|
#elif defined (EIGHT_BIT_ARBITRARY_PIN_MODE)
|
2015-10-01 08:06:08 +00:00
|
|
|
// Reset data lines to zeros
|
|
|
|
LCD_DBUS7_PORT &= ~(1 << LCD_DBUS7);
|
|
|
|
LCD_DBUS6_PORT &= ~(1 << LCD_DBUS6);
|
|
|
|
LCD_DBUS5_PORT &= ~(1 << LCD_DBUS5);
|
|
|
|
LCD_DBUS4_PORT &= ~(1 << LCD_DBUS4);
|
|
|
|
LCD_DBUS3_PORT &= ~(1 << LCD_DBUS3);
|
|
|
|
LCD_DBUS2_PORT &= ~(1 << LCD_DBUS2);
|
|
|
|
LCD_DBUS1_PORT &= ~(1 << LCD_DBUS1);
|
|
|
|
LCD_DBUS0_PORT &= ~(1 << LCD_DBUS0);
|
|
|
|
|
|
|
|
// Write 1's where appropriate on data lines
|
|
|
|
if (b & (1 << 7)) LCD_DBUS7_PORT |= (1 << LCD_DBUS7);
|
|
|
|
if (b & (1 << 6)) LCD_DBUS6_PORT |= (1 << LCD_DBUS6);
|
|
|
|
if (b & (1 << 5)) LCD_DBUS5_PORT |= (1 << LCD_DBUS5);
|
|
|
|
if (b & (1 << 4)) LCD_DBUS4_PORT |= (1 << LCD_DBUS4);
|
|
|
|
if (b & (1 << 3)) LCD_DBUS3_PORT |= (1 << LCD_DBUS3);
|
|
|
|
if (b & (1 << 2)) LCD_DBUS2_PORT |= (1 << LCD_DBUS2);
|
|
|
|
if (b & (1 << 1)) LCD_DBUS1_PORT |= (1 << LCD_DBUS1);
|
|
|
|
if (b & (1 << 0)) LCD_DBUS0_PORT |= (1 << LCD_DBUS0);
|
2015-10-01 07:43:07 +00:00
|
|
|
|
|
|
|
clkLCD();
|
|
|
|
#else
|
2015-10-01 07:04:33 +00:00
|
|
|
LCD_DBUS_PORT = b;
|
|
|
|
clkLCD();
|
2015-10-01 07:43:07 +00:00
|
|
|
#endif
|
2015-09-29 06:48:09 +00:00
|
|
|
}
|
|
|
|
|
2015-10-15 04:26:46 +00:00
|
|
|
/*
|
2015-10-26 08:49:19 +00:00
|
|
|
Given a 8 bit integer representing a LCD instruction, sends it to the LCD display.
|
|
|
|
|
|
|
|
Sets RS=RW=0 and writes the given 8 bit integer to the LCD databus.
|
|
|
|
|
|
|
|
Note that this function does not ensure the LCD is ready to accept a new instruction and thus
|
|
|
|
needs to be handled by the caller.
|
2015-10-19 08:58:03 +00:00
|
|
|
*/
|
2015-10-26 08:49:19 +00:00
|
|
|
static void writeLCDInstr_(uint8_t instr) {
|
2015-10-15 04:26:46 +00:00
|
|
|
LCD_RS_PORT &= ~(1 << LCD_RS); // RS=0
|
|
|
|
LCD_RW_PORT &= ~(1 << LCD_RW); // RW=0
|
2015-10-01 07:04:33 +00:00
|
|
|
|
2015-10-25 07:54:54 +00:00
|
|
|
writeLCDDBusByte_(instr);
|
2015-09-29 06:48:09 +00:00
|
|
|
}
|
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
/*
|
|
|
|
Given a 8 bit integer representing a LCD instruction, waits until the LCD is ready and sends
|
|
|
|
the instruction.
|
|
|
|
*/
|
|
|
|
static inline void writeLCDInstr(uint8_t instr) {
|
2015-09-29 06:48:09 +00:00
|
|
|
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
|
|
|
writeLCDInstr_(instr);
|
|
|
|
}
|
|
|
|
|
2015-10-15 04:26:46 +00:00
|
|
|
/*
|
|
|
|
Sets RS=1, RW=0 and accepts a char (8 bit) and outputs it to the current cursor position of
|
|
|
|
the LCD. In the default 8-bit mode and EIGHT_BIT_ARBITRARY_PIN_MODE, the given data is
|
2015-10-25 07:54:54 +00:00
|
|
|
written in one cycle using the writeLCDDBusByte_ function. In FOUR_BIT_MODE however, the given
|
|
|
|
data is written in two cycles using two successive calls to the writeLCDDBusNibble_ function.
|
2015-10-19 08:58:03 +00:00
|
|
|
*/
|
2015-10-26 08:49:19 +00:00
|
|
|
static void writeCharToLCD_(char c) {
|
2015-10-01 07:04:33 +00:00
|
|
|
LCD_RS_PORT |= (1 << LCD_RS); // RS=1
|
|
|
|
LCD_RW_PORT &= ~(1 << LCD_RW); // RW=0
|
|
|
|
|
2015-10-25 07:54:54 +00:00
|
|
|
writeLCDDBusByte_(c);
|
2015-09-29 06:48:09 +00:00
|
|
|
}
|
|
|
|
|
2015-10-28 08:30:40 +00:00
|
|
|
static uint8_t readLCDDBusByte_(void) {
|
|
|
|
LCD_RS_PORT |= (1 << LCD_RS); // RS=1
|
|
|
|
LCD_RW_PORT |= (1 << LCD_RW); // RW=1
|
|
|
|
|
|
|
|
LCD_ENABLE_PORT |= (1 << LCD_ENABLE);
|
|
|
|
_delay_us(1); // 'delay data time' and 'enable pulse width'
|
|
|
|
|
|
|
|
// Read data
|
|
|
|
char c = 0;
|
|
|
|
#if defined(FOUR_BIT_MODE)
|
|
|
|
if (LCD_DBUS7_PIN & (1 << LCD_DBUS7)) c |= (1 << 7);
|
|
|
|
if (LCD_DBUS6_PIN & (1 << LCD_DBUS6)) c |= (1 << 6);
|
|
|
|
if (LCD_DBUS5_PIN & (1 << LCD_DBUS5)) c |= (1 << 5);
|
|
|
|
if (LCD_DBUS4_PIN & (1 << LCD_DBUS4)) c |= (1 << 4);
|
|
|
|
|
|
|
|
LCD_ENABLE_PORT &= ~(1 << LCD_ENABLE);
|
|
|
|
_delay_us(1); // 'address hold time', 'data hold time' and 'enable cycle width'
|
|
|
|
LCD_ENABLE_PORT |= (1 << LCD_ENABLE);
|
|
|
|
_delay_us(1); // 'delay data time' and 'enable pulse width'
|
|
|
|
|
|
|
|
if (LCD_DBUS7_PIN & (1 << LCD_DBUS7)) c |= (1 << 3);
|
|
|
|
if (LCD_DBUS6_PIN & (1 << LCD_DBUS6)) c |= (1 << 2);
|
|
|
|
if (LCD_DBUS5_PIN & (1 << LCD_DBUS5)) c |= (1 << 1);
|
|
|
|
if (LCD_DBUS4_PIN & (1 << LCD_DBUS4)) c |= (1 << 0);
|
|
|
|
#elif defined(EIGHT_BIT_ARBITRARY_PIN_MODE)
|
|
|
|
if (LCD_DBUS7_PIN & (1 << LCD_DBUS7)) c |= (1 << 7);
|
|
|
|
if (LCD_DBUS6_PIN & (1 << LCD_DBUS6)) c |= (1 << 6);
|
|
|
|
if (LCD_DBUS5_PIN & (1 << LCD_DBUS5)) c |= (1 << 5);
|
|
|
|
if (LCD_DBUS4_PIN & (1 << LCD_DBUS4)) c |= (1 << 4);
|
|
|
|
if (LCD_DBUS3_PIN & (1 << LCD_DBUS3)) c |= (1 << 3);
|
|
|
|
if (LCD_DBUS2_PIN & (1 << LCD_DBUS2)) c |= (1 << 2);
|
|
|
|
if (LCD_DBUS1_PIN & (1 << LCD_DBUS1)) c |= (1 << 1);
|
|
|
|
if (LCD_DBUS0_PIN & (1 << LCD_DBUS0)) c |= (1 << 0);
|
|
|
|
#else
|
|
|
|
c = LCD_DBUS_PIN;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
LCD_ENABLE_PORT &= ~(1 << LCD_ENABLE);
|
|
|
|
_delay_us(1); // 'address hold time', 'data hold time' and 'enable cycle width'
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
/*
|
|
|
|
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* 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.
|
|
|
|
*/
|
|
|
|
static uint8_t readASCIINumber(char* str, uint8_t* found_num, char** new_loc) {
|
|
|
|
uint8_t nums[3];
|
|
|
|
|
|
|
|
*found_num = 0;
|
|
|
|
while (*str != '\0' && *found_num < 3) {
|
|
|
|
if (*str >= 0x30 && *str <= 0x39) {
|
|
|
|
// Use *str as a number (specified in ASCII)
|
|
|
|
nums[(*found_num)++] = *str - 0x30;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
*new_loc = str;
|
|
|
|
|
|
|
|
uint8_t ret = 0;
|
|
|
|
uint8_t i = *found_num - 1;
|
|
|
|
for (uint8_t fnd = 0; fnd < *found_num; fnd++)
|
|
|
|
ret += nums[fnd] * pow(10, i--);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2015-10-28 08:30:40 +00:00
|
|
|
Set all pins of LCD_DBUS as outputs
|
2015-10-26 08:49:19 +00:00
|
|
|
*/
|
2015-10-28 08:30:40 +00:00
|
|
|
static inline void setLCDDBusAsOutputs(void) {
|
2015-10-26 08:49:19 +00:00
|
|
|
#if defined (FOUR_BIT_MODE) || defined (EIGHT_BIT_ARBITRARY_PIN_MODE)
|
|
|
|
LCD_DBUS7_DDR |= (1 << LCD_DBUS7);
|
|
|
|
LCD_DBUS6_DDR |= (1 << LCD_DBUS6);
|
|
|
|
LCD_DBUS5_DDR |= (1 << LCD_DBUS5);
|
|
|
|
LCD_DBUS4_DDR |= (1 << LCD_DBUS4);
|
|
|
|
#ifdef EIGHT_BIT_ARBITRARY_PIN_MODE
|
|
|
|
LCD_DBUS3_DDR |= (1 << LCD_DBUS3);
|
|
|
|
LCD_DBUS2_DDR |= (1 << LCD_DBUS2);
|
|
|
|
LCD_DBUS1_DDR |= (1 << LCD_DBUS1);
|
|
|
|
LCD_DBUS0_DDR |= (1 << LCD_DBUS0);
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
LCD_DBUS_DDR = 0xff;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2015-10-28 08:30:40 +00:00
|
|
|
Set all pins of LCD_DBUS as inputs (disabling their output)
|
2015-10-26 08:49:19 +00:00
|
|
|
*/
|
2015-10-28 08:30:40 +00:00
|
|
|
static inline void setLCDDBusAsInputs(void) {
|
2015-10-26 08:49:19 +00:00
|
|
|
#if defined (FOUR_BIT_MODE) || defined (EIGHT_BIT_ARBITRARY_PIN_MODE)
|
|
|
|
LCD_DBUS7_DDR &= ~(1 << LCD_DBUS7);
|
|
|
|
LCD_DBUS6_DDR &= ~(1 << LCD_DBUS6);
|
|
|
|
LCD_DBUS5_DDR &= ~(1 << LCD_DBUS5);
|
|
|
|
LCD_DBUS4_DDR &= ~(1 << LCD_DBUS4);
|
|
|
|
#ifdef EIGHT_BIT_ARBITRARY_PIN_MODE
|
|
|
|
LCD_DBUS3_DDR &= ~(1 << LCD_DBUS3);
|
|
|
|
LCD_DBUS2_DDR &= ~(1 << LCD_DBUS2);
|
|
|
|
LCD_DBUS1_DDR &= ~(1 << LCD_DBUS1);
|
|
|
|
LCD_DBUS0_DDR &= ~(1 << LCD_DBUS0);
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
LCD_DBUS_DDR = 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Set RS=RW=0 and write the CMD_INIT command to the LCD data bus. Note that an appropriate
|
|
|
|
pause must follow before sending new commands to the LCD using writeLCD*_ functions.
|
|
|
|
*/
|
|
|
|
static inline void softwareLCDInitPulse(void) {
|
|
|
|
LCD_RS_PORT &= ~(1 << LCD_RS); // RS=0
|
|
|
|
LCD_RW_PORT &= ~(1 << LCD_RW); // RW=0
|
|
|
|
|
|
|
|
#ifdef FOUR_BIT_MODE
|
|
|
|
writeLCDDBusNibble_(CMD_INIT);
|
|
|
|
#else
|
|
|
|
writeLCDDBusByte_(CMD_INIT);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
|
|
// Library function definitions
|
|
|
|
|
|
|
|
/*
|
|
|
|
Do software initialization as specified by the datasheet
|
|
|
|
*/
|
|
|
|
void initLCD(void) {
|
2015-10-28 08:30:40 +00:00
|
|
|
// Set LCD_RS, LCD_RW and LCD_ENABLE as outputs
|
|
|
|
LCD_RS_DDR |= (1 << LCD_RS);
|
|
|
|
LCD_RW_DDR |= (1 << LCD_RW);
|
|
|
|
LCD_ENABLE_DDR |= (1 << LCD_ENABLE);
|
|
|
|
|
|
|
|
setLCDDBusAsOutputs();
|
2015-10-26 08:49:19 +00:00
|
|
|
|
|
|
|
_delay_us(LCD_INIT_DELAY0); // Wait minimum 15ms as per datasheet
|
|
|
|
softwareLCDInitPulse();
|
|
|
|
_delay_us(LCD_INIT_DELAY1); // Wait minimum 4.1ms as per datasheet
|
|
|
|
softwareLCDInitPulse();
|
|
|
|
_delay_us(LCD_INIT_DELAY2); // Wait minimum 100us as per datasheet
|
|
|
|
softwareLCDInitPulse();
|
|
|
|
|
|
|
|
#if defined (FOUR_BIT_MODE)
|
2015-10-27 05:02:02 +00:00
|
|
|
// Function Set (4-bit interface)
|
2015-10-26 08:49:19 +00:00
|
|
|
writeLCDDBusNibble_(CMD_INIT_FOUR_BIT);
|
2015-10-27 05:02:02 +00:00
|
|
|
writeLCDInstr_(CMD_INIT_FOUR_BIT | LCD_LINES | LCD_FONT);
|
2015-10-26 08:49:19 +00:00
|
|
|
#else
|
2015-10-27 05:02:02 +00:00
|
|
|
// Function set (8-bit interface)
|
|
|
|
writeLCDInstr_(INSTR_FUNC_SET | (1 << INSTR_FUNC_SET_DL) | LCD_LINES | LCD_FONT);
|
2015-10-26 08:49:19 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* BF now can be checked */
|
|
|
|
|
|
|
|
// Set functions of LCD
|
|
|
|
writeLCDInstr(INSTR_DISPLAY); // Display off
|
|
|
|
|
|
|
|
// Clear display
|
|
|
|
writeLCDInstr(CMD_CLEAR_DISPLAY);
|
|
|
|
|
|
|
|
// Increment mode, no shift
|
|
|
|
writeLCDInstr(INSTR_ENTRY_SET | (1 << INSTR_ENTRY_SET_ID));
|
|
|
|
|
|
|
|
// Display on, cursor on, blink off
|
|
|
|
lcdState = (1 << INSTR_DISPLAY_D) | (1 << INSTR_DISPLAY_C);
|
|
|
|
writeLCDInstr(INSTR_DISPLAY | lcdState);
|
|
|
|
}
|
|
|
|
|
2015-10-15 04:26:46 +00:00
|
|
|
/*
|
|
|
|
Given a single character, checks whether its a ASCII escape and does the following:
|
|
|
|
|
|
|
|
- Newline '\n': moves the cursor to the next physical line of the LCD display; if the cursor is on
|
2015-10-19 08:58:03 +00:00
|
|
|
the last line of the display, clears the display and positions the cursor at the top left
|
|
|
|
of the LCD
|
2015-10-15 04:26:46 +00:00
|
|
|
- Carriage return '\r': moves the cursor to the beginning of the current line
|
|
|
|
- Backspace '\b': moves the cursor one position backwards, wrapping to the end of the
|
2015-10-19 08:58:03 +00:00
|
|
|
previous line when at the beginning of a line (other then the first one). A space is then
|
|
|
|
inserted to replace the character at point, without moving the cursor. When the cursor is
|
|
|
|
at the beginning of the first line, does nothing.
|
2015-10-15 04:26:46 +00:00
|
|
|
- Form feed '\f': clears the LCD display and places the cursor at the beginning of the first line.
|
|
|
|
- Alarm '\a': ignored
|
|
|
|
|
|
|
|
Any other character is sent to the LCD display using writeCharToLCD_.
|
2015-10-19 08:58:03 +00:00
|
|
|
*/
|
2015-09-29 06:48:09 +00:00
|
|
|
void writeCharToLCD(char c) {
|
2015-10-06 09:49:59 +00:00
|
|
|
switch (c) {
|
|
|
|
case '\n': // Line feed
|
|
|
|
if (currentLineNum == LCD_NUMBER_OF_LINES - 1) {
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
scrollUp(1);
|
|
|
|
|
|
|
|
currentLineChars = 0;
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | lineBeginnings[currentLineNum]);
|
2015-10-06 09:49:59 +00:00
|
|
|
} else {
|
|
|
|
currentLineChars = 0;
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | lineBeginnings[++currentLineNum]);
|
2015-10-06 09:49:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '\a': // Alarm
|
|
|
|
break;
|
2015-10-08 02:38:57 +00:00
|
|
|
case '\b': // Backspace (non-destructive)
|
|
|
|
if (currentLineChars == 0 && currentLineNum == 0) {
|
|
|
|
// At first line, first column; there is no where to move; do nothing
|
|
|
|
break;
|
|
|
|
} else if (currentLineChars == 0) {
|
|
|
|
// At beginning of line, need to move the end of previous line
|
|
|
|
currentLineChars = LCD_CHARACTERS_PER_LINE - 1;
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[--currentLineNum] + currentLineChars));
|
|
|
|
} else {
|
|
|
|
// OK, simply go back one character
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + --currentLineChars));
|
|
|
|
}
|
|
|
|
|
2015-10-06 09:49:59 +00:00
|
|
|
break;
|
|
|
|
case '\r': // Carriage return
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | lineBeginnings[currentLineNum]);
|
|
|
|
currentLineChars = 0;
|
|
|
|
break;
|
2015-10-08 02:38:57 +00:00
|
|
|
case '\f': // Form feed
|
|
|
|
clearDisplay();
|
|
|
|
break;
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
default: // Printable character
|
2015-10-08 02:38:57 +00:00
|
|
|
if (currentLineChars == LCD_CHARACTERS_PER_LINE - 1 && currentLineNum == LCD_NUMBER_OF_LINES - 1) {
|
|
|
|
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
|
|
|
writeCharToLCD_(c);
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
|
|
|
|
scrollUp(1);
|
|
|
|
|
2015-10-08 02:38:57 +00:00
|
|
|
currentLineChars = 0;
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
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);
|
2015-10-06 07:05:56 +00:00
|
|
|
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
currentLineChars = 0;
|
2015-10-08 02:38:57 +00:00
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | lineBeginnings[++currentLineNum]);
|
|
|
|
} else {
|
|
|
|
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
|
|
|
writeCharToLCD_(c);
|
|
|
|
currentLineChars++;
|
|
|
|
}
|
2015-10-06 09:49:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-20 09:21:03 +00:00
|
|
|
void writeStringToLCD(char* str) {
|
2015-10-06 09:49:59 +00:00
|
|
|
while (*str != '\0') {
|
2015-10-26 09:43:15 +00:00
|
|
|
#ifdef LCD_ANSI_ESCAPE_ENABLE
|
2015-10-19 09:04:53 +00:00
|
|
|
// Check for ANSI CSI (Control Sequence Introducer)
|
|
|
|
if (*str == '\e') {
|
|
|
|
if (*(++str) != '\0' && *str == '[') {
|
2015-10-24 04:42:54 +00:00
|
|
|
char* str_ref = ++str;
|
|
|
|
switch (*str) {
|
|
|
|
case 's': // SCP - Save cursor position
|
|
|
|
saveCursorPosition();
|
|
|
|
return;
|
|
|
|
case 'u': // RCP - Restore cursor position
|
|
|
|
restoreCursorPosition();
|
|
|
|
return;
|
2015-10-24 07:45:32 +00:00
|
|
|
case '?': // DECTCEM
|
|
|
|
if (*(++str_ref) != '\0' && *str_ref == '2') {
|
|
|
|
if (*(++str_ref) != '\0' && *str_ref == '5') {
|
|
|
|
if (*(++str_ref) != '\0') {
|
|
|
|
if (*str_ref == 'l') {
|
|
|
|
hideCursor();
|
|
|
|
} else if (*str_ref == 'h') {
|
|
|
|
showCursor();
|
|
|
|
} else {
|
|
|
|
// Invalid escape
|
|
|
|
}
|
|
|
|
} // Invalid escape (early termination)
|
|
|
|
} // Invalid escape
|
|
|
|
} // Invalid escape
|
|
|
|
return;
|
2015-10-24 04:42:54 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-10-19 09:04:53 +00:00
|
|
|
// Read optional variable length number in ASCII (0x30 - 0x3f) where 0x3a - 0x3f are
|
2015-10-20 09:21:03 +00:00
|
|
|
// ignored (they are used as flags by some terminals)
|
2015-10-19 09:04:53 +00:00
|
|
|
uint8_t fnd0;
|
2015-10-24 04:42:54 +00:00
|
|
|
uint8_t num0 = readASCIINumber(str, &fnd0, &str);
|
2015-10-19 09:04:53 +00:00
|
|
|
|
|
|
|
// Read optional (semicolon followed by optional variable length number)
|
|
|
|
uint8_t fnd1;
|
|
|
|
uint8_t num1;
|
2015-10-20 09:21:03 +00:00
|
|
|
if (*str != '\0' && *str == ';') {
|
2015-10-22 04:28:28 +00:00
|
|
|
num1 = readASCIINumber(++str, &fnd1, &str);
|
2015-10-19 09:04:53 +00:00
|
|
|
|
|
|
|
// Read control character (between 0x40 - 0x7e) for two argument sequences
|
|
|
|
switch (*str) {
|
|
|
|
case 'f': // HVP - Horizontal and vertical position
|
|
|
|
case 'H': // CUP - Cursor position
|
|
|
|
num0 = fnd0 ? num0 : 1;
|
|
|
|
num1 = fnd1 ? num1 : 1;
|
|
|
|
setCursorPosition(num0, num1);
|
|
|
|
break;
|
|
|
|
default: // Invalid control character
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (*str != '\0') {
|
|
|
|
// Read control character (between 0x40 - 0x7e) for single argument sequences
|
|
|
|
switch (*str) {
|
|
|
|
case 'A': // CUU - Cursor up
|
|
|
|
num0 = fnd0 ? num0 : 1;
|
|
|
|
moveCursorUp(num0);
|
|
|
|
break;
|
|
|
|
case 'B': // CUD - Cursor down
|
|
|
|
num0 = fnd0 ? num0 : 1;
|
|
|
|
moveCursorDown(num0);
|
|
|
|
break;
|
|
|
|
case 'C': // CUF - Cursor forward
|
|
|
|
num0 = fnd0 ? num0 : 1;
|
|
|
|
moveCursorForward(num0);
|
|
|
|
break;
|
|
|
|
case 'D': // CUB - Cursor back
|
|
|
|
num0 = fnd0 ? num0 : 1;
|
|
|
|
moveCursorBackward(num0);
|
|
|
|
break;
|
|
|
|
case 'E': // CNL - Cursor next line
|
|
|
|
num0 = fnd0 ? num0 : 1;
|
|
|
|
moveCursorNextLine(num0);
|
|
|
|
break;
|
|
|
|
case 'F': // CPL - Cursor previous line
|
|
|
|
num0 = fnd0 ? num0 : 1;
|
|
|
|
moveCursorPreviousLine(num0);
|
|
|
|
break;
|
|
|
|
case 'G': // CHA - Cursor horizontal absolute
|
|
|
|
num0 = fnd0 ? num0 : 1;
|
|
|
|
moveCursorToColumn(num0);
|
|
|
|
break;
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
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;
|
2015-10-19 09:04:53 +00:00
|
|
|
default: // Invalid control character
|
2015-10-20 09:21:03 +00:00
|
|
|
writeCharToLCD(*str);
|
2015-10-19 09:04:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return; // Invalid escape sequence (terminated early)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
writeCharToLCD(*str);
|
|
|
|
}
|
|
|
|
|
2015-09-29 10:06:37 +00:00
|
|
|
str++;
|
2015-10-26 09:43:15 +00:00
|
|
|
#else
|
|
|
|
writeCharToLCD(*(str++));
|
|
|
|
#endif
|
2015-09-29 10:06:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
//---------------------------------------------------------------------------------------------
|
|
|
|
// LCD command functions (all have associated ANSI escape)
|
|
|
|
|
2015-10-15 04:26:46 +00:00
|
|
|
/*
|
|
|
|
Writes the CMD_CLEAR_DISPLAY command to the LCD using writeLCDINSTR, and clears the local
|
|
|
|
char and line counters.
|
2015-10-19 08:58:03 +00:00
|
|
|
*/
|
2015-09-30 08:46:49 +00:00
|
|
|
void clearDisplay(void) {
|
|
|
|
writeLCDInstr(CMD_CLEAR_DISPLAY);
|
2015-10-06 07:05:56 +00:00
|
|
|
|
|
|
|
// Reset line and char number tracking
|
|
|
|
currentLineNum = 0;
|
|
|
|
currentLineChars = 0;
|
2015-09-30 08:46:49 +00:00
|
|
|
}
|
|
|
|
|
2015-10-15 04:26:46 +00:00
|
|
|
/*
|
|
|
|
Writes the CMD_RETURN_HOME command to the LCD using writeLCDInstr, and clears the local char
|
|
|
|
and line counters.
|
2015-10-19 08:58:03 +00:00
|
|
|
*/
|
2015-09-30 08:46:49 +00:00
|
|
|
void returnHome(void) {
|
|
|
|
writeLCDInstr(CMD_RETURN_HOME);
|
2015-10-06 07:05:56 +00:00
|
|
|
|
|
|
|
// Reset line and char number tracking
|
|
|
|
currentLineNum = 0;
|
|
|
|
currentLineChars = 0;
|
2015-09-29 10:06:37 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 09:04:53 +00:00
|
|
|
void getCursorPosition(uint8_t* row, uint8_t* column) {
|
|
|
|
*row = currentLineNum + 1;
|
|
|
|
*column = currentLineChars + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setCursorPosition(uint8_t row, uint8_t column) {
|
|
|
|
// Set currentLineNum and currentLineChars
|
|
|
|
currentLineNum = row ? row - 1 : 0;
|
|
|
|
currentLineChars = column ? column - 1 : 0;
|
|
|
|
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + currentLineChars));
|
|
|
|
}
|
|
|
|
|
|
|
|
void moveCursorUp(uint8_t n) {
|
|
|
|
if (n < currentLineNum + 1) {
|
|
|
|
currentLineNum -= n;
|
|
|
|
} else {
|
|
|
|
currentLineNum = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + currentLineChars));
|
|
|
|
}
|
|
|
|
|
|
|
|
void moveCursorDown(uint8_t n) {
|
2015-10-22 04:27:54 +00:00
|
|
|
if (n + currentLineNum < LCD_NUMBER_OF_LINES) {
|
2015-10-19 09:04:53 +00:00
|
|
|
currentLineNum += n;
|
|
|
|
} else {
|
|
|
|
currentLineNum = LCD_NUMBER_OF_LINES - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + currentLineChars));
|
|
|
|
}
|
|
|
|
|
|
|
|
void moveCursorForward(uint8_t n) {
|
2015-10-22 04:27:54 +00:00
|
|
|
if (n + currentLineChars < LCD_CHARACTERS_PER_LINE) {
|
2015-10-19 09:04:53 +00:00
|
|
|
currentLineChars += n;
|
|
|
|
} else {
|
|
|
|
currentLineChars = LCD_CHARACTERS_PER_LINE - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + currentLineChars));
|
|
|
|
}
|
|
|
|
|
|
|
|
void moveCursorBackward(uint8_t n) {
|
|
|
|
if (n < currentLineChars + 1) {
|
2015-10-20 09:21:03 +00:00
|
|
|
currentLineChars -= n;
|
2015-10-19 09:04:53 +00:00
|
|
|
} else {
|
|
|
|
currentLineChars = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + currentLineChars));
|
|
|
|
}
|
|
|
|
|
|
|
|
void moveCursorNextLine(uint8_t n) {
|
2015-10-22 04:27:54 +00:00
|
|
|
currentLineChars = 0;
|
|
|
|
|
|
|
|
if (n + currentLineNum < LCD_NUMBER_OF_LINES) {
|
2015-10-19 09:04:53 +00:00
|
|
|
currentLineNum += n;
|
|
|
|
} else {
|
|
|
|
currentLineNum = LCD_NUMBER_OF_LINES - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + currentLineChars));
|
|
|
|
}
|
|
|
|
|
|
|
|
void moveCursorPreviousLine(uint8_t n) {
|
2015-10-22 04:27:54 +00:00
|
|
|
currentLineChars = 0;
|
|
|
|
|
2015-10-19 09:04:53 +00:00
|
|
|
if (n < currentLineNum + 1) {
|
|
|
|
currentLineNum -= n;
|
|
|
|
} else {
|
|
|
|
currentLineNum = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + currentLineChars));
|
|
|
|
}
|
|
|
|
|
|
|
|
void moveCursorToColumn(uint8_t n) {
|
2015-10-22 04:27:54 +00:00
|
|
|
if (n <= LCD_CHARACTERS_PER_LINE) {
|
2015-10-19 09:04:53 +00:00
|
|
|
currentLineChars = n ? n - 1 : 0;
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + currentLineChars));
|
|
|
|
} // else index out of range (off screen column)
|
|
|
|
}
|
|
|
|
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
void eraseDisplay(uint8_t n) {
|
2015-10-28 08:20:35 +00:00
|
|
|
uint8_t old_row, old_column;
|
|
|
|
getCursorPosition(&old_row, &old_column);
|
|
|
|
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
switch (n) {
|
|
|
|
case 0: // Clear from cursor to end of screen
|
2015-10-28 08:20:35 +00:00
|
|
|
{
|
|
|
|
uint8_t len = (LCD_NUMBER_OF_LINES - old_row)*LCD_CHARACTERS_PER_LINE + (LCD_CHARACTERS_PER_LINE - old_column);
|
|
|
|
for (uint8_t i = 0; i < len; i++)
|
|
|
|
writeCharToLCD(' ');
|
|
|
|
|
|
|
|
// Write last char without scrolling
|
|
|
|
loop_until_LCD_BF_clear();
|
|
|
|
writeCharToLCD_(' ');
|
|
|
|
break;
|
|
|
|
}
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
case 1: // Clear from cursor to beginning of screen
|
2015-10-28 08:20:35 +00:00
|
|
|
{
|
|
|
|
uint8_t len = (old_row - 1)*LCD_CHARACTERS_PER_LINE + old_column;
|
|
|
|
returnHome();
|
|
|
|
for (uint8_t i = 0; i < len; i++)
|
|
|
|
writeCharToLCD(' ');
|
|
|
|
|
|
|
|
// Write last char without scrolling
|
|
|
|
loop_until_LCD_BF_clear();
|
|
|
|
writeCharToLCD_(' ');
|
|
|
|
break;
|
|
|
|
}
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
case 2: // Clear entire screen
|
|
|
|
clearDisplay();
|
|
|
|
break;
|
|
|
|
default: // Invalid argument; do nothing
|
|
|
|
break;
|
|
|
|
}
|
2015-10-28 08:20:35 +00:00
|
|
|
|
|
|
|
setCursorPosition(old_row, old_column);
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void eraseInline(uint8_t n) {
|
2015-10-28 05:59:02 +00:00
|
|
|
uint8_t old_row, old_column;
|
|
|
|
getCursorPosition(&old_row, &old_column);
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
|
|
|
|
switch (n) {
|
|
|
|
case 0: // Clear from cursor to end of line
|
2015-10-28 05:59:02 +00:00
|
|
|
for (uint8_t i = old_column; i <= LCD_CHARACTERS_PER_LINE; i++)
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
writeCharToLCD(' ');
|
|
|
|
break;
|
|
|
|
case 1: // Clear from cursor to beginning of line
|
2015-10-28 05:59:02 +00:00
|
|
|
setCursorPosition(old_row, 1);
|
|
|
|
for (uint8_t i = 1; i <= old_column; i++)
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
writeCharToLCD(' ');
|
|
|
|
break;
|
|
|
|
case 2: // Clear entire line
|
2015-10-28 05:59:02 +00:00
|
|
|
setCursorPosition(old_row, 1);
|
|
|
|
for (uint8_t i = 1; i <= LCD_CHARACTERS_PER_LINE; i++) {
|
|
|
|
loop_until_LCD_BF_clear();
|
|
|
|
writeCharToLCD_(' ');
|
|
|
|
}
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
break;
|
2015-10-28 05:59:02 +00:00
|
|
|
default: // Invalid argument; do nothing
|
|
|
|
return;
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
}
|
2015-10-28 05:59:02 +00:00
|
|
|
|
|
|
|
setCursorPosition(old_row, old_column);
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void scrollUp(uint8_t n) {
|
2015-10-28 08:40:52 +00:00
|
|
|
#if LCD_NUMBER_OF_LINES == 1
|
|
|
|
clearDisplay();
|
|
|
|
#else
|
|
|
|
if (n >= LCD_NUMBER_OF_LINES) {
|
|
|
|
clearDisplay();
|
|
|
|
} else {
|
|
|
|
uint8_t old_row, old_column;
|
|
|
|
getCursorPosition(&old_row, &old_column);
|
|
|
|
|
|
|
|
uint8_t len = (LCD_NUMBER_OF_LINES - n)*LCD_CHARACTERS_PER_LINE + 1;
|
|
|
|
char str[len];
|
|
|
|
readCharsFromLCD(n + 1, 1, LCD_NUMBER_OF_LINES, LCD_CHARACTERS_PER_LINE, str, len);
|
|
|
|
setCursorPosition(1, 1); // returnHome();
|
|
|
|
writeStringToLCD(str);
|
|
|
|
|
|
|
|
// Add n newlines to bottom of screen
|
|
|
|
for (uint8_t i = 0; i < n; i++) {
|
|
|
|
setCursorPosition(LCD_NUMBER_OF_LINES - i, 1);
|
|
|
|
eraseInline(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
setCursorPosition(old_row, old_column);
|
|
|
|
}
|
|
|
|
#endif
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void scrollDown(uint8_t n) {
|
2015-10-28 08:40:52 +00:00
|
|
|
#if LCD_NUMBER_OF_LINES == 1
|
|
|
|
clearDisplay();
|
|
|
|
#else
|
|
|
|
if (n >= LCD_NUMBER_OF_LINES) {
|
|
|
|
clearDisplay();
|
|
|
|
} else {
|
|
|
|
uint8_t old_row, old_column;
|
|
|
|
getCursorPosition(&old_row, &old_column);
|
|
|
|
|
|
|
|
uint8_t len = (LCD_NUMBER_OF_LINES - n)*LCD_CHARACTERS_PER_LINE + 1;
|
|
|
|
char str[len];
|
|
|
|
readCharsFromLCD(1, 1, LCD_NUMBER_OF_LINES - n, LCD_CHARACTERS_PER_LINE, str, len);
|
|
|
|
|
|
|
|
for (uint8_t column = n + 1, i = 0; column <= LCD_NUMBER_OF_LINES; column++) {
|
|
|
|
setCursorPosition(column , 1);
|
|
|
|
for (uint8_t row = 1; row <= LCD_CHARACTERS_PER_LINE; row++) {
|
|
|
|
loop_until_LCD_BF_clear();
|
|
|
|
writeCharToLCD_(str[i++]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add n newlines to top of screen
|
|
|
|
for (uint8_t i = 1; i <= n; i++) {
|
|
|
|
setCursorPosition(i, 1);
|
|
|
|
eraseInline(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
setCursorPosition(old_row, old_column);
|
|
|
|
}
|
|
|
|
#endif
|
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 <collin.doering@rekahsoft.ca>
2015-10-25 04:27:51 +00:00
|
|
|
}
|
|
|
|
|
2015-10-24 04:42:54 +00:00
|
|
|
void saveCursorPosition() {
|
|
|
|
saveCursorLineNum = currentLineNum;
|
|
|
|
saveCursorLineChars = currentLineChars;
|
|
|
|
}
|
|
|
|
|
|
|
|
void restoreCursorPosition() {
|
|
|
|
currentLineNum = saveCursorLineNum;
|
|
|
|
currentLineChars = saveCursorLineChars;
|
|
|
|
writeLCDInstr(INSTR_DDRAM_ADDR | (lineBeginnings[currentLineNum] + currentLineChars));
|
|
|
|
}
|
2015-10-24 07:45:32 +00:00
|
|
|
|
|
|
|
void hideCursor(void) {
|
|
|
|
lcdState &= ~(1 << INSTR_DISPLAY_C);
|
|
|
|
writeLCDInstr(INSTR_DISPLAY | lcdState);
|
|
|
|
}
|
|
|
|
|
|
|
|
void showCursor(void) {
|
|
|
|
lcdState |= (1 << INSTR_DISPLAY_C);
|
|
|
|
writeLCDInstr(INSTR_DISPLAY | lcdState);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------
|
2015-10-26 08:49:19 +00:00
|
|
|
// Utility functions (with no associated ASCII or ANSI escape)
|
2015-10-24 07:45:32 +00:00
|
|
|
|
|
|
|
void blinkCursorOff(void) {
|
|
|
|
lcdState &= ~(1 << INSTR_DISPLAY_B);
|
|
|
|
writeLCDInstr(INSTR_DISPLAY | lcdState);
|
|
|
|
}
|
|
|
|
|
|
|
|
void blinkCursorOn(void) {
|
|
|
|
lcdState |= (1 << INSTR_DISPLAY_B);
|
|
|
|
writeLCDInstr(INSTR_DISPLAY | lcdState);
|
|
|
|
}
|
|
|
|
|
|
|
|
void displayOff(void) {
|
|
|
|
lcdState &= ~(1 << INSTR_DISPLAY_D);
|
|
|
|
writeLCDInstr(INSTR_DISPLAY | lcdState);
|
|
|
|
}
|
|
|
|
|
|
|
|
void displayOn(void) {
|
|
|
|
lcdState |= (1 << INSTR_DISPLAY_D);
|
|
|
|
writeLCDInstr(INSTR_DISPLAY | lcdState);
|
|
|
|
}
|
|
|
|
|
2015-10-19 09:04:53 +00:00
|
|
|
//-----------------------------------------------------------------------------------------------
|
|
|
|
|
2015-10-28 08:30:40 +00:00
|
|
|
char readCharFromLCD(uint8_t row, uint8_t column) {
|
|
|
|
uint8_t old_row, old_column;
|
|
|
|
getCursorPosition(&old_row, &old_column);
|
|
|
|
|
|
|
|
setCursorPosition(row, column);
|
2015-09-29 06:48:09 +00:00
|
|
|
|
2015-10-28 08:30:40 +00:00
|
|
|
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
|
|
|
setLCDDBusAsInputs();
|
|
|
|
char c = readLCDDBusByte_();
|
|
|
|
setLCDDBusAsOutputs();
|
2015-09-29 06:48:09 +00:00
|
|
|
|
2015-10-28 08:30:40 +00:00
|
|
|
setCursorPosition(old_row, old_column);
|
|
|
|
return c;
|
|
|
|
}
|
2015-09-29 06:48:09 +00:00
|
|
|
|
2015-10-28 08:30:40 +00:00
|
|
|
void readLCDLine(uint8_t i, char* str) {
|
|
|
|
readCharsFromLCD(i, 1, i, LCD_CHARACTERS_PER_LINE, str, LCD_CHARACTERS_PER_LINE + 1);
|
|
|
|
}
|
2015-09-29 06:48:09 +00:00
|
|
|
|
2015-10-26 08:49:19 +00:00
|
|
|
//---------------------------------------------------------------------------------------------
|
|
|
|
// Advanced functions for special cases
|
2015-09-29 06:48:09 +00:00
|
|
|
|
2015-10-28 08:30:40 +00:00
|
|
|
void readCharsFromLCD(uint8_t from_row, uint8_t from_column, uint8_t to_row, uint8_t to_column, char* str, uint8_t len) {
|
|
|
|
uint8_t old_row, old_column;
|
|
|
|
getCursorPosition(&old_row, &old_column);
|
|
|
|
setCursorPosition(from_row, from_column);
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < len - 1 && from_row <= to_row; i++) {
|
|
|
|
if (from_row == LCD_NUMBER_OF_LINES && from_column == LCD_CHARACTERS_PER_LINE) {
|
|
|
|
// Last character on screen
|
|
|
|
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
|
|
|
setLCDDBusAsInputs();
|
|
|
|
*(str++) = readLCDDBusByte_();
|
|
|
|
setLCDDBusAsOutputs();
|
|
|
|
} else if (from_column == LCD_CHARACTERS_PER_LINE) { // End of line (but not last one)
|
|
|
|
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
|
|
|
setLCDDBusAsInputs();
|
|
|
|
*(str++) = readLCDDBusByte_();
|
|
|
|
setLCDDBusAsOutputs();
|
|
|
|
|
|
|
|
from_row += 1;
|
|
|
|
from_column = 1;
|
|
|
|
setCursorPosition(from_row, from_column);
|
|
|
|
} else {
|
|
|
|
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
|
|
|
setLCDDBusAsInputs();
|
|
|
|
*(str++) = readLCDDBusByte_();
|
|
|
|
setLCDDBusAsOutputs();
|
|
|
|
|
|
|
|
from_column++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure array is terminated with null character
|
|
|
|
*str = '\0';
|
|
|
|
|
|
|
|
setCursorPosition(old_row, old_column);
|
|
|
|
setLCDDBusAsOutputs();
|
|
|
|
}
|
|
|
|
|
2015-10-02 07:46:44 +00:00
|
|
|
/*
|
|
|
|
Initialize LCD using the internal reset circuitry.
|
|
|
|
|
|
|
|
Note: This currently only works with 8 bit modes, but is not recommended. Instead use the
|
|
|
|
initLCD function which uses the software initialization method and works for 8-bit
|
|
|
|
modes as well the 4-bit mode.
|
|
|
|
*/
|
2015-09-29 10:06:37 +00:00
|
|
|
void initLCDByInternalReset(void) {
|
2015-10-28 08:30:40 +00:00
|
|
|
setLCDDBusAsOutputs();
|
2015-10-02 07:46:44 +00:00
|
|
|
|
|
|
|
// Function set (8-bit interface; 2 lines with 5x7 dot character font)
|
2015-10-01 07:43:07 +00:00
|
|
|
writeLCDInstr_(INSTR_FUNC_SET | (1 << INSTR_FUNC_SET_DL) | (1 << INSTR_FUNC_SET_N));
|
2015-10-02 07:46:44 +00:00
|
|
|
|
2015-09-29 06:48:09 +00:00
|
|
|
writeLCDInstr_(0x0F);
|
|
|
|
writeLCDInstr_(0x06);
|
2015-10-01 07:43:07 +00:00
|
|
|
writeLCDInstr_(CMD_CLEAR_DISPLAY);
|
|
|
|
_delay_ms(LCD_CLEAR_DISPLAY_DELAY);
|
2015-09-29 06:48:09 +00:00
|
|
|
}
|