- OWINIT save Register used in C
[owSlave2.git] / programmer / programmer / programmer_4mhz.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 0x01 ;4mhz
92                 ldi mode,OWM_SLEEP
93                 ldi temp,(1<<CS01) //2us
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                 sbrc writelow,0         ;test of zero send
119                 sbi OW_DDR,OW_PIN       ;yes pull line to low 2us faster
120                 sbrs writelow,0     ;test egain 2us faster.....
121                 rjmp pro_loop1          ;no ? goes next
122                 ldi param,20            ;wait for 50 us
123                 rcall wait_time
124                 clr writelow            ;reset write low indecator
125                 cbi OW_DDR,OW_PIN   ;release line
126                 owwh                            ;wait for line is high (it can takes some time cause of the capacity of line)
127 pro_loop1:
128                 tst smode                       ;smode=1 for slave sends to master
129                 breq pro_loop_resv
130 pro_loop_send:
131                 tst bitp
132                 brne pro_loop_send1
133                 rcall pro_hb
134                 tst smode
135                 breq pro_loop_end ; now reading ... do nothing 
136 pro_loop_send1:  ;prebare next bit
137                 sbrs rwbyte ,0; if bit 0 set in rwbyte then skip next command
138                 inc writelow
139                 lsl bitp
140                 ror rwbyte
141                 rjmp pro_loop_end
142
143 pro_loop_resv:
144                 ldi param,7  ;wait 15us
145                 rcall wait_time
146                 lsr rwbyte
147                 ;cbi PORTB,0
148                 sbic OW_PINN,OW_PIN  ;test line
149                 ori rwbyte,0x80
150                 lsl bitp
151                 brne pro_loop_end ;no handle need
152                 rcall pro_hb
153                 tst smode
154                 brne pro_loop_send ; Nach dem Gelesen byte koennte gesendet werden muessen....
155 pro_loop_end:
156                 //owwh
157                 out TCNT0,zero
158 pro_loop_end_test_reset:
159                 sbic OW_PINN,OW_PIN  //leitung wieder high
160                 rjmp pro_loop
161                 in temp,TCNT0
162                 cpi temp,63
163                 brlo pro_loop_end_test_reset
164                 rcall pro_sleep_s2
165                 rjmp pro_loop
166
167
168
169
170 pro_sleep:
171                 out TCNT0,zero
172 pro_sleep_s1:
173                 sbic OW_PINN,OW_PIN  //leitung wieder high
174                 ret
175                 in temp,TCNT0
176                 cpi temp,100
177                 brlo pro_sleep_s1
178                 //leitung wieder high
179 pro_sleep_s2:
180                 owwh 
181                 ldi param,20
182                 rcall wait_time
183                 //Presents Impuls
184                 sbi OW_DDR,OW_PIN
185                 ldi param,75
186                 rcall wait_time
187                 cbi OW_DDR,OW_PIN
188                 //init read byte
189                 ldi bitp,0x01
190                 ldi rwbyte,0
191                 clr smode
192                 ldi mode,OWM_READ_ROM_COMMAND
193                 //Wait for all other devices presents impuls finished
194                 ldi param,20
195                 rcall wait_time
196                 ret
197
198
199
200 pro_hb:
201                 ldi ZL,low(pro_stable) 
202                 ldi ZH,high(pro_stable) 
203                 add ZL,mode 
204                 adc ZH,zero
205                 icall
206                 ret
207
208 pro_stable: 
209                 rjmp pro_read_rom_command
210                 rjmp pro_sleep 
211                 rjmp pro_match_rom
212                 rjmp pro_search_rom_s
213                 rjmp pro_search_rom_r
214                 rjmp pro_read_command
215                 rjmp pro_write_scratchpad
216                 rjmp pro_read_scratchpad
217                 rjmp pro_programm_page
218                 rjmp pro_recall_flash
219
220 pro_read_rom_command:
221                 ldi mode,OWM_SLEEP
222                 cpi rwbyte,0xCC
223                 brne pro_rcc_1
224                 ldi mode,OWM_READ_COMMAND
225                 rjmp pro_out_bitp1
226 pro_rcc_1:
227                 cpi rwbyte,0xF0 ;Searchrom
228                 brne pro_rcc_2
229                 ldi XL,low(sowid)  ;init sram pointer
230                 ldi XH,high(sowid)
231                 ld srbyte,X+
232                 ldi bytep,0
233                 rjmp pro_serchrom_next_bit
234 pro_rcc_2:
235                 cpi rwbyte,0x55 ;Matchrom
236                 brne pro_rcc_3
237 //              rcall pro_owidinit
238                 ldi XL,low(sowid)  ;init sram pointer
239                 ldi XH,high(sowid)
240                 ldi mode,OWM_MATCH_ROM
241                 rjmp pro_out_bytep0
242
243 pro_rcc_3:
244                 ret
245
246 pro_match_rom:          
247                 ld temp,X+
248                 cp temp,rwbyte
249                 breq pro_match_rom_next
250                 ldi mode,OWM_SLEEP
251                 ret
252 pro_match_rom_next:                                     
253                 cpi XL,SRAM_START+8
254                 breq pro_match_rom_found
255                 rjmp pro_out_bitp1
256 pro_match_rom_found:
257             ldi mode,OWM_READ_COMMAND
258                 rjmp pro_out_bitp1
259
260 pro_read_command:
261                 ldi mode,OWM_SLEEP
262                 cpi rwbyte,0x0F ;; Write to Scratchpad
263                 brne pro_rc_1
264                 ldi mode,OWM_WRITE_SCRATCHPAD
265                 ldi XL,low(scratchpad)  ;init sram pointer
266                 ldi XH,high(scratchpad)
267                 rjmp pro_out_bytep0
268 pro_rc_1:
269                 cpi rwbyte,0xAA
270                 brne pro_rc_2
271                 ldi mode,OWM_READ_SCRATCHPAD  ;;Read from Scratchpad
272                 ldi XL,low(scratchpad)  ;init sram pointer
273                 ldi XH,high(scratchpad)
274                 inc smode
275                 ld rwbyte,X+
276                 rjmp pro_out_bytep0
277
278 pro_rc_2:
279                 cpi rwbyte,0xB8
280                 brne pro_rc_3
281                 ldi mode,OWM_RECALL_FLASH  ;; copy Flash page in Scratchpad
282                 ldi XL,low(scratchpad)  ;init sram pointer
283                 ldi XH,high(scratchpad)
284                 rjmp pro_out_bytep0
285 pro_rc_3:
286                 cpi rwbyte,0x55 ; copy Scratchpad to Flash
287                 brne pro_rc_4
288                 ldi mode,OWM_SLEEP
289                 rjmp pro_programm_page
290                 
291 pro_rc_4:
292                 cpi rwbyte,0x89 ; Reset Device /Boot (new) Firmware
293                 brne pro_rc_5
294                 rjmp jreset             
295 pro_rc_5:
296                 cpi rwbyte,0x8B ; Clear the OWID saved in EEPROM / one ID1
297                 brne pro_rc_6   
298                 ldi temp,7
299 pro_rc_5a:
300                 ldi XL,low(E2END)
301                 ldi XH,high(E2END)
302                 sub XL,temp
303                 out EEARH,XH
304                 out EEARL,XL
305                 ldi temp, (0<<EEPM1)|(0<<EEPM0)
306                 out EECR, temp
307                 ldi temp,0xFF
308                 out EEDR, temp
309                 sbi EECR, EEMPE
310                 sbi EECR, EEPE
311                 ret
312
313
314 pro_rc_6:
315                 cpi rwbyte,0x8C ; Clear the OWID saved in EEPROM / one ID2
316                 brne pro_rc_7
317                 ldi temp,7+8
318                 rjmp pro_rc_5a
319
320 pro_rc_7:
321                 ret
322
323 pro_write_scratchpad:
324                 st X+,rwbyte
325                 cpi XL,SRAM_START+8+66
326                 brlo pro_write_scratchpad_next
327                 ldi mode,OWM_SLEEP
328                 ret             
329 pro_write_scratchpad_next:
330                 ldi bitp,1
331                 ret
332
333 pro_read_scratchpad:
334                 cpi XL,SRAM_START+8+66
335                 brlo pro_read_scratchpad_next
336                 ldi mode,OWM_SLEEP
337                 clr smode
338                 ret
339 pro_read_scratchpad_next:
340                 ld rwbyte,X+
341                 rjmp pro_out_bitp1
342
343
344 pro_programm_page:
345 .equ PAGESIZEB = PAGESIZE*2;PAGESIZEB is page size in BYTES, not words
346 // .org SMALLBOOTSTART
347 write_page:
348                 ;transfer data from RAM to Flash page buffer
349                 ldi bytep, PAGESIZEB ;init loop variable
350                 ldi YL,low(scratchpad)  ;init sram pointer
351                 ldi YH,high(scratchpad)
352                 ld ZL,Y+
353                 ld ZH,Y+
354                 ;page erase
355                 ldi spmcrval, (1<<PGERS) + (1<<SPMEN)
356                 rcall do_spm
357 wrloop:
358                 ld r0, Y+
359                 ld r1, Y+
360                 ldi spmcrval, (1<<SPMEN)
361                 rcall do_spm
362                 adiw ZH:ZL, 2
363                 subi bytep, 2;use subi for PAGESIZEB<=256
364                 brne wrloop
365                 ;execute page write
366                 subi ZL, low(PAGESIZEB) ;restore pointer
367                 sbci ZH, high(PAGESIZEB) ;not required for PAGESIZEB<=256
368                 ldi spmcrval, (1<<PGWRT) + (1<<SPMEN)
369                 rcall do_spm
370                 ;read back and check, optional
371                 ldi bytep, PAGESIZEB
372                 subi YL, low(PAGESIZEB) ;restore pointer
373                 sbci YH, high(PAGESIZEB)
374 rdloop:
375                 lpm r0, Z+
376                 ld r1, Y+
377                 cpse r0, r1
378                 rjmp error
379                 subi bytep, 2;use subi for PAGESIZEB<=256
380                 brne rdloop
381                 ;return
382                 ret
383 do_spm:
384                  ;input: spmcrval determines SPM action
385                 ;disable interrupts if enabled, store status
386                 in temp2, SREG
387                 cli
388                 ;check for previous SPM complete
389 wait:
390                 in temp, SPMCSR
391                 sbrc temp, SPMEN
392                 rjmp wait
393                 ;SPM timed sequence
394                 out SPMCSR, spmcrval
395                 spm
396                 ;restore SREG (to enable interrupts if originally enabled)
397                 out SREG, temp2
398                 ret
399
400 error:
401
402
403                 ret
404
405 pro_recall_flash:
406                 st X+,rwbyte
407                 ;inc bytep
408                 cpi XL,SRAM_START+8+2
409                 brlo pro_out_bitp1;pro_recall_flash_next
410                 lds ZL,scratchpad
411                 lds ZH,scratchpad+1
412 pro_recall_flash_cl:
413                 lpm temp,Z+
414                 st X+,temp
415                 cpi XL,SRAM_START+8+66
416                 brne pro_recall_flash_cl
417                 ldi mode,OWM_SLEEP
418                 ret
419
420 pro_out_read_command:
421                 ldi mode,OWM_READ_COMMAND
422 pro_out_bytep0:
423                 ldi bytep,0
424 pro_out_bitp1:
425                 ldi bitp,1
426                 ret             
427
428
429
430 pro_serchrom_next_bit:
431                 mov rwbyte,srbyte
432                 mov temp2,rwbyte
433                 com rwbyte
434                 ror temp2  ;first bit in C
435                 rol rwbyte ;C in first bit 
436                 inc smode
437                 ldi bitp,0x40
438                 ldi mode,OWM_SEARCH_ROM_R  ;next mod Resive
439                 ret
440
441
442 pro_search_rom_s:
443                 clr temp2
444                 lsr srbyte ;shift in C lowest bit
445                 ror temp2  ; shift in temp2 as highest bit
446                 andi rwbyte,0x80  ;  clear other bits
447                 eor temp2,rwbyte
448                 breq pro_search_rom_s_goon
449                 ldi mode,OWM_SLEEP
450                 ret
451 pro_search_rom_s_goon:
452                 inc bytep
453                 mov temp2,bytep
454                 andi temp2,0x07
455                 brne pro_serchrom_next_bit ;prepare next bit
456                 mov temp2,bytep
457                 andi temp2,0x40 ;;end
458                 brne pro_search_rom_found
459                 ;read next byte
460                 ld srbyte,X+
461                 rjmp pro_serchrom_next_bit
462
463 pro_search_rom_found:
464                 ldi mode,OWM_READ_COMMAND
465                 rjmp pro_out_bytep0
466
467 pro_search_rom_r:
468                 clr smode
469                 ldi mode,OWM_SEARCH_ROM_S
470                 ldi bitp,0  ;go to searchrom_s after bit get
471                 ret
472
473 pro_owid: .DB  0xA3, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xFA
474
475
476
477
478
479 wait_time:
480                 out TCNT0,zero
481 wait_time1:
482                 in temp,TCNT0
483                 cp temp,param
484                 brlo wait_time1
485                 ret
486
487
488 .DSEG
489 sowid: .BYTE 8
490 scratchpad: .BYTE 66