.equ sr_enca = 0x0080 ; Encoder A-Entprellung (Phase A)
.equ sr_encb = 0x0081 ; Encoder B-Entprellung (Phase B)
.equ sr_encp = 0x0082 ; Encoder P-Entprellung (Push-Button)
.equ sr_encm = 0x0083 ; Encoder Memory (Ergebnis AB-Aktuell/Zuletzt)
.equ sr_enct = 0x0084 ; Encoder Toggle (Ergebnis Push-Button Aktuell/Zuletzt)
.equ sr_encc = 0x0085 ; Encoder Counter (+/- ueber Drehung)
.equ sr_encd = 0x0086 ; Encoder Diff (+1/0/-1 ueber Drehung)
; ==================================================================
; ===== Encoder-Daten verarbeiten ==================================
; ==================================================================
encoder:
push r19 ; r19 auf Stack retten (fuer wiederherstellung)
push r20 ; r20 auf Stack retten (fuer wiederherstellung)
push r21 ; r21 auf Stack retten (fuer wiederherstellung)
push r22 ; r22 auf Stack retten (fuer wiederherstellung)
; r19 -- Eingabe Encoder-Port , Ergebnis Tastenentprellung (Bit6 fuer Pushbutton)
; r20 -- A/B/P-Entprellung , Differenz
; r21 -- Ergebnis AB-Aktuell/Zuletzt (Statemachine) ,
; Ergebnis C-Aktuell/Zuletzt (Flankenerkennung)
; r22 -- Zaehlwert , Encoder-Statemachine Nibble-Rettung
;
; r20 00001111<-A
; r20 00000011<-A
; ||||
; \\\\_ 0000=0, 1111=1 => 4Zyklen-Entprellung (oder auch mehr)
;
; == Rechts == Uhrzeigersinn ==
;
; B ___________------------____________------------______ R - Rastung
; | : | : | : | : | : | : | : | : | 1 - 1/4
; A _____------------____________------------____________ 2 - Halb
; | : | : | : | : | : | : | : | : | 3 - 3/4
; 2 : 3 : R : 1 : 2 : 3 : R : 1 : 2 : - Flanken
; : : : : : : : :
; B 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 Bit3 aktuell
; A 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 Bit2________
; b 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 Bit1
; a 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 Bit0 zuletzt
; ->->-> 4 5>13 15 11 10 2 0 4 5>13 15 11 10 2 ->->->
; ++ ++ inc
;
; == Links == Gegen-Uhrzeigersinn ==
;
; B _____------------____________------------____________ R - Rastung
; | : | : | : | : | : | : | : | : | 1 - 1/4
; A ___________------------____________------------______ 2 - Halb
; | : | : | : | : | : | : | : | : | 3 - 3/4
; 2 : 3 : R : 1 : 2 : 3 : R : 1 : 2 : - Flanken
; : : : : : : : :
; B 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 Bit3 aktuell
; A 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 Bit2________
; b 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 Bit1
; a 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 Bit0 zuletzt
; ->->-> 8 10>14 15 7 5 1 0 8 10>14 15 7 5 1 ->->->
; -- -- dec
;
lds r19,sr_541e ; Encoder-Input aus SRAM-Puffer holen
; =========================================
; ========== ENCODER-BEARBEITUNG ==========
; =========================================
; ===== Statemachine vorbereiten =====
lds r21,sr_encm ; Memory Encoder-Statemachine <- SRAM
cbr r21,0b11110000 ; uraltes gerettetes Nibble vernichten
mov r22,r21 ; alten Komplettwert retten
swap r22 ; Nibbles tauschen (alten Komplettwert in Bits 7-4)
lsr r21 ; 2 Bits nach rechts ( ab00 -> 00ab )
lsr r21 ; Auf Position fuer letzte Abfrage
; ===== A entprellen =====
lds r20,sr_enca ; Entprellung Phase A <- SRAM
bst r19,0 ; Bit 0 von r19 in T-Bit setzen
sec ; Carry setzen
brbs 6,a_on ; Branch if Bit6 (T) ist set
clc ; Carry loeschen
a_on: rol r20 ; Carry ins Entprell-Reg nach links einrotieren
cbr r20,0b11110000 ; Maske fuer ON-Zyklen
; |||||||| ; Bei 4Zyklen-Entprellung => Maske 0x11110000 / Test 0x00001111
cpi r20,0b00001111 ; r20 auf 0b00001111 testen (A x Zyklen on)
brne a_on1 ; springen wenn nicht gleich
sbr r21,0b00000100 ; Bit 2 in r21 setzen (A an und entprellt) -> Statemachine
a_on1: cpi r20,0 ; r20 auf 0b00000000 testen (A x Zyklen off)
brne a_on0 ; springen wenn nicht gleich
cbr r21,0b00000100 ; Bit 2 in r21 loeschen (A nicht an und entprellt) -> Statemachine
a_on0:
sts sr_enca,r20 ; Entprellung Phase A -> SRAM
; ===== B entprellen =====
lds r20,sr_encb ; Entprellung Phase B <- SRAM
bst r19,1 ; Bit 1 von r19 in T-Bit setzen
sec ; Carry setzen
brbs 6,b_on ; Branch if Bit6 (T) ist set
clc ; Carry loeschen
b_on: rol r20 ; Carry ins Entprell-Reg nach links einrotieren
cbr r20,0b11110000 ; Maske fuer ON-Zyklen
; |||||||| ; Bei 4Zyklen-Entprellung => Maske 0x11110000 / Test 0x00001111
cpi r20,0b00001111 ; r20 auf 0b00001111 testen (B x Zyklen on)
brne b_on1 ; springen wenn nicht gleich
sbr r21,0b00001000 ; Bit 3 in r21 setzen (B an und entprellt) -> Statemachine
b_on1: cpi r20,0 ; r20 auf 0b00000000 testen (B x Zyklen off)
brne b_on0 ; springen wenn nicht gleich
cbr r21,0b00001000 ; Bit 3 in r21 loeschen (B nicht an und entprellt) -> Statemachine
b_on0:
sts sr_encb,r20 ; Entprellung Phase B -> SRAM
; ===== Statemachine erweitern =====
add r21,r22 ; altes gerettetes Nibble hinzuaddieren
; altes _____ _____aktuelles Nibble
; AB ab AB ab
; 01 01 11 01 - 5/13 = 0x5D -> rechts = inc
; 10 10 11 10 - 10/14 = 0xAE -> links = dec
sts sr_encm,r21 ; Memory Encoder-Statemachine -> SRAM
; ===== Statemachine abfragen =====
clr r20 ; Diff auf 0x00 (+1/0/-1 => 2er Complement => 0x01/0x00/0xFF)
lds r22,sr_encc ; Encoder Counter (8Bit) <- SRAM
cpi r21,0x5D ; r21 auf 0x5D testen (Rechts herum)
brne nrechts ; springen wenn nicht gleich (nicht rechts -> links oder nix)
inc r20 ; Diff = +1 (0x01)
inc r22 ; 8Bit-Counter +1
rjmp nlinks ; rechts rum ist abgearbeitet -> weiter
nrechts:
cpi r21,0xAE ; r21 auf 0xAE testen (Links herum)
brne nlinks ; springen wenn nicht gleich (nicht links -> bleibt nix)
dec r20 ; Diff = -1 (0xFF)
dec r22 ; 8Bit-Counter -1
nlinks:
sts sr_encd,r20 ; Encoder Diff -> SRAM
sts sr_encc,r22 ; Encoder Counter (8Bit) -> SRAM
; State-Machine wird ab hier nicht mehr benoetigt -> r21 wieder frei
; =============================================
; ========== PUSH-BUTTON-BEARBEITUNG ==========
; =============================================
; ===== Flankenerkennung vorbereiten =====
lds r21,sr_enct ; Memory Push-Button Flankenerkennung <- SRAM
cbr r21,0b11111100 ; ueberschuessiges sicherheitshalber vernichten
lsr r21 ; Auf Position fuer letzte Abfrage ( p0 -> 0p )
; ===== P entprellen =====
bst r19,2 ; Bit 1 von r19 in T-Bit setzen
lds r20,sr_encp ; Entprellung Push-Button <- SRAM
lds r19,sr_keys ; Ergebnis Tasten-Entprellung <- SRAM
sec ; Carry setzen
brbs 6,p_on ; Branch if Bit6 (T) ist set
clc ; Carry loeschen
p_on: rol r20 ; Carry ins Entprell-Reg nach links einrotieren
cbr r20,0b11110000 ; Maske fuer ON-Zyklen
; |||||||| ; Bei 4Zyklen-Entprellung => Maske 0x11110000 / Test 0x00001111
cpi r20,0b00001111 ; r20 auf 0b00001111 testen (P x Zyklen on)
brne p_on1 ; springen wenn nicht gleich
sbr r21,0b00000010 ; Bit 3 in r21 setzen (P an und entprellt) -> Flankenerkennung
sbr r19,0b01000000 ; ebenso Bit 6 in r19 setzen -> Ergebnis Tastenentprellung
p_on1: cpi r20,0 ; r20 auf 0b00000000 testen (P x Zyklen off)
brne p_on0 ; springen wenn nicht gleich
cbr r21,0b00000010 ; Bit 3 in r21 loeschen (P nicht an und entprellt) -> Flankenerkennung
cbr r19,0b01000000 ; ebenso Bit 6 in r19 loeschen -> Ergebnis Tastenentprellung
p_on0:
sts sr_encp,r20 ; Entprellung Push-Button -> SRAM
sts sr_enct,r21 ; Memory Push-Button Flankenerkennung -> SRAM
sts sr_keys,r19 ; Ergebnis Tasten-Entprellung -> SRAM
; ===== Flankenerkennung abfragen =====
cpi r21,0x02 ; r21 auf 0x02 testen (gedrueckt --__ )
brne npress ; springen wenn nicht gleich (nicht gedrueckt -> losgelassen oder nix)
; WAS TUN #######################################
rjmp nrelease ; gedrueckt ist abgearbeitet -> weiter
npress:
cpi r21,0x01 ; r21 auf 0x01 testen (losgelassen __-- )
brne nrelease ; springen wenn nicht gleich (nicht losgelassen -> bleibt nix)
; WAS TUN #######################################
nrelease:
pop r22 ; r21 wiederherstellen
pop r21 ; r21 wiederherstellen
pop r20 ; r20 wiederherstellen
pop r19 ; r19 wiederherstellen
ret ; Subroutine Ende