From 2c6ab08d516caf612c59eb80828fe0fd2d6b2da1 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 30 Jun 2019 11:17:12 -0400 Subject: [PATCH] recipes/rc2014/ps2: add "resend" requests on parity check failures --- recipes/rc2014/ps2/ps2ctl.asm | 130 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 115 insertions(+), 15 deletions(-) diff --git a/recipes/rc2014/ps2/ps2ctl.asm b/recipes/rc2014/ps2/ps2ctl.asm index f4bad78..7728f0d 100644 --- a/recipes/rc2014/ps2/ps2ctl.asm +++ b/recipes/rc2014/ps2/ps2ctl.asm @@ -75,7 +75,7 @@ ; - 2: awaiting parity bit ; - 3: awaiting stop bit ; it reaches 11, we know we're finished with the frame. -; R19: Register used for parity computations +; R19: Register used for parity computations and tmp value in some other places ; R20: data being sent to the 595 ; Y: pointer to the memory location where the next scan code from ps/2 will be ; written. @@ -174,14 +174,13 @@ loop: ; Process the data bit received in INT0 handler. processbit: - in r16, GPIOR0 ; backup GPIOR0 before we reset T - andi r16, 0x1 ; only keep the first flag + in r19, GPIOR0 ; backup GPIOR0 before we reset T + andi r19, 0x1 ; only keep the first flag cbi GPIOR0, 0 clt ; ready to receive another bit ; We've received a bit. reset timer - ldi r19, TIMER_INITVAL - out TCNT0, r19 + rcall resetTimer ; Which step are we at? tst r18 @@ -193,7 +192,7 @@ processbit: ; step 3: stop bit clr r18 ; happens in all cases ; DATA has to be set - tst r16 ; Was DATA set? + tst r19 ; Was DATA set? breq loop ; not set? error, don't push to buffer ; push r17 to the buffer st Y+, r17 @@ -203,7 +202,7 @@ processbit: processbits0: ; step 0 - start bit ; DATA has to be cleared - tst r16 ; Was DATA set? + tst r19 ; Was DATA set? brne loop ; Set? error. no need to do anything. keep r18 ; as-is. ; DATA is cleared. prepare r17 and r18 for step 1 @@ -216,7 +215,7 @@ processbits1: ; We're about to rotate the carry flag into r17. Let's set it first ; depending on whether DATA is set. clc - sbrc r16, 0 ; skip if DATA cleared. + sbrc r19, 0 ; skip if DATA cleared. sec ; Carry flag is set ror r17 @@ -228,21 +227,23 @@ processbits1: rjmp loop processbits2: ; step 2 - parity bit - mov r1, r16 + mov r1, r19 mov r19, r17 rcall checkParity ; --> r16 cp r1, r16 - ; TODO: implement "resend requests" on parity check failure - brne processbitReset ; r1 != r16? wrong parity + brne processbitError ; r1 != r16? wrong parity inc r18 rjmp loop +processbitError: + clr r18 + ldi r19, 0xfe + rcall sendToPS2 + rjmp loop + processbitReset: clr r18 - ldi r16, TIMER_INITVAL - out TCNT0, r16 - ldi r16, (1< r16 + + ; Wait for CLK to go low + sbic PINB, CLK + rjmp PC-1 + + ; set parity bit + cbi PORTB, DATA + sbrc r16, 0 ; parity bit in r16 + sbi PORTB, DATA + + ; Wait for CLK to go high + sbis PINB, CLK + rjmp PC-1 + + ; Wait for CLK to go low + sbic PINB, CLK + rjmp PC-1 + + ; We can now release the DATA line + cbi DDRB, DATA + + ; Wait for DATA to go low. That's our ACK + sbic PINB, DATA + rjmp PC-1 + + ; Wait for CLK to go low + sbic PINB, CLK + rjmp PC-1 + + ; We're finished! Enable INT0, reset timer, everything back to normal! + rcall resetTimer + clt ; also, make sure T isn't mistakely set. + ldi r16, (1<