Hello Ganimides,
The assembly code shown in the file Wiegand26.asm seems to actually refer to the 31-bit Wiegand protocol, rather than the 26-bit protocol that you appear to require. Additionally, by attempting to separate the raw data, as received, into only the lower nybble of a number of byte registers has resulted in code that is much more complex than it needs to be. This is probably not a good example to attempt to convert to C code.
A simpler approach, and assuming a 26-bit protocol with 24 data bits, would be to shift the data bits into a three byte register. The separation into six nybbles, to represent either hexadecimal or BCD data, and the conversion to ASCII characters, can then be done once the data accumulation is complete, and outside of any ISR. This is quite a simple process. I am assuming that the first and last (parity) bits of the sequence would simply be ignored.
There appears to be no particular advantage to consuming a pair of timer channels to detect the data pulses. I would probably consider using the keyboard interrupt facility. You will still need to monitor timer overflow to detect timeout of the Wiegand sequence.
Here are some untested assembly code snippets to demonstrate the simplification. I have not shown initialisation for the DATA0 and DATA1 input pins, the KB module, or the timer.
The following page 0 RAM registers are used within the code -
ORG RAM
OVFCNT DS 1 ; TIM overflow counter
BITCNT DS 1 ; Bit counter
DATREG DS 3 ; Register for Wiegand data
The following code would be required within the main loop -
LDA BITCNT
CMP #25 ; Test for new data available
BNE ML1 ; Branch if not
LDA DATREG
JSR DISPHEX ; Display byte as hexadecimal
LDA DATREG+1
JSR DISPHEX ; Display byte as hexadecimal
LDA DATREG+2
JSR DISPHEX ; Display byte as hexadecimal
; Clear registers for next reading
CLR DATREG
CLR DATREG+1
CLR DATREG+2
CLR BITCNT
BSET ACKK,KBSCR ; Clear KB flag
BCLR IMASKK,KBSCR ; Enable KB interrupts
ML1:
Here are the supporting sub-routines used. The SENDCHR routine sends a single ASCII character to a suitable display device, e.g. LCD display, or perhaps SCI.
***************************************************************
* DISPLAY BYTE AS HEXADECIMAL VALUE
* On entry, ACC = byte value
***************************************************************
DISPHEX: PSHA ; Save value for later
JSR UHEX2ASC ; Convert upper nybble
JSR SENDCHR ; Display character
PULA
JSR LHEX2ASC ; Convert lower nybble
JSR SENDCHR ; Display character
RTS
***************************************************************
* CONVERT NYBBLE VALUE TO ASCII
* On entry, ACC = byte value for conversion
***************************************************************
LHEX2ASC: ; Convert lower nybble
AND #$0F
BRA H2A1 ; Branch always
UHEX2ASC: ; Convert upper nybble
LSRA
LSRA
LSRA
LSRA
H2A1: CMP #9
BLS *+4 ; Skip next if numeric value
ADD #7
ADD #'0' ; Convert to ASCII value
RTS
And now for the ISR code -
***************************************************************
* KEYBOARD ISR
***************************************************************
KB_ISR: CLR OVFCNT ; Clear TIM overflow count
LDA BITCNT
BEQ KBI1 ; Branch if first parity bit
BRCLR DATA0,PTA,*+3 ; Set/clear CF - current bit state
ROL DATREG+2
ROL DATREG+1
ROL DATREG
KBI1: INC BITCNT
LDA BITCNT
CMP #25 ; Test for last data bit
BLO KBI2 ; Exit if not
BSET IMASKK,KBSCR ; Mask further KB interrupts
KBI2: BSET ACKK,KBSCR ; Clear KB flag
RTI
***************************************************************
* TIMER OVERFLOW ISR
***************************************************************
TIM_ISR: TST BITCNT
BEQ TIR2 ; Exit if already initialised
TST OVFCNT
BNE TIR1 ; Branch if prior overflow
INC OVFCNT ; Increment value
BRA TIR2 ; Exit always
TIR1: LDA BITCNT
CMP #25 ; Test for data complete
BHS TIR2 ; Exit if so
; Premature timeout for end of data
CLR DATREG
CLR DATREG+1
CLR DATREG+2
CLR BITCNT
TIR2: BCLR TOF,TSC ; Clear TIM overflow flag
RTI
Regards,
Mac
Message Edited by bigmac on 2006-09-2901:40 PM