1 | ; bibRFM12.asm
|
2 | ; enthält RFM12 Sende-/ Empfangsfunktionen
|
3 | ; Hauptroutinen
|
4 |
|
5 |
|
6 | .NOLIST ; Listing ausschalten
|
7 | .INCLUDE "m32def.inc" ; Deklaration für mega32
|
8 | .LIST ; Listing einschalten
|
9 | ; Konstante für RFM12
|
10 | ; RFM12 senden, RFM12sendStep, SchrittketteRFM12_REC_END
|
11 | .EQU RFM12_SEND_STEP_IDLE = 1 ; RFM12 senden: nix zu tun
|
12 | .EQU RFM12_SEND_STEP_ISR_START = 2 ; RFM12 senden: TXon, isr Start
|
13 | .EQU RFM12_SEND_STEP_ISR_AKTIV = 3 ; RFM12 senden: aktiv
|
14 | .EQU RFM12_SEND_STEP_ISR_ENDE = 4 ; RFM12 senden: isr fertig, alles gesendet
|
15 | ; .EQU RFM12_SEND_STEP_TXOFF = 5 ; RFM12 senden: TXoff senden
|
16 |
|
17 | ; RFM12 senden, RFM12sendCmdStat, Kommandos, Status
|
18 | .EQU RFM12_SEND_IDLE = 7 ; Bit7: RFM12_senden: senden fertig, nix zu tun
|
19 | .EQU RFM12_SEND_AKTIV = 6 ; Bit6: RFM12 senden: senden aktiv
|
20 | .EQU RFM12_SEND_EXEC = 0 ; Bit0: RFM12 senden: exec senden
|
21 |
|
22 | ; RFM12 empfangen, RFM12recStep, Schrittkette
|
23 | .EQU RFM12_REC_STEP_IDLE = 10 ; RFM12 empfangen: nix zu tun
|
24 | .EQU RFM12_REC_STEP_ISR_START = 11 ; RFM12 empfangen: RXon, isr Start
|
25 | .EQU RFM12_REC_STEP_ISR_AKTIV = 12 ; RFM12 empfangen: aktiv
|
26 | .EQU RFM12_REC_STEP_ISR_ENDE = 13 ; RFM12 empfangen: isr fertig, alles empfangen
|
27 |
|
28 | ; RFM12 empfangen, RFM12recCmdStat, Kommandos, Status
|
29 | .EQU RFM12_REC_IDLE = 7 ; Bit7: RFM12 empfangen: empfangen fertig, nix zu tun
|
30 | .EQU RFM12_REC_AKTIV = 6 ; Bit6: RFM12 empfangen: empfangen aktiv
|
31 | .EQU RFM12_REC_EXEC = 0 ; Bit0: RFM12 empfangen: exec empfangen
|
32 |
|
33 | ; Timer
|
34 | .EQU TIM_RFM12 = 7 ; Bit7: Timer für RFM12
|
35 |
|
36 | ;***************************************
|
37 | ;********** CSEG: Codesegment **********
|
38 | ;***************************************
|
39 | .CSEG
|
40 |
|
41 | ; Interruptvektor
|
42 | ; .ORG INT0addr ; Einsprung INT0, externer Interrupt
|
43 | ; rjmp isrRFM12rec
|
44 |
|
45 | ; INT0 programmieren
|
46 | ; in r16,MCUCR ; altes Steuerregister
|
47 | ; sbr r16,1<<ISC01 ; Interrupt INT0 auf fallende Flanke
|
48 | ; cbr r16,1<<ISC00
|
49 | ; out MCUCR,r16
|
50 |
|
51 | ; in r16,GICR ; altes Freigaberegister
|
52 | ; cbr r16,1<<INT0 ; INT0 sperren
|
53 | ; out GICR,r16
|
54 |
|
55 | ; PORTS definieren
|
56 | ; cbi DDRB,PINB6 ; Eingang MISO <- SDO
|
57 | ; cbi DDRB,PINB2 ; Eingang PINB2 <- nIRQ
|
58 | ;
|
59 | ; sbi DDRB,PORTB4 ; Ausgang nSS (muß gesetzt sein, wegen SPI Masterbetrieb)
|
60 | ; sbi DDRB,PORTB5 ; Ausgang MOSI -> SDI
|
61 | ; sbi DDRB,PORTB7 ; Ausgang SCK -> SCK
|
62 | ; sbi DDRB,PORTB1 ; Ausgang PORTB1 -> nSEL
|
63 |
|
64 | ; Ports setzen
|
65 | ; sbi PORTB,PORTB4 ; Ausgang nSS (muß gesetzt sein, wegen SPI Masterbetrieb)
|
66 | ; sbi PORTB,PORTB1 ; Ausgang nSEL setzen
|
67 |
|
68 | ; SPI init
|
69 | ; ldi r16,(1<<SPE) | (1<<MSTR) | (0<<SPR1) |(1<<SPR0) ; SPI frei, MSB erst
|
70 | ; out SPCR,r16 ;
|
71 | ; ldi r16,(1<<SPI2X) ; SPI2X=1, SPR1=0, SPR0=1: f(osc)/8 = 14.7456 MHz/8 = 1.8432 MHz
|
72 | ; out SPSR,r16
|
73 |
|
74 | ;***********************************************************
|
75 | ;********** subRFM12paramIni: initialisiert RFM12 **********
|
76 | ;***********************************************************
|
77 | ; initialisert RFM12
|
78 |
|
79 | subRFM12paramIni: push r16
|
80 | push r17
|
81 |
|
82 | call subReadStatus
|
83 |
|
84 | ldi r17,0xC0 ; Unterspannungs-Detektor und Taktausgangsteiler (LowBatt / µC Clock Control C0xx)
|
85 | ldi r16,0xE0 ; AVR CLK: 10MHz
|
86 | call subSPIsend ;
|
87 | call subReadStatus
|
88 |
|
89 | ldi r17,0x80 ; Grundkonfiguration (Configuration Setting 80xx)
|
90 | ldi r16,0xE7 ; 868MHz, EL, EF, 11.5pF
|
91 | call subSPIsend ;
|
92 | call subReadStatus
|
93 |
|
94 | ldi r17,0xC2 ; Empfangsdatenrekonstruktion (Data Filter C2xx)
|
95 | ldi r16,0xAB ; Data Filter: internal
|
96 | call subSPIsend ;
|
97 | call subReadStatus
|
98 |
|
99 | ldi r17,0xCA ; FIFO-Steuerung (FIFO and RESET Mode CAxx)
|
100 | ldi r16,0x81 ; Set FIFO mode
|
101 | call subSPIsend ;
|
102 | call subReadStatus
|
103 |
|
104 | ldi r17,0xE0 ; Zeitgeber für Wake-Up (Wake-Up Timer Exxx .. Fxxx)
|
105 | ldi r16,0x00 ; disable wakeuptimer
|
106 | call subSPIsend ;
|
107 | call subReadStatus
|
108 |
|
109 | ldi r17,0xC8 ; Automatisch zyklischer Empfänger (Low Duty-Cycle C8xx)
|
110 | ldi r16,0x00 ; disable low duty cycle
|
111 | call subSPIsend ;
|
112 | call subReadStatus
|
113 |
|
114 | ldi r17,0xC4 ; Automatische Frequenznachregelung (Automatic Frequency Control, AFC C4xx)
|
115 | ldi r16,0xF7 ; AFC settings: autotuning: -10kHz...+7,5kHz
|
116 | call subSPIsend ;
|
117 | call subReadStatus
|
118 |
|
119 | ldi r17,0xA6 ; Frequenzeinstellung (Frequency Setting Axxx)
|
120 | ldi r16,0xF8 ; (freq-860.0)/0.005 = (868.92 - 860.0)/0.005 = 1784 = 0x06F8
|
121 | call subSPIsend ;
|
122 | call subReadStatus
|
123 |
|
124 | ldi r17,0x90 ; Empfängersteuerung (Receiver Control 9xxx 9000 .. 97FF)
|
125 | ldi r16,0x8C ; 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm = 0b_1001_0000_1000_1100 = 0x908C
|
126 | call subSPIsend ;
|
127 | call subReadStatus
|
128 |
|
129 | ldi r17,0xC6 ; Bitrate (Data Rate C6xx)
|
130 | ldi r16,0x11 ; 19200 baud-> r=17 = 0x11
|
131 | call subSPIsend ;
|
132 | call subReadStatus
|
133 |
|
134 | ldi r17,0x98 ; Senderkonfiguration (TX Configuration 9800 oder 9900)
|
135 | ldi r16,0x60 ; 6*15kHz=120kHz Frequenzshift, 1mW Ausgangangsleistung (0db)
|
136 | call subSPIsend ;
|
137 | call subReadStatus
|
138 |
|
139 | pop r17
|
140 | pop r16
|
141 | ret
|
142 |
|
143 | ;********************************************************
|
144 | ;********** subRFM12sendIni: RFM12 senden init **********
|
145 | ;********************************************************
|
146 | ; Initialisierung Variablen für RFM12 Senden
|
147 |
|
148 | subRFM12sendIni: push r16
|
149 | push r17
|
150 | push XL
|
151 | push XH
|
152 |
|
153 | ldi r16,(1<<RFM12_SEND_IDLE) ; nix zu tun
|
154 | sts RFM12sendCmdStat,r16 ; Kommando/ Status RFM12 Senden
|
155 |
|
156 | clr r16
|
157 | sts RFM12sendCount,r16 ; Zähler für zu sendende Bytes
|
158 |
|
159 | ldi r16,RFM12_SEND_STEP_IDLE ; Schrittkette
|
160 | sts RFM12sendStep,r16
|
161 |
|
162 | ldi XH,HIGH(RFM12sendPrefix) ; Anfadr. RFM12sendPrefix
|
163 | ldi XL,LOW(RFM12sendPrefix)
|
164 | ldi r16,0xAA ; Synchronierbytes für Empfänger
|
165 | st X+,r16
|
166 | st X+,r16
|
167 | st X+,r16
|
168 | ldi r16,0x2D ; 2DD4: Datenanfang für Empfänger
|
169 | st X+,r16
|
170 | ldi r16,0xD4
|
171 | st X+,r16
|
172 |
|
173 | ldi XH,HIGH(RFM12sendData) ; Anfadr. Nutzdaten
|
174 | ldi XL,LOW(RFM12sendData)
|
175 | ldi r17,16 ; Sendeprefix 5 Byte, Nutzdaten 11 Byte
|
176 | ldi r16,0
|
177 |
|
178 | subRFM12sendIniLop: st X+,r16 ; Sendeprefix/ Nutzdaten
|
179 | dec r17 ; Schleifenzähler dec
|
180 | brbc SREG_Z,subRFM12sendIniLop ;
|
181 |
|
182 | pop XH
|
183 | pop XL
|
184 | pop r17
|
185 | pop r16
|
186 | ret
|
187 |
|
188 | ;**********************************************************
|
189 | ;********** subRFM12recIni: RFM12 empfangen init **********
|
190 | ;**********************************************************
|
191 | ; Initialisierung Variablen für RFM12 Empfang
|
192 |
|
193 | subRFM12recIni: push r16
|
194 | push r17
|
195 | push XL
|
196 | push XH
|
197 |
|
198 | ldi r16,(1<<RFM12_REC_IDLE) ; nix zu tun
|
199 | sts RFM12recCmdStat,r16 ; Kommando/ Status RFM12 Empfang
|
200 |
|
201 | clr r16
|
202 | sts RFM12recCount,r16 ; Zähler für empfange Bytes
|
203 |
|
204 | ldi r16,RFM12_REC_STEP_IDLE ; Schrittkette
|
205 | sts RFM12recStep,r16
|
206 |
|
207 | ldi XH,HIGH(RFM12recData) ; Anfadr. Nutzdaten
|
208 | ldi XL,LOW(RFM12recData)
|
209 | ldi r17,11 ; Schleife
|
210 | ldi r16,0
|
211 |
|
212 | subRFM12recIniLoop: st X+,r16 ; Nutzdaten
|
213 | dec r17 ; Schleifenzähler dec
|
214 | brbc SREG_Z,subRFM12recIniLoop ;
|
215 |
|
216 | pop XH
|
217 | pop XL
|
218 | pop r17
|
219 | pop r16
|
220 | ret
|
221 |
|
222 | ;************************************************
|
223 | ;********** subRFM12send: RFM12 senden **********
|
224 | ;************************************************
|
225 | ; Senderoutine für RFM12
|
226 | ; muß zyklisch durchlaufen werden
|
227 | ; holt zu sendende Daten aus RFM12sendData ab
|
228 | ; sendet Prefix: 5 Bytes Vorspann: AA, AA, AA, 2D, D4
|
229 | ; Daten werden von isrRFM12send gesendet
|
230 |
|
231 | subRFM12send: push r16
|
232 | push r17
|
233 |
|
234 | lds r16,RFM12sendStep
|
235 |
|
236 | ; Sprungleiste: RFM12_SEND_STEP_IDLE, nix zu tun
|
237 | cpi r16,RFM12_SEND_STEP_IDLE
|
238 | breq subRFM12sendIdle
|
239 |
|
240 | ; Sprungleiste: RFM12_SEND_STEP_ISR_ENDE, warten auf isr Ende
|
241 | cpi r16,RFM12_SEND_STEP_ISR_ENDE
|
242 | breq subRFM12sendIsrEnd
|
243 |
|
244 | rjmp subRFM12sendRet
|
245 |
|
246 | ; step: RFM12_SEND_STEP_IDLE, nix zu tun
|
247 | subRFM12sendIdle: lds r16,RFM12sendCmdStat
|
248 | andi r16,(1<<RFM12_SEND_EXEC) ; exec Senden liegt an ?
|
249 | brbs SREG_Z,subRFM12sendRet ; nein: Aussprung
|
250 |
|
251 | ; exec senden: Vorbereitung auf Senden
|
252 | call subDebTraceD6 ; debug senden
|
253 |
|
254 | call subRFM12TXon ; Sender einschalten
|
255 | ; Status setzen
|
256 | ldi r16,((1<<RFM12_SEND_AKTIV)|(1<<RFM12_SEND_EXEC))
|
257 | sts RFM12sendCmdStat,r16
|
258 | ; next step: isr start (für isr)
|
259 | ldi r16,RFM12_SEND_STEP_ISR_START
|
260 | sts RFM12sendStep,r16
|
261 |
|
262 | rjmp subRFM12sendRet ; und raus
|
263 |
|
264 | ; step: RFM12_SEND_STEP_ISR_ENDE, isr Ende (wird von isr gesetzt)
|
265 | subRFM12sendIsrEnd: ldi r16,(1<<TIM_RFM12)
|
266 | ldi r17, 2 ; 5 mSek
|
267 | call subDelay8
|
268 |
|
269 | call subRFM12TXoff ; Sender ausschalten
|
270 |
|
271 | ldi r16,RFM12_SEND_STEP_IDLE ; next step: nix zu tun
|
272 | sts RFM12sendStep,r16
|
273 |
|
274 | ldi r16,1<<RFM12_SEND_IDLE ; Status setzen
|
275 | sts RFM12sendCmdStat,r16
|
276 |
|
277 | call subDebTraceD6 ; debug senden
|
278 |
|
279 | rjmp subRFM12sendRet ; und raus
|
280 |
|
281 | subRFM12sendRet: pop r17
|
282 | pop r16
|
283 | ret
|
284 |
|
285 | ;**************************************************
|
286 | ;********** subRFM12rec: RFM12 empfangen **********
|
287 | ;**************************************************
|
288 | ; Empfangsroutine für RFM12
|
289 | ; muß zyklisch durchlaufen werden, wartet auf Daten
|
290 | ; legt empfangene Daten in RFM12recData ab
|
291 | ; Daten werden von isrRFM12rec abgeholt
|
292 |
|
293 | subRFM12rec: push r16
|
294 |
|
295 | lds r16,RFM12recStep
|
296 |
|
297 | ; Sprungleiste: RFM12_REC_STEP_IDLE, nix zu tun
|
298 | cpi r16,RFM12_REC_STEP_IDLE
|
299 | breq subRFM12recIdle
|
300 |
|
301 | ; Sprungleiste: RFM12_REC_STEP_ISR_ENDE, isr ist fertig, alles empfangen
|
302 | cpi r16,RFM12_REC_STEP_ISR_ENDE
|
303 | breq subRFM12recIsrEnd
|
304 |
|
305 | rjmp subRFM12recRet
|
306 |
|
307 | ; step: RFM12_REC_STEP_IDLE, nix zu tun
|
308 | subRFM12recIdle: lds r16,RFM12recCmdStat
|
309 | andi r16,(1<<RFM12_REC_EXEC) ; exec empfangen liegt an ?
|
310 | brbs SREG_Z,subRFM12recRet ; nein: Aussprung
|
311 |
|
312 | ; exec empfangen: Vorbereitung auf Empfang
|
313 | call subRFM12RXon ; Empfänger einschalten
|
314 | ; Status setzen
|
315 | ldi r16,((1<<RFM12_REC_AKTIV)|(1<<RFM12_REC_EXEC))
|
316 | sts RFM12recCmdStat,r16
|
317 | ; next step: isr start (für isr)
|
318 | ldi r16,RFM12_REC_STEP_ISR_START
|
319 | sts RFM12recStep,r16
|
320 |
|
321 | rjmp subRFM12recRet ; und raus
|
322 |
|
323 | ; step: RFM12_REC_STEP_ISR_ENDE, isr ist fertig, alles empfangen
|
324 | subRFM12recIsrEnd: ; call subRFM12RXoff ; Empfänger ausschalten
|
325 |
|
326 | ldi r16,RFM12_REC_STEP_IDLE ; next step: nix zu tun
|
327 | sts RFM12recStep,r16
|
328 |
|
329 | ldi r16,1<<RFM12_REC_IDLE ; Status setzen
|
330 | sts RFM12recCmdStat,r16
|
331 |
|
332 | ; call subDebTraceD7 ; debug empfangen
|
333 | cbi PORTD,PORTD7 ; debug empfangen
|
334 |
|
335 | rjmp subRFM12recRet ; und raus
|
336 |
|
337 | subRFM12recRet: pop r16
|
338 | ret
|
339 |
|
340 |
|
341 | ;**********************************
|
342 | ;********** isr isrRFM12 **********
|
343 | ;**********************************
|
344 | ; ruft die isr-Routinen für senden/ empfangan auf
|
345 | ; abhängig davon, ob senden oder empfangen aktiv ist
|
346 |
|
347 | isrRFM12: push r16
|
348 | in r16,SREG
|
349 | push r16
|
350 |
|
351 | call subDebTraceB0 ; debug isr senden/ empfangen
|
352 |
|
353 | ; senden
|
354 | lds r16,RFM12sendCmdStat
|
355 | andi r16,(1<<RFM12_SEND_AKTIV) ; senden aktiv ?
|
356 | brbs SREG_Z,intRFM12rec ; nein: springe
|
357 |
|
358 | call isrRFM12send ; senden aktiv
|
359 |
|
360 | rjmp isrRFM12End
|
361 |
|
362 | ; empfangen: wenn nicht senden, dann empfangen, damit jeder Interrupt behandelt wird
|
363 | intRFM12rec: call isrRFM12rec ; empfangen,
|
364 |
|
365 | isrRFM12End: call subDebTraceB0 ; debug isr senden/ empfangen
|
366 |
|
367 | pop r16
|
368 | out SREG,r16
|
369 | pop r16
|
370 | reti
|
371 |
|
372 | ;**************************************
|
373 | ;********** isr isrRFM12send **********
|
374 | ;**************************************
|
375 | ; sendet Daten über Interrupt INT0
|
376 | ; 1. 5 Bytes Prefix (AA, AA, AA, 2D, D4)
|
377 | ; 2. aus RFM12sendData
|
378 | ; erstes Byte: Länge Nutzdaten
|
379 | ; anschließend: Nutzdaten
|
380 |
|
381 | isrRFM12send: push r16
|
382 | push r17
|
383 | push r18
|
384 | push XL
|
385 | push XH
|
386 | in r16,SREG
|
387 | push r16
|
388 |
|
389 | call subDebTraceB2 ; debug isr senden
|
390 |
|
391 | lds r16,RFM12sendStep
|
392 |
|
393 | ; Sprungleiste: RFM12_SEND_STEP_ISR_START, erster Durchlauf isr
|
394 | cpi r16,RFM12_SEND_STEP_ISR_START
|
395 | breq isrRFM12sendFirst
|
396 |
|
397 | ; Sprungleiste: RFM12_SEND_STEP_ISR_AKTIV, Byte senden
|
398 | cpi r16,RFM12_SEND_STEP_ISR_AKTIV
|
399 | breq isrRFM12sendByte
|
400 |
|
401 | rjmp isrRFM12sendEnd ; sollte nicht vorkommen !!!
|
402 |
|
403 | ; step: RFM12_SEND_STEP_ISR_START, erster Durchlauf isr
|
404 | ; Byte Zähler berechnen
|
405 | isrRFM12sendFirst: lds r16,RFM12sendData ; Byte0: Länge der Nutzdaten (ohne Längenbyte !!)
|
406 | ldi r17,6 ; 1 Längenbyte + 5 Byte Prefix
|
407 | add r16,r17 ; Zähler = Länge Nutzdaten + 1 Längenbyte + 5 Byte Prefix
|
408 | sts RFM12sendCount,r16 ; sichern
|
409 |
|
410 | lds r16,RFM12sendStep ; next step: senden
|
411 | ldi r16,RFM12_SEND_STEP_ISR_AKTIV
|
412 | sts RFM12sendStep,r16
|
413 | ; kein Aussprung, Byte muß gesendet werden !!
|
414 | ; step: RFM12_SEND_STEP_ISR_AKTIV, Byte senden
|
415 | ; Offset Speicherdresse aus Zähler berechnen, Adresse Nutzbyte
|
416 | isrRFM12sendByte: lds r17,RFM12sendData ; Länge Nutzdaten
|
417 | ldi r16,6 ; + 1 Längenbyte + 5 Byte Prefix
|
418 | add r17,r16 ; Gesamtlänge
|
419 |
|
420 | lds r18,RFM12sendCount ; Sendezähler
|
421 |
|
422 | sub r17,r18 ; Offset = Gesamtlänge - Sendezähler
|
423 |
|
424 | ldi XL,LOW(RFM12sendPrefix) ; Adr Nutzdaten (5 Byte Prefix !!)
|
425 | ldi XH,HIGH(RFM12sendPrefix)
|
426 |
|
427 | ldi r16,0
|
428 | add XL,r17 ; Offset für RFM12sendPrefix addieren
|
429 | adc XH,r16
|
430 |
|
431 | ; Byte senden
|
432 | ldi r17,0xB8 ; senden
|
433 | ld r16,X ; Nutzdaten
|
434 | call subSPIsend
|
435 | call subReadStatus ; Status und Interrupt quittieren
|
436 |
|
437 | ; Sendezähler dec
|
438 | dec r18 ; Sendezähler
|
439 | sts RFM12sendCount,r18 ; sichern
|
440 | brbc SREG_Z,isrRFM12sendEnd ; Zähler > 0: weiter senden, Aussprung
|
441 |
|
442 | ; Zähler = 0: alles gesendet, Schlußbearbeitung
|
443 | lds r16,RFM12sendStep ; next step: isr fertig mit senden
|
444 | ldi r16,RFM12_SEND_STEP_ISR_ENDE
|
445 | sts RFM12sendStep,r16
|
446 |
|
447 | isrRFM12sendEnd: call subDebTraceB2 ; debug isr senden
|
448 |
|
449 | pop r16
|
450 | out SREG,r16
|
451 | pop XH
|
452 | pop XL
|
453 | pop r18
|
454 | pop r17
|
455 | pop r16
|
456 | ret
|
457 |
|
458 | ;*************************************
|
459 | ;********** isr isrRFM12rec **********
|
460 | ;*************************************
|
461 | ; empfängt Daten über Interrupt INT0
|
462 | ; speichern in RFM12recData
|
463 | ; erstes Byte: Länge Nutzdaten, speichern in RFM12recCount
|
464 | ; anschließend: Nutzdaten
|
465 |
|
466 | isrRFM12rec: push r16
|
467 | push r17 ; RFM12recCount
|
468 | push r18
|
469 | push r19
|
470 | push XL
|
471 | push XH
|
472 | in r16,SREG
|
473 | push r16
|
474 |
|
475 | ; call subDebTraceD7 ; debug empfangen
|
476 | sbi PORTD,PORTD7 ; debug empfangen
|
477 |
|
478 | call subDebTraceB3 ; debug isr empfangen
|
479 |
|
480 | lds r16,RFM12recStep
|
481 |
|
482 | ; Sprungleiste: RFM12_REC_STEP_ISR_START, erster Durchlauf isr
|
483 | cpi r16,RFM12_REC_STEP_ISR_START
|
484 | breq isrRFM12recFirst
|
485 |
|
486 | ; Sprungleiste: RFM12_REC_STEP_ISR_AKTIV, Byte empfangen
|
487 | cpi r16,RFM12_REC_STEP_ISR_AKTIV
|
488 | breq isrRFM12recByte
|
489 |
|
490 | ; rjmp isrRFM12recEnd ; sollte nicht vorkommen !!!
|
491 | rjmp isrRFM12dummyRead
|
492 |
|
493 | ; step: RFM12_REC_STEP_ISR_START, erster Durchlauf isr
|
494 | isrRFM12recFirst: ldi r17,0xB0 ; Daten lesen
|
495 | ldi r16,0x00
|
496 | call subSPIsend ; r16: empfangenes Byte
|
497 |
|
498 | sts RFM12recData,r16 ; erstes Byte: Länge Nutzdaten
|
499 | sts RFM12recCount,r16
|
500 |
|
501 | lds r16,RFM12recStep ; next step: Byte empfangen
|
502 | ldi r16,RFM12_REC_STEP_ISR_AKTIV
|
503 | sts RFM12recStep,r16
|
504 |
|
505 | call subReadStatus ; Status und Interrupt quittieren
|
506 |
|
507 | rjmp isrRFM12recEnd ; und raus
|
508 |
|
509 | ; step: RFM12_REC_STEP_ISR_AKTIV, Nutzdatenbyte empfangen
|
510 | isrRFM12recByte: ldi r17,0xB0 ; Daten lesen
|
511 | ldi r16,0x00
|
512 | call subSPIsend ; r16: empfangenes Byte
|
513 |
|
514 | ; Offset Speicherdresse aus Zähler berechnen
|
515 | lds r17,RFM12recCount ; Zähler
|
516 | lds r18,RFM12recData ; Byte0: Länge der Nutzdaten
|
517 |
|
518 | sub r18,r17 ; Offset = Länge - Zähler
|
519 | inc r18 ; Offset = Offset + 1 (wegen Länge Nutzdaten !!!)
|
520 |
|
521 | ldi XL,LOW(RFM12recData) ; Adr Nutzdaten
|
522 | ldi XH,HIGH(RFM12recData)
|
523 |
|
524 | ldi r19,0
|
525 | add XL,r18 ; Offset für RFM12recData addieren
|
526 | adc XH,r19
|
527 |
|
528 | st X,r16 ; empf. Byte speichern
|
529 |
|
530 | call subReadStatus ; Status und Interrupt quittieren
|
531 |
|
532 | ; Zähler dec, alles empfangen ?
|
533 | dec r17 ; Zähler dec
|
534 | sts RFM12recCount,r17 ; speichern
|
535 |
|
536 | brbc SREG_Z,isrRFM12recEnd ; Zähler <> 0: noch nicht alles empfangen
|
537 |
|
538 | ; alles empfangen, Schlußbearbeitung
|
539 | lds r16,RFM12recStep ; next step: isr fertig mit senden
|
540 | ldi r16,RFM12_REC_STEP_ISR_ENDE
|
541 | sts RFM12recStep,r16
|
542 |
|
543 | call subRFM12RXoff ; Empfänger ausschalten
|
544 |
|
545 | rjmp isrRFM12recEnd ; und raus
|
546 |
|
547 | ; step: dummy read
|
548 | isrRFM12dummyRead: ldi r17,0xB0 ; Daten lesen
|
549 | ldi r16,0x00
|
550 | call subSPIsend ; r16: empfangenes Byte
|
551 | call subReadStatus ; Status und Interrupt quittieren
|
552 |
|
553 | isrRFM12recEnd: call subDebTraceB3 ; debug isr empfangen
|
554 |
|
555 | pop r16
|
556 | out SREG,r16
|
557 | pop XH
|
558 | pop XL
|
559 | pop r19
|
560 | pop r18
|
561 | pop r17
|
562 | pop r16
|
563 | ret
|
564 |
|
565 | ;***********************************************************
|
566 | ;********** subRFM12TXon: RFM12 senden einschalten **********
|
567 | ;************************************************************
|
568 | ; schaltet RFM12 Sender ein
|
569 |
|
570 | subRFM12TXon: push r16
|
571 | push r17
|
572 |
|
573 | ldi r17,0x82 ; TX on
|
574 | ldi r16,0x38
|
575 | call subSPIsend
|
576 |
|
577 | call subReadStatus ; RFM12 Statusregister lesen: RFM12 nIRQ löschen
|
578 |
|
579 | pop r17
|
580 | pop r16
|
581 | ret
|
582 |
|
583 | ;***************************************************************
|
584 | ;********** subRFM12RXon: RFM12 empfangen einschalten **********
|
585 | ;***************************************************************
|
586 | ; schaltet RFM12 Empfänger ein
|
587 |
|
588 | subRFM12RXon: push r16
|
589 | push r17
|
590 |
|
591 | ; ldi r17,0xCA ; set FIFO mode
|
592 | ; ldi r16,0x81
|
593 | ; call subSPIsend
|
594 |
|
595 | ldi r17,0xCA ; enable FIFO
|
596 | ldi r16,0x83
|
597 | call subSPIsend
|
598 |
|
599 | ldi r17,0x82 ; RX on
|
600 | ldi r16,0xC8
|
601 | call subSPIsend
|
602 |
|
603 | call subReadStatus ; RFM12 Statusregister lesen: RFM12 nIRQ löschen
|
604 |
|
605 | pop r17
|
606 | pop r16
|
607 | ret
|
608 |
|
609 | ;*************************************************************
|
610 | ;********** subRFM12TXoff: RFM12 senden ausschalten **********
|
611 | ;*************************************************************
|
612 | ; schaltet RFM12 Sender aus
|
613 |
|
614 | subRFM12TXoff: push r16
|
615 | push r17
|
616 |
|
617 | ldi r17,0x82 ; TX off
|
618 | ldi r16,0x08
|
619 | call subSPIsend
|
620 |
|
621 | call subReadStatus ; RFM12 Statusregister lesen: RFM12 nIRQ löschen
|
622 |
|
623 | pop r17
|
624 | pop r16
|
625 | ret
|
626 |
|
627 | ;****************************************************************
|
628 | ;********** subRFM12RXoff: RFM12 empfangen ausschalten **********
|
629 | ;****************************************************************
|
630 | ; schaltet RFM12 Empfänger aus
|
631 |
|
632 | subRFM12RXoff: push r16
|
633 | push r17
|
634 |
|
635 | ; ldi r17,0xCA ; FIFO disable
|
636 | ; ldi r16,0x81
|
637 | ; call subSPIsend
|
638 |
|
639 | ldi r17,0x82 ; RX off
|
640 | ldi r16,0x08
|
641 | call subSPIsend
|
642 |
|
643 | call subReadStatus ; RFM12 Statusregister lesen: RFM12 nIRQ löschen
|
644 |
|
645 | pop r17
|
646 | pop r16
|
647 | ret
|
648 |
|
649 | ;*******************************************************************
|
650 | ;********** subSPIsend: sendet Kommando über SPI an RFM12 **********
|
651 | ;*******************************************************************
|
652 | ; Eingang
|
653 | ; r17,r16: 16 Bit Kommando für RFM12
|
654 | ; Ausgang
|
655 | ; r16: von SPI gelesenes Byte
|
656 |
|
657 | subSPIsend: cbi PORTB,PORTB1 ; nSEL = 0, für RFM12: Kommandoübertragung beginnt
|
658 |
|
659 | out SPDR,r17 ; high Wert
|
660 | subSPIsendWait1: sbis SPSR,SPIF ; SPIF=1: Übertragung fertig
|
661 | jmp subSPIsendWait1 ; warte auf Ende der Übertragung
|
662 | in r17,SPDR ; SPIF wieder 0
|
663 |
|
664 | out SPDR,r16 ; low Wert
|
665 | subSPIsendWait2: sbis SPSR,SPIF ; SPIF=1: Übertragung fertig
|
666 | jmp subSPIsendWait2 ; warte auf Ende der Übertragung
|
667 | in r16,SPDR ; SPIF wieder 0
|
668 |
|
669 | sbi PORTB,PORTB1 ; nSEL = 1, für RFM12: Kommandoübertragung beendet
|
670 |
|
671 | ret
|
672 |
|
673 | ;***************************************************************
|
674 | ;********** subReadStatus: liest RFM12 Statusregister **********
|
675 | ;***************************************************************
|
676 | ; Ausgang
|
677 | ; r16: Status RFM12
|
678 |
|
679 | subReadStatus: push r17
|
680 |
|
681 | ldi r17,0x00 ; 0x0000: Statusregister lesen
|
682 | ldi r16,0x00
|
683 | call subSPIsend
|
684 |
|
685 | pop r17
|
686 | ret
|
687 |
|
688 | ;****************************************
|
689 | ;********** DSEG: Datensegment **********
|
690 | ;****************************************
|
691 | .DSEG
|
692 |
|
693 | ; RFM12 senden
|
694 | RFM12sendCmdStat: .BYTE 1 ; Kommandos, Status
|
695 | RFM12sendStep: .BYTE 1 ; Schrittkette
|
696 | RFM12sendCount: .BYTE 1 ; Zähler für zu sendende Bytes
|
697 | RFM12sendPrefix: .BYTE 5 ; 5 Bytes Vorspann: AA, AA, AA, 2D, D4
|
698 | RFM12sendData: .BYTE 11 ; Byte0: Länge der Nutzdaten (= 1..10 !!, Länge zählt nicht dazu)
|
699 | ; Byte1..10: Nutzdaten
|
700 | ; RFM12 empfangen
|
701 | RFM12recCmdStat: .BYTE 1 ; Kommandos, Status
|
702 | RFM12recStep: .BYTE 1 ; Schrittkette
|
703 | RFM12recCount: .BYTE 1 ; Zähler für empfangene Bytes
|
704 | RFM12recData: .BYTE 11 ; Byte0: Länge der Nutzdaten (= 1..10 !!, Länge zählt nicht dazu)
|
705 | ; Byte1..10: Nutzdaten
|
706 |
|
707 | .EXIT
|