; bibRFM12.asm ; enthält RFM12 Sende-/ Empfangsfunktionen ; Hauptroutinen .NOLIST ; Listing ausschalten .INCLUDE "m32def.inc" ; Deklaration für mega32 .LIST ; Listing einschalten ; Konstante für RFM12 ; RFM12 senden, RFM12sendStep, SchrittketteRFM12_REC_END .EQU RFM12_SEND_STEP_IDLE = 1 ; RFM12 senden: nix zu tun .EQU RFM12_SEND_STEP_ISR_START = 2 ; RFM12 senden: TXon, isr Start .EQU RFM12_SEND_STEP_ISR_AKTIV = 3 ; RFM12 senden: aktiv .EQU RFM12_SEND_STEP_ISR_ENDE = 4 ; RFM12 senden: isr fertig, alles gesendet ; .EQU RFM12_SEND_STEP_TXOFF = 5 ; RFM12 senden: TXoff senden ; RFM12 senden, RFM12sendCmdStat, Kommandos, Status .EQU RFM12_SEND_IDLE = 7 ; Bit7: RFM12_senden: senden fertig, nix zu tun .EQU RFM12_SEND_AKTIV = 6 ; Bit6: RFM12 senden: senden aktiv .EQU RFM12_SEND_EXEC = 0 ; Bit0: RFM12 senden: exec senden ; RFM12 empfangen, RFM12recStep, Schrittkette .EQU RFM12_REC_STEP_IDLE = 10 ; RFM12 empfangen: nix zu tun .EQU RFM12_REC_STEP_ISR_START = 11 ; RFM12 empfangen: RXon, isr Start .EQU RFM12_REC_STEP_ISR_AKTIV = 12 ; RFM12 empfangen: aktiv .EQU RFM12_REC_STEP_ISR_ENDE = 13 ; RFM12 empfangen: isr fertig, alles empfangen ; RFM12 empfangen, RFM12recCmdStat, Kommandos, Status .EQU RFM12_REC_IDLE = 7 ; Bit7: RFM12 empfangen: empfangen fertig, nix zu tun .EQU RFM12_REC_AKTIV = 6 ; Bit6: RFM12 empfangen: empfangen aktiv .EQU RFM12_REC_EXEC = 0 ; Bit0: RFM12 empfangen: exec empfangen ; Timer .EQU TIM_RFM12 = 7 ; Bit7: Timer für RFM12 ;*************************************** ;********** CSEG: Codesegment ********** ;*************************************** .CSEG ; Interruptvektor ; .ORG INT0addr ; Einsprung INT0, externer Interrupt ; rjmp isrRFM12rec ; INT0 programmieren ; in r16,MCUCR ; altes Steuerregister ; sbr r16,1< SDI ; sbi DDRB,PORTB7 ; Ausgang SCK -> SCK ; sbi DDRB,PORTB1 ; Ausgang PORTB1 -> nSEL ; Ports setzen ; sbi PORTB,PORTB4 ; Ausgang nSS (muß gesetzt sein, wegen SPI Masterbetrieb) ; sbi PORTB,PORTB1 ; Ausgang nSEL setzen ; SPI init ; ldi r16,(1< r=17 = 0x11 call subSPIsend ; call subReadStatus ldi r17,0x98 ; Senderkonfiguration (TX Configuration 9800 oder 9900) ldi r16,0x60 ; 6*15kHz=120kHz Frequenzshift, 1mW Ausgangangsleistung (0db) call subSPIsend ; call subReadStatus pop r17 pop r16 ret ;******************************************************** ;********** subRFM12sendIni: RFM12 senden init ********** ;******************************************************** ; Initialisierung Variablen für RFM12 Senden subRFM12sendIni: push r16 push r17 push XL push XH ldi r16,(1< 0: weiter senden, Aussprung ; Zähler = 0: alles gesendet, Schlußbearbeitung lds r16,RFM12sendStep ; next step: isr fertig mit senden ldi r16,RFM12_SEND_STEP_ISR_ENDE sts RFM12sendStep,r16 isrRFM12sendEnd: call subDebTraceB2 ; debug isr senden pop r16 out SREG,r16 pop XH pop XL pop r18 pop r17 pop r16 ret ;************************************* ;********** isr isrRFM12rec ********** ;************************************* ; empfängt Daten über Interrupt INT0 ; speichern in RFM12recData ; erstes Byte: Länge Nutzdaten, speichern in RFM12recCount ; anschließend: Nutzdaten isrRFM12rec: push r16 push r17 ; RFM12recCount push r18 push r19 push XL push XH in r16,SREG push r16 ; call subDebTraceD7 ; debug empfangen sbi PORTD,PORTD7 ; debug empfangen call subDebTraceB3 ; debug isr empfangen lds r16,RFM12recStep ; Sprungleiste: RFM12_REC_STEP_ISR_START, erster Durchlauf isr cpi r16,RFM12_REC_STEP_ISR_START breq isrRFM12recFirst ; Sprungleiste: RFM12_REC_STEP_ISR_AKTIV, Byte empfangen cpi r16,RFM12_REC_STEP_ISR_AKTIV breq isrRFM12recByte ; rjmp isrRFM12recEnd ; sollte nicht vorkommen !!! rjmp isrRFM12dummyRead ; step: RFM12_REC_STEP_ISR_START, erster Durchlauf isr isrRFM12recFirst: ldi r17,0xB0 ; Daten lesen ldi r16,0x00 call subSPIsend ; r16: empfangenes Byte sts RFM12recData,r16 ; erstes Byte: Länge Nutzdaten sts RFM12recCount,r16 lds r16,RFM12recStep ; next step: Byte empfangen ldi r16,RFM12_REC_STEP_ISR_AKTIV sts RFM12recStep,r16 call subReadStatus ; Status und Interrupt quittieren rjmp isrRFM12recEnd ; und raus ; step: RFM12_REC_STEP_ISR_AKTIV, Nutzdatenbyte empfangen isrRFM12recByte: ldi r17,0xB0 ; Daten lesen ldi r16,0x00 call subSPIsend ; r16: empfangenes Byte ; Offset Speicherdresse aus Zähler berechnen lds r17,RFM12recCount ; Zähler lds r18,RFM12recData ; Byte0: Länge der Nutzdaten sub r18,r17 ; Offset = Länge - Zähler inc r18 ; Offset = Offset + 1 (wegen Länge Nutzdaten !!!) ldi XL,LOW(RFM12recData) ; Adr Nutzdaten ldi XH,HIGH(RFM12recData) ldi r19,0 add XL,r18 ; Offset für RFM12recData addieren adc XH,r19 st X,r16 ; empf. Byte speichern call subReadStatus ; Status und Interrupt quittieren ; Zähler dec, alles empfangen ? dec r17 ; Zähler dec sts RFM12recCount,r17 ; speichern brbc SREG_Z,isrRFM12recEnd ; Zähler <> 0: noch nicht alles empfangen ; alles empfangen, Schlußbearbeitung lds r16,RFM12recStep ; next step: isr fertig mit senden ldi r16,RFM12_REC_STEP_ISR_ENDE sts RFM12recStep,r16 call subRFM12RXoff ; Empfänger ausschalten rjmp isrRFM12recEnd ; und raus ; step: dummy read isrRFM12dummyRead: ldi r17,0xB0 ; Daten lesen ldi r16,0x00 call subSPIsend ; r16: empfangenes Byte call subReadStatus ; Status und Interrupt quittieren isrRFM12recEnd: call subDebTraceB3 ; debug isr empfangen pop r16 out SREG,r16 pop XH pop XL pop r19 pop r18 pop r17 pop r16 ret ;*********************************************************** ;********** subRFM12TXon: RFM12 senden einschalten ********** ;************************************************************ ; schaltet RFM12 Sender ein subRFM12TXon: push r16 push r17 ldi r17,0x82 ; TX on ldi r16,0x38 call subSPIsend call subReadStatus ; RFM12 Statusregister lesen: RFM12 nIRQ löschen pop r17 pop r16 ret ;*************************************************************** ;********** subRFM12RXon: RFM12 empfangen einschalten ********** ;*************************************************************** ; schaltet RFM12 Empfänger ein subRFM12RXon: push r16 push r17 ; ldi r17,0xCA ; set FIFO mode ; ldi r16,0x81 ; call subSPIsend ldi r17,0xCA ; enable FIFO ldi r16,0x83 call subSPIsend ldi r17,0x82 ; RX on ldi r16,0xC8 call subSPIsend call subReadStatus ; RFM12 Statusregister lesen: RFM12 nIRQ löschen pop r17 pop r16 ret ;************************************************************* ;********** subRFM12TXoff: RFM12 senden ausschalten ********** ;************************************************************* ; schaltet RFM12 Sender aus subRFM12TXoff: push r16 push r17 ldi r17,0x82 ; TX off ldi r16,0x08 call subSPIsend call subReadStatus ; RFM12 Statusregister lesen: RFM12 nIRQ löschen pop r17 pop r16 ret ;**************************************************************** ;********** subRFM12RXoff: RFM12 empfangen ausschalten ********** ;**************************************************************** ; schaltet RFM12 Empfänger aus subRFM12RXoff: push r16 push r17 ; ldi r17,0xCA ; FIFO disable ; ldi r16,0x81 ; call subSPIsend ldi r17,0x82 ; RX off ldi r16,0x08 call subSPIsend call subReadStatus ; RFM12 Statusregister lesen: RFM12 nIRQ löschen pop r17 pop r16 ret ;******************************************************************* ;********** subSPIsend: sendet Kommando über SPI an RFM12 ********** ;******************************************************************* ; Eingang ; r17,r16: 16 Bit Kommando für RFM12 ; Ausgang ; r16: von SPI gelesenes Byte subSPIsend: cbi PORTB,PORTB1 ; nSEL = 0, für RFM12: Kommandoübertragung beginnt out SPDR,r17 ; high Wert subSPIsendWait1: sbis SPSR,SPIF ; SPIF=1: Übertragung fertig jmp subSPIsendWait1 ; warte auf Ende der Übertragung in r17,SPDR ; SPIF wieder 0 out SPDR,r16 ; low Wert subSPIsendWait2: sbis SPSR,SPIF ; SPIF=1: Übertragung fertig jmp subSPIsendWait2 ; warte auf Ende der Übertragung in r16,SPDR ; SPIF wieder 0 sbi PORTB,PORTB1 ; nSEL = 1, für RFM12: Kommandoübertragung beendet ret ;*************************************************************** ;********** subReadStatus: liest RFM12 Statusregister ********** ;*************************************************************** ; Ausgang ; r16: Status RFM12 subReadStatus: push r17 ldi r17,0x00 ; 0x0000: Statusregister lesen ldi r16,0x00 call subSPIsend pop r17 ret ;**************************************** ;********** DSEG: Datensegment ********** ;**************************************** .DSEG ; RFM12 senden RFM12sendCmdStat: .BYTE 1 ; Kommandos, Status RFM12sendStep: .BYTE 1 ; Schrittkette RFM12sendCount: .BYTE 1 ; Zähler für zu sendende Bytes RFM12sendPrefix: .BYTE 5 ; 5 Bytes Vorspann: AA, AA, AA, 2D, D4 RFM12sendData: .BYTE 11 ; Byte0: Länge der Nutzdaten (= 1..10 !!, Länge zählt nicht dazu) ; Byte1..10: Nutzdaten ; RFM12 empfangen RFM12recCmdStat: .BYTE 1 ; Kommandos, Status RFM12recStep: .BYTE 1 ; Schrittkette RFM12recCount: .BYTE 1 ; Zähler für empfangene Bytes RFM12recData: .BYTE 11 ; Byte0: Länge der Nutzdaten (= 1..10 !!, Länge zählt nicht dazu) ; Byte1..10: Nutzdaten .EXIT