1 | .include "tn26def.inc" ; Deklarationen für ATtiny26
|
2 |
|
3 | .equ adress = 127 ; TWI Adresse
|
4 |
|
5 |
|
6 | .cseg ; Programm-Flash
|
7 | rjmp init ; Reset-Einsprung
|
8 |
|
9 | .org 0x007 ; USI Start Interrupt
|
10 | rjmp usi_start
|
11 |
|
12 | .org 0x008 ; USI Overflow Interrupt
|
13 | rjmp twis
|
14 |
|
15 |
|
16 | .org 0x00C ; Interrupteinsprünge übergehen
|
17 |
|
18 | init: ldi R16, RAMEND ; Stapel anlegen
|
19 | out SP, R16
|
20 |
|
21 | ldi R16, 0b11111111 ; PortA als Ausgang
|
22 | out DDRA, R16
|
23 |
|
24 | ; USI Control Register
|
25 | ldi R16, (1 << USISIE) | (1 << USIWM1) | (1 << USIWM0) | (1 << USICS1)
|
26 | out USICR, R16
|
27 |
|
28 | ldi R16, 0xF0
|
29 | out USISR, R16
|
30 |
|
31 | sei ; Interrupts aktivieren
|
32 |
|
33 | loop: rjmp loop ; Endlosschleife
|
34 |
|
35 |
|
36 |
|
37 | usi_start:
|
38 | push R16 ; Register retten
|
39 |
|
40 | ; Start Condition Interrupt Flag zurücksetzen
|
41 | ldi R16, (1 << USISIF)
|
42 | out USISR, R16
|
43 |
|
44 | ; Overflow Interrupt aktivieren
|
45 | ldi R16, (1 << USISIE) | (1 << USIOIE) | (1 << USIWM1) | (1 << USIWM0) | (1 << USICS1)
|
46 | out USICR, R16
|
47 |
|
48 | ldi R16, 10 ; Neuen Status laden
|
49 | sts TWSR, R16 ; Status im SRAM speichern
|
50 |
|
51 | pop R16 ; Register wiederherstellen
|
52 | reti ; Kehre zurück
|
53 |
|
54 |
|
55 |
|
56 | twis: push R16 ; Register retten
|
57 |
|
58 | ; Counter Overflow Interrupt Flag zurücksetzen
|
59 | ldi R16, (1 << USIOIF)
|
60 | out USISR, R16
|
61 |
|
62 | ;- Adresse überprüfen -----------------------------------------------------------------
|
63 |
|
64 | lds R16, TWSR ; Virtuelles statusregister aus dem SRAM laden
|
65 | cpi R16, 10 ; 10 = Start Condition wurde erkannt, Adresse wurde gesendet
|
66 | brne twis2 ; Springe zu twis2 wenn ungleich
|
67 |
|
68 | in R16, USIDR ; Adresse + R/W in R16 laden
|
69 | andi R16, 0b11111110 ; Maskieren
|
70 |
|
71 | push R17 ; Register retten
|
72 | ldi R17, (adress << 1) ; Slave Adresse laden
|
73 |
|
74 | cp R16, R17 ; Vergleichen
|
75 | pop R17 ; Register wiederherstellen
|
76 | breq twis1 ; Überspringe nächste 3 Befehle wenn gleich
|
77 |
|
78 | ; Adresse stimmt nicht überein
|
79 | ; Overflow Interrupt bis zur nächsten START condition deaktivieren
|
80 | ldi R16, (1 << USISIE) | (1 << USIWM1) | (1 << USIWM0) | (1 << USICS1)
|
81 | out USICR, R16
|
82 |
|
83 | rjmp twis_end ; Springe zum Ende der ISR
|
84 |
|
85 | ;- Adresse stimmt überein, ACK senden -------------------------------------------------
|
86 |
|
87 | twis1: clr R16 ; Schieberegister leeren
|
88 | out USIDR, R16
|
89 |
|
90 | sbi DDRB, 0 ; Ausgangstreiber an SDA aktivieren
|
91 |
|
92 | ldi R16, 13 ; Counter laden
|
93 | out USISR, R16
|
94 |
|
95 | ldi R16, 20 ; Neuen Status laden
|
96 | sts TWSR, R16 ; Status im SRAM speichern
|
97 |
|
98 | rjmp twis_end ; Springe zum Ende der ISR
|
99 |
|
100 | ;- Datenempfang vorbereiten------------------------------------------------------------
|
101 |
|
102 | twis2: lds R16, TWSR ; Virtuelles statusregister aus dem SRAM laden
|
103 | cpi R16, 20 ; 20 = Eigene Slave-Adresse + R/W wurde empfangen; ACK wurde gesendet
|
104 | brne twis3 ; Springe wenn ungleich
|
105 |
|
106 | cbi DDRB, 0 ; DDR an SDA auf low
|
107 |
|
108 | ldi R16, 30 ; Neuen Status laden
|
109 | sts TWSR, R16 ; Status im SRAM speichern
|
110 |
|
111 | rjmp twis_end ; Springe zum Ende der ISR
|
112 |
|
113 | ;- Daten wurden empfangen -------------------------------------------------------------
|
114 |
|
115 | twis3: lds R16, TWSR ; Virtuelles statusregister aus dem SRAM laden
|
116 | cpi R16, 30 ; 30 = Daten wurden empfangen
|
117 | brne twis4 ; Springe wenn ungleich
|
118 |
|
119 | in R16, USIDR ; Daten einlesen
|
120 | out PORTA, R16
|
121 |
|
122 | ;- Daten wurden empfangen, ACK senden -------------------------------------------------
|
123 |
|
124 | clr R16 ; Schieberegister leeren
|
125 | out USIDR, R16
|
126 |
|
127 | sbi DDRB, 0 ; Ausgangstreiber an SDA aktivieren
|
128 |
|
129 | ldi R16, 13 ; Counter laden
|
130 | out USISR, R16
|
131 |
|
132 | ldi R16, 40 ; Neuen Status laden
|
133 | sts TWSR, R16 ; Status im SRAM speichern
|
134 |
|
135 | rjmp twis_end ; Springe zum Ende der ISR
|
136 |
|
137 | ;- Datenempfang vorbereiten------------------------------------------------------------
|
138 |
|
139 | twis4: lds R16, TWSR ; Virtuelles statusregister aus dem SRAM laden
|
140 | cpi R16, 40 ; 40 = Daten wurden empfangen; ACK wurde gesendet
|
141 | brne twis_end ; Springe wenn ungleich
|
142 |
|
143 | cbi DDRB, 0 ; DDR an SDA auf low
|
144 |
|
145 | ldi R16, 20 ; Neuen Status laden
|
146 | sts TWSR, R16 ; Status im SRAM speichern
|
147 |
|
148 | twis_end:
|
149 | pop R16 ; Register wiederherstellen
|
150 | reti ; Kehre zurück
|
151 |
|
152 |
|
153 |
|
154 | .DSEG
|
155 |
|
156 |
|
157 | ; USI - TWI Status Register
|
158 | TWSR:
|
159 | .byte 1
|