1 | ; TWI I2C SLAVE
|
2 | ; 10/2005
|
3 | ; Bernhard.Erfurt@gmx.de
|
4 | ;
|
5 | ; TAKT=1.0 MHZ
|
6 | ;
|
7 | .include "m8def.inc"
|
8 |
|
9 |
|
10 | ; TWI Slave Receiver Codes
|
11 | .equ TW_SR_SLA_ACK = 0x60; x60 01100000 (SLA+W wurde empfangen-ACK wurde zurückgesendet)
|
12 | .equ TW_SR_ARB_LOST_SLA_ACK = 0x68; x68 01101000 (Arbitration verloren in SLA+R/W als MASTER; SLA+W wurde empfangen; ACK wurde zurückgesendet
|
13 | .equ TW_SR_GCALL_ACK = 0x70; x70 01110000 (General call address wurde empfangen; ACK wurde zurückgesendet
|
14 | .equ TW_SR_ARB_LOST_GCALL_ACK=0x78; x78 01111000 (Arbitration verloren in SLA+R/W als MASTER;General call address wurde empfangen; ACK wurde zurückgesendet
|
15 | .equ TW_SR_DATA_ACK = 0x80; x80 10000000 (die vorher adressierten (SLA+W) Daten wurden empfangen; ACK wurde zurückgesendet
|
16 | .equ TW_SR_DATA_NACK = 0x88; x88 10001000 (die vorher adressierten (SLA+W) Daten wurden empfangen; ACK wurde nicht zurückgesedet
|
17 | .equ TW_SR_GCALL_DATA_ACK = 0x90; x90 10010000 (die vorher adressierten (General call) Daten wurden empfangen; ACK wurde zurückgesendet
|
18 | .equ TW_SR_GCALL_DATA_NACK = 0x98; x98 10011000 (die vorher adressierten (General call) Daten wurden empfangen; ACK wurde nicht zurückgesendet
|
19 | .equ TW_SR_STOP = 0xA0; xA0 10100000 (STOP wurde empfangen, oder wiederholter Start)
|
20 | ; TWI Slave Transmitter Codes
|
21 | .equ TW_ST_SLA_ACK = 0xA8; xA8 10101000 (SLA+R wurde empfangen; ACK wurde zurückgesendet)
|
22 | .equ TW_ST_ARB_LOST_SLA_ACK = 0xB0; xB0 10110000 (Arbitration verlor SLA+R/W als MASTER, ACK wurde zurückgesendet)
|
23 | .equ TW_ST_DATA_ACK = 0xB8; xB8 10111000 (TWDR ist übertragen worden; ACK ist empfangen worden
|
24 | .equ TW_ST_DATA_NACK = 0xC0; xC0 11000000 (TWDR ist übertragen worden; ACK ist NICHT empfangen worden
|
25 | .equ TW_ST_LAST_DATA = 0xC8; xC8 11001000 (Letztes Datenbyte in TWDR ist übertragen worden (TWEA = "0"); Ack ist empfangen worden
|
26 | .equ TW_NO_INFO = 0xF8; xF8 11111000 (Keine relevanten Zustandinformationen vorhanden; TWINT = "0" keine TWDR-Tätigkeit
|
27 | .equ TW_BUS_ERROR = 0x00; x00 00000000 (Bus-Error wegen ungültige STARToder STOP BEDIgung; keine TWDR-Tätigkeit
|
28 |
|
29 | ; TWI SLAVE EINSTELLUNGEN
|
30 | .equ TWI_SLAVE_ADRESSE = 127 ; eigene SLAVE ADRESSE 1...127
|
31 | .equ TWI_GENERAL_CALL_enable = 1 ; 1=Generral Call enabled / 0=disabled
|
32 | ; REGISTER
|
33 | .def DATA=R15
|
34 |
|
35 | .def TEMP = R16
|
36 | .def TEMP1= R17
|
37 | .def TEMP2= R18
|
38 | .def TEMP3= R19
|
39 | .def TEMP4= R20
|
40 |
|
41 |
|
42 | .cseg ;Beginn eines Code-Segmentes
|
43 | .org 0 ;Startadresse=0
|
44 |
|
45 | rjmp RESET ; Reset Handler
|
46 | reti ;rjmp EXT_INT0 ; IRQ0 Handler
|
47 | reti ;rjmp EXT_INT1 ; IRQ1 Handler
|
48 | reti ;rjmp TIM2_COMP ; Timer2 Compare Handler
|
49 | reti ;rjmp TIM2_OVF ; Timer2 Overflow Handler
|
50 | reti ;rjmp TIM1_CAPT ; Timer1 Capture Handler
|
51 | reti ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
|
52 | reti ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
|
53 | reti ;rjmp TIM1_OVF ; Timer1 Overflow Handler
|
54 | reti ;rjmp TIM0_OVF ; Timer0 Overflow Handler
|
55 | reti ;rjmp SPI_STC ; SPI Transfer Complete Handler
|
56 | reti ;rjmp USART_RXC ; USART RX Complete Handler
|
57 | reti ;rjmp USART_UDRE ; UDR Empty Handler
|
58 | reti ;rjmp USART_TXC ; USART TX Complete Handler
|
59 | reti ;rjmp ADC ; ADC Conversion Complete Handler
|
60 | reti ;rjmp EE_RDY ; EEPROM Ready Handler
|
61 | reti ;rjmp ANA_COMP ; Analog Comparator Handler
|
62 | rjmp TWSI ; Two-wire Serial Interface Handler
|
63 | reti ;rjmp SPM_RDY ; Store Program Memory Ready Handler
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | RESET:
|
70 |
|
71 | ;STACK initialisieren
|
72 | ldi temp, LOW(RAMEND)
|
73 | out SPL, temp
|
74 | ldi temp, HIGH(RAMEND)
|
75 | out SPH, temp
|
76 | ; PORT B + D alles AUSGÄNGE
|
77 | ldi temp, 0b11111111
|
78 | out DDRB, temp
|
79 | out PORTB,temp
|
80 | out DDRD, temp
|
81 | out PORTD,temp
|
82 | ; PORT C alles EINGÄNGE
|
83 | clr TEMP
|
84 | out DDRC,temp
|
85 | ; TWI INITIALISIERUNG
|
86 | rcall TWI_INI
|
87 | ; STARTWERTE
|
88 | clr DATA
|
89 | ; alle Interrupts freigeben
|
90 | sei
|
91 |
|
92 |
|
93 | LOOP:
|
94 |
|
95 |
|
96 | rjmp LOOP
|
97 |
|
98 |
|
99 | ; #############################################################################
|
100 | ; #############################################################################
|
101 | ; #############################################################################
|
102 | ; TWI INTERRUPPT-Routine
|
103 | TWSI:
|
104 | push temp ; temp auf dem Stack sichern
|
105 | in TEMP,SREG ; Einlesen des SREG
|
106 | push TEMP ; Schreiben von SREG im Stack (KOPIE)
|
107 | ;-------
|
108 |
|
109 | in temp, TWSR ; Status-Register abfragen
|
110 | andi temp, 0xF8 ; Bit0...2 ausblenden (Prescaler und Reserve-Bit)
|
111 |
|
112 | cpi temp, TW_SR_SLA_ACK ; x60
|
113 | breq TWSI_TW_SR_SLA_ACK
|
114 | cpi temp, TW_SR_ARB_LOST_SLA_ACK ; x68
|
115 | breq TWSI_TW_SR_ARB_LOST_SLA_ACK
|
116 | cpi temp, TW_SR_GCALL_ACK ; x70
|
117 | breq TWSI_TW_SR_GCALL_ACK
|
118 | cpi temp, TW_SR_ARB_LOST_GCALL_ACK ; x78
|
119 | breq TWSI_TW_SR_ARB_LOST_GCALL_ACK
|
120 | cpi temp, TW_SR_DATA_ACK ; x80
|
121 | breq TWSI_TW_SR_DATA_ACK
|
122 | cpi temp, TW_SR_DATA_NACK ; x88
|
123 | breq TWSI_TW_SR_DATA_NACK
|
124 | cpi temp, TW_SR_GCALL_DATA_ACK ; x90
|
125 | breq TWSI_TW_SR_GCALL_DATA_ACK
|
126 | cpi temp, TW_SR_GCALL_DATA_NACK ; x98
|
127 | breq TWSI_TW_SR_GCALL_DATA_NACK
|
128 | cpi temp, TW_SR_STOP ; xA0
|
129 | breq TWSI_TW_SR_STOP
|
130 | ;
|
131 | cpi temp, TW_ST_SLA_ACK ; 0xA8
|
132 | breq TWSI_TW_ST_SLA_ACK
|
133 | cpi temp, TW_ST_ARB_LOST_SLA_ACK ; 0xB0
|
134 | breq TWSI_TW_ST_ARB_LOST_SLA_ACK
|
135 | cpi temp, TW_ST_DATA_ACK ; 0xB8
|
136 | breq TWSI_TW_ST_DATA_ACK
|
137 | cpi temp, TW_ST_DATA_NACK ; 0xC0
|
138 | breq TWSI_TW_ST_DATA_NACK
|
139 | cpi temp, TW_ST_LAST_DATA ; 0xC8
|
140 | breq TWSI_TW_ST_LAST_DATA
|
141 | cpi temp, TW_NO_INFO ; 0xF8
|
142 | breq TWSI_TW_NO_INFO
|
143 | cpi temp, TW_BUS_ERROR ; 0x00
|
144 | breq TWSI_TW_BUS_ERROR
|
145 | rjmp TWSI_TW_BUS_ERROR ; nicht behandelte Status-Zustände
|
146 |
|
147 | ; SLAVE RECEIVER
|
148 | TWSI_TW_SR_SLA_ACK: ; x60 01100000 (SLA+W wurde empfangen-ACK wurde zurückgesendet)
|
149 | ldi temp, 255
|
150 | out PORTB,temp ; LED's alle aus
|
151 | cbi PORTB,0
|
152 | rjmp TWSI_w
|
153 | TWSI_TW_SR_ARB_LOST_SLA_ACK: ; x68 01101000 (Arbitration verloren in SLA+R/W als MASTER; SLA+W wurde empfangen; ACK wurde zurückgesendet
|
154 | cbi PORTB,1
|
155 | rjmp TWSI_w
|
156 | TWSI_TW_SR_GCALL_ACK: ; x70 01110000 (General call address wurde empfangen; ACK wurde zurückgesendet
|
157 | cbi PORTB,2
|
158 | rjmp TWSI_w
|
159 | TWSI_TW_SR_ARB_LOST_GCALL_ACK: ; x78 01111000 (Arbitration verloren in SLA+R/W als MASTER;General call address wurde empfangen; ACK wurde zurückgesendet
|
160 | cbi PORTB,3
|
161 | rjmp TWSI_w
|
162 | TWSI_TW_SR_DATA_ACK: ; x80 10000000 (die vorher adressierten (SLA+W) Daten wurden empfangen; ACK wurde zurückgesendet
|
163 | cbi PORTB,4
|
164 | in DATA, TWDR ; DATA
|
165 | rjmp TWSI_w
|
166 | TWSI_TW_SR_DATA_NACK: ; x88 10001000 (die vorher adressierten (SLA+W) Daten wurden empfangen; ACK wurde nicht zurückgesedet
|
167 | cbi PORTB,5
|
168 | rjmp TWSI_w
|
169 | TWSI_TW_SR_GCALL_DATA_ACK: ; x90 10010000 (die vorher adressierten (General call) Daten wurden empfangen; ACK wurde zurückgesendet
|
170 | cbi PORTB,6
|
171 | rjmp TWSI_w
|
172 | TWSI_TW_SR_GCALL_DATA_NACK: ; x98 10011000 (die vorher adressierten (General call) Daten wurden empfangen; ACK wurde nicht zurückgesendet
|
173 | cbi PORTB,7
|
174 | rjmp TWSI_w
|
175 | TWSI_TW_SR_STOP: ; xA0 10100000 (STOP wurde empfangen, oder wiederholter Start)
|
176 | cbi PORTB,7
|
177 | rjmp TWSI_w
|
178 | ; SLAVE TRANSMITTER
|
179 | TWSI_TW_ST_SLA_ACK: ; xA8 10101000 (SLA+R wurde empfangen; ACK wurde zurückgesendet)
|
180 | ldi temp,255
|
181 | out PORTB,temp ; LEDs alle aus
|
182 | cbi PORTB,0
|
183 | OUT TWDR, DATA ; DATA
|
184 | rjmp TWSI_w
|
185 | TWSI_TW_ST_ARB_LOST_SLA_ACK: ; xB0 10110000 (Arbitration verlor SLA+R/W als MASTER, ACK wurde zurückgesendet)
|
186 | cbi PORTB,1
|
187 | rjmp TWSI_w
|
188 | TWSI_TW_ST_DATA_ACK: ; xB8 10111000 (TWDR ist übertragen worden; ACK ist empfangen worden
|
189 | cbi PORTB,2
|
190 | OUT TWDR, DATA ; DATA
|
191 | rjmp TWSI_w
|
192 | TWSI_TW_ST_DATA_NACK: ; xC0 11000000 (TWDR ist übertragen worden; ACK ist NICHT empfangen worden
|
193 | cbi PORTB,3
|
194 | OUT TWDR, DATA ; DATA
|
195 | rjmp TWSI_w
|
196 | TWSI_TW_ST_LAST_DATA: ; xC8 11001000 (Letztes Datenbyte in TWDR ist übertragen worden (TWEA = "0"); Ack ist empfangen worden
|
197 | cbi PORTB,4
|
198 | rjmp TWSI_w
|
199 | TWSI_TW_NO_INFO: ; xF8 11111000 (Keine relevanten Zustandinformationen vorhanden; TWINT = "0" keine TWDR-Tätigkeit
|
200 | cbi PORTB,5
|
201 | rjmp TWSI_w
|
202 | TWSI_TW_BUS_ERROR: ; x00 00000000 (Bus-Error wegen ungültige STARToder STOP BEDIgung; keine TWDR-Tätigkeit
|
203 | rcall TWI_ERROR
|
204 |
|
205 | rjmp TWSI_w
|
206 |
|
207 | ;-------
|
208 | TWSI_w:
|
209 |
|
210 | rcall wait_1s ; diese Warteschleife ist nicht nötig, kann entfernd werden
|
211 |
|
212 | ;das TWINT-Flag löschen ((logisch 1)
|
213 | ldi temp, 1<<TWINT|1<<TWEA|1<<TWEN|1<<TWIE
|
214 | out TWCR,temp
|
215 |
|
216 |
|
217 | ;-------
|
218 | pop TEMP ; LESEN von SREG vom STACK (KOPIE)
|
219 | out SREG,TEMP ; Wiederherstellen von SREG
|
220 | pop temp ; temp wiederherstellen
|
221 |
|
222 | reti
|
223 | ; #############################################################################
|
224 | ; #############################################################################
|
225 | ; #############################################################################
|
226 | TWI_INI:
|
227 | ; TWI TWAR (nur SLAVE) Adress-Register
|
228 | ldi temp,(TWI_SLAVE_ADRESSE<<TWA0 | TWI_GENERAL_CALL_ENABLE<<TWGCE)
|
229 | out TWAR,temp
|
230 | ; TWI TWCR Control-REGISTER
|
231 | ldi temp, 1<<TWINT|1<<TWEA|0<<TWSTA|0<<TWSTO|0<<TWWC|1<<TWEN|1<<TWIE
|
232 | out TWCR,temp
|
233 | ret
|
234 | ; #############################################################################
|
235 | ; #############################################################################
|
236 | ; #############################################################################
|
237 | TWI_ERROR:
|
238 |
|
239 | cbi PORTD,0
|
240 |
|
241 | ; TWI STOP
|
242 | ldi r16, (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)
|
243 | out TWCR, r16
|
244 | ; TWI aus
|
245 | ldi r16, (0<<TWEN)
|
246 | out TWCR, r16
|
247 | ; TWI INITIALISIERUNG
|
248 | rcall TWI_INI
|
249 |
|
250 | rcall wait_1s
|
251 |
|
252 | sbi PORTD,0
|
253 |
|
254 |
|
255 | ret
|
256 | ; #############################################################################
|
257 | ; #############################################################################
|
258 | ; #############################################################################
|
259 | ; Wait for TWINT Flag set.
|
260 | TWI_TWINT_wait:
|
261 | in temp, TWCR
|
262 | sbrs temp, TWINT
|
263 | rjmp TWI_TWINT_wait
|
264 | ret
|
265 | ; #############################################################################
|
266 | ; #############################################################################
|
267 | ; #############################################################################
|
268 | WAIT_1s:
|
269 | push temp1 ; temp1 auf dem Stack sichern
|
270 | push temp2 ; temp2 auf dem Stack sichern
|
271 | push temp3 ; temp3 auf dem Stack sichern
|
272 |
|
273 | ;------------
|
274 | ldi temp3,5
|
275 | clr temp2
|
276 | clr temp1
|
277 | wait1s_w:
|
278 | dec temp1
|
279 | brne wait1s_w
|
280 | dec temp2
|
281 | brne wait1s_w
|
282 | dec temp3
|
283 | brne wait1s_w
|
284 | ;------------
|
285 | pop temp3 ; temp3 wiederherstellen
|
286 | pop temp2 ; temp2 wiederherstellen
|
287 | pop temp1 ; temp1 wiederherstellen
|
288 | ret
|