- OWINIT save Register used in C
[owSlave2.git] / programmer / programmer / programmer.asm
1 .def srbyte = r12  ;byty for search rom algorithm
2 .def writelow = r13;  marker for send low
3 .def zero =r14;  always zero 
4 .def smode=r15; if 1 then send 
5 .def temp = r16 ; 
6 .def temp2 = r17; 
7 .def mode = r18 ; 
8 .def bitp = r19 ; bit counter ... shift...
9 .def rwbyte = r21;
10 .def param = r22;
11 .def bytep = r23  ;byte counter
12 #define spmcrval  param
13
14
15 .equ OWM_READ_ROM_COMMAND=0 ; 0 wegen schnellen test ist dieser wert 0! Daturch wird die Sprungdabelle nicht verwendet
16 .equ OWM_SLEEP=1 ; Warten auf Reset
17 .equ OWM_MATCH_ROM=2
18 .equ OWM_SEARCH_ROM_S=3  ;send bit
19 .equ OWM_SEARCH_ROM_R=4  ;resive master
20 .equ OWM_READ_COMMAND=5
21 .equ OWM_WRITE_SCRATCHPAD=6
22 .equ OWM_READ_SCRATCHPAD=7
23 .equ OWM_PROGRAMM_PAGE=8
24 .equ OWM_RECALL_FLASH=9
25
26
27 .equ OW_DDR = DDRB 
28 .equ OW_PIN = PORTB2
29 .equ OW_PORT = PORTB 
30 .equ OW_PINN = PINB 
31
32 ;.equ SRAM_START = 0x60
33
34 .macro set_clock
35                 ldi temp,0x80;
36                 out CLKPR,temp
37                 ldi temp,@0
38                 out CLKPR,temp
39 .endmacro 
40
41 .macro owwl
42                 sbic OW_PINN,OW_PIN
43                 rjmp pc-1
44 .endmacro 
45
46 .macro owwh
47                 sbis OW_PINN,OW_PIN
48                 rjmp pc-1
49 .endmacro 
50
51
52
53
54  ;---------------------------------------------------
55 ; START of PROG 
56 ;---------------------------------------------------
57
58
59 .CSEG 
60 .ORG 0x000
61 jreset:
62                 rjmp start ; Reset-Vector 
63                 reti ; 
64                 reti ; 
65                 reti ; 
66                 reti ; 
67                 reti ; 
68                 reti ; 
69                 reti ; 
70                 reti ; 
71                 reti ; 
72                 reti ; 
73                 reti ; 
74                 reti ; 
75                 reti ; 
76                 reti ; 
77                 reti ; 
78                 reti ; 
79                 reti ; 
80                 reti ; 
81                 reti ; 
82                 reti ; 
83
84
85 .ORG 0x0EC0
86
87 start: 
88                 cli
89                 ldi temp,0
90                 mov zero,temp
91                 set_clock 0x00 ;8mhz
92                 ldi mode,OWM_SLEEP
93                 ldi temp,(1<<CS01) //1us
94                 out TCCR0B,temp
95                 ldi temp, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse 
96                 out SPH, temp 
97                 ldi temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse 
98                 out SPL, temp 
99                 ;ldi temp,1
100                 ;out DDRB,temp
101                 clr writelow
102                 clr bitp
103         
104                 ;sbi PORTB,0
105                 ldi ZL,low(pro_owid*2) 
106                 ldi ZH,high(pro_owid*2) 
107                 ldi XL,low(sowid)
108                 ldi XH,high(sowid)
109                 ;ldi temp2,8
110 pro_copy_loop: ;copy ID on SRAM for better handling
111                 lpm temp,Z+
112                 st X+,temp
113                 cpi XL,SRAM_START+8
114                 brlo pro_copy_loop
115 pro_loop:
116                 ;sbi PORTB,0
117                 owwl                            ;wait for line goes low (polling)
118                 sbrs writelow,0         ;test of zero send
119                 rjmp pro_loop1          ;no ? goes next
120                 sbi OW_DDR,OW_PIN       ;yes pull line to low
121                 ldi param,45            ;wait for 50 us
122                 rcall wait_time
123                 clr writelow            ;reset write low indecator
124                 cbi OW_DDR,OW_PIN   ;release line
125                 owwh                            ;wait for line is high (it can takes some time cause of the capacity of line)
126 pro_loop1:
127                 tst smode                       ;smode=1 for slave sends to master
128                 breq pro_loop_resv
129 pro_loop_send:
130                 tst bitp
131                 brne pro_loop_send1
132                 rcall pro_hb
133                 tst smode
134                 breq pro_loop_end ; now reading ... do nothing 
135 pro_loop_send1:  ;prebare next bit
136                 sbrs rwbyte ,0; if bit 0 set in rwbyte then skip next command
137                 inc writelow
138                 lsl bitp
139                 ror rwbyte
140                 rjmp pro_loop_end
141
142 pro_loop_resv:
143                 ldi param,15  ;wait 15us
144                 rcall wait_time
145                 lsr rwbyte
146                 ;cbi PORTB,0
147                 sbic OW_PINN,OW_PIN  ;test line
148                 ori rwbyte,0x80
149                 lsl bitp
150                 brne pro_loop_end ;no handle need
151                 rcall pro_hb
152                 tst smode
153                 brne pro_loop_send ; Nach dem Gelesen byte koennte gesendet werden muessen....
154 pro_loop_end:
155                 //owwh
156                 out TCNT0,zero
157 pro_loop_end_test_reset:
158                 sbic OW_PINN,OW_PIN  //leitung wieder high
159                 rjmp pro_loop
160                 in temp,TCNT0
161                 cpi temp,130
162                 brlo pro_loop_end_test_reset
163                 rcall pro_sleep_s2
164                 rjmp pro_loop
165
166
167
168
169 pro_sleep:
170                 out TCNT0,zero
171 pro_sleep_s1:
172                 sbic OW_PINN,OW_PIN  //leitung wieder high
173                 ret
174                 in temp,TCNT0
175                 cpi temp,200
176                 brlo pro_sleep_s1
177                 //leitung wieder high
178 pro_sleep_s2:
179                 owwh 
180                 ldi param,40
181                 rcall wait_time
182                 //Presents Impuls
183                 sbi OW_DDR,OW_PIN
184                 ldi param,130
185                 rcall wait_time
186                 cbi OW_DDR,OW_PIN
187                 //init read byte
188                 ldi bitp,0x01
189                 ldi rwbyte,0
190                 clr smode
191                 ldi mode,OWM_READ_ROM_COMMAND
192                 //Wait for all other devices presents impuls finished
193                 ldi param,40
194                 rcall wait_time
195                 ret
196
197
198
199 pro_hb:
200                 ldi ZL,low(pro_stable) 
201                 ldi ZH,high(pro_stable) 
202                 add ZL,mode 
203                 adc ZH,zero
204                 icall
205                 ret
206
207 pro_stable: 
208                 rjmp pro_read_rom_command
209                 rjmp pro_sleep 
210                 rjmp pro_match_rom
211                 rjmp pro_search_rom_s
212                 rjmp pro_search_rom_r
213                 rjmp pro_read_command
214                 rjmp pro_write_scratchpad
215                 rjmp pro_read_scratchpad
216                 rjmp pro_programm_page
217                 rjmp pro_recall_flash
218
219 pro_read_rom_command:
220                 ldi mode,OWM_SLEEP
221                 cpi rwbyte,0xCC
222                 brne pro_rcc_1
223                 ldi mode,OWM_READ_COMMAND
224                 rjmp pro_out_bitp1
225 pro_rcc_1:
226                 cpi rwbyte,0xF0 ;Searchrom
227                 brne pro_rcc_2
228                 ldi XL,low(sowid)  ;init sram pointer
229                 ldi XH,high(sowid)
230                 ld srbyte,X+
231                 ldi bytep,0
232                 rjmp pro_serchrom_next_bit
233 pro_rcc_2:
234                 cpi rwbyte,0x55 ;Matchrom
235                 brne pro_rcc_3
236 //              rcall pro_owidinit
237                 ldi XL,low(sowid)  ;init sram pointer
238                 ldi XH,high(sowid)
239                 ldi mode,OWM_MATCH_ROM
240                 rjmp pro_out_bytep0
241
242 pro_rcc_3:
243                 ret
244
245 pro_match_rom:          
246                 ld temp,X+
247                 cp temp,rwbyte
248                 breq pro_match_rom_next
249                 ldi mode,OWM_SLEEP
250                 ret
251 pro_match_rom_next:                                     
252                 cpi XL,SRAM_START+8
253                 breq pro_match_rom_found
254                 rjmp pro_out_bitp1
255 pro_match_rom_found:
256             ldi mode,OWM_READ_COMMAND
257                 rjmp pro_out_bitp1
258
259 pro_read_command:
260                 ldi mode,OWM_SLEEP
261                 cpi rwbyte,0x0F ;; Write to Scratchpad
262                 brne pro_rc_1
263                 ldi mode,OWM_WRITE_SCRATCHPAD
264                 ldi XL,low(scratchpad)  ;init sram pointer
265                 ldi XH,high(scratchpad)
266                 rjmp pro_out_bytep0
267 pro_rc_1:
268                 cpi rwbyte,0xAA
269                 brne pro_rc_2
270                 ldi mode,OWM_READ_SCRATCHPAD  ;;Read from Scratchpad
271                 ldi XL,low(scratchpad)  ;init sram pointer
272                 ldi XH,high(scratchpad)
273                 inc smode
274                 ld rwbyte,X+
275                 rjmp pro_out_bytep0
276
277 pro_rc_2:
278                 cpi rwbyte,0xB8
279                 brne pro_rc_3
280                 ldi mode,OWM_RECALL_FLASH  ;; copy Flash page in Scratchpad
281                 ldi XL,low(scratchpad)  ;init sram pointer
282                 ldi XH,high(scratchpad)
283                 rjmp pro_out_bytep0
284 pro_rc_3:
285                 cpi rwbyte,0x55 ; copy Scratchpad to Flash
286                 brne pro_rc_4
287                 ldi mode,OWM_SLEEP
288                 rjmp pro_programm_page
289                 
290 pro_rc_4:
291                 cpi rwbyte,0x89 ; Reset Device /Boot (new) Firmware
292                 brne pro_rc_5
293                 rjmp jreset             
294 pro_rc_5:
295                 cpi rwbyte,0x8B ; Clear the OWID saved in EEPROM / one ID1
296                 brne pro_rc_6   
297                 ldi temp,7
298 pro_rc_5a:
299                 ldi XL,low(E2END)
300                 ldi XH,high(E2END)
301                 sub XL,temp
302                 out EEARH,XH
303                 out EEARL,XL
304                 ldi temp, (0<<EEPM1)|(0<<EEPM0)
305                 out EECR, temp
306                 ldi temp,0xFF
307                 out EEDR, temp
308                 sbi EECR, EEMPE
309                 sbi EECR, EEPE
310                 ret
311
312
313 pro_rc_6:
314                 cpi rwbyte,0x8C ; Clear the OWID saved in EEPROM / one ID2
315                 brne pro_rc_7
316                 ldi temp,7+8
317                 rjmp pro_rc_5a
318
319 pro_rc_7:
320                 ret
321
322 pro_write_scratchpad:
323                 st X+,rwbyte
324                 cpi XL,SRAM_START+8+66
325                 brlo pro_write_scratchpad_next
326                 ldi mode,OWM_SLEEP
327                 ret             
328 pro_write_scratchpad_next:
329                 ldi bitp,1
330                 ret
331
332 pro_read_scratchpad:
333                 cpi XL,SRAM_START+8+66
334                 brlo pro_read_scratchpad_next
335                 ldi mode,OWM_SLEEP
336                 clr smode
337                 ret
338 pro_read_scratchpad_next:
339                 ld rwbyte,X+
340                 rjmp pro_out_bitp1
341
342
343 pro_programm_page:
344 .equ PAGESIZEB = PAGESIZE*2;PAGESIZEB is page size in BYTES, not words
345 // .org SMALLBOOTSTART
346 write_page:
347                 ;transfer data from RAM to Flash page buffer
348                 ldi bytep, PAGESIZEB ;init loop variable
349                 ldi YL,low(scratchpad)  ;init sram pointer
350                 ldi YH,high(scratchpad)
351                 ld ZL,Y+
352                 ld ZH,Y+
353                 ;page erase
354                 ldi spmcrval, (1<<PGERS) + (1<<SPMEN)
355                 rcall do_spm
356 wrloop:
357                 ld r0, Y+
358                 ld r1, Y+
359                 ldi spmcrval, (1<<SPMEN)
360                 rcall do_spm
361                 adiw ZH:ZL, 2
362                 subi bytep, 2;use subi for PAGESIZEB<=256
363                 brne wrloop
364                 ;execute page write
365                 subi ZL, low(PAGESIZEB) ;restore pointer
366                 sbci ZH, high(PAGESIZEB) ;not required for PAGESIZEB<=256
367                 ldi spmcrval, (1<<PGWRT) + (1<<SPMEN)
368                 rcall do_spm
369                 ;read back and check, optional
370                 ldi bytep, PAGESIZEB
371                 subi YL, low(PAGESIZEB) ;restore pointer
372                 sbci YH, high(PAGESIZEB)
373 rdloop:
374                 lpm r0, Z+
375                 ld r1, Y+
376                 cpse r0, r1
377                 rjmp error
378                 subi bytep, 2;use subi for PAGESIZEB<=256
379                 brne rdloop
380                 ;return
381                 ret
382 do_spm:
383                  ;input: spmcrval determines SPM action
384                 ;disable interrupts if enabled, store status
385                 in temp2, SREG
386                 cli
387                 ;check for previous SPM complete
388 wait:
389                 in temp, SPMCSR
390                 sbrc temp, SPMEN
391                 rjmp wait
392                 ;SPM timed sequence
393                 out SPMCSR, spmcrval
394                 spm
395                 ;restore SREG (to enable interrupts if originally enabled)
396                 out SREG, temp2
397                 ret
398
399 error:
400
401
402                 ret
403
404 pro_recall_flash:
405                 st X+,rwbyte
406                 ;inc bytep
407                 cpi XL,SRAM_START+8+2
408                 brlo pro_out_bitp1;pro_recall_flash_next
409                 lds ZL,scratchpad
410                 lds ZH,scratchpad+1
411 pro_recall_flash_cl:
412                 lpm temp,Z+
413                 st X+,temp
414                 cpi XL,SRAM_START+8+66
415                 brne pro_recall_flash_cl
416                 ldi mode,OWM_SLEEP
417                 ret
418
419 pro_out_read_command:
420                 ldi mode,OWM_READ_COMMAND
421 pro_out_bytep0:
422                 ldi bytep,0
423 pro_out_bitp1:
424                 ldi bitp,1
425                 ret             
426
427
428
429 pro_serchrom_next_bit:
430                 mov rwbyte,srbyte
431                 mov temp2,rwbyte
432                 com rwbyte
433                 ror temp2  ;first bit in C
434                 rol rwbyte ;C in first bit 
435                 inc smode
436                 ldi bitp,0x40
437                 ldi mode,OWM_SEARCH_ROM_R  ;next mod Resive
438                 ret
439
440
441 pro_search_rom_s:
442                 clr temp2
443                 lsr srbyte ;shift in C lowest bit
444                 ror temp2  ; shift in temp2 as highest bit
445                 andi rwbyte,0x80  ;  clear other bits
446                 eor temp2,rwbyte
447                 breq pro_search_rom_s_goon
448                 ldi mode,OWM_SLEEP
449                 ret
450 pro_search_rom_s_goon:
451                 inc bytep
452                 mov temp2,bytep
453                 andi temp2,0x07
454                 brne pro_serchrom_next_bit ;prepare next bit
455                 mov temp2,bytep
456                 andi temp2,0x40 ;;end
457                 brne pro_search_rom_found
458                 ;read next byte
459                 ld srbyte,X+
460                 rjmp pro_serchrom_next_bit
461
462 pro_search_rom_found:
463                 ldi mode,OWM_READ_COMMAND
464                 rjmp pro_out_bytep0
465
466 pro_search_rom_r:
467                 clr smode
468                 ldi mode,OWM_SEARCH_ROM_S
469                 ldi bitp,0  ;go to searchrom_s after bit get
470                 ret
471
472 pro_owid: .DB  0xA3, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xFA
473
474
475
476
477
478 wait_time:
479                 out TCNT0,zero
480 wait_time1:
481                 in temp,TCNT0
482                 cp temp,param
483                 brlo wait_time1
484                 ret
485
486
487 .DSEG
488 sowid: .BYTE 8
489 scratchpad: .BYTE 66