Here is a version of keypad that I hacked up.. Hopefully it will help.
Brian
/*
* This code is a severely hacked version of the keypad demo.
* I don't suggest that you adapt to your needs.
*
* The debouncing may or may not be done properly..I'm leaning towards no.
*
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <fcntl.h>
#define GPIO 0x80840000 // General
Purpose I/O Base Address
#define PBDR (0x04/sizeof(unsigned int)) // Port B Data Register
#define PBDDR (0x14/sizeof(unsigned int)) // Port B Directection Register
unsigned int getkeys();
void printkey(unsigned int);
volatile unsigned int *gpio;
volatile unsigned int *pbdr;
volatile unsigned int *pbddr;
// Key Mappings
struct key {
unsigned int hex_key;
unsigned char char_key;
} keys[] = {
0xee,'1', 0xde,'2', 0xbe,'3', 0x7e,'A',
0xed,'4', 0xdd,'5', 0xbd,'6', 0x7d,'B',
0xeb,'7', 0xdb,'8', 0xbb,'9', 0x7b,'C',
0xe7,'*', 0xd7,'0', 0xb7,'?', 0x77,'D'
};
int main()
{
unsigned int key = 0,pressed = 0;
int fd = open("/dev/mem", O_RDWR|O_SYNC);
gpio = mmap(0,getpagesize(),PROT_READ|PROT_WRITE,MAP_SHARED,fd,GPIO);
// set pointers to register addresses
pbdr = &gpio[PBDR];
pbddr = &gpio[PBDDR];
// set port b register to output
*pbddr = 0xf;
for(;;){
unsigned int changed;
key = getkeys();
// xor
changed = pressed ^ key;
if(changed){
printkey(key);
pressed = key;
}
usleep(1000000/30);
}
close(fd);
return 0;
}
unsigned int getkeys(){
unsigned int pos, on = 0;
for(pos=0;pos < 4;pos++ ){
// left shift by pos then flip bits ( 1's comp)
*pbdr = ~(1 << pos);
// if true
if((*pbdr >> 4) ^ 0xf){
on = *pbdr;
return on;
}
}
// nothing pressed
return 0;
}
void printkey(unsigned int key){
int i;
for(i=0;i<sizeof(keys)/sizeof(keys[0]);i++){
if(key == keys[i].hex_key){
printf("%c\n",keys[i].char_key);
}
}
}
--- In "ticrus00" <> wrote:
>
> Jason, thank you I think I am half way there. My failure to
> understand how the keypad seems to be my problem.
>
> I have a few more questions. If it is setting 1 bit in *dat, why the
> need to invert? Is 1 treated as low voltage and 0 as a large voltage?
> I noticed it is setting a bit in the far right nibble. If A,B,C,D
> are set in that nibble, is 1,2,3,4 the left nibble? If so, am I right
> in saying that if you change bits in the first nibble for A,B,C, or D,
> then the left nibble will change? Also what happens if 2 or more lines
> are selected, such as A and B at the same time? Could you explain the
> second line, 'on |= (~(*dat >> 4) & 0xf) << (4 * pos);'? I appreciate
> the time you have taken to help me out.
>
> Justin
> --- In Jason Stahls <jason@> wrote:
> >
> > The 4x4 keypad works like this
> >
> > ABC D
> > 1 + + + +
> > 2 + + + +
> > 3 + + + +
> > 4 + + + +
> >
> > Where you apply power to A, then check for that voltage on 1, 2,
3, and
> > 4. You then apply power to B and check 1, 2, 3, and 4 again, and so
> on.
> >
> > *dat = ~(1 << pos);
> >
> > This line is setting a bit in dat, if we break all of it down it
looks
> > like this (I think, I still much up bitwise some days)
> >
> > 1 << pos, this bit shifts 1 to the left pos positions. So, in binary
> > (I'm going to pad this to nibble size) if we shift 0001 left 2
> places we
> > get 0100, 1 is 0010, ect.
> >
> > ~(1 << pos), we then invert the result from (1 << pos), so if we had
> > 0010 and inverted it with ~ we'd get 1101
> >
> > Hope that helps.
> >
> > Jason
> >
> > ticrus00 wrote:
> > > Forgive me I am new at this. I am trying to understand whats
going on
> > > in the keypad.c sample code provided with the ts-7200 board.
> > > Specifically:
> > >
> > > unsigned int get_keys(void) {
> > > unsigned int pos, on = 0;
> > >
> > > for(pos = 0; pos < 4; pos++) {
> > > *dat = ~(1 << pos); <- I DON'T UNDERSTAND THIS
> > > on |= (~(*dat >> 4) & 0xf) << (4 * pos);
> > > }
> > > return on;
> > > }
> > >
> > > The above arrow is the line I am not following because to me its is
> > > setting *dat equal to ~(1 << pos). But when *dat is used in
the line
> > > below it is a different value. I don't know anything about the
keypad
> > > and maybe thats my problem. Is it some sort of msg to the
keypad? Is
> > > there any documentation out there besides the keypad.c and the
> > > hardware guide that came with the board?
> > >
> > >
> > >
> > >
> > >
> > >
> > > Yahoo! Groups Links
> > >
> > >
> > >
> > >
> > >
> >
>
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|