home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
linuxmafia.com 2016
/
linuxmafia.com.tar
/
linuxmafia.com
/
pub
/
palmos
/
stepcounter-1.3.tar.gz
/
stepcounter-1.3.tar
/
stepcounter-1.3
/
tilt_p3
/
tilt_p3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-12
|
7KB
|
304 lines
/*
tilt_p3.c - (c) 1999 Till Harbaum
tilt sensor driver for old style palm tilt sensor
t.harbaum@tu-bs.de
*/
#include <SysAll.h>
#include <Pilot.h>
#include "../tilt.h"
#define BYTEREG(a) (*(volatile unsigned char*)a)
#define PEDIR BYTEREG(0xfffff420)
#define PEDATA BYTEREG(0xfffff421)
#define PEUP BYTEREG(0xfffff422)
#define PESEL BYTEREG(0xfffff423)
#define PJDIR BYTEREG(0xfffff438)
#define PJDATA BYTEREG(0xfffff439)
#define PJSEL BYTEREG(0xfffff43b)
#define LONGREG(a) (*(volatile unsigned long*)a)
#define PORTE LONGREG(0xfffff420)
#define PORTJ LONGREG(0xfffff438)
/* interrupt mask register */
#define IMR (*(unsigned long*)0xfffff304)
static int tilt_check_cpu(void) {
/* if we're not using a new include file, define things appropriately */
#ifndef sysFtrNumProcessorID
#define sysFtrNumProcessorID 2
/* Product id */
/* 0xMMMMRRRR, where MMMM is the processor model */
/* and RRRR is the revision. */
#define sysFtrNumProcessorMask 0xFFFF0000 // Mask to obtain processor model
#define sysFtrNumProcessor328 0x00010000 // Motorola 68328 (Dragonball)
#define sysFtrNumProcessorEZ 0x00020000 // Motorola 68EZ328 (Dragonball EZ)
#endif
DWord id, chip;
Err err;
err = FtrGet(sysFtrCreator, sysFtrNumProcessorID, &id);
if (err) {
// can't get that feature; we must be on an old unit
// without it defined, thus we're on a DragonBall.
chip = sysFtrNumProcessor328;
} else
chip = id & sysFtrNumProcessorMask;
return(chip == sysFtrNumProcessor328);
}
/* Dispatch table declarations */
ULong install_dispatcher(UInt,SysLibTblEntryPtr);
Ptr *gettable(void);
typedef struct {
Word zero_x;
Word zero_y;
Word refcount;
} Lib_globals;
ULong start (UInt refnum, SysLibTblEntryPtr entryP) {
ULong ret;
asm("
movel %%fp@(10),%%sp@-
movew %%fp@(8),%%sp@-
jsr install_dispatcher(%%pc)
movel %%d0,%0
jmp out(%%pc)
gettable:
lea jmptable(%%pc),%%a0
rts
jmptable:
dc.w 50 | 6n+2 = 50
dc.w 18 | 2n+4i+2
dc.w 22
dc.w 26
dc.w 30
dc.w 34
dc.w 38
dc.w 42
dc.w 46
jmp open(%%pc)
jmp close(%%pc)
jmp sleep(%%pc)
jmp wake(%%pc)
jmp tilt_zero(%%pc)
jmp tilt_get(%%pc)
jmp tilt_get_abs(%%pc)
jmp unused2(%%pc)
.asciz \"Tilt Sensor Lib\"
.even
out:
" : "=r" (ret) :);
return ret;
}
ULong install_dispatcher(UInt refnum, SysLibTblEntryPtr entryP) {
Ptr *table = gettable();
entryP->dispatchTblP = table;
entryP->globalsP = NULL;
return 0;
}
/* switch power pin on/off */
void tilt_power(int on) {
if(on) PJDATA |= 0x80;
else PJDATA &= ~0x80;
}
/* switch self test pin on/off */
void tilt_selftest(int on) {
if(on) PJDATA |= 0x40;
else PJDATA &= ~0x40;
}
void tilt_setup(void) {
/* Port E */
/* set upper two bits to gpio */
PESEL |= 0x60;
/* disable pullups */
PEUP &= ~0x60;
/* set both pins to input */
PEDIR &= ~0x60;
/* Port J */
/* set upper two bits to gpio */
PJSEL |= 0xc0;
/* set both pins to output */
PJDIR |= 0xc0;
/* both output pins low (chip off) */
PJDATA &= ~0xc0;
/* now switch on chip */
tilt_power(1);
tilt_selftest(0);
}
#define SAMPLE 8
Boolean tilt_measure(Word *x, Word *y) {
unsigned long irq_save;
unsigned short i,j;
int ax=0,ay=0;
int t2[SAMPLE];
short a[SAMPLE][6];
/* disable all irqs */
irq_save = IMR;
IMR = 0x00ffffff;
for(i=0;i<SAMPLE;i++)
getvals(a[i]);
/* reenable irqs */
IMR = irq_save;
/* counter went down to 0?? -> no chip found */
if((a[0][0]==-1)||(a[0][1]==-1)) return false;
for(i=0;i<SAMPLE;i++) {
for(j=0;j<6;j++)
a[i][j] = 2000-a[i][j];
/* calculate T2 */
t2[i] = a[i][2]/2 + a[i][3] + a[i][4] + a[i][5]/2;
ax += ((unsigned long)a[i][2]<<8)/t2[i];
ay += ((unsigned long)a[i][5]<<8)/t2[i];
}
*x=(ax/SAMPLE);
*y=(ay/SAMPLE);
return true;
}
Err open(UInt refnum) {
/* Get the current globals value */
SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
Lib_globals *gl = (Lib_globals*)entryP->globalsP;
if (gl) {
/* We are already open in some other application; just
increment the refcount */
gl->refcount++;
return 0;
}
/* We need to allocate space for the globals */
entryP->globalsP = MemPtrNew(sizeof(Lib_globals));
MemPtrSetOwner(entryP->globalsP, 0);
gl = (Lib_globals*)entryP->globalsP;
/* Initialize the globals */
gl->refcount = 1;
gl->zero_x = 0;
gl->zero_y = 0;
/* is this the right hardware */
if(!tilt_check_cpu()) return TILT_WRONG_OS;
/* initialize sensor */
tilt_setup();
/* try to access sensor */
if(!tilt_measure(&gl->zero_x, &gl->zero_y))
return TILT_NO_SENSOR;
/* sensor is fine */
return 0;
}
Err close(UInt refnum, UIntPtr numappsP) {
/* Get the current globals value */
SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
Lib_globals *gl = (Lib_globals*)entryP->globalsP;
if (!gl) return 1;
/* power down chip */
tilt_power(0);
/* Clean up */
*numappsP = --gl->refcount;
if (*numappsP == 0) {
MemChunkFree(entryP->globalsP);
entryP->globalsP = NULL;
}
return 0;
}
Err sleep(UInt refnum) {
/* shut down sensor */
tilt_power(0);
return 0;
}
Err wake(UInt refnum) {
/* power up sensor */
tilt_power(1);
return 0;
}
/* zero the tilt sensor */
Err tilt_zero(UInt refnum) {
/* Get the current globals value */
SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
Lib_globals *gl = (Lib_globals*)entryP->globalsP;
if (!gl) return 1; /* We're not open! */
/* get zero values */
tilt_measure(&gl->zero_x, &gl->zero_y);
return 0;
}
/* return normalized tilt value */
Err tilt_get(UInt refnum, Word *x, Word *y) {
/* Get the current globals value */
SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
Lib_globals *gl = (Lib_globals*)entryP->globalsP;
if (!gl) return 1; /* We're not open! */
tilt_measure(x,y);
*x -= gl->zero_x;
*y -= gl->zero_y;
return 0;
}
/* return absolute tilt value */
Err tilt_get_abs(UInt refnum, Word *x, Word *y) {
/* Get the current globals value */
SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
Lib_globals *gl = (Lib_globals*)entryP->globalsP;
if (!gl) return 1; /* We're not open! */
tilt_measure(x,y);
return 0;
}
/* unused function 2 */
Err unused2(UInt refnum) {
return 0;
}