Refactor, tidy and comment
Signed-off-by: Collin J. Doering <collin.doering@rekahsoft.ca>
This commit is contained in:
parent
7977f14d5a
commit
827989bd51
357
lcdLib.c
357
lcdLib.c
@ -21,33 +21,46 @@
|
||||
* Date: Sep 29, 2015
|
||||
*/
|
||||
|
||||
// Includes -----------------------------------------------------------------------------------
|
||||
#include <math.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
// Include header
|
||||
#include "lcdLib.h"
|
||||
|
||||
// Globals
|
||||
volatile uint8_t currentLineNum;
|
||||
volatile uint8_t currentLineChars;
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// Static global variables
|
||||
|
||||
volatile uint8_t saveCursorLineNum;
|
||||
volatile uint8_t saveCursorLineChars;
|
||||
static volatile uint8_t currentLineNum;
|
||||
static volatile uint8_t currentLineChars;
|
||||
|
||||
volatile uint8_t lcdState;
|
||||
static volatile uint8_t saveCursorLineNum;
|
||||
static volatile uint8_t saveCursorLineChars;
|
||||
|
||||
const uint8_t lineBeginnings[LCD_NUMBER_OF_LINES] = { LCD_LINE_BEGINNINGS };
|
||||
static volatile uint8_t lcdState;
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Function definitions
|
||||
static const uint8_t lineBeginnings[LCD_NUMBER_OF_LINES] = { LCD_LINE_BEGINNINGS };
|
||||
|
||||
void clkLCD(void) {
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// 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) {
|
||||
LCD_ENABLE_PORT |= (1 << LCD_ENABLE);
|
||||
_delay_us(LCD_ENABLE_HIGH_DELAY);
|
||||
LCD_ENABLE_PORT &= ~(1 << LCD_ENABLE);
|
||||
_delay_us(LCD_ENABLE_LOW_DELAY);
|
||||
}
|
||||
|
||||
void loop_until_LCD_BF_clear(void) {
|
||||
/*
|
||||
Wait until LCD_BF (busy flag) is cleared (low).
|
||||
*/
|
||||
static void loop_until_LCD_BF_clear(void) {
|
||||
uint8_t bf;
|
||||
|
||||
LCD_RS_PORT &= ~(1 << LCD_RS); // RS=0
|
||||
@ -90,8 +103,13 @@ void loop_until_LCD_BF_clear(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
#ifdef FOUR_BIT_MODE
|
||||
void writeLCDDBusNibble_(uint8_t b) {
|
||||
static void writeLCDDBusNibble_(uint8_t b) {
|
||||
// Reset data lines to zeros
|
||||
LCD_DBUS7_PORT &= ~(1 << LCD_DBUS7);
|
||||
LCD_DBUS6_PORT &= ~(1 << LCD_DBUS6);
|
||||
@ -109,7 +127,17 @@ void writeLCDDBusNibble_(uint8_t b) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void writeLCDDBusByte_(uint8_t b) {
|
||||
/*
|
||||
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) {
|
||||
#ifdef FOUR_BIT_MODE
|
||||
writeLCDDBusNibble_(b);
|
||||
writeLCDDBusNibble_(b << 4);
|
||||
@ -141,25 +169,26 @@ void writeLCDDBusByte_(uint8_t b) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void writeLCDDBusByte(uint8_t b) {
|
||||
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
||||
writeLCDDBusByte_(b);
|
||||
}
|
||||
|
||||
/*
|
||||
Sets RS=RW=0 and writes the given 8 bit integer to the LCD databus. 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.
|
||||
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.
|
||||
*/
|
||||
void writeLCDInstr_(uint8_t instr) {
|
||||
static void writeLCDInstr_(uint8_t instr) {
|
||||
LCD_RS_PORT &= ~(1 << LCD_RS); // RS=0
|
||||
LCD_RW_PORT &= ~(1 << LCD_RW); // RW=0
|
||||
|
||||
writeLCDDBusByte_(instr);
|
||||
}
|
||||
|
||||
void writeLCDInstr(uint8_t instr) {
|
||||
/*
|
||||
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) {
|
||||
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
||||
writeLCDInstr_(instr);
|
||||
}
|
||||
@ -170,13 +199,150 @@ void writeLCDInstr(uint8_t instr) {
|
||||
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.
|
||||
*/
|
||||
void writeCharToLCD_(char c) {
|
||||
static void writeCharToLCD_(char c) {
|
||||
LCD_RS_PORT |= (1 << LCD_RS); // RS=1
|
||||
LCD_RW_PORT &= ~(1 << LCD_RW); // RW=0
|
||||
|
||||
writeLCDDBusByte_(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* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
Set all pins of LCD_DBUS, as well as pins LCD_RS, and LCD_RW as outputs
|
||||
*/
|
||||
static inline void enableLCDOutput(void) {
|
||||
LCD_RS_DDR |= (1 << LCD_RS);
|
||||
LCD_RW_DDR |= (1 << LCD_RW);
|
||||
LCD_ENABLE_DDR |= (1 << LCD_ENABLE);
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
/*
|
||||
Set all pins of LCD_DBUS as well as LCD_RS, and LCD_RW as inputs (disabling their output)
|
||||
*/
|
||||
static inline void disableLCDOutput(void) {
|
||||
LCD_RS_DDR &= ~(1 << LCD_RS);
|
||||
LCD_RW_DDR &= ~(1 << LCD_RW);
|
||||
LCD_ENABLE_DDR &= ~(1 << LCD_ENABLE);
|
||||
|
||||
#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) {
|
||||
enableLCDOutput();
|
||||
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) {
|
||||
enableLCDOutput();
|
||||
|
||||
_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)
|
||||
// Function Set (4-bit interface; 2 lines with 5x7 dot character font)
|
||||
writeLCDDBusNibble_(CMD_INIT_FOUR_BIT);
|
||||
writeLCDInstr_(CMD_INIT_FOUR_BIT | (1 << INSTR_FUNC_SET_N));
|
||||
#else
|
||||
// Function set (8-bit interface; 2 lines with 5x7 dot character font)
|
||||
// RS=RW=0, DBUS=b00111000,0x38
|
||||
writeLCDInstr_(INSTR_FUNC_SET | (1 << INSTR_FUNC_SET_DL) | (1 << INSTR_FUNC_SET_N));
|
||||
#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);
|
||||
}
|
||||
|
||||
/*
|
||||
Given a single character, checks whether its a ASCII escape and does the following:
|
||||
|
||||
@ -252,36 +418,6 @@ 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* 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];
|
||||
|
||||
*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;
|
||||
}
|
||||
|
||||
void writeStringToLCD(char* str) {
|
||||
while (*str != '\0') {
|
||||
// Check for ANSI CSI (Control Sequence Introducer)
|
||||
@ -428,6 +564,9 @@ void writeStringToLCD(char* str) {
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// LCD command functions (all have associated ANSI escape)
|
||||
|
||||
/*
|
||||
Writes the CMD_CLEAR_DISPLAY command to the LCD using writeLCDINSTR, and clears the local
|
||||
char and line counters.
|
||||
@ -610,6 +749,7 @@ void showCursor(void) {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Utility functions (with no associated ASCII or ANSI escape)
|
||||
|
||||
void blinkCursorOff(void) {
|
||||
lcdState &= ~(1 << INSTR_DISPLAY_B);
|
||||
@ -645,110 +785,9 @@ void displayOn(void) {
|
||||
/* return c; */
|
||||
/* } */
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Set all pins of LCD_DBUS, as well as pins LCD_RS, and LCD_RW as outputs
|
||||
*/
|
||||
static inline void enableLCDOutput(void) {
|
||||
LCD_RS_DDR |= (1 << LCD_RS);
|
||||
LCD_RW_DDR |= (1 << LCD_RW);
|
||||
LCD_ENABLE_DDR |= (1 << LCD_ENABLE);
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
/*
|
||||
Set all pins of LCD_DBUS as well as LCD_RS, and LCD_RW as inputs (disabling their output)
|
||||
*/
|
||||
static inline void disableLCDOutput(void) {
|
||||
LCD_RS_DDR &= ~(1 << LCD_RS);
|
||||
LCD_RW_DDR &= ~(1 << LCD_RW);
|
||||
LCD_ENABLE_DDR &= ~(1 << LCD_ENABLE);
|
||||
|
||||
#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) {
|
||||
enableLCDOutput();
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
Do software initialization as specified by the datasheet
|
||||
*/
|
||||
void initLCD (void) {
|
||||
enableLCDOutput();
|
||||
|
||||
_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)
|
||||
// Function Set (4-bit interface; 2 lines with 5x7 dot character font)
|
||||
writeLCDDBusNibble_(CMD_INIT_FOUR_BIT);
|
||||
writeLCDInstr_(CMD_INIT_FOUR_BIT | (1 << INSTR_FUNC_SET_N));
|
||||
#else
|
||||
// Function set (8-bit interface; 2 lines with 5x7 dot character font)
|
||||
// RS=RW=0, DBUS=b00111000,0x38
|
||||
writeLCDInstr_(INSTR_FUNC_SET | (1 << INSTR_FUNC_SET_DL) | (1 << INSTR_FUNC_SET_N));
|
||||
#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);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// Advanced functions for special cases
|
||||
|
||||
/*
|
||||
Initialize LCD using the internal reset circuitry.
|
||||
|
229
lcdLib.h
229
lcdLib.h
@ -22,116 +22,20 @@
|
||||
* @brief Functions to initialize, and operate a character LCD.
|
||||
*/
|
||||
|
||||
// Includes -------------------------------------------------------------------------------
|
||||
#ifndef LCD_LIB_H
|
||||
#define LCD_LIB_H
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <math.h>
|
||||
// Includes -----------------------------------------------------------------------------------
|
||||
#include "lcd_instr.h"
|
||||
#include "lcdLibConfig.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
/* LCD Commands */
|
||||
|
||||
// Simple commands with no options
|
||||
#define CMD_INIT 0x30
|
||||
#define CMD_INIT_FOUR_BIT 0x20
|
||||
#define CMD_CLEAR_DISPLAY 0x01
|
||||
#define CMD_RETURN_HOME 0x02
|
||||
|
||||
// Entry Set instruction and associated options
|
||||
#define INSTR_ENTRY_SET 0x04
|
||||
#define INSTR_ENTRY_SET_ID 1
|
||||
#define INSTR_ENTRY_SET_S 0
|
||||
|
||||
// Display control instruction and associated options
|
||||
#define INSTR_DISPLAY 0x08
|
||||
#define INSTR_DISPLAY_D 2
|
||||
#define INSTR_DISPLAY_C 1
|
||||
#define INSTR_DISPLAY_B 0
|
||||
|
||||
// Cursor or display shift instruction and associated options
|
||||
#define INSTR_MOV_SHIFT 0x10
|
||||
#define INSTR_MOV_SHIFT_SC 3
|
||||
#define INSTR_MOV_SHIFT_RL 2
|
||||
|
||||
// Function set instruction and associated options
|
||||
#define INSTR_FUNC_SET 0x20
|
||||
#define INSTR_FUNC_SET_DL 4
|
||||
#define INSTR_FUNC_SET_N 3
|
||||
#define INSTR_FUNC_SET_F 2
|
||||
|
||||
// Set CG RAM address instruction
|
||||
#define INSTR_CGRAM_ADDR 0x60
|
||||
|
||||
// Set DD RAM address instruction
|
||||
#define INSTR_DDRAM_ADDR 0x80
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
|
||||
#define LCD_CHARACTERS_PER_SCREEN (LCD_CHARACTERS_PER_LINE * LCD_NUMBER_OF_LINES)
|
||||
|
||||
|
||||
//------------------------------------
|
||||
// Function definitions
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// Library function declarations
|
||||
|
||||
/**
|
||||
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
|
||||
Initialize the LCD display via software initialization as specified by the datasheet.
|
||||
*/
|
||||
void clkLCD(void);
|
||||
|
||||
/**
|
||||
Wait until LCD_BF (busy flag) is cleared (low).
|
||||
*/
|
||||
void loop_until_LCD_BF_clear(void);
|
||||
|
||||
/**
|
||||
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
|
||||
*/
|
||||
#ifdef FOUR_BIT_MODE
|
||||
void writeLCDDBusNibble_(uint8_t);
|
||||
#endif
|
||||
|
||||
/**
|
||||
Given an 8 bit integer, writes it to the LCD data bus.
|
||||
|
||||
This function does not ensure the LCD is ready to accept new data and thus needs to
|
||||
be handled by the caller.
|
||||
*/
|
||||
void writeLCDDBusByte_(uint8_t);
|
||||
|
||||
/**
|
||||
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).
|
||||
*/
|
||||
void writeLCDDBusByte(uint8_t b);
|
||||
|
||||
/**
|
||||
Given a 8 bit integer representing a LCD instruction, sends it to the LCD display.
|
||||
|
||||
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.
|
||||
*/
|
||||
void writeLCDInstr_(uint8_t);
|
||||
|
||||
/**
|
||||
Given a 8 bit integer representing a LCD instruction, waits until the LCD is ready and sends
|
||||
the instruction.
|
||||
*/
|
||||
void writeLCDInstr(uint8_t);
|
||||
|
||||
/**
|
||||
Writes a character to the LCD display at the current cursor position.
|
||||
|
||||
Note that this function does not ensure the LCD is ready to accept a new character and thus
|
||||
needs to be handled by the caller.
|
||||
*/
|
||||
void writeCharToLCD_(char);
|
||||
void initLCD(void);
|
||||
|
||||
/**
|
||||
Writes a character to the LCD display at the current cursor position after the LCD display is
|
||||
@ -145,18 +49,8 @@ void writeCharToLCD(char);
|
||||
*/
|
||||
void writeStringToLCD(char*);
|
||||
|
||||
/**
|
||||
Saves the cursors current position.
|
||||
*/
|
||||
void saveCursorPosition(void);
|
||||
|
||||
/**
|
||||
Restores the last saved cursor position.
|
||||
*/
|
||||
void restoreCursorPosition(void);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// LCD command functions
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// LCD command functions (all have associated ANSI escape)
|
||||
|
||||
/**
|
||||
Clears the display and positions the cursor in the top left of the LCD screen.
|
||||
@ -169,12 +63,14 @@ void clearDisplay(void);
|
||||
void returnHome(void);
|
||||
|
||||
/**
|
||||
Gets the current row and column of the LCD cursor.
|
||||
Gets the current row and column of the LCD cursor and sets given pointers row and column to
|
||||
their respective values. Note indexes start at 1.
|
||||
*/
|
||||
void getCursorPosition(uint8_t* row, uint8_t* column);
|
||||
|
||||
/**
|
||||
Sets given pointers row and column to the current row and column occupied by the LCD cursor.
|
||||
Using the given parameters row and column, sets the current row and column occupied by the LCD
|
||||
cursor. Note indexes start at 1.
|
||||
*/
|
||||
void setCursorPosition(uint8_t row, uint8_t column);
|
||||
|
||||
@ -223,6 +119,16 @@ void scrollUp(uint8_t n);
|
||||
*/
|
||||
void scrollDown(uint8_t n);
|
||||
|
||||
/**
|
||||
Saves the cursors current position.
|
||||
*/
|
||||
void saveCursorPosition(void);
|
||||
|
||||
/**
|
||||
Restores the last saved cursor position.
|
||||
*/
|
||||
void restoreCursorPosition(void);
|
||||
|
||||
/**
|
||||
Clears part or all of screen dependent on the value of n:
|
||||
0 or missing: clear from cursor to end of screen
|
||||
@ -249,7 +155,8 @@ void hideCursor(void);
|
||||
*/
|
||||
void showCursor(void);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// Utility functions (with no associated ASCII or ANSI escape)
|
||||
|
||||
/**
|
||||
Turns the cursor blink off.
|
||||
@ -271,19 +178,17 @@ void displayOff(void);
|
||||
*/
|
||||
void displayOn(void);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
UNIMPLEMENTED
|
||||
*/
|
||||
char readCharFromLCD(void);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initialize the LCD display via software initialization as specified by the datasheet.
|
||||
*/
|
||||
void initLCD(void);
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// Advanced functions for special cases
|
||||
|
||||
/**
|
||||
Initialize the LCD display via its internal reset circuit.
|
||||
@ -294,29 +199,78 @@ void initLCD(void);
|
||||
*/
|
||||
void initLCDByInternalReset(void);
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Mode and settings sanity check
|
||||
*/
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// Mode and settings sanity check (preprocessor tests of lcdLibConfig.h)
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
#if !defined (LCD_RS) || !defined (LCD_RS_PORT) || !defined (LCD_RS_DDR) || !defined (LCD_RW) || !defined (LCD_RW_PORT) || !defined (LCD_RW_DDR) || !defined (LCD_ENABLE) || !defined (LCD_ENABLE_PORT) || !defined (LCD_ENABLE_DDR)
|
||||
#if !defined(LCD_CHARACTERS_PER_LINE)
|
||||
#error "All modes require LCD_CHARACTERS_PER_LINE to be defined."
|
||||
#elif !defined(LCD_NUMBER_OF_LINES)
|
||||
#error "All modes require LCD_NUMBER_OF_LINES to be defined."
|
||||
#elif !defined(LCD_LINE_BEGINNINGS)
|
||||
#error "All modes require LCD_LINE_BEGINNINGS to be defined."
|
||||
#else
|
||||
#define LCD_CHARACTERS_PER_SCREEN (LCD_CHARACTERS_PER_LINE * LCD_NUMBER_OF_LINES)
|
||||
#endif
|
||||
|
||||
#if !defined (LCD_RS) || \
|
||||
!defined (LCD_RS_PORT) || \
|
||||
!defined (LCD_RS_DDR) || \
|
||||
!defined (LCD_RW) || \
|
||||
!defined (LCD_RW_PORT) || \
|
||||
!defined (LCD_RW_DDR) || \
|
||||
!defined (LCD_ENABLE) || \
|
||||
!defined (LCD_ENABLE_PORT) || \
|
||||
!defined (LCD_ENABLE_DDR)
|
||||
#error "All modes require LCD_RS[,_PORT,_DDR], LCD_RW[,_PORT,_DDR], and LCD_ENABLE[,_PORT,_DDR] be defined."
|
||||
#endif
|
||||
|
||||
#if defined (EIGHT_BIT_ARBITRARY_PIN_MODE) && defined (FOUR_BIT_MODE)
|
||||
#if defined (EIGHT_BIT_ARBITRARY_PIN_MODE) && \
|
||||
defined (FOUR_BIT_MODE)
|
||||
#error "EIGHT_BIT_ARBITRARY_PIN_MODE and FOUR_BIT_MODE are mutually exclusive. Choose one."
|
||||
#elif defined (EIGHT_BIT_ARBITRARY_PIN_MODE) || defined (FOUR_BIT_MODE)
|
||||
#elif defined (EIGHT_BIT_ARBITRARY_PIN_MODE) || \
|
||||
defined (FOUR_BIT_MODE)
|
||||
|
||||
// EIGHT_BIT_ARBITRARY_PIN_MODE specific requirements
|
||||
#ifdef EIGHT_BIT_ARBITRARY_PIN_MODE
|
||||
#if !defined (LCD_DBUS0) || !defined (LCD_DBUS0_PORT) || !defined (LCD_DBUS0_DDR) || !defined (LCD_DBUS0_PIN) || !defined (LCD_DBUS1) || !defined (LCD_DBUS1_PORT) || !defined (LCD_DBUS1_DDR) || !defined (LCD_DBUS1_PIN) || !defined (LCD_DBUS2) || !defined (LCD_DBUS2_PORT) || !defined (LCD_DBUS2_DDR) || !defined (LCD_DBUS2_PIN) || !defined (LCD_DBUS3) || !defined (LCD_DBUS3_PORT) || !defined (LCD_DBUS3_DDR) || !defined (LCD_DBUS3_PIN)
|
||||
#if !defined (LCD_DBUS0) || \
|
||||
!defined (LCD_DBUS0_PORT) || \
|
||||
!defined (LCD_DBUS0_DDR) || \
|
||||
!defined (LCD_DBUS0_PIN) || \
|
||||
!defined (LCD_DBUS1) || \
|
||||
!defined (LCD_DBUS1_PORT) || \
|
||||
!defined (LCD_DBUS1_DDR) || \
|
||||
!defined (LCD_DBUS1_PIN) || \
|
||||
!defined (LCD_DBUS2) || \
|
||||
!defined (LCD_DBUS2_PORT) || \
|
||||
!defined (LCD_DBUS2_DDR) || \
|
||||
!defined (LCD_DBUS2_PIN) || \
|
||||
!defined (LCD_DBUS3) || \
|
||||
!defined (LCD_DBUS3_PORT) || \
|
||||
!defined (LCD_DBUS3_DDR) || \
|
||||
!defined (LCD_DBUS3_PIN)
|
||||
#error "EIGHT_BIT_ARBITRARY_PIN_MODE require that LCD_DBUS*[,_PORT,_DDR,_PIN] be defined."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Requirements for EIGHT_BIT_ARBITRARY_PIN_MODE and FOUR_BIT_MODE
|
||||
#if !defined (LCD_DBUS4) || !defined (LCD_DBUS4_PORT) || !defined (LCD_DBUS4_DDR) || !defined (LCD_DBUS4_PIN) || !defined (LCD_DBUS5) || !defined (LCD_DBUS5_PORT) || !defined (LCD_DBUS5_DDR) || !defined (LCD_DBUS5_PIN) || !defined (LCD_DBUS6) || !defined (LCD_DBUS6_PORT) || !defined (LCD_DBUS6_DDR) || !defined (LCD_DBUS6_PIN) || !defined (LCD_DBUS7) || !defined (LCD_DBUS7_PORT) || !defined (LCD_DBUS7_DDR) || !defined (LCD_DBUS7_PIN)
|
||||
#if !defined (LCD_DBUS4) || \
|
||||
!defined (LCD_DBUS4_PORT) || \
|
||||
!defined (LCD_DBUS4_DDR) || \
|
||||
!defined (LCD_DBUS4_PIN) || \
|
||||
!defined (LCD_DBUS5) || \
|
||||
!defined (LCD_DBUS5_PORT) || \
|
||||
!defined (LCD_DBUS5_DDR) || \
|
||||
!defined (LCD_DBUS5_PIN) || \
|
||||
!defined (LCD_DBUS6) || \
|
||||
!defined (LCD_DBUS6_PORT) || \
|
||||
!defined (LCD_DBUS6_DDR) || \
|
||||
!defined (LCD_DBUS6_PIN) || \
|
||||
!defined (LCD_DBUS7) || \
|
||||
!defined (LCD_DBUS7_PORT) || \
|
||||
!defined (LCD_DBUS7_DDR) || \
|
||||
!defined (LCD_DBUS7_PIN)
|
||||
#error "Both EIGHT_BIT_ARBITRARY_PIN_MODE and FOUR_BIT_MODE require that LCD_DBUS*[,_PORT,_DDR,_PIN] be defined."
|
||||
#endif
|
||||
|
||||
@ -325,7 +279,10 @@ void initLCDByInternalReset(void);
|
||||
#define LCD_BF LCD_DBUS7
|
||||
|
||||
#else
|
||||
#if !defined (LCD_DBUS_PORT) || !defined (LCD_DBUS_DDR) || !defined (LCD_DBUS_PIN) || !defined (LCD_BF)
|
||||
#if !defined (LCD_DBUS_PORT) || \
|
||||
!defined (LCD_DBUS_DDR) || \
|
||||
!defined (LCD_DBUS_PIN) || \
|
||||
!defined (LCD_BF)
|
||||
#error "Default mode requires that LCD_DBUS_[PORT,DDR,PIN] and LCD_BF be defined."
|
||||
#endif
|
||||
|
||||
@ -336,3 +293,5 @@ void initLCDByInternalReset(void);
|
||||
#undef LCD_DBUS7_PIN
|
||||
#define LCD_DBUS7_PIN LCD_DBUS_PIN
|
||||
#endif
|
||||
|
||||
#endif /* LCD_LIB_H */
|
||||
|
61
lcd_instr.h
Normal file
61
lcd_instr.h
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* (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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lcd_instr.h
|
||||
* @author Collin J. Doering <collin.doering@rekahsoft.ca>
|
||||
* @date Oct 26, 2015
|
||||
* @brief Constant macro definitions of HD44780 compatible character LCD instruction set
|
||||
*/
|
||||
|
||||
/*
|
||||
LCD character display instructions
|
||||
*/
|
||||
|
||||
// Simple instructions with no options
|
||||
#define CMD_INIT 0x30
|
||||
#define CMD_INIT_FOUR_BIT 0x20
|
||||
#define CMD_CLEAR_DISPLAY 0x01
|
||||
#define CMD_RETURN_HOME 0x02
|
||||
|
||||
// Entry Set instruction and associated options
|
||||
#define INSTR_ENTRY_SET 0x04
|
||||
#define INSTR_ENTRY_SET_ID 1
|
||||
#define INSTR_ENTRY_SET_S 0
|
||||
|
||||
// Display control instruction and associated options
|
||||
#define INSTR_DISPLAY 0x08
|
||||
#define INSTR_DISPLAY_D 2
|
||||
#define INSTR_DISPLAY_C 1
|
||||
#define INSTR_DISPLAY_B 0
|
||||
|
||||
// Cursor or display shift instruction and associated options
|
||||
#define INSTR_MOV_SHIFT 0x10
|
||||
#define INSTR_MOV_SHIFT_SC 3
|
||||
#define INSTR_MOV_SHIFT_RL 2
|
||||
|
||||
// Function set instruction and associated options
|
||||
#define INSTR_FUNC_SET 0x20
|
||||
#define INSTR_FUNC_SET_DL 4
|
||||
#define INSTR_FUNC_SET_N 3
|
||||
#define INSTR_FUNC_SET_F 2
|
||||
|
||||
// Set CG RAM address instruction
|
||||
#define INSTR_CGRAM_ADDR 0x60
|
||||
|
||||
// Set DD RAM address instruction
|
||||
#define INSTR_DDRAM_ADDR 0x80
|
Loading…
Reference in New Issue
Block a user