Received: from Menudo.UH.EDU by karazm.math.UH.EDU with SMTP id AA04432 (5.65c/IDA-1.4.4 for ); Thu, 24 Oct 1991 19:23:36 -0500 Received: from Moxie.Hou.TX.US by Menudo.UH.EDU with UUCP id AA02410 (5.65c+/IDA-1.4.4 for karazm.math.uh.edu!glove-list); Thu, 24 Oct 1991 19:19:26 -0500 Received: by moxie.hou.tx.us (Smail3.1.19) id ; Thu, 24 Oct 91 19:17 CDT Received: from sunbird.Central.Sun.COM by texsun.Central.Sun.COM (4.1/SMI-4.1) id AA13053; Thu, 24 Oct 91 18:11:38 CDT Received: from tellab5.UUCP by sunbird.Central.Sun.COM (4.1/SMI-4.1-900117) id AA13100; Thu, 24 Oct 91 18:11:35 CDT Received: from sunJe.TELLABS.COM by tellab5.tellabs.com (4.1/smail2.5/10-21-91) id AA04478; Thu, 24 Oct 91 16:41:41 CDT Received: by sunJe.TELLABS.COM (4.0/4.7) id AA03488; Thu, 24 Oct 91 16:41:38 CDT Date: Thu, 24 Oct 91 16:41:38 CDT From: menelli@sunje.tellabs.com (Ron Menelli) Message-Id: <9110242141.AA03488@sunJe.TELLABS.COM> To: glove-list@karazm.math.uh.edu Subject: 68HC11 power glove code (long) Here's the 68HC11 power glove code. Notice that it does not include deglitching. This is mainly because I think there is a problem in the glove read routine, and I wanted it to be more obvious (for now). I haven't tried any of the other versions of the software, so I don't know the proper behavior, but my code seems to receive a large amount of noise, and it gets worse when you make a fist with the glove. My guess is that there is some timing that is slightly off, and the reduced sample rate when a fist is made makes it worse. I haven't had time to play with it, and many people have been asking for the code, so I'll send it as is... Please send me any comments/suggestions/corrections/flames or whatever! -Ron Menelli menellli@tellabs.com ------------------------cut here---------------------------------------- ;/********************************************************************** ; ; Originally "power.c" (c) manfredo 9/91 (manfredo@opal.cs.tu-berlin.de) ; Developed on an ATARI 1040ST with TC 1.1 using a logic analyzer to get ; the correct timings. ; ;**********************************************************************/ ;/********************************************************************* ; ported to PC compatibles by ; Greg Alt 10/91 ; ; galt@peruvian.utah.edu ; or galt@es.dsd.com ; ;**********************************************************************/ ;/********************************************************************* ; ; Substantially rewritten by Dave Stampe (c) 1991: PWRFILT.C ; No cash, no warranty, no flames. ; This stuff works great, so gimme credit. ; ; Goals were: ; ; Higher speed, smaller code. ; Polled operation is now possible. ; Graphics test (VGA) ; Noise reduction added, gets rid of 99.5% of noise with NO DELAY! ; ; This runs on a 486/25 with an i/o card. ; Someone should adapt it for the usual printer port adapter. ; It was compiled with Turbo C++ 2.0 but will probably ; work on any Turbo C directly. MSC will need library calls checked. ; ; ; dstamp@watserv1.uwaterloo.ca 17/10/91 ;**********************************************************************/ ; ; ; 68HC11 version by Ron Menelli, 10/23/91 ; ; A million thanks to the above people for taking this project as far ; as it has gone! This version runs on the MC68HC11 processor, specifically ; Motorola's MC68HC11EVB board. The assembler I used was Matt Dillon's ; DASM for the Amiga - this code will have to be converted a bit to be ; used on Motorola's freeware assembler. ; ; As it stands, this code is a direct port of Dave Stampe's code minus ; the IBM specific stuff (VGA, for example). The way this code works is ; by sending the data received from the Power Glove over the serial port ; at 9600 baud. By sending single character commands, the serial port ; action can be controlled as follows: ; ; Send Action ; ==== ========= ; C Start continuous mode - send every time the glove is read. ; The data is sent with a certain byte preceding it as a ; flag marking the beginning. The format I have used is: ; ; A0 X Y Z rot fingers keys ; ; ^ ; +--- Flag character (A0 used for old time's sake!) ; ; R Start request mode - send the 6 byte data packet when ; requested by user. Format is the same as above, minus ; the flag character. ; ; ? In request mode, this causes the controller to report ; the current glove data. ; ; *** Note that the deglitching code is not in this version ; ; Please send me any suggestions you have regarding improvements to this ; code! ; ; -Ron Menelli menelli@tellabs.com ; PROCESSOR 68HC11 ; Needed for DAsm ORG $D000 ; Jump to this address to start ; This is the beginning of RAM for the EVB. ; ; Macro definitions ; ; Delay 3us (made a macro because a subroutine would be too slow) MAC DELAY3US NOP NOP NOP ENDM ; Set Clock = 0, Latch = 0 MAC C0L0 LDAB #0 STAB PORTA ENDM ; Set Clock = 0, Latch = 1 MAC C0L1 LDAB #GLATCH STAB PORTA ENDM ; Set Clock = 1, Latch = 0 MAC C1L0 LDAB #GCLOCK STAB PORTA ENDM ; Set Clock = 1, Latch = 1 MAC C1L1 LDAB #GCLOLAT STAB PORTA ENDM ; ; RAM allocation ; BITCNT EQU $0000 BYTECNT EQU $0001 GLOVEFLAG EQU $0002 ; Flag byte for continuous mode GLOVEDATA EQU $0003 ; 7 byte array UNREADY EQU $0009 MODEFLAG EQU $000A ; Mode flag - continuous or request ; ; Port A definitions ; ; bit 0 - Data in ; bit 4 - Clock out ; bit 5 - Latch out ; PORTA EQU $1000 PACTL EQU $1026 GDATA EQU $01 GCLOCK EQU $10 GLATCH EQU $20 GCLOLAT EQU $30 ; ; Serial port definitions ; BAUD EQU $102B SCCR1 EQU $102C SCCR2 EQU $102D SCSR EQU $102E SCDR EQU $102F ; ; Timing constants (for an 8Mhz crystal) ; D2BYTES EQU 30 ; 96us D2SLOW EQU 700 ; ~= 2100us ; Other stuff CONTMODE EQU 0 ; Continuous mode REQMODE EQU 1 ; Request mode CONTCHAR EQU 'C ; Character to request cont. mode REQCHAR EQU 'R ; Character to request request mode QUERYCHAR EQU '? ; Character to request a data packet ; * Only valid in request mode FLAGCHAR EQU $A0 ; Flag indicating beginning of packet in ; continuous mode ; ; *********************** ; * Program begins here * ; *********************** ; INIT: LDS #$00FF ; Initialize stack pointer LDAA #0 ; Disable pulse accumulator on port A STAA PACTL LDAA #$01 ; Set EVB to serial receive normally STAA $4000 LDAA #$30 ; Set serial port for 9600 baud ; (using 8 MHz XTAL) ; (Set to $20 for 31.25 kbaud) STAA BAUD LDAA #$0C ; Transmit & receive enable STAA SCCR2 LDAA #FLAGCHAR ; Set up flag character in buffer STAA GLOVEFLAG LDAA #CONTMODE ; Start in request mode STAA MODEFLAG INITGLOVE: JSR HIRES ; Set hi-res mode ; ; ********************* ; * Main program loop * ; ********************* ; MAIN: LDAA #0 ; Zero the retry counter STAA UNREADY LDX #D2SLOW ; Wait a while JSR DELAY CHECKRDY: JSR GETBYTE ; Check to see if glove is ready CMPA #$A0 ; Is it A0 (the start of the sequence?) BEQ READDATA ; Yes, read the rest of the data sequence INC UNREADY ; Increment retry counter BEQ INITGLOVE ; If 256 tries, initialize the glove again LDX #D2SLOW ; Wait and try again JSR DELAY BRA CHECKRDY READDATA: LDY #GLOVEDATA JSR GETGLOVE ; Read glove data into buffer LDY #GLOVEDATA LDAA SCSR ; Check serial port receive status ANDA #$20 BEQ CHECKMODE LDAA SCDR ; Character received - check it CMPA #QUERYCHAR ; Is it the query character? BNE NOTQRYCH ; No - skip this LDAA MODEFLAG ; Yes - check to see what mode we're in CMPA #REQMODE ; If not in request mode, skip this BNE CHECKMODE LDY #GLOVEDATA ; Send 6 bytes over the serial port LDAB #6 JSR SENDSER ; This does our pausing for us (6.25 ms) BRA MAIN ; No need to continue checking NOTQRYCH: CMPA #CONTCHAR ; Is it the cont. mode activator? BNE NOTCONTCH ; No - skip this LDAA #CONTMODE ; Yes - set continuous mode STAA MODEFLAG BRA CHECKMODE NOTCONTCH: CMPA #REQCHAR ; Is it the request mode activator? BNE CHECKMODE ; No - skip this LDAA #REQMODE ; Yes - set request mode STAA MODEFLAG BRA WAIT ; No need to continue checking CHECKMODE: LDAA MODEFLAG ; Check the mode flag CMPA #CONTMODE ; Is it continuous mode? BNE WAIT ; No - wait and start the loop again LDY #GLOVEFLAG ; Send data (6 + Flag) over serial port LDAB #7 JSR SENDSER ; This provides approx. 7.29 ms of delay ; at 9600 baud BRA MAIN WAIT: LDX #D2SLOW ; Wait a while before continuing JSR DELAY BRA MAIN ; ; ************************************** ; * Delay subroutine * ; * (Delay proportional to value in X) * ; ************************************** ; DELAY: DEX BNE DELAY RTS ; ; ******************* ; * Set hi-res mode * ; ******************* ; HIRES: C1L0 ; Dummy read 4 dummy bits from glove C1L1 DELAY3US C1L0 DELAY3US C0L0 C1L0 DELAY3US C0L0 C1L0 DELAY3US C0L0 C1L0 DELAY3US C0L0 C1L0 C1L0 LDX #2402 ; Delay 7212us JSR DELAY C1L1 LDX #752 ; Delay 2260us JSR DELAY LDAA #7 STAA BYTECNT LDY #HRCODE ; Send the 7 byte code BYTELOOP: LDAA #8 STAA BITCNT LDAA 0,Y BITLOOP: LSLA BCC BITOFF C1L1 C0L1 C1L1 BRA NEXTLOOP BITOFF: C1L0 C0L0 C1L0 NEXTLOOP: DELAY3US DEC BITCNT BNE BITLOOP LDX #D2BYTES JSR DELAY INY DEC BYTECNT BNE BYTELOOP LDX #296 ; Delay 892us JSR DELAY C1L0 LDX #20000 ; Delay a "long time" JSR DELAY RTS ; ; Glove initialization bytes ; HRCODE: dc.b $06,$C1,$08,$00,$02,$FF,$01 ; ; ******************************************* ; * Get the 6 byte data packet * ; * (Places data in buffer pointed to by Y) * ; ******************************************* ; GETGLOVE: JSR GETBYTE ; Get each byte consecutively STAA 0,Y ; and store in memory INY LDX #D2BYTES JSR DELAY JSR GETBYTE STAA 0,Y INY LDX #D2BYTES JSR DELAY JSR GETBYTE STAA 0,Y INY LDX #D2BYTES JSR DELAY JSR GETBYTE STAA 0,Y INY LDX #D2BYTES JSR DELAY JSR GETBYTE STAA 0,Y INY LDX #D2BYTES JSR DELAY JSR GETBYTE STAA 0,Y LDX #D2BYTES JSR DELAY JSR GETBYTE ; Throw away last two bytes LDX #D2BYTES JSR DELAY JSR GETBYTE RTS ; ; ***************************** ; * Get a byte from the glove * ; * (Returns byte in A) * ; ***************************** ; GETBYTE: C1L0 ; Pulse the latch line C1L1 DELAY3US C1L0 LDAA #8 STAA BITCNT GETLOOP: LSLA ; Read 8 bits sequentially LDAB PORTA ANDB #GDATA ; Mask off other bits ABA ; Assemble the data byte C0L0 C1L0 DEC BITCNT BNE GETLOOP RTS ; ; *********************************************** ; * Send an X byte packet over the serial port * ; * (Y contains the address of the data buffer, * ; * B contains the number of bytes to send) * ; *********************************************** ; SENDSER: LDAA SCSR ; Check status register for Tx ready ANDA #$80 BEQ SENDSER ; Try again if not ready LDAA 0,Y ; Send byte to the serial port STAA SCDR INY ; Move to next data byte DECB BNE SENDSER ; Send next byte if not done RTS