1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-17 06:18:06 +11:00

recipes/rc2014/ps2: add parity checks

Also, add timer to reset reception status after 100us.
This commit is contained in:
Virgil Dupras 2019-06-29 20:45:08 -04:00
parent 360446e731
commit 0f82ebe02d

View File

@ -75,6 +75,7 @@
; - 2: awaiting parity bit ; - 2: awaiting parity bit
; - 3: awaiting stop bit ; - 3: awaiting stop bit
; it reaches 11, we know we're finished with the frame. ; it reaches 11, we know we're finished with the frame.
; R19: Register used for parity computations
; R20: data being sent to the 595 ; R20: data being sent to the 595
; Y: pointer to the memory location where the next scan code from ps/2 will be ; Y: pointer to the memory location where the next scan code from ps/2 will be
; written. ; written.
@ -88,6 +89,9 @@
.equ CE = PINB4 .equ CE = PINB4
.equ RCLK = PINB0 .equ RCLK = PINB0
; init value for TCNT0 so that overflow occurs in 100us
.equ TIMER_INITVAL = 0x100-100
rjmp main rjmp main
rjmp hdlINT0 rjmp hdlINT0
rjmp hdlPCINT rjmp hdlPCINT
@ -145,6 +149,13 @@ main:
clr ZH clr ZH
ldi ZL, low(SRAM_START) ldi ZL, low(SRAM_START)
; Setup timer. We use the timer to clear up "processbit" registers after
; 100us without a clock. This allows us to start the next frame in a
; fresh state. at 8MHZ, setting the counter's prescaler to 8 gives us
; a nice 1us for each TCNT0.
ldi r16, (1<<CS01) ; clk/8 prescaler
out TCCR0B, r16
; init DDRB ; init DDRB
sbi DDRB, SRCLK sbi DDRB, SRCLK
cbi PORTB, RCLK ; RCLK is generally kept low cbi PORTB, RCLK ; RCLK is generally kept low
@ -156,6 +167,9 @@ loop:
brts processbit ; flag T set? we have a bit to process brts processbit ; flag T set? we have a bit to process
cp YL, ZL ; if YL == ZL, buffer is empty cp YL, ZL ; if YL == ZL, buffer is empty
brne sendTo595 ; YL != ZL? our buffer has data brne sendTo595 ; YL != ZL? our buffer has data
in r16, TIFR
sbrc r16, TOV0
rjmp processbitReset ; Timer0 overflow? reset processbit
rjmp loop rjmp loop
; Process the data bit received in INT0 handler. ; Process the data bit received in INT0 handler.
@ -165,6 +179,10 @@ processbit:
cbi GPIOR0, 0 cbi GPIOR0, 0
clt ; ready to receive another bit clt ; ready to receive another bit
; We've received a bit. reset timer
ldi r19, TIMER_INITVAL
out TCNT0, r19
; Which step are we at? ; Which step are we at?
tst r18 tst r18
breq processbits0 breq processbits0
@ -181,6 +199,7 @@ processbit:
st Y+, r17 st Y+, r17
rcall checkBoundsY rcall checkBoundsY
rjmp loop rjmp loop
processbits0: processbits0:
; step 0 - start bit ; step 0 - start bit
; DATA has to be cleared ; DATA has to be cleared
@ -209,10 +228,23 @@ processbits1:
rjmp loop rjmp loop
processbits2: processbits2:
; step 2 - parity bit ; step 2 - parity bit
; TODO: check parity mov r1, r16
mov r19, r17
rcall checkParity ; --> r16
cp r1, r16
; TODO: implement "resend requests" on parity check failure
brne processbitReset ; r1 != r16? wrong parity
inc r18 inc r18
rjmp loop rjmp loop
processbitReset:
clr r18
ldi r16, TIMER_INITVAL
out TCNT0, r16
ldi r16, (1<<TOV0)
out TIFR, r16
rjmp loop
; send next scan code in buffer to 595, MSB. ; send next scan code in buffer to 595, MSB.
sendTo595: sendTo595:
sbic GPIOR0, 1 sbic GPIOR0, 1
@ -280,3 +312,16 @@ checkBoundsZ:
clr ZH clr ZH
ldi ZL, low(SRAM_START) ldi ZL, low(SRAM_START)
ret ret
; Counts the number of 1s in r19 and set r16 to 1 if there's an even number of
; 1s, 0 if they're odd.
checkParity:
ldi r16, 1
lsr r19
brcc PC+2 ; Carry unset? skip next
inc r16 ; Carry set? We had a 1
tst r19 ; is r19 zero yet?
brne checkParity+1 ; no? loop and skip first LDI
andi r16, 0x1 ; Sets Z accordingly
ret