Prepare for 4 bit mode of operation
Signed-off-by: Collin J. Doering <collin.doering@rekahsoft.ca>
This commit is contained in:
parent
3ba737fc7b
commit
5777e2b831
156
lcdLib.c
156
lcdLib.c
|
@ -21,8 +21,6 @@
|
|||
* Date: Sep 29, 2015
|
||||
*/
|
||||
|
||||
//#include <avr/interrupt.h>
|
||||
//#include <avr/power.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
// Include header
|
||||
|
@ -42,48 +40,108 @@ void flashLED(uint8_t times) {
|
|||
//------------------------------------
|
||||
|
||||
void clkLCD(void) {
|
||||
LCD_CTRL_PORT |= 1 << LCD_ENABLE;
|
||||
_delay_us(LCD_DELAY);
|
||||
LCD_CTRL_PORT &= ~(1 << LCD_ENABLE);
|
||||
_delay_us(LCD_DELAY);
|
||||
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) {
|
||||
LCD_CTRL_PORT = (LCD_CTRL_PORT & ~(1 << LCD_RS)) | (1 << LCD_RW); // RS=0, RW=1
|
||||
LCD_DBUS_DDR &= ~(1 << LCD_BF); // Set LCD_BF as input
|
||||
LCD_RS_PORT &= ~(1 << LCD_RS); // RS=0
|
||||
LCD_RW_PORT |= (1 << LCD_RW); // RW=1
|
||||
|
||||
// Set LCD_BF as input
|
||||
#ifdef FOUR_BIT_MODE
|
||||
LCD_DBUS7_PORT &= ~(1 << LCD_BF);
|
||||
#else
|
||||
LCD_DBUS_DDR &= ~(1 << LCD_BF);
|
||||
#endif
|
||||
|
||||
STATUS_LED_PORT |= 1 << STATUS_LED; // DEBUG
|
||||
do {
|
||||
clkLCD();
|
||||
} while (bit_is_clear(LCD_DBUS_PIN, LCD_BF));
|
||||
/* loop_until_bit_is_clear(LCD_DBUS_PIN, LCD_BF); */
|
||||
}
|
||||
#ifdef FOUR_BIT_MODE
|
||||
while (bit_is_clear(LCD_DBUS7_PIN, LCD_BF));
|
||||
#else
|
||||
while (bit_is_clear(LCD_DBUS_PIN, LCD_BF));
|
||||
#endif
|
||||
STATUS_LED_PORT &= ~(1 << STATUS_LED); // DEBUG
|
||||
|
||||
|
||||
#ifdef FOUR_BIT_MODE
|
||||
LCD_DBUS7_DDR = 0;
|
||||
LCD_DBUS6_DDR = 0;
|
||||
LCD_DBUS5_DDR = 0;
|
||||
LCD_DBUS4_DDR = 0;
|
||||
#else
|
||||
LCD_DBUS_DDR = 0xff; // Reset all LCD_DBUS_PORT pins as outputs
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FOUR_BIT_MODE
|
||||
/*
|
||||
Writes one nibble to the LCD data bus. Does not touch the RS or RW control lines.
|
||||
Note: the bits that are sent are the four MSBs of the given argument
|
||||
*/
|
||||
void writeLCDNibble_(uint8_t b) {
|
||||
// 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
|
||||
|
||||
/*
|
||||
Write a byte to the LCD data bus. Does not touch the RS or RW control lines.
|
||||
*/
|
||||
void writeLCDByte_(uint8_t b) {
|
||||
LCD_DBUS_PORT = b;
|
||||
clkLCD();
|
||||
}
|
||||
|
||||
void writeLCDInstr_(uint8_t instr) {
|
||||
LCD_CTRL_PORT &= ~((1 << LCD_RS) | (1 << LCD_RW)); // RS=RW=0
|
||||
LCD_RS_PORT &= ~(1 << LCD_RS); // RS=0
|
||||
LCD_RW_PORT &= ~(1 << LCD_RW); // RW=0
|
||||
|
||||
#ifdef FOUR_BIT_MODE
|
||||
writeLCDNibble_(instr);
|
||||
writeLCDNibble_(instr << 4);
|
||||
#else
|
||||
LCD_DBUS_PORT = instr;
|
||||
clkLCD();
|
||||
#endif
|
||||
}
|
||||
|
||||
void writeLCDInstr(uint8_t instr) {
|
||||
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
||||
|
||||
writeLCDInstr_(instr);
|
||||
}
|
||||
|
||||
void writeCharToLCD_(char c) {
|
||||
LCD_CTRL_PORT |= (1 << LCD_RS); // RS=1
|
||||
LCD_CTRL_PORT &= ~(1 << LCD_RW); // RW=0
|
||||
LCD_RS_PORT |= (1 << LCD_RS); // RS=1
|
||||
LCD_RW_PORT &= ~(1 << LCD_RW); // RW=0
|
||||
|
||||
#ifdef FOUR_BIT_MODE
|
||||
writeLCDNibble_(c);
|
||||
writeLCDNibble_(c << 4);
|
||||
#else
|
||||
LCD_DBUS_PORT = c;
|
||||
clkLCD();
|
||||
#endif
|
||||
}
|
||||
|
||||
void writeCharToLCD(char c) {
|
||||
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
||||
|
||||
writeCharToLCD_(c);
|
||||
}
|
||||
|
||||
|
@ -96,49 +154,77 @@ void writeStringToLCD(const char* str) {
|
|||
|
||||
void clearDisplay(void) {
|
||||
writeLCDInstr(CMD_CLEAR_DISPLAY);
|
||||
_delay_us(LCD_CLEAR_DISPLAY_DELAY);
|
||||
}
|
||||
|
||||
void returnHome(void) {
|
||||
writeLCDInstr(CMD_RETURN_HOME);
|
||||
_delay_us(LCD_RETURN_HOME_DELAY);
|
||||
}
|
||||
|
||||
char readCharFromLCD(void) {
|
||||
loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions
|
||||
/* char readCharFromLCD(void) { */
|
||||
/* loop_until_LCD_BF_clear(); // Wait until LCD is ready for new instructions */
|
||||
|
||||
LCD_CTRL_PORT |= (1 << LCD_RW) | (1 << LCD_RW); // RS=RW=1
|
||||
LCD_DBUS_DDR = 0; // Set all LCD_DBUS_PORT pins as inputs
|
||||
clkLCD();
|
||||
/* LCD_CTRL_PORT |= (1 << LCD_RW) | (1 << LCD_RW); // RS=RW=1 */
|
||||
/* LCD_DBUS_DDR = 0; // Set all LCD_DBUS_PORT pins as inputs */
|
||||
/* clkLCD(); */
|
||||
|
||||
char c = LCD_DBUS_PIN;
|
||||
LCD_DBUS_DDR = 0xff; // Reset all LCD_DBUS_PORT pins to outputs
|
||||
return c;
|
||||
}
|
||||
/* char c = LCD_DBUS_PIN; */
|
||||
/* LCD_DBUS_DDR = 0xff; // Reset all LCD_DBUS_PORT pins to outputs */
|
||||
/* return c; */
|
||||
/* } */
|
||||
|
||||
/*
|
||||
Set all pins of LCD_DBUS_PORT, as well as pins LCD_RS, and LCD_RW, on
|
||||
LCD_CTRL_PORT as outputs
|
||||
Set all pins of LCD_DBUS, as well as pins LCD_RS, and LCD_RW as outputs
|
||||
*/
|
||||
static inline void enableLCDOutput(void) {
|
||||
LCD_CTRL_DDR |= (1 << LCD_RS) | (1 << LCD_RW) | (1 << LCD_ENABLE);
|
||||
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_PORT as well as LCD_RS, and LCD_RW on LCD_CTRL_PORT as
|
||||
inputs (disabling their output)
|
||||
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_CTRL_DDR &= ~((1 << LCD_RS) | (1 << LCD_RW) | (1 << LCD_ENABLE));
|
||||
LCD_RS_DDR &= ~(1 << LCD_RS);
|
||||
LCD_RW_DDR &= ~(1 << LCD_RW);
|
||||
LCD_ENABLE_DDR &= ~(1 << LCD_ENABLE);
|
||||
|
||||
#ifdef FOUR_BIT_MODE
|
||||
LCD_DBUS7 &= ~(1 << LCD_DBUS7);
|
||||
LCD_DBUS6 &= ~(1 << LCD_DBUS6);
|
||||
LCD_DBUS5 &= ~(1 << LCD_DBUS5);
|
||||
LCD_DBUS4 &= ~(1 << LCD_DBUS4);
|
||||
#else
|
||||
LCD_DBUS_DDR = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void softwareLCDInitPulse(void) {
|
||||
enableLCDOutput();
|
||||
LCD_CTRL_PORT &= ~((1 << LCD_RS) | (1 << LCD_RW)); // RS=RW=0
|
||||
LCD_RS_PORT &= ~(1 << LCD_RS); // RS=0
|
||||
LCD_RW_PORT &= ~(1 << LCD_RW); // RW=0
|
||||
|
||||
#ifdef FOUR_BIT_MODE
|
||||
writeLCDNibble_(CMD_INIT);
|
||||
#else
|
||||
LCD_DBUS_PORT = CMD_INIT;
|
||||
clkLCD();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -148,7 +234,7 @@ void initLCD (void) {
|
|||
enableLCDOutput();
|
||||
|
||||
// Wait minimum 15ms as per datasheet
|
||||
_delay_ms(LCD_INIT_DELAY0);
|
||||
_delay_us(LCD_INIT_DELAY0);
|
||||
|
||||
softwareLCDInitPulse();
|
||||
|
||||
|
|
165
lcdLib.h
165
lcdLib.h
|
@ -21,37 +21,143 @@
|
|||
* Date: Sep 29, 2015
|
||||
*/
|
||||
|
||||
/*
|
||||
Usage
|
||||
=====
|
||||
|
||||
Operates in 3 mutually exclusive modes:
|
||||
1. Default Mode
|
||||
8-bit mode that requires all its data bus lines be on the same PORT.
|
||||
2. EIGHT_BIT_ARBITRARY_PIN_MODE
|
||||
8-bit mode that allows the data bus lines to use any IO pin.
|
||||
3. FOUR_BIT_MODE
|
||||
4-bit mode that allows the data bus lines to use any IO pin.
|
||||
*/
|
||||
|
||||
// Includes
|
||||
#include <avr/io.h>
|
||||
|
||||
// LCD data bus PORT, PIN and DDR
|
||||
|
||||
/* Modes */
|
||||
|
||||
// Default mode: 8-bit data bus
|
||||
|
||||
// 8-bit mode with data bus on arbitrary pins
|
||||
//#define EIGHT_BIT_ARBITRARY_PIN_MODE
|
||||
|
||||
// LCD in 4-bit mode (default is 8 bit mode)
|
||||
//#define FOUR_BIT_MODE
|
||||
|
||||
// Mode sanity check
|
||||
#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."
|
||||
#endif
|
||||
|
||||
|
||||
/* All mode options */
|
||||
|
||||
#define LCD_RS PD2
|
||||
#define LCD_RS_PORT PORTD
|
||||
#define LCD_RS_DDR DDRD
|
||||
|
||||
#define LCD_RW PD3
|
||||
#define LCD_RW_PORT PORTD
|
||||
#define LCD_RW_DDR DDRD
|
||||
|
||||
#define LCD_ENABLE PD4
|
||||
#define LCD_ENABLE_PORT PORTD
|
||||
#define LCD_ENABLE_DDR DDRD
|
||||
|
||||
/* Mode specific settings */
|
||||
|
||||
// Default Mode
|
||||
// LCD data bus PORT, PIN and DDR.
|
||||
#define LCD_DBUS_PORT PORTB
|
||||
|
||||
#define LCD_DBUS_DDR DDRB
|
||||
#define LCD_DBUS_PIN PINB
|
||||
|
||||
#define LCD_CTRL_PORT PORTD
|
||||
#define LCD_CTRL_DDR DDRD
|
||||
|
||||
#define LCD_RS PD2
|
||||
#define LCD_RW PD3
|
||||
#define LCD_ENABLE PD4
|
||||
|
||||
#define LCD_DBUS0 PB0
|
||||
#define LCD_DBUS1 PB1
|
||||
#define LCD_DBUS2 PB2
|
||||
#define LCD_DBUS3 PB3
|
||||
#define LCD_DBUS4 PB4
|
||||
#define LCD_DBUS5 PB5
|
||||
#define LCD_DBUS6 PB6
|
||||
#define LCD_DBUS7 PB7
|
||||
// This must be set in default mode to the MSB of the data lines
|
||||
#define LCD_BF PB7
|
||||
|
||||
// LCD in 4 bit mode (default is 8 bit mode)
|
||||
//#define FOUR_BIT_MODE
|
||||
|
||||
// LCD delays (in microseconds when unspecified)
|
||||
#define LCD_DELAY 25
|
||||
#define LCD_INIT_DELAY0 15 // milliseconds
|
||||
// EIGHT_BIT_ARBITRARY_PIN_MODE specific settings
|
||||
#ifdef EIGHT_BIT_ARBITRARY_PIN_MODE
|
||||
#define LCD_DBUS0 PB0
|
||||
#define LCD_DBUS0_PORT PORTB
|
||||
#define LCD_DBYS0_DDR DDRB
|
||||
#define LCD_DBUS0_PIN PINB
|
||||
|
||||
#define LCD_DBUS1 PB1
|
||||
#define LCD_DBUS1_PORT PORTB
|
||||
#define LCD_DBUS1_DDR DDRB
|
||||
#define LCD_DBUS1_PIN PINB
|
||||
|
||||
#define LCD_DBUS2 PB2
|
||||
#define LCD_DBUS2_PORT PORTB
|
||||
#define LCD_DBUS2_DDR DDRB
|
||||
#define LCD_DBUS2_PIN PINB
|
||||
|
||||
#define LCD_DBUS3 PB3
|
||||
#define LCD_DBUS3_PORT PORTB
|
||||
#define LCD_DBUS3_DDR DDRB
|
||||
#define LCD_DBUS3_PIN PINB
|
||||
|
||||
#define LCD_DBUS4 PB4
|
||||
#define LCD_DBUS4_PORT PORTB
|
||||
#define LCD_DBUS4_DDR DDRB
|
||||
#define LCD_DBUS4_PIN PINB
|
||||
|
||||
#define LCD_DBUS5 PB5
|
||||
#define LCD_DBUS5_PORT PORTB
|
||||
#define LCD_DBUS5_DDR DDRB
|
||||
#define LCD_DBUS5_PIN PINB
|
||||
|
||||
#define LCD_DBUS6 PB6
|
||||
#define LCD_DBUS6_PORT PORTB
|
||||
#define LCD_DBUS6_DDR DDRB
|
||||
#define LCD_DBUS6_PIN PINB
|
||||
|
||||
#define LCD_DBUS7 PB7
|
||||
#define LCD_DBUS7_PORT PORTB
|
||||
#define LCD_DBUS7_DDR DDRB
|
||||
#define LCD_DBUS7_PIN PINB
|
||||
#endif
|
||||
|
||||
// FOUR_BIT_MODE specific settings
|
||||
#ifdef FOUR_BIT_MODE
|
||||
#define LCD_DBUS4 PB4
|
||||
#define LCD_DBUS4_PORT PORTB
|
||||
#define LCD_DBUS4_DDR DDRB
|
||||
#define LCD_DBUS4_PIN PINB
|
||||
|
||||
#define LCD_DBUS5 PB5
|
||||
#define LCD_DBUS5_PORT PORTB
|
||||
#define LCD_DBUS5_DDR DDRB
|
||||
#define LCD_DBUS5_PIN PINB
|
||||
|
||||
#define LCD_DBUS6 PB6
|
||||
#define LCD_DBUS6_PORT PORTB
|
||||
#define LCD_DBUS6_DDR DDRB
|
||||
#define LCD_DBUS6_PIN PINB
|
||||
|
||||
#define LCD_DBUS7 PB7
|
||||
#define LCD_DBUS7_PORT PORTB
|
||||
#define LCD_DBUS7_DDR DDRB
|
||||
#define LCD_DBUS7_PIN PINB
|
||||
#endif
|
||||
|
||||
#if defined (FOUR_BIT_MODE) || defined (EIGHT_BIT_ARBITRARY_PIN_MODE)
|
||||
#undef LCD_BF
|
||||
#define LCD_BF LCD_DBUS7
|
||||
#endif
|
||||
|
||||
|
||||
/* LCD delays (in microseconds when unspecified) */
|
||||
|
||||
#define LCD_ENABLE_HIGH_DELAY 25
|
||||
#define LCD_ENABLE_LOW_DELAY 25
|
||||
#define LCD_INIT_DELAY0 15000
|
||||
#define LCD_INIT_DELAY1 8200
|
||||
#define LCD_INIT_DELAY2 200
|
||||
|
||||
|
@ -59,6 +165,7 @@
|
|||
#define LCD_RETURN_HOME_DELAY 16000
|
||||
#define LCD_GENERIC_INSTR_DELAY 50
|
||||
|
||||
|
||||
/* LCD Commands */
|
||||
|
||||
// Simple commands with no options
|
||||
|
@ -110,15 +217,21 @@ void clkLCD(void);
|
|||
|
||||
void loop_until_LCD_BF_clear(void);
|
||||
|
||||
void writeLCDInstr_(uint8_t instr);
|
||||
#ifdef FOUR_BIT_MODE
|
||||
void writeLCDNibble_(uint8_t);
|
||||
#endif
|
||||
|
||||
void writeLCDInstr(uint8_t instr);
|
||||
void writeLCDByte_(uint8_t);
|
||||
|
||||
void writeCharToLCD_(char c);
|
||||
void writeLCDInstr_(uint8_t);
|
||||
|
||||
void writeCharToLCD(char c);
|
||||
void writeLCDInstr(uint8_t);
|
||||
|
||||
void writeStringToLCD(const char* str);
|
||||
void writeCharToLCD_(char);
|
||||
|
||||
void writeCharToLCD(char);
|
||||
|
||||
void writeStringToLCD(const char*);
|
||||
|
||||
void clearDisplay(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue