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