HD44780 keypad update. (second try)

This commit is contained in:
robijn
2001-10-05 21:01:24 +00:00
parent 4829ed367f
commit 16cce2fe2d
4 changed files with 355 additions and 141 deletions
+12 -5
View File
@@ -6,7 +6,8 @@
enum ifWidth { IF_4bit, IF_8bit };
void common_init (enum ifWidth ifwidth);
//void common_init (enum ifWidth ifwidth);
void common_init ();
// Structures holding pointers to HD44780 specific functions
typedef struct hwDependentFns {
@@ -16,7 +17,7 @@ typedef struct hwDependentFns {
// senddata to the LCD
// dispID - display to send data to (0 = all displays)
// flags - data or instruction command (RS_DATA | RS_INSTR)
// ch - character to display or instruction value
// ch - character to display or instruction value
void (*senddata) (unsigned char dispID, unsigned char flags, unsigned char ch);
// position the cursor
@@ -25,8 +26,14 @@ typedef struct hwDependentFns {
void (*position) (int dispID, int DDaddr);
// toggle vertical autoscroll on all displays
// on - non-zero turns autoscroll on, zero value turns it off
// on - non-zero turns autoscroll on, zero value turns it off
void (*autoscroll) (int on);
// read the keypad
// Ydata - the up to 11 bits that should be put on the Y side of the matrix
// return - the up to 5 bits that are read out on the X side of the matrix
unsigned char (*readkeypad) (unsigned int Ydata);
} HD44780_functions; /* for want of a better name :-) */
extern HD44780_functions *hd44780_functions;
@@ -81,7 +88,7 @@ extern HD44780_functions *hd44780_functions;
#define nSEL 0x08
#define SEL 0x08
#define OUTMASK 0x0B
#define OUTMASK 0x0B /* SEL, LF and STRB are hardware inverted */
// Input lines
#define nFAULT 0x08
@@ -92,6 +99,6 @@ extern HD44780_functions *hd44780_functions;
#define ACK 0x40
#define BUSY 0x80
#define INMASK 0x48
#define INMASK 0x84 /* BUSY input and the IRQ indicator are inverted */
#endif
+102 -49
View File
@@ -4,82 +4,118 @@
* 4094 shift register and supports a keypad.
*
* Copyright (c) 1999 Andrew McMeikan <andrewm@engineer.com>
* modular driver 1999 Benjamin Tse <blt@Comports.com>
* modular driver 1999 Benjamin Tse <blt@Comports.com>
*
* 2001 Joris Robijn <joris@robijn.net>
* - Keypad support
* - Changed for 2 line wire control
*
* Full connection details at http://members.xoom.com/andrewmuck/LCD.htm
*
* printer port 4094/LCD
* printer port 4094/LCD
* D2 (4) EN (6 - LCD)
* D3 (5) D (2 - 4094)
* D4 (6) CLK (3 - 4094)
* +Vcc OE, STR (15, 1 - 4094)
* +Vcc OE, STR (15, 1 - 4094)
* D7 (9) EN2 (6 - LCD2) (optional)
*
* 4094 LCD
* 4094 LCD
* Q1 (4) D4 (11)
* Q2 (5) D5 (12)
* Q3 (6) D6 (13)
* Q4 (7) D7 (14)
* Q6 (13) RS (4)
* Gnd nRW (5)
* Gnd nRW (5)
*
* Keypad connection (optional):
* This is connected on the 4094 parallel to the LCD.
* Some diodes and resistors are needed, see further documentation.
* Q1 (4) Y0
* Q2 (5) Y1
* Q3 (6) Y2
* Q4 (7) Y3
* Q5 (14) Y4
* Q6 (13) Y5
* The 'output' of the keys should be connected to the following LPT pins:
* nACK (10) X0
* BUSY (11) X1
* PAPEREND (12) X2
* SELIN (13) X3
* nFAULT (15) X4
* If you want to use as few LPT lines as possible, only use X0.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*/
#include "hd44780-serialLpt.h"
#include "hd44780.h"
#include "port.h"
#include "shared/str.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "hd44780-serialLpt.h"
#include "port.h"
// Hardware specific functions
void lcdserLpt_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch);
unsigned char lcdserLpt_HD44780_readkeypad (unsigned int YData);
static char lcdserLpt_HD44780_getkey (void);
static char lcdserLpt_HD44780_getkey (void); // old keypad code
void rawshift (unsigned char r);
void shiftreg (unsigned char displayID, unsigned char r);
#define RS 16
#define LCDDATA 8
#define RS 32
#define LCDDATA 8
#define LCDCLOCK 16
#define EN1 4
#define EN2 32
#define EN1 4
#define EN2 32
static unsigned int lp;
static char lastkey = 0;
static unsigned int lptPort;
static char keypad;
static char stuckinputs = 0; // if an input line is stuck, it will be ignored
static char lastkey = 0; // currently not in use, old keypad code
// Initialisation
int
hd_init_serialLpt (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port)
{
int displayID = EN1 | EN2;
unsigned char enableLines = EN1 | EN2;
lp = port;
if (port_access (lp) || port_access (lp +1)) {
fprintf (stderr, "HD44780_init: failed (%s)\n", strerror (errno));
return( -1 );
};
// Reserve the port registers
lptPort = port;
port_access(lptPort);
port_access(lptPort+1);
port_access(lptPort+2);
hd44780_functions->senddata = lcdserLpt_HD44780_senddata;
hd44780_functions->readkeypad = lcdserLpt_HD44780_readkeypad;
// TODO: enable keypad only if specified on command line
driver->getkey = lcdserLpt_HD44780_getkey;
if (keypad) {
driver->getkey = lcdserLpt_HD44780_getkey;
}
// Clear the shiftregister
rawshift (0);
// setup the lcd in 4 bit mode
shiftreg (displayID, 3);
shiftreg (enableLines, 3);
hd44780_functions->uPause (4100);
shiftreg (displayID, 3);
shiftreg (enableLines, 3);
hd44780_functions->uPause (100);
shiftreg (displayID, 3);
shiftreg (enableLines, 3);
hd44780_functions->uPause (40);
shiftreg (displayID, 2);
shiftreg (enableLines, 2);
hd44780_functions->uPause (40);
hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_4BIT | TWOLINE | SMALLCHAR);
common_init ();
/*
// set display type functions
lcdserLpt_HD44780_senddata (0, RS_INSTR, FUNCSET | IF_4BIT | TWOLINE | SMALLCHAR);
// clear
@@ -88,6 +124,7 @@ hd_init_serialLpt (HD44780_functions * hd44780_functions, lcd_logical_driver * d
// Now turn on the display
lcdserLpt_HD44780_senddata (displayID, RS_INSTR, ONOFFCTRL | DISPON | CURSOROFF | CURSORNOBLINK);
hd44780_functions->uPause (1600);
*/
return 0;
}
@@ -95,22 +132,24 @@ hd_init_serialLpt (HD44780_functions * hd44780_functions, lcd_logical_driver * d
void
lcdserLpt_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch)
{
unsigned char dispID = 0, portControl = 0, h = ch >> 4, l = ch & 15;
unsigned char enableLines;
unsigned char portControl = 0;
unsigned char h = ch >> 4, l = ch & 15;
if (displayID == 1)
dispID |= EN1;
enableLines = EN1;
else if (displayID == 2)
dispID |= EN2;
enableLines = EN2;
else
dispID |= EN1 | EN2;
enableLines = EN1 | EN2;
if (flags == RS_DATA)
portControl = RS;
else
portControl = 0;
shiftreg (displayID, flags | portControl | h);
shiftreg (displayID, flags | portControl | l);
shiftreg (enableLines, portControl | h);
shiftreg (enableLines, portControl | l);
/* TODO: instead of delay read keys here */
}
@@ -119,49 +158,63 @@ char
lcdserLpt_HD44780_getkey ()
{
// TODO: a keypad scan that does not use shift register
// define a key table
// define a key table
char keytr[] = "ABCDEFGH";
int n;
rawshift (0); //send all line on shift register low
// disabled now !
return 0;
rawshift (0); //send all line on shift register low
hd44780_functions->uPause (1);
if ((port_in (lp + 1) & 32) == 0) //test if line back is low - if not return(0)
{ //else
//start walking a single zero across the eight lines
if ((port_in (lptPort + 1) & 32) == 0) //test if line back is low - if not return(0)
{ //else
//start walking a single zero across the eight lines
for (n = 7; n >= 0; n--) {
rawshift (255 - (1 << n));
hd44780_functions->uPause (1);
if ((port_in (lp + 1) & 32) == 0) // check if line back is low if yes debounce
if ((port_in (lptPort + 1) & 32) == 0) // check if line back is low if yes debounce
{
if (lastkey == keytr[n])
return (0);
// printf("key is %c %d\n",keytr[n],n);
lastkey = keytr[n];
return (keytr[n]); //return correct key code.
return (keytr[n]); //return correct key code.
}
}
} //else fall out and return(0) [too transient a keypress]
} //else fall out and return(0) [too transient a keypress]
lastkey = 0;
return (0);
}
unsigned char lcdserLpt_HD44780_readkeypad (unsigned int YData)
{
return 0;
}
/* this function sends r out onto the shift register */
void
rawshift (unsigned char r)
{
int i;
for (i = 7; i >= 0; i--) { /* MSB first */
port_out (lp, ((r >> i) & 1) * LCDDATA); /*set up data */
port_out (lp, (((r >> i) & 1) * LCDDATA) | LCDCLOCK); /*rising edge of clock */
for (i = 7; i >= 0; i--) { /* MSB first */
port_out (lptPort, ((r >> i) & 1) * LCDDATA); /*set up data */
port_out (lptPort, (((r >> i) & 1) * LCDDATA) | LCDCLOCK); /*rising edge of clock */
}
}
// displayID = value on parallel port to toggle the correct display
// enableLines = value on parallel port to toggle the correct display
void
shiftreg (unsigned char displayID, unsigned char r)
shiftreg (unsigned char enableLines, unsigned char r)
{
rawshift (r);
port_out (lp, displayID); //latch it, to correct display
port_out (lp, 0);
//unsigned char mr;
//mr = (r & 0xF0) | ((r<<3) & 0x0F) | ((r<<1) & 0x04) |
// ((r>>1) & 0x02) | ((r>>3) & 0x01);
rawshift (r | 0x80); // highest bit always set to 1 for Clear
port_out (lptPort, enableLines); //latch it, to correct display
hd44780_functions->uPause (1);
port_out (lptPort, 0);
hd44780_functions->uPause (3);
}
+72 -20
View File
@@ -4,16 +4,19 @@
* PC parallel port.
*
* Copyright (c) 1999 Andrew McMeikan <andrewm@engineer.com>
* modular driver 1999-2000 Benjamin Tse <blt@Comports.com>
* modular driver 1999-2000 Benjamin Tse <blt@Comports.com>
*
* Modified July 2000 by Charles Steinkuehler for enhanced
* performance and reduced CPU usage
* - provided required setup time for RS valid to E high
* - 1 uS call to uPause removed as it is unnecessary
*
* 2001 Joris Robijn <joris@robijn.net>
* - Keypad support
*
* The connections are:
* printer port LCD
* D0 (2) D0 (7)
* printer port LCD
* D0 (2) D0 (7)
* D1 (3) D1 (8)
* D2 (4) D2 (9)
* D3 (5) D3 (10)
@@ -26,6 +29,26 @@
* INIT (16) RS (4)
* nSEL (17) EN2 (6 - LCD 2) (optional)
*
* Keypad connection (optional):
* Some diodes and resistors are needed, see further documentation.
* printer port keypad
* D0 (2) Y0
* D1 (3) Y1
* D2 (4) Y2
* D3 (5) Y3
* D4 (6) Y4
* D5 (7) Y5
* D6 (7) Y6
* D7 (7) Y7
* nLF (14) Y8
* INIT (16) Y9
* nSEL (17) Y10
* nACK (10) X0
* BUSY (11) X1
* PAPEREND (12) X2
* SELIN (13) X3
* nFAULT (15) X4
*
* Created modular driver Dec 1999, Benjamin Tse <blt@Comports.com>
*
* This file is released under the GNU General Public License. Refer to the
@@ -33,25 +56,30 @@
*/
#include "hd44780-winamp.h"
#include "port.h"
#include "hd44780.h"
#include "port.h"
#include "shared/str.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
void lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch);
#include "port.h"
#define EN1 STRB
#define EN2 SEL
#define EN3 LF
#define RS INIT
void lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch);
unsigned char lcdwinamp_HD44780_readkeypad (unsigned int YData);
#define EN1 STRB
#define EN2 SEL
#define EN3 LF
#define RS INIT
static unsigned char EnMask[] = { EN1, EN2, EN3 };
static int EnMaskSize = sizeof (EnMask) / sizeof (unsigned char);
static int extIF = 0; // non-zero if extended interface
static unsigned int lptPort;
static int extIF = 0; // non-zero if extended interface
static char stuckinputs = 0; // if an input line is stuck, it will be ignored
// initialise the driver
int
@@ -62,22 +90,32 @@ hd_init_winamp (HD44780_functions * hd44780_functions, lcd_logical_driver * driv
int argc;
int i;
hd44780_functions->senddata = lcdwinamp_HD44780_senddata;
// Reserve the port registers
lptPort = port;
port_access(lptPort);
port_access(lptPort+1);
port_access(lptPort+2);
hd44780_functions->senddata = lcdwinamp_HD44780_senddata;
hd44780_functions->readkeypad = lcdwinamp_HD44780_readkeypad;
// parse command-line arguments
argc = get_args (argv, args, 64);
for (i = 0; i < argc; ++i)
for (i = 0; i < argc; ++i) {
if (strcmp (argv[i], "-e") == 0 || strcmp (argv[i], "--extended") == 0)
extIF = 1;
if (port_access (lptPort + 2) || port_access (lptPort)) {
fprintf (stderr, "HD44780_init: failed (%s)\n", strerror (errno));
return -1;
}
common_init (IF_8bit);
// setup the lcd in 8 bit mode
hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT);
hd44780_functions->uPause (4100);
hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT);
hd44780_functions->uPause (100);
hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT | TWOLINE | SMALLCHAR);
hd44780_functions->uPause (40);
common_init ();
return 0;
}
@@ -100,12 +138,12 @@ lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsign
// 40 nS setup time for RS valid to EN high, so set RS
port_out (lptPort + 2, portControl ^ OUTMASK);
// then set EN high
port_out (lptPort + 2, (dispID | portControl) ^ OUTMASK);
// Output the actual data
port_out (lptPort, ch);
// then set EN high
port_out (lptPort + 2, (dispID | portControl) ^ OUTMASK);
// 80 nS setup from valid data to EN low will be met without any delay
// unless you are running a REALLY FAST ISA bus (like 75 MHZ!)
// 230 nS minimum E high time provided by ISA bus delays as well...
@@ -115,3 +153,17 @@ lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsign
// 10 nS data hold time provided by the length of ISA write for EN
}
unsigned char lcdwinamp_HD44780_readkeypad (unsigned int YData)
{
unsigned char readval;
// 10 bits output
// Convert the positive logic to the negative logic on the LPT port
port_out (lptPort, ~YData & 0x00FF );
port_out (lptPort + 2, ( ((~YData & 0x0100) >> 7) | ((~YData & 0x0200) >> 7 )) ^ OUTMASK);
// And convert it back.
readval = ~ port_in (lptPort + 1) ^ INMASK;
return ( (readval >> 4 & 0x03) | (readval >> 5 & 0x04) | (readval >> 3 & 0x08) | (readval << 1 & 0x10) ) & ~stuckinputs;
}
+169 -67
View File
@@ -1,4 +1,4 @@
/*
/*
* Base driver module for Hitachi HD44780 based LCD displays. This is
* a modular driver that readily allows support for alternative HD44780
* designs to be added in a flexible and maintainable manner.
@@ -13,21 +13,24 @@
* 3. Create the low-level driver (use hd44780-ext8bit.c as a starting point)
* 4. Modify the makefile
*
* Modular driver created and generic support for multiple displays added
* Dec 1999, Benjamin Tse <blt@Comports.com>.
* Modular driver created and generic support for multiple displays added
* Dec 1999, Benjamin Tse <blt@Comports.com>
*
* Modified July 2000 by Charles Steinkuehler to use one of 3 methods for delay
* timing. I/O reads, gettimeofday, and nanosleep. Of the three, nanosleep
* seems to work best, so that's what is set by default.
*
* Modified May 2001 by Joris Robijn to add Keypad support.
*
* Character mapping for correct display of some special ASCII chars added
* Sep 2001, Mark Haemmerling <mail@markh.de>.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 2001 Mark Haemmerling <mail@markh.de>
* 2000, 1999, 1995 Benjamin Tse <blt@Comports.com>
* Copyright (c) 2000, 1999, 1995 Benjamin Tse <blt@Comports.com>
* 2001 Joris Robijn <joris@robijn.net>
* 2001 Mark Haemmerling <mail@markh.de>
* 2000 Charles Steinkuehler <cstein@newtek.com>
* 1999 Andrew McMeikan <andrewm@engineer.com>
* 1998 Richard Rognlie <rrognlie@gamerz.net>
@@ -51,7 +54,6 @@
//#define DELAY_GETTIMEOFDAY
#define DELAY_NANOSLEEP
#if defined DELAY_GETTIMEOFDAY
# if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
@@ -64,6 +66,7 @@
# endif
// Only one alternate delay method at a time, please ;-)
#if defined DELAY_GETTIMEOFDAY
# undef DELAY_NANOSLEEP
#elif defined DELAY_NANOSLEEP
# include <sched.h>
@@ -82,7 +85,7 @@
// default parallel port address
#ifndef LPTPORT
#define LPTPORT 0x378
#define LPTPORT 0x378
#endif
unsigned int port = LPTPORT;
@@ -107,10 +110,46 @@ static int numDisplays = 0;
// input span list but is kept to save some cpu cycles.
static int *dispSizes = NULL;
// Keypad option
char keypad = 0; // off by default
// This var is not static, so it's accessable from all sub-drivers
// Indeed, this should become cleaner... later...
// Maximum sizes of the keypad
// DO NOT CHANGE THESE 2 VALUES, unless you change the functions too
#define KEYPAD_MAXX 5
#define KEYPAD_MAXY 11
// Autorepeat values
#define KEYPAD_AUTOREPEAT_DELAY 500
#define KEYPAD_AUTOREPEAT_FREQ 15
// keyMapDirect contains an array of the ascii-codes that should be generated
// when a directly connected key is pressed (not in matrix).
static char keyMapDirect[KEYPAD_MAXX] = { 'A', 'B', 'C', 'D', 'E' };
// keyMapMatrix contrains an array with arrays of the ascii-codes that should be generated
// when a key in the matrix is pressed.
static char keyMapMatrix[KEYPAD_MAXY][KEYPAD_MAXX] = {
{ '1', '2', '3', 'A', 0 },
{ '4', '5', '6', 'B', 0 },
{ '7', '8', '9', 'C', 0 },
{ '*', '0', '#', 'D', 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 }};
static char pressed_key = 0;
static int pressed_key_repetitions = 0;
static struct timeval pressed_key_time;
// function declarations
void HD44780_flush ();
void HD44780_flush_box (int lft, int top, int rgt, int bot);
int HD44780_contrast (int contrast);
void HD44780_backlight (int on);
void HD44780_init_vbar ();
void HD44780_init_hbar ();
@@ -132,6 +171,7 @@ static void common_position (int display, int DDaddr);
static void common_autoscroll (int on);
static void uPause (int delayCalls);
static void HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch);
static char HD44780_getkey ();
static int parse_span_list (int *spanListArray[], int *spLsize, int *dispOffsets[], int *dOffsize, int *dispSizeArray[], char *spanlist);
@@ -205,6 +245,10 @@ HD44780_init (lcd_logical_driver * driver, char *args)
return -1;
}
++i;
} else if (strcmp (argv[i], "-k") == 0 || strcmp (argv[i], "--keypad") == 0) {
keypad = 1;
printf( "HD44780 keypad extension enabled\n" );
} else if (0 == strcmp (argv[i], "-h") || 0 == strcmp (argv[i], "--help")) {
int i;
printf ("LCDproc HD44780 driver\n" "\t-p n\t--port n\tSelect the output device to use port n\n" "\t-c type\t--connect type\tSet the connection type (default 4 bit)\n" "\t\t\t\ttype = %s", connectionMapping[0].connectionTypeStr);
@@ -259,12 +303,7 @@ HD44780_init (lcd_logical_driver * driver, char *args)
}
}
#endif
// Set up io port correctly, and open it...
if (port_access (port)) {
fprintf (stderr, "HD44780_init: failed (%s)\n", strerror (errno));
return -1;
}
// Make sure the frame buffer is there...
// Make sure the frame buffer is there...
if (!HD44780->framebuf)
HD44780->framebuf = (unsigned char *) malloc (HD44780->wid * HD44780->hgt);
@@ -288,12 +327,15 @@ HD44780_init (lcd_logical_driver * driver, char *args)
driver->close = (void *) -1;
driver->flush = HD44780_flush;
driver->flush_box = HD44780_flush_box;
driver->contrast = HD44780_contrast;
//driver->contrast = HD44780_contrast; // contrast by potmeter
driver->backlight = HD44780_backlight;
driver->set_char = HD44780_set_char;
driver->icon = HD44780_icon;
driver->draw_frame = HD44780_draw_frame;
driver->getkey = NULL;
if( keypad ) {
driver->getkey = HD44780_getkey;
}
if ((hd44780_functions = (HD44780_functions *) malloc (sizeof (HD44780_functions))) == NULL) {
return -1;
@@ -309,28 +351,14 @@ HD44780_init (lcd_logical_driver * driver, char *args)
return port;
}
// common initialisation sequence - sets twoline, small characters (5x8),
// cursor off and not blinking, clear display and homecursor
// Common initialisation sequence - sets cursor off and not blinking,
// clear display and homecursor
// Does not set twoline mode nor small characters (5x8). The init function of
// the connectiontype should do this.
void
common_init (enum ifWidth ifwidth)
common_init ()
{
if (ifwidth == IF_8bit) {
// setup the lcd in 8 bit mode
hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT);
hd44780_functions->uPause (4100);
hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT);
hd44780_functions->uPause (100);
hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT);
hd44780_functions->uPause (40);
}
// else 4bit
// senddata can't generate the timings to initialise a four bit device
// properly but it might just work properly anyway ....
// set display type functions
hd44780_functions->senddata (0, RS_INSTR, FUNCSET | ((ifwidth == IF_4BIT) ? IF_4BIT : IF_8BIT) | TWOLINE | SMALLCHAR);
hd44780_functions->uPause (40);
hd44780_functions->senddata (0, RS_INSTR, ONOFFCTRL | DISPON | CURSOROFF | CURSORNOBLINK);
hd44780_functions->uPause (40);
hd44780_functions->senddata (0, RS_INSTR, CLEAR);
@@ -368,11 +396,10 @@ uPause (int delayCalls)
delay.tv_sec = remaining.tv_sec;
delay.tv_nsec = remaining.tv_nsec;
}
#else
#else // using I/O timing
int i;
for (i = 0; i < delayCalls; ++i)
port_in (port);
//TODO: put in option for nanosleep rather than dummy I/O call
#endif
}
@@ -381,14 +408,14 @@ static void
HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch)
{
hd44780_functions->senddata (displayID, flags, ch);
hd44780_functions->uPause (40);
hd44780_functions->uPause (40); // Minimum exec time for all commands
}
/////////////////////////////////////////////////////////////////
// Clean-up
//
/*
void HD44780_close()
void HD44780_close()
{
drv_base_close();
}
@@ -420,7 +447,7 @@ void
common_position (int display, int DDaddr)
{
hd44780_functions->senddata (display, RS_INSTR, POSITION | DDaddr);
hd44780_functions->uPause (40);
hd44780_functions->uPause (40); // Minimum exec time for all commands
}
void HD44780_chr (int x, int y, char ch)
@@ -453,21 +480,12 @@ HD44780_flush_box (int lft, int top, int rgt, int bot)
}
/////////////////////////////////////////////////////////////////
// Changes screen contrast (0-255; 140 seems good)
//
int
HD44780_contrast (int contrast)
{
return 0;
}
/////////////////////////////////////////////////////////////////
// Sets the backlight on or off -- can be done quickly for
// an intermediate brightness...
// Sets the backlight on or off
//
void
HD44780_backlight (int on)
{
//hd44780_functions->backlight (on);
}
/////////////////////////////////////////////////////////////////
@@ -491,7 +509,7 @@ void
common_autoscroll (int on)
{
hd44780_functions->senddata (0, RS_INSTR, ENTRYMODE | E_MOVERIGHT | ((on) ? EDGESCROLL : NOSCROLL));
hd44780_functions->uPause (1600);
hd44780_functions->uPause (40);
}
/////////////////////////////////////////////////////////////////
@@ -680,9 +698,7 @@ HD44780_hbar (int x, int y, int len)
void
HD44780_init_num ()
{
char out[3];
snprintf (out, sizeof(out), "%cn", 254);
//write(fd, out, 2);
}
/////////////////////////////////////////////////////////////////
@@ -691,10 +707,8 @@ HD44780_init_num ()
void
HD44780_num (int x, int num)
{
char out[5];
printf("Size of out is %d\n", sizeof(out));
snprintf (out, sizeof(out), "%c#%c%c", 254, x, num);
//write(fd, out, 4);
int offset = HD44780->wid * ( HD44780->hgt / 2 );
HD44780->framebuf[x+offset] = num + '0';
}
/////////////////////////////////////////////////////////////////
@@ -732,7 +746,7 @@ HD44780_icon (int which, char dest)
{
char icons[3][5 * 8] = {
{
1, 1, 1, 1, 1, // Empty Heart
1, 1, 1, 1, 1, // Empty Heart
1, 0, 1, 0, 1,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
@@ -743,7 +757,7 @@ HD44780_icon (int which, char dest)
},
{
1, 1, 1, 1, 1, // Filled Heart
1, 1, 1, 1, 1, // Filled Heart
1, 0, 1, 0, 1,
0, 1, 0, 1, 0,
0, 1, 1, 1, 0,
@@ -754,7 +768,7 @@ HD44780_icon (int which, char dest)
},
{
0, 0, 0, 0, 0, // Ellipsis
0, 0, 0, 0, 0, // Ellipsis
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
@@ -794,12 +808,12 @@ HD44780_draw_frame (char *dat)
// Parse the span list
// spanListArray - array to store vertical spans
// spLsize - size of spanListArray
// spLsize - size of spanListArray
// dispOffsets - array to store display offsets
// dOffsize - size of dispOffsets
// dOffsize - size of dispOffsets
// dispSizeArray - array of display vertical sizes (= spanlist)
// spanlist - null terminated input span list in comma delimited
// format. All span elements [1-9] e.g. "1,4,2"
// spanlist - null terminated input span list in comma delimited
// format. All span elements [1-9] e.g. "1,4,2"
// returns number of span elements, -1 on parse error
int
@@ -842,3 +856,91 @@ parse_span_list (int *spanListArray[], int *spLsize, int *dispOffsets[], int *dO
}
return retVal;
}
char HD44780_getkey()
{
unsigned int keybits;
unsigned int shiftcount;
unsigned int shiftingbit;
unsigned int Ypattern;
unsigned int Yval;
char exp;
char ch = 0;
char ch_set = 0;
struct timeval curr_time, time_diff;
gettimeofday(&curr_time,NULL);
// First check if a directly connected key is pressed
// Put all zeros on Y of keypad
keybits = hd44780_functions->readkeypad (0);
if (keybits) {
// A directly connected key was pressed
// Which key was it ?
shiftingbit = 1;
for (shiftcount=0; shiftcount<KEYPAD_MAXX && !ch; shiftcount++) {
if ( keybits & shiftingbit) {
// Found ! Return from function.
ch = keyMapDirect[shiftcount];
}
shiftingbit <<= 1;
}
}
else {
// Now check the matrix
// First check with all 1's
Ypattern = (1 << KEYPAD_MAXY) - 1;
if( hd44780_functions->readkeypad (Ypattern)) {
// Yes, a key on the matrix is pressed
// OK, now we know a key is pressed.
// Determine which one it is
// Do a 'binary search' to determine in what row a key is pressed
Ypattern = 0;
Yval = 0;
for (exp=3; exp>=0; exp--) {
Ypattern = ((1 << (1 << exp)) - 1) << Yval;
keybits = hd44780_functions->readkeypad (Ypattern);
if (!keybits) {
Yval += (1 << exp);
}
}
// Which key is pressed in that row ?
keybits = hd44780_functions->readkeypad (1<<Yval);
shiftingbit=1;
for (shiftcount=0; shiftcount<KEYPAD_MAXX && !ch; shiftcount++) {
if ( keybits & shiftingbit) {
// Found !
ch = keyMapMatrix[Yval][shiftcount];
}
shiftingbit <<= 1;
}
}
}
if (ch) {
if (ch == pressed_key) {
timersub (&curr_time, &pressed_key_time, &time_diff);
if (((time_diff.tv_usec / 1000 + time_diff.tv_sec * 1000) - KEYPAD_AUTOREPEAT_DELAY) < 1000 * pressed_key_repetitions / KEYPAD_AUTOREPEAT_FREQ ) {
// The key is already pressed quite some time
// but it's not yet time to return a repeated keypress
return 0;
}
// Otherwise a keypress will be returned
pressed_key_repetitions ++;
}
else {
// It's a new keypress
pressed_key_time = curr_time;
pressed_key_repetitions = 0;
printf( "Key: %c\n", ch );
}
}
// Store the key for the next round
pressed_key = ch;
return ch;
}