Refactor, tidy and comment

Signed-off-by: Collin J. Doering <collin.doering@rekahsoft.ca>
This commit is contained in:
Collin J. Doering 2015-10-26 04:49:19 -04:00
parent 7977f14d5a
commit 827989bd51
3 changed files with 354 additions and 295 deletions

357
lcdLib.c
View File

@ -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
View File

@ -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
View 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