1 | ; rfm12/stk500.asm
|
2 | ;
|
3 | ; Funkmodul rfm12
|
4 | ; senden:
|
5 | ; auf negative Flanke auf steckbrett
|
6 | ; empfangen
|
7 | ; auf STK500
|
8 | ; siehe Oszi Bild
|
9 | ; senden: 5 mal Prolog, 3 mal Daten (1 Länge, 2 Nutzdaten)
|
10 | ; empfangen: 3 mal Daten (1 Länge, 2 Nutzdaten)
|
11 | ; in den isr Routinen für Senden/ empfangen werden bei Start und Ende Ports gesetzt
|
12 | ;
|
13 | ; Takt 14.7456MHz
|
14 |
|
15 | .LIST ; Listing ausschalten
|
16 | .INCLUDE "m32def.inc" ; Deklaration für mega32
|
17 | .LIST ; Listing einschalten
|
18 |
|
19 | ; Softwaretimer
|
20 | .EQU TIM_TMP = 0b_0001_0000 ; tmp-Timer
|
21 |
|
22 | ; USART Baudrate
|
23 | .EQU USART_BAUDRATE = 23 ; USART: Baudrate 38400
|
24 |
|
25 | ;***************************************
|
26 | ;********** CSEG: Codesegment **********
|
27 | ;***************************************
|
28 |
|
29 | .CSEG ; Programm Flash
|
30 | rjmp prgReset ; Reset Einsprung
|
31 | .ORG INT0addr ; Einsprung INT0, externer Interrupt
|
32 | rjmp isrRFM12 ; RFM12 senden/ empfangen
|
33 | .ORG OVF0addr ; Timer 0 Überlauf Einsprung
|
34 | rjmp isrTIMER0 ; nach Interrupt Service Programm
|
35 | .ORG INT_VECTORS_SIZE ; weitere Interrupt Einsprünge übergehen
|
36 |
|
37 | ;********************************************
|
38 | ;********** Hauptprogramm Hochlauf **********
|
39 | ;********************************************
|
40 |
|
41 | prgReset: ldi r16,LOW(RAMEND) ; Stapel anlegen
|
42 | out SPL,r16
|
43 | ldi r16,HIGH(RAMEND)
|
44 | out SPH,r16
|
45 |
|
46 | call subRegisterIni
|
47 |
|
48 | ; PORTS definieren
|
49 | ; Debug
|
50 | ; cbi DDRD,PIND7 ; Eingang: Taster
|
51 |
|
52 | sbi DDRD,PORTD3 ; Ausgang: LED grün
|
53 | sbi DDRD,PORTD4 ; Ausgang: LED gelb
|
54 | sbi DDRD,PORTD5 ; Ausgang: LED rot
|
55 | sbi DDRD,PORTD6 ; Ausgang: debug senden
|
56 | sbi DDRD,PORTD7 ; Ausgang: debug empfangen
|
57 | sbi DDRB,PORTB0 ; Ausgang: debug isr senden/ empfangen
|
58 | sbi DDRB,PORTB2 ; Ausgang: debug isr senden
|
59 | sbi DDRB,PORTB3 ; Ausgang: debug isr empfangen
|
60 |
|
61 | ; RFM12
|
62 | cbi DDRB,PINB6 ; Eingang MISO <- SDO
|
63 | cbi DDRD,PIND2 ; Eingang PIND2 <- nIRQ
|
64 |
|
65 | sbi DDRB,PORTB4 ; Ausgang nSS (muß gesetzt sein, wegen SPI Masterbetrieb)
|
66 | sbi DDRB,PORTB5 ; Ausgang MOSI -> SDI
|
67 | sbi DDRB,PORTB7 ; Ausgang SCK -> SCK
|
68 | sbi DDRB,PORTB1 ; Ausgang PORTB1 -> nSEL
|
69 |
|
70 | ; Ports setzen
|
71 | ; Debug
|
72 | sbi PORTD,PORTD3 ; LED grün aus
|
73 | sbi PORTD,PORTD4 ; LED gelb aus
|
74 | sbi PORTD,PORTD5 ; LED rot aus
|
75 |
|
76 | cbi PORTD,PORTD6 ; Ausgang: debug senden
|
77 | cbi PORTD,PORTD7 ; Ausgang: debug empfangen
|
78 | cbi PORTB,PORTB0 ; Ausgang: debug isr senden/ empfangen
|
79 | cbi PORTB,PORTB2 ; Ausgang: debug isr senden
|
80 | cbi PORTB,PORTB3 ; Ausgang: debug isr empfangen
|
81 | cbi PORTB,PORTB4 ; Ausgang: debug isr senden/ empfangen
|
82 |
|
83 | ; RFM12
|
84 | sbi PORTB,PORTB4 ; Ausgang nSS (muß gesetzt sein, wegen SPI Masterbetrieb)
|
85 | sbi PORTB,PORTB1 ; Ausgang nSEL setzen
|
86 |
|
87 | ; SPI init
|
88 | ldi r16,(1<<SPE) | (1<<MSTR) | (0<<SPR1) |(1<<SPR0) ; SPI frei, MSB erst
|
89 | out SPCR,r16 ;
|
90 | ldi r16,(1<<SPI2X) ; SPI2X=1, SPR1=0, SPR0=1: f(osc)/8 = 14.7456 MHz/8 = 1.8432 MHz
|
91 | out SPSR,r16
|
92 |
|
93 | ; Timerticks der Softwaretimer init
|
94 | call subTimer16ini ; 16 Bit Timer initialisieren
|
95 | call subTimer8ini ; 8 Bit Timer initialisieren
|
96 |
|
97 | ; TCNT0 init
|
98 | call subTIMER0init
|
99 | sei
|
100 | ; USART init
|
101 | ldi r16,LOW(USART_BAUDRATE)
|
102 | ldi r17,HIGH(USART_BAUDRATE)
|
103 | call subUSARTini
|
104 |
|
105 | ; USART senden init
|
106 | call subUSARTsendIni
|
107 |
|
108 | ; INT0 für RFM12 programmieren
|
109 | ; RFM12
|
110 | in r16,MCUCR ; MCU Steuerregister (MCU contol register)
|
111 | sbr r16,1<<ISC01 ; Interrupt INT0 auf fallende Flanke
|
112 | cbr r16,1<<ISC00
|
113 | out MCUCR,r16
|
114 |
|
115 | in r16,GICR ; General Interrupt Control Register
|
116 | ; cbr r16,1<<INT0 ; INT0 sperren
|
117 | sbr r16,1<<INT0 ; INT0 freigeben
|
118 | out GICR,r16
|
119 |
|
120 | ; Wartezeit für Hochlauf RFM12
|
121 | ldi r16,TIM_TMP
|
122 | ldi r17, 100 ; 100 mSek
|
123 | call subDelay8
|
124 |
|
125 | ; RFM12, senden, empfangen initialisieren
|
126 | call subRFM12paramIni ; RFM12 Parameter init
|
127 | call subRFM12sendIni ; Senden init
|
128 | call subRFM12recIni ; Empfangen init
|
129 |
|
130 | ldi r16,1 ; Testschrittkette, step 1: starte Empfang
|
131 | sts tstStepCounter,r16 ; stepCounter
|
132 |
|
133 | ; Wartezeit für Hochlauf
|
134 | cbi PORTD,PORTD4 ; LED gelb an
|
135 |
|
136 | ldi r16,TIM_TMP
|
137 | ldi r17, 250 ; 1 Sek Wartezeit
|
138 | call subDelay8
|
139 | call subDelay8
|
140 | call subDelay8
|
141 | call subDelay8
|
142 |
|
143 | sbi PORTD,PORTD4 ; LED gelb aus
|
144 | cbi PORTD,PORTD3 ; LED grün an
|
145 |
|
146 | ;****************************************
|
147 | ;********** Hauptprogramm Loop **********
|
148 | ;****************************************
|
149 |
|
150 | prgLoop: ; step1: Empfang starten
|
151 | lds r17,tstStepCounter
|
152 | cpi r17,1 ; step 1: Empfang starten
|
153 | brne prgStep2
|
154 |
|
155 | call subClearRecData ; Empfangspuffer löschen
|
156 |
|
157 | ldi r16,(1<<RFM12_REC_EXEC) ; Empfang starten
|
158 | sts RFM12recCmdStat,r16
|
159 |
|
160 | ldi r17,2 ; next step: warten auf Empfangsende
|
161 | sts tstStepCounter,r17
|
162 | rjmp prgZyk
|
163 |
|
164 | ; step2: warten auf Ende Empfang
|
165 | prgStep2: lds r17,tstStepCounter
|
166 | cpi r17,2 ; step 2: warten auf Empfangsende
|
167 | brne prgStep3
|
168 |
|
169 | lds r16,RFM12recCmdStat
|
170 | andi r16,(1<<RFM12_REC_IDLE) ; Empfang fertig ?
|
171 | brbs SREG_Z,prgZyk ; nein: springe
|
172 |
|
173 | call subDebTraceD5 ; LED rot
|
174 |
|
175 | ldi r16,22 ; Kennung: 20: STK500, 2: empfangen
|
176 | call subCopRecDataRS232 ; Traceausgabe
|
177 |
|
178 | call subUSARTsend
|
179 |
|
180 | ldi r17,3 ; next step: Sender einschalten
|
181 | ; ldi r17,1 ; next step: Empfang starten
|
182 |
|
183 | sts tstStepCounter,r17
|
184 | rjmp prgZyk
|
185 |
|
186 | ; step3: Sender einschalten
|
187 | prgStep3: lds r17,tstStepCounter
|
188 | cpi r17,3 ; step 3: Sender einschalten
|
189 | brne prgStep4
|
190 |
|
191 | call subInitSendData ; Sendedaten vorbereiten
|
192 |
|
193 | ldi r16,(1<<RFM12_SEND_EXEC) ; senden starten
|
194 | sts RFM12sendCmdStat,r16
|
195 |
|
196 | ldi r17,4
|
197 | sts tstStepCounter,r17 ; next step: warten auf Sendenende
|
198 | rjmp prgZyk ; Aussprung
|
199 |
|
200 | ; step4: warten auf Sendenende
|
201 | prgStep4: lds r17,tstStepCounter
|
202 | cpi r17,4 ; step 4: warten auf Sendenende
|
203 | brne prgZyk
|
204 |
|
205 | lds r16,RFM12sendCmdStat
|
206 | andi r16,(1<<RFM12_SEND_IDLE) ; Senden fertig ?
|
207 | brbs SREG_Z,prgZyk ; nein: springe
|
208 |
|
209 | call subDebTraceD4 ; LED gelb
|
210 |
|
211 | ldi r17,1 ; next step: Empfang starten
|
212 | ; ldi r17,10 ; next step: ab in den Wald
|
213 | sts tstStepCounter,r17
|
214 | rjmp prgZyk ; Aussprung
|
215 |
|
216 | prgZyk: call subRFM12Rec
|
217 | call subRFM12Send
|
218 | rjmp prgLoop
|
219 |
|
220 | ;*************************************
|
221 | ;********** subClearRecData **********
|
222 | ;*************************************
|
223 | ; löscht die RFM12 Empfangsdaten, 11 Bytes
|
224 | ; Byte0: Länge, Byte1..Byte10: Daten
|
225 |
|
226 | subClearRecData: push r16
|
227 | push r17
|
228 | push XL
|
229 | push XH
|
230 |
|
231 | ldi XL,LOW(RFM12recData) ; RFM12 Empfangsdaten
|
232 | ldi XH,HIGH(RFM12recData) ;
|
233 |
|
234 | clr r16
|
235 | ldi r17,11 ; 11: Feldlänge
|
236 |
|
237 | subClRecDatLoop: st X+,r16
|
238 | dec r17
|
239 | brbc SREG_Z,subClRecDatLoop ; noch nicht fertig: springe
|
240 |
|
241 | pop XH
|
242 | pop XL
|
243 | pop r17
|
244 | pop r16
|
245 | ret
|
246 |
|
247 | ;************************************
|
248 | ;********** subCopSendData **********
|
249 | ;************************************
|
250 | ; kopiert die empfangenen Daten in die Sendedaten
|
251 |
|
252 | subCopSendData: push r16
|
253 | push r17
|
254 | push XL
|
255 | push XH
|
256 | push YL
|
257 | push YH
|
258 |
|
259 | ldi XL,LOW(RFM12recData) ; RFM12 Empfangsdaten
|
260 | ldi XH,HIGH(RFM12recData) ;
|
261 | ldi YL,LOW(RFM12sendData) ; RFM12 Sendedaten
|
262 | ldi YH,HIGH(RFM12sendData) ;
|
263 |
|
264 | ldi r17,11 ; 11: Feldlänge
|
265 |
|
266 | subCoSendDatLoop: ld r16,X+
|
267 | st Y+,r16
|
268 | dec r17
|
269 | brbc SREG_Z,subCoSendDatLoop ; noch nicht fertig: springe
|
270 |
|
271 | pop YH
|
272 | pop YL
|
273 | pop XH
|
274 | pop XL
|
275 | pop r17
|
276 | pop r16
|
277 | ret
|
278 |
|
279 |
|
280 | ;*************************************
|
281 | ;********** subInitSendData **********
|
282 | ;*************************************
|
283 | ; initialisert die Sendedaten
|
284 |
|
285 | subInitSendData: push r16
|
286 | push YL
|
287 | push YH
|
288 |
|
289 | ldi YH,HIGH(RFM12sendData) ; RFM12 Senden starten
|
290 | ldi YL,LOW(RFM12sendData) ; Sendedaten
|
291 |
|
292 | ldi r16,2 ; Länge der Nutzdaten
|
293 | st Y+,r16
|
294 |
|
295 | ldi r16,0b_1111_0000 ; Nutzdaten
|
296 | st Y+,r16
|
297 |
|
298 | ldi r16,0b_0000_1111 ; Nutzdaten
|
299 | st Y+,r16
|
300 |
|
301 | pop YH
|
302 | pop YL
|
303 | pop r16
|
304 | ret
|
305 |
|
306 | ;****************************************
|
307 | ;********** subCopRecDataRS232 **********
|
308 | ;****************************************
|
309 | ; kopiert 10 Bytes Empfangsdaten nach
|
310 | ; RS232 Puffer, für Debugausgabe
|
311 | ; Eingang
|
312 | ; r16 12: Empfangsdaten auf steckbrett, 22: Empfangsdaten auf STK500
|
313 |
|
314 | subCopRecDataRS232: push r16
|
315 | push r17
|
316 | push XL
|
317 | push XH
|
318 | push YL
|
319 | push YH
|
320 |
|
321 | ldi XL,LOW(RFM12recData) ; RFM12 Empfangsdaten
|
322 | ldi XH,HIGH(RFM12recData) ;
|
323 | ldi YL,LOW(USARTsendData) ; Adresse RS232 Daten
|
324 | ldi YH,HIGH(USARTsendData)
|
325 |
|
326 | ld r17,X+ ; Länge Nutzdaten
|
327 | inc r17 ; wegen Kennung Empfänger
|
328 | st Y+,r17
|
329 |
|
330 | st Y+,r16 ; Kennung Empfänger (12, 22)
|
331 |
|
332 | ld r17,X+ ; Nutzdaten
|
333 | st Y+,r17
|
334 | ld r17,X+ ; Nutzdaten
|
335 | st Y+,r17
|
336 | ld r17,X+ ; Nutzdaten
|
337 | st Y+,r17
|
338 | ld r17,X+ ; Nutzdaten
|
339 | st Y+,r17
|
340 | ld r17,X+ ; Nutzdaten
|
341 | st Y+,r17
|
342 | ld r17,X+ ; Nutzdaten
|
343 | st Y+,r17
|
344 | ld r17,X+ ; Nutzdaten
|
345 | st Y+,r17
|
346 | ld r17,X+ ; Nutzdaten
|
347 | st Y+,r17
|
348 | ld r17,X+ ; Nutzdaten
|
349 | st Y+,r17
|
350 | ld r17,X+ ; Nutzdaten
|
351 | st Y+,r17
|
352 |
|
353 | pop YH
|
354 | pop YL
|
355 | pop XH
|
356 | pop XL
|
357 | pop r17
|
358 | pop r16
|
359 | ret
|
360 |
|
361 | ;****************************************
|
362 | ;********** DSEG: Datensegment **********
|
363 | ;****************************************
|
364 | .DSEG
|
365 |
|
366 | tstStepCounter: .BYTE 1 ; Testschrittzähler
|
367 |
|
368 | ;*****************************
|
369 | ;********** includes **********
|
370 | ;******************************
|
371 | .INCLUDE "bibTimer.asm"
|
372 | .INCLUDE "bibMisc.asm"
|
373 | .INCLUDE "bibRFM12.asm"
|
374 | .INCLUDE "bibDebug.asm"
|
375 | .INCLUDE "bibUSART.asm"
|
376 | .EXIT
|