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 >
C/C++ Source or Header  |  1999-12-12  |  7KB  |  304 lines

  1. /* 
  2.    tilt_p3.c  -  (c) 1999 Till Harbaum
  3.  
  4.    tilt sensor driver for old style palm tilt sensor
  5.  
  6.    t.harbaum@tu-bs.de
  7. */
  8.  
  9. #include <SysAll.h>
  10. #include <Pilot.h>
  11. #include "../tilt.h"
  12.  
  13. #define BYTEREG(a)  (*(volatile unsigned char*)a)
  14. #define PEDIR       BYTEREG(0xfffff420)
  15. #define PEDATA      BYTEREG(0xfffff421)
  16. #define PEUP        BYTEREG(0xfffff422)
  17. #define PESEL       BYTEREG(0xfffff423)
  18. #define PJDIR       BYTEREG(0xfffff438)
  19. #define PJDATA      BYTEREG(0xfffff439)
  20. #define PJSEL       BYTEREG(0xfffff43b)
  21.  
  22. #define LONGREG(a)  (*(volatile unsigned long*)a)
  23. #define PORTE       LONGREG(0xfffff420)
  24. #define PORTJ       LONGREG(0xfffff438)
  25.  
  26. /* interrupt mask register */
  27. #define IMR  (*(unsigned long*)0xfffff304)
  28.  
  29. static int tilt_check_cpu(void) {
  30.   /* if we're not using a new include file, define things appropriately */
  31. #ifndef sysFtrNumProcessorID
  32. #define sysFtrNumProcessorID    2
  33.   /* Product id */
  34.   /* 0xMMMMRRRR, where MMMM is the processor model */
  35.   /* and RRRR is the revision. */
  36. #define sysFtrNumProcessorMask  0xFFFF0000 // Mask to obtain processor model
  37. #define sysFtrNumProcessor328   0x00010000 // Motorola 68328 (Dragonball)
  38. #define sysFtrNumProcessorEZ    0x00020000 // Motorola 68EZ328 (Dragonball EZ)
  39. #endif
  40.   DWord id, chip;
  41.   Err err;
  42.  
  43.   err = FtrGet(sysFtrCreator, sysFtrNumProcessorID, &id);
  44.   if (err) {
  45.     // can't get that feature; we must be on an old unit
  46.     // without it defined, thus we're on a DragonBall.
  47.     chip = sysFtrNumProcessor328;
  48.   } else
  49.     chip = id & sysFtrNumProcessorMask;
  50.  
  51.   return(chip == sysFtrNumProcessor328);
  52. }
  53.  
  54. /* Dispatch table declarations */
  55. ULong install_dispatcher(UInt,SysLibTblEntryPtr);
  56. Ptr   *gettable(void);
  57.  
  58. typedef struct {
  59.   Word zero_x;
  60.   Word zero_y;
  61.  
  62.   Word refcount;
  63. } Lib_globals;
  64.  
  65. ULong start (UInt refnum, SysLibTblEntryPtr entryP) {
  66.   ULong ret;
  67.  
  68.   asm("
  69.         movel %%fp@(10),%%sp@-
  70.         movew %%fp@(8),%%sp@-
  71.         jsr install_dispatcher(%%pc)
  72.         movel %%d0,%0
  73.         jmp out(%%pc)
  74. gettable:
  75.         lea jmptable(%%pc),%%a0
  76.         rts
  77.  
  78. jmptable:
  79.         dc.w 50 | 6n+2 = 50
  80.         dc.w 18 | 2n+4i+2
  81.         dc.w 22
  82.         dc.w 26
  83.         dc.w 30
  84.         dc.w 34
  85.         dc.w 38
  86.         dc.w 42
  87.         dc.w 46
  88.         jmp open(%%pc)
  89.         jmp close(%%pc)
  90.         jmp sleep(%%pc)
  91.         jmp wake(%%pc)
  92.         jmp tilt_zero(%%pc)
  93.         jmp tilt_get(%%pc)
  94.         jmp tilt_get_abs(%%pc)
  95.         jmp unused2(%%pc)
  96.         .asciz \"Tilt Sensor Lib\"
  97.     .even
  98.     out:
  99.         " : "=r" (ret) :);
  100.   return ret;
  101. }
  102.  
  103. ULong install_dispatcher(UInt refnum, SysLibTblEntryPtr entryP) {
  104.   Ptr *table = gettable();
  105.   entryP->dispatchTblP = table;
  106.   entryP->globalsP = NULL;
  107.   return 0;
  108. }
  109.  
  110. /* switch power pin on/off */
  111. void tilt_power(int on) { 
  112.   if(on) PJDATA |=  0x80;
  113.   else   PJDATA &= ~0x80;
  114. }
  115.  
  116. /* switch self test pin on/off */
  117. void tilt_selftest(int on) {
  118.   if(on) PJDATA |=  0x40;
  119.   else   PJDATA &= ~0x40;
  120. }
  121.  
  122. void tilt_setup(void) {
  123.  
  124.   /* Port E */
  125.   /* set upper two bits to gpio */
  126.   PESEL |= 0x60; 
  127.  
  128.   /* disable pullups */
  129.   PEUP  &= ~0x60; 
  130.  
  131.   /* set both pins to input */
  132.   PEDIR &= ~0x60;
  133.  
  134.   /* Port J */
  135.   /* set upper two bits to gpio */
  136.   PJSEL |= 0xc0; 
  137.  
  138.   /* set both pins to output */
  139.   PJDIR |=  0xc0;
  140.  
  141.   /* both output pins low (chip off) */
  142.   PJDATA &= ~0xc0;
  143.  
  144.   /* now switch on chip */
  145.   tilt_power(1);
  146.   tilt_selftest(0);
  147. }
  148.  
  149. #define SAMPLE 8
  150. Boolean tilt_measure(Word *x, Word *y) {
  151.   unsigned long irq_save;
  152.   unsigned short i,j;
  153.   int ax=0,ay=0;
  154.   int t2[SAMPLE];
  155.   short a[SAMPLE][6];
  156.  
  157.   /* disable all irqs */
  158.   irq_save = IMR;
  159.   IMR = 0x00ffffff;
  160.  
  161.   for(i=0;i<SAMPLE;i++)
  162.     getvals(a[i]);
  163.  
  164.   /* reenable irqs */
  165.   IMR = irq_save;
  166.  
  167.   /* counter went down to 0?? -> no chip found */
  168.   if((a[0][0]==-1)||(a[0][1]==-1)) return false;
  169.  
  170.   for(i=0;i<SAMPLE;i++) {
  171.     for(j=0;j<6;j++)  
  172.       a[i][j] = 2000-a[i][j];
  173.  
  174.     /* calculate T2 */
  175.     t2[i] = a[i][2]/2 + a[i][3] + a[i][4] + a[i][5]/2;
  176.  
  177.     ax += ((unsigned long)a[i][2]<<8)/t2[i];
  178.     ay += ((unsigned long)a[i][5]<<8)/t2[i];
  179.   }
  180.  
  181.   *x=(ax/SAMPLE); 
  182.   *y=(ay/SAMPLE);
  183.  
  184.   return true;
  185. }
  186.  
  187. Err open(UInt refnum) {
  188.   /* Get the current globals value */
  189.   SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
  190.   Lib_globals *gl = (Lib_globals*)entryP->globalsP;
  191.  
  192.   if (gl) {
  193.     /* We are already open in some other application; just
  194.        increment the refcount */
  195.     gl->refcount++;
  196.     return 0;
  197.   }
  198.  
  199.   /* We need to allocate space for the globals */
  200.   entryP->globalsP = MemPtrNew(sizeof(Lib_globals));
  201.   MemPtrSetOwner(entryP->globalsP, 0);
  202.   gl = (Lib_globals*)entryP->globalsP;
  203.   
  204.   /* Initialize the globals */
  205.   gl->refcount = 1;
  206.   gl->zero_x   = 0;
  207.   gl->zero_y   = 0;
  208.  
  209.   /* is this the right hardware */
  210.   if(!tilt_check_cpu()) return TILT_WRONG_OS;
  211.  
  212.   /* initialize sensor */
  213.   tilt_setup();
  214.  
  215.   /* try to access sensor */
  216.   if(!tilt_measure(&gl->zero_x, &gl->zero_y)) 
  217.     return TILT_NO_SENSOR;
  218.  
  219.   /* sensor is fine */
  220.   return 0;
  221. }
  222.  
  223. Err close(UInt refnum, UIntPtr numappsP) {
  224.   /* Get the current globals value */
  225.   SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
  226.   Lib_globals *gl = (Lib_globals*)entryP->globalsP;
  227.   if (!gl) return 1;
  228.  
  229.   /* power down chip */
  230.   tilt_power(0);
  231.  
  232.   /* Clean up */
  233.   *numappsP = --gl->refcount;
  234.   if (*numappsP == 0) {
  235.     MemChunkFree(entryP->globalsP);
  236.     entryP->globalsP = NULL;
  237.   }
  238.   
  239.   return 0;
  240. }
  241.  
  242. Err sleep(UInt refnum) {
  243.   /* shut down sensor */
  244.   tilt_power(0);
  245.  
  246.   return 0;
  247. }
  248.  
  249. Err wake(UInt refnum) {
  250.   /* power up sensor */
  251.   tilt_power(1);
  252.  
  253.   return 0;
  254. }
  255.  
  256. /* zero the tilt sensor */
  257. Err tilt_zero(UInt refnum) {
  258.   /* Get the current globals value */
  259.   SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
  260.   Lib_globals *gl = (Lib_globals*)entryP->globalsP;
  261.  
  262.   if (!gl) return 1; /* We're not open! */  
  263.  
  264.   /* get zero values */
  265.   tilt_measure(&gl->zero_x, &gl->zero_y);
  266.  
  267.   return 0;
  268. }
  269.  
  270. /* return normalized tilt value */
  271. Err tilt_get(UInt refnum, Word *x, Word *y) {
  272.   /* Get the current globals value */
  273.   SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
  274.   Lib_globals *gl = (Lib_globals*)entryP->globalsP;
  275.  
  276.   if (!gl) return 1; /* We're not open! */
  277.  
  278.   tilt_measure(x,y);
  279.   *x -= gl->zero_x;
  280.   *y -= gl->zero_y;
  281.  
  282.   return 0;
  283. }
  284.  
  285. /* return absolute tilt value */
  286. Err tilt_get_abs(UInt refnum, Word *x, Word *y) {
  287.   /* Get the current globals value */
  288.   SysLibTblEntryPtr entryP = SysLibTblEntry(refnum);
  289.   Lib_globals *gl = (Lib_globals*)entryP->globalsP;
  290.  
  291.   if (!gl) return 1; /* We're not open! */
  292.  
  293.   tilt_measure(x,y);
  294.  
  295.   return 0;
  296. }
  297.  
  298. /* unused function 2 */
  299. Err unused2(UInt refnum) {
  300.   return 0;
  301. }
  302.  
  303.  
  304.