e88941611e28d3977f2055d32ae628b02aa7c3c3
[owSlave2.git] / common / OWRomFunctions.s
1 // Copyright (c) 2015, Tobias Mueller tm(at)tm3d.de
2 // All rights reserved. 
3 // 
4 // Redistribution and use in source and binary forms, with or without 
5 // modification, are permitted provided that the following conditions are 
6 // met: 
7 // 
8 //  * Redistributions of source code must retain the above copyright 
9 //    notice, this list of conditions and the following disclaimer. 
10 //  * Redistributions in binary form must reproduce the above copyright 
11 //    notice, this list of conditions and the following disclaimer in the 
12 //    documentation and/or other materials provided with the 
13 //    distribution. 
14 //  * All advertising materials mentioning features or use of this 
15 //    software must display the following acknowledgement: This product 
16 //    includes software developed by tm3d.de and its contributors. 
17 //  * Neither the name of tm3d.de nor the names of its contributors may 
18 //    be used to endorse or promote products derived from this software 
19 //    without specific prior written permission. 
20 // 
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
32
33
34
35 .macro cjmp val,addr
36         cpi r_rwbyte,\val
37         breq \addr
38 .endm
39 .macro cljmp val,addr; Weiter sprung, wenn das ziel zu weit entfernt fuer brxx
40         cpi r_rwbyte,\val
41         brne 1f
42         rjmp \addr
43 1:
44 .endm
45
46 .macro cset val,mod ;Nur der Mode wird gesetzt. Abkuerzung da oft nur das noch bleibt
47         cpi r_rwbyte,\val
48         brne 1f
49         ldi r_mode,\mod
50         rjmp handle_end
51 1:
52 .endm
53
54
55
56
57 #define OW_SLEEP 0
58 #define OW_READ_ROM_COMMAND 1
59 #define OW_MATCHROM 2
60 #define OW_SEARCHROMS 3  ;next send two bit
61 #define OW_SEARCHROMR 4  ; next resive master answer
62 #define OW_READROM 5
63 #define OW_READ_COMMAND 6
64 #define OW_FWCONFIGINFO 7
65
66
67 #ifdef _CHANGEABLE_ID_
68 #define OW_WRITE_NEWID 8
69 #define OW_READ_NEWID 9
70 #define OW_SET_NEWID 10
71 #define OW_FIRST_COMMAND 11
72 .comm newid,8
73
74        
75 .macro CHANGE_ID_COMMANDS
76         cset 0x75,OW_WRITE_NEWID
77         cljmp 0xA7,hrc_set_readid
78         cljmp 0x79,hrc_set_setid
79 .endm
80
81
82 #else
83 #define OW_FIRST_COMMAND 8
84 #endif
85
86 #ifndef _DIS_FLASH_
87 ; test auf run flasher command 0x88 in h_readcommand
88 .macro FLASH_COMMANDS
89         cpi r_rwbyte,0x88
90         brne 1f
91         rjmp hrc_jmp_flasher
92 1: ldi r_temp,0 ;Anderes Kommando flashmarker zuruecksetzen...
93         sts flashmarker,r_temp
94 .endm
95 #endif
96
97 .macro FW_CONFIG_INFO
98         cljmp 0x85,hrc_fw_configinfo
99 .endm
100
101
102 #ifdef _CHANGEABLE_ID_
103 ; lesen der ID aus dem EEPROM beim Start
104 read_EEPROM_ID:  
105         push r_bytep
106         push r_rwbyte//r_temp2 and Z is not in gnu C save area
107         ldi r_temp2,lo8(E2END)
108         ldi zh,hi8(E2END)
109         subi r_temp2,7
110         out _SFR_IO_ADDR(EEARH), zh
111         ldi r_bytep,0
112         ldi  zl,lo8(owid)       
113     ldi  zh,hi8(owid)
114 read_EEPROM_ID_loop:
115         sbic _SFR_IO_ADDR(EECR), EEPE
116         rjmp read_EEPROM_ID_loop
117         out _SFR_IO_ADDR(EEARL),r_temp2
118         sbi _SFR_IO_ADDR(EECR), EERE
119         in r_rwbyte,_SFR_IO_ADDR(EEDR)
120         cpi r_rwbyte,0xFF
121         breq read_EEPROM_ID_end
122         st Z+,r_rwbyte
123         inc r_bytep
124         inc r_temp2
125         cpi r_bytep,8
126         brne read_EEPROM_ID_loop
127 read_EEPROM_ID_end:
128         pop r_rwbyte
129         pop r_bytep
130         ret
131 #endif
132
133
134
135
136
137
138 handle_stable: 
139                 rjmp handle_end_no_bcount // sleep eventuell reset, nichts tun und auf Timeout warten
140                 rjmp h_readromcommand 
141                 rjmp h_matchrom 
142                 rjmp h_searchroms 
143                 rjmp h_searchromr
144                 rjmp h_readrom
145                 rjmp h_readcommand 
146                 rjmp h_fwconfiginfo
147 #ifdef _CHANGEABLE_ID_
148                 rjmp h_writeid
149                 rjmp h_readid
150                 rjmp h_setid
151 #endif
152                 COMMAND_TABLE
153
154
155
156 h_readromcommand:
157         clr r_bytep
158         cset 0x55,OW_MATCHROM 
159         cjmp 0xF0,hrc_set_searchrom
160         cjmp 0xCC,hrc_start_read_command ;skip rom
161         cjmp 0x33,hrc_set_read_rom
162         cjmp 0xEC,hrc_set_alarm_search
163         
164         rjmp handle_end_sleep
165
166 #ifndef _DIS_FLASH_
167 ;sprung zum flasher
168 hrc_jmp_flasher:
169         lds r_temp,flashmarker
170         cpi r_temp,2
171         brne hrc_jmp_flasher_inc
172         ldi r_temp,0xC0
173         push r_temp
174         ldi r_temp,0x0E
175         push r_temp
176         ret ; Direkter Sprung zum Bootloader
177 hrc_jmp_flasher_inc:
178         inc r_temp
179         sts flashmarker,r_temp
180         rjmp handle_end_sleep
181 #endif
182
183
184 hrc_set_searchrom:      
185         lds r_rwbyte,owid ;erstes Byte lesen
186         rjmp h_searchrom_next_bit
187
188 hrc_start_read_command: ;Skip rom und Matchrom ok...
189         ldi r_mode,OW_READ_COMMAND
190         CRCInit1
191         rjmp handle_end
192
193 hrc_set_read_rom:
194         ldi r_mode,OW_READROM
195         ldi r_sendflag,1
196         rjmp h_readrom
197
198 hrc_set_alarm_search:
199         lds r_temp,alarmflag
200         tst r_temp
201         brne hrc_set_searchrom ;alarm flag nicht 0 also gehe zu searchrom
202         ; sonst tue nichts
203         rjmp handle_end_sleep
204
205
206 hrc_fw_configinfo:
207         ldi r_mode,OW_FWCONFIGINFO
208         ldi r_sendflag,1
209         CRCInit2
210         rjmp h_fwconfiginfo
211
212
213 ;---------------------------------------------------
214 ;   MATCH ROM
215 ;---------------------------------------------------
216         
217
218 h_matchrom:
219         configZ owid,r_bytep
220         ld r_temp,Z
221         cp r_temp,r_rwbyte
222         breq hmr_next_byte
223         rjmp handle_end_sleep
224
225 hmr_next_byte:
226         cpi r_bytep,7
227         breq hrc_start_read_command ;Starten von Read Command
228         rjmp handle_end_inc
229
230
231
232 ;---------------------------------------------------
233 ;   SEARCH ROM
234 ;---------------------------------------------------
235
236
237 h_searchrom_next_bit:  ;Setup next Bit of ID
238         sts srbyte,r_rwbyte ;erstes Byte speichern von der Aufrufenden Ebene
239         mov r_temp2,r_rwbyte
240         com r_rwbyte ; negieren
241         ror r_temp2 ; erstes unnegiertes bit in Carry
242         rol r_rwbyte ;und dann als erstes bit in r_rwbyte
243         ldi r_sendflag,1
244         ldi r_bcount,0x40 ; zwei bits sensden dann zu Searchromr 
245         ldi r_mode,OW_SEARCHROMR
246         rjmp handle_end_no_bcount
247
248
249
250 h_searchroms:  ; Modus Send zwei bit
251         clr r_temp
252         sbrc r_rwbyte,7 ; bit gesetz (1 empfangen)
253         ldi r_temp,1
254         lds r_bcount,srbyte ;r_bcount wird am ende gesetzt
255         eor r_temp,r_bcount
256         sbrs r_temp,0
257         rjmp h_searchroms_next ; Vergleich des letzen gelesenen bits mit der id
258         ;Ungleich....
259         ;goto sleep
260         ;clr r_sendflag
261         ; ist ja auf lesen
262         rjmp handle_end_sleep
263 h_searchroms_next: ; Setup next bit
264         inc r_bytep  ; zaehler der Bits erhoehen
265         sbrc r_bytep,6 ; 64 bit erreicht 
266         rjmp h_searchrom_end_ok ;alles ok auf Command warten
267         mov r_temp,r_bytep 
268         andi r_temp,0x07
269         brne h_searchroms_next_bit  ; bit zwischen 0 und 8
270         mov r_bcount,r_bytep  ; next Byte lesen
271         lsr r_bcount    
272         lsr r_bcount
273         lsr r_bcount
274
275         configZ owid,r_bcount
276         ld r_rwbyte,Z
277         sts srbyte,r_rwbyte
278         rjmp h_searchrom_next_bit
279                 
280 h_searchroms_next_bit: ;next Bit lesen
281         ;sts srbytep,r_bcount
282         lds r_rwbyte,srbyte
283         lsr r_rwbyte ;aktuelles byte weiterschieben r_rwbyte hier zweckefrei verwendet
284         rjmp h_searchrom_next_bit  ;algemeine routine zum vorbereiten
285 h_searchrom_end_ok:
286         clr r_sendflag
287         rjmp hrc_start_read_command
288
289 h_searchromr:
290         clr r_sendflag
291         ldi r_mode,OW_SEARCHROMS
292         ldi r_bcount,0
293         rjmp handle_end_no_bcount
294
295
296 ;---------------------------------------------------
297 ;   READ ROM
298 ;---------------------------------------------------
299
300 h_readrom:
301         cpi  r_bytep,8
302         breq h_readrom_all
303         configZ owid,r_bytep
304         ld   r_rwbyte,Z
305         rjmp handle_end_inc
306 h_readrom_all:
307         rjmp handle_end_sleep
308
309
310 ;---------------------------------------------------
311 ;   FW_CONFIG_INFO
312 ;---------------------------------------------------
313
314 h_fwconfiginfo:
315         cpi  r_bytep,16
316         breq h_fwconfiginfo_crc
317 #ifdef _CRC8_
318         cpi  r_bytep,17
319         breq h_fwconfiginfo_all
320 #elif defined _CRC16_
321         cpi  r_bytep,17
322         breq h_fwconfiginfo_crc2
323         cpi  r_bytep,18
324         breq h_fwconfiginfo_all
325 #else
326         cpi  r_bytep,16
327         breq h_fwconfiginfo_all
328 #warning No CRC known code implemented
329 #endif
330         configZ config_info,r_bytep
331         ld   r_rwbyte,Z
332         rjmp handle_end_inc
333 h_fwconfiginfo_crc:
334         lds r_rwbyte,crc
335         rjmp handle_end_inc
336 h_fwconfiginfo_crc2:
337         lds r_rwbyte,crc+1
338         rjmp handle_end_inc
339 h_fwconfiginfo_all:
340         rjmp handle_end_sleep
341
342
343 ;---------------------------------------------------
344 ;   CHANGE ROM FUNCTIONS
345 ;---------------------------------------------------
346
347
348 #ifdef _CHANGEABLE_ID_
349
350 h_writeid:
351         configZ newid,r_bytep
352         st   Z,r_rwbyte
353         cpi  r_bytep,7
354         breq h_writeid_all
355         rjmp handle_end_inc
356 h_writeid_all:
357         rjmp handle_end_sleep
358
359
360 hrc_set_readid:
361         ldi r_mode,OW_READ_NEWID
362         ldi r_sendflag,1
363 h_readid:
364         cpi  r_bytep,8
365         breq h_readid_all
366         configZ newid,r_bytep
367         ld   r_rwbyte,Z
368         rjmp handle_end_inc
369 h_readid_all:
370         clr  r_sendflag
371         rjmp handle_end_sleep
372
373 hrc_set_setid:
374         ldi r_mode,OW_SET_NEWID
375         ;ldi r_bytep,1 ;start to write in 2
376         rjmp handle_end_inc ;set r_bytep to 1!!!
377
378 h_setid:
379         configZ owid,r_bytep
380         ld r_temp,Z
381         cp r_rwbyte,r_temp
382         brne h_setid_bad_code_all
383         cpi r_bytep,1
384         breq h_setid_set2
385         cpi r_bytep,5 
386         breq h_setid_set3
387         cpi r_bytep,6
388         breq h_setid_copy_id
389         rjmp h_setid_bad_code_all ;sollte eigentlich nicht passieren
390 h_setid_set2:
391         ldi r_temp,3
392         add r_bytep,r_temp
393 h_setid_set3:
394         inc r_bytep
395         rjmp handle_end
396 h_setid_copy_id:
397         ldi r_temp2,lo8(E2END)
398         ldi zh,hi8(E2END)
399         ldi r_temp,7
400         sub r_temp2,r_temp
401         ;ldi r_temp,0 ;kommt nicht vor das ein E2ROM genau n*256+(0 bis 7) byte gross ist
402         ;sbc zh
403         out _SFR_IO_ADDR(EEARH),zh
404         ldi zl,lo8(newid)
405         ldi zh,hi8(newid)
406         ldi r_bytep,0
407 h_setid_EEPROM_write:
408         sbic _SFR_IO_ADDR(EECR), EEPE   
409         rjmp h_setid_EEPROM_write
410         ldi r_temp, (0<<EEPM1)|(0<<EEPM0)
411         out _SFR_IO_ADDR(EECR), r_temp
412         ;nur adresse L schreiben H bleibt aus oben genannten grund gleich.
413         out _SFR_IO_ADDR(EEARL),r_temp2
414         ld  r_rwbyte,Z+
415         out _SFR_IO_ADDR(EEDR), r_rwbyte
416         sbi _SFR_IO_ADDR(EECR), EEMPE
417         sbi _SFR_IO_ADDR(EECR), EEPE
418         inc r_bytep
419         inc r_temp2
420         cpi r_bytep,8
421         brne h_setid_EEPROM_write
422         rcall read_EEPROM_ID
423 h_setid_bad_code_all:
424         rjmp handle_end_sleep
425
426
427
428 #endif
429
430
431 spause:
432         nop
433         nop
434         nop
435         nop
436         ret
437
438
439 .global OWINIT
440 OWINIT:
441 #ifndef _DIS_FLASH_
442 ; check for bootloader jumper
443         ;vor allen anderen Registerconfigs
444         push r_temp
445         ldi r_temp,(1<<PUD) ;enable pullup 
446         out _SFR_IO_ADDR(MCUCR) ,r_temp
447         sbi _SFR_IO_ADDR(PORTA),PINA5 ;internal pullup on PINA5
448         sbi _SFR_IO_ADDR(PORTA),PINA4 ;internal pullup on PINA4
449         rcall spause
450         sbis _SFR_IO_ADDR(PINA),PINA5
451         rjmp owinit_botest_end  ;PinA5 nicht auf 1
452         sbis _SFR_IO_ADDR(PINA),PINA4
453         rjmp owinit_botest_end ;PinA4 nicht auf 1
454         cbi _SFR_IO_ADDR(PORTA),PINA4 
455         sbi _SFR_IO_ADDR(DDRA),PINA4  ;PINA4 AUSGANG und 0
456         rcall spause
457         sbic _SFR_IO_ADDR(PINA),PINA5 
458         rjmp owinit_botest_end ;PINA5 nicht 0.... nicht verbunden
459         cbi _SFR_IO_ADDR(DDRA),PINA4
460         ldi r_temp,0xC0
461         push r_temp
462         ldi r_temp,0x0E
463         push r_temp
464         ret ; Direkter Sprung zum Bootloader*/
465 owinit_botest_end:
466 #endif
467         HW_INIT  //Microcontroller specific
468         CHIP_INIT //1-Wire device specific
469 #ifdef _CHANGEABLE_ID_
470         rcall read_EEPROM_ID
471 #endif
472         ldi r_temp,0
473         sts mode,r_temp
474         sts bcount,r_temp
475         sts alarmflag,r_temp
476         RESETZEROMARKER
477         pop r_temp
478         ret
479
480
481 .global EXTERN_SLEEP
482 EXTERN_SLEEP:
483         cli
484         push r_temp
485         ldi r_temp,0
486         sts mode,r_temp ;SLEEP
487         sts gcontrol,r_temp
488         sts sendflag,r_temp
489         sts bcount,r_temp
490         RESETZEROMARKER
491         pop r_temp
492         sei
493         ret