bibRFM12.asm


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