Many changes from 2018
[owSlave2.git] / programmer_atmega328 / programmer_atmega328 / programmer_atmega328.asm
diff --git a/programmer_atmega328/programmer_atmega328/programmer_atmega328.asm b/programmer_atmega328/programmer_atmega328/programmer_atmega328.asm
new file mode 100644 (file)
index 0000000..816731c
--- /dev/null
@@ -0,0 +1,497 @@
+\r
+.def srbyte = r12  ;byty for search rom algorithm\r
+.def writelow = r13;  marker for send low\r
+.def zero =r14;  always zero \r
+.def smode=r15; if 1 then send \r
+.def temp = r16 ; \r
+.def temp2 = r17; \r
+.def mode = r18 ; \r
+.def bitp = r19 ; bit counter ... shift...\r
+.def rwbyte = r21;\r
+.def param = r22;\r
+.def bytep = r23  ;byte counter\r
+#define spmcrval  param\r
+\r
+\r
+.equ OWM_READ_ROM_COMMAND=0 ; 0 wegen schnellen test ist dieser wert 0! Daturch wird die Sprungdabelle nicht verwendet\r
+.equ OWM_SLEEP=1 ; Warten auf Reset\r
+.equ OWM_MATCH_ROM=2\r
+.equ OWM_SEARCH_ROM_S=3  ;send bit\r
+.equ OWM_SEARCH_ROM_R=4  ;resive master\r
+.equ OWM_READ_COMMAND=5\r
+.equ OWM_WRITE_SCRATCHPAD=6\r
+.equ OWM_READ_SCRATCHPAD=7\r
+.equ OWM_PROGRAMM_PAGE=8\r
+.equ OWM_RECALL_FLASH=9\r
+\r
+\r
+\r
+.equ OW_DDR = DDRD \r
+.equ OW_PIN = PORTD2\r
+.equ OW_PORT = PORTD \r
+.equ OW_PINN = PIND\r
+\r
+//.equ SPMEN = 0\r
+\r
+;.equ SRAM_START = 0x60\r
+\r
+.macro set_clock\r
+               ldi temp,0x80;\r
+               sts CLKPR,temp\r
+               ldi temp,@0\r
+               sts CLKPR,temp\r
+.endmacro \r
+\r
+.macro owwl\r
+               sbic OW_PINN,OW_PIN\r
+               rjmp pc-1\r
+.endmacro \r
+\r
+.macro owwh\r
+               sbis OW_PINN,OW_PIN\r
+               rjmp pc-1\r
+.endmacro \r
+\r
+\r
+\r
+\r
+ ;---------------------------------------------------\r
+; START of PROG \r
+;---------------------------------------------------\r
+\r
+\r
+.CSEG \r
+.ORG 0x000\r
+jreset:\r
+               jmp start ; Reset-Vector \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+               reti ; \r
+\r
+\r
+.ORG 0x3E00\r
+start: \r
+               cli\r
+               ldi temp,0\r
+               mov zero,temp\r
+               set_clock 0x01 ;4mhz\r
+               ldi mode,OWM_SLEEP\r
+               ldi temp,(1<<CS01) //2us\r
+               out TCCR0B,temp\r
+               ldi temp, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse \r
+               out SPH, temp \r
+               ldi temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse \r
+               out SPL, temp \r
+               ;ldi temp,1\r
+               ;out DDRB,temp\r
+               clr writelow\r
+               clr bitp\r
+       \r
+               ;sbi PORTB,0\r
+               ldi ZL,low(pro_owid*2) \r
+               ldi ZH,high(pro_owid*2) \r
+               ldi XL,low(sowid)\r
+               ldi XH,high(sowid)\r
+               ;ldi temp2,8\r
+pro_copy_loop: ;copy ID on SRAM for better handling\r
+               lpm temp,Z+\r
+               st X+,temp\r
+               cpi XL,low(SRAM_START+8) ;#################################\r
+               brlo pro_copy_loop\r
+pro_loop:\r
+               ;sbi PORTB,0\r
+               owwl                            ;wait for line goes low (polling)\r
+               sbrc writelow,0         ;test of zero send\r
+               sbi OW_DDR,OW_PIN       ;yes pull line to low 2us faster\r
+               sbrs writelow,0     ;test egain 2us faster.....\r
+               rjmp pro_loop1          ;no ? goes next\r
+               ldi param,20            ;wait for 50 us\r
+               rcall wait_time\r
+               clr writelow            ;reset write low indecator\r
+               cbi OW_DDR,OW_PIN   ;release line\r
+               owwh                            ;wait for line is high (it can takes some time cause of the capacity of line)\r
+pro_loop1:\r
+               tst smode                       ;smode=1 for slave sends to master\r
+               breq pro_loop_resv\r
+pro_loop_send:\r
+               tst bitp\r
+               brne pro_loop_send1\r
+               rcall pro_hb\r
+               tst smode\r
+               breq pro_loop_end ; now reading ... do nothing \r
+pro_loop_send1:  ;prebare next bit\r
+               sbrs rwbyte ,0; if bit 0 set in rwbyte then skip next command\r
+               inc writelow\r
+               lsl bitp\r
+               ror rwbyte\r
+               rjmp pro_loop_end\r
+\r
+pro_loop_resv:\r
+               ldi param,7  ;wait 15us\r
+               rcall wait_time\r
+               lsr rwbyte\r
+               ;cbi PORTB,0\r
+               sbic OW_PINN,OW_PIN  ;test line\r
+               ori rwbyte,0x80\r
+               lsl bitp\r
+               brne pro_loop_end ;no handle need\r
+               rcall pro_hb\r
+               tst smode\r
+               brne pro_loop_send ; Nach dem Gelesen byte koennte gesendet werden muessen....\r
+pro_loop_end:\r
+               //owwh\r
+               out TCNT0,zero\r
+pro_loop_end_test_reset:\r
+               sbic OW_PINN,OW_PIN  //leitung wieder high\r
+               rjmp pro_loop\r
+               in temp,TCNT0\r
+               cpi temp,63\r
+               brlo pro_loop_end_test_reset\r
+               rcall pro_sleep_s2\r
+               rjmp pro_loop\r
+\r
+\r
+\r
+\r
+pro_sleep:\r
+               out TCNT0,zero\r
+pro_sleep_s1:\r
+               sbic OW_PINN,OW_PIN  //leitung wieder high\r
+               ret\r
+               in temp,TCNT0\r
+               cpi temp,100\r
+               brlo pro_sleep_s1\r
+               //leitung wieder high\r
+pro_sleep_s2:\r
+               owwh \r
+               ldi param,20\r
+               rcall wait_time\r
+               //Presents Impuls\r
+               sbi OW_DDR,OW_PIN\r
+               ldi param,75\r
+               rcall wait_time\r
+               cbi OW_DDR,OW_PIN\r
+               //init read byte\r
+               ldi bitp,0x01\r
+               ldi rwbyte,0\r
+               clr smode\r
+               ldi mode,OWM_READ_ROM_COMMAND\r
+               //Wait for all other devices presents impuls finished\r
+               ldi param,20\r
+               rcall wait_time\r
+               ret\r
+\r
+\r
+\r
+pro_hb:\r
+               ldi ZL,low(pro_stable) \r
+               ldi ZH,high(pro_stable) \r
+               add ZL,mode \r
+               adc ZH,zero\r
+               icall\r
+               ret\r
+\r
+pro_stable: \r
+               rjmp pro_read_rom_command\r
+               rjmp pro_sleep \r
+               rjmp pro_match_rom\r
+               rjmp pro_search_rom_s\r
+               rjmp pro_search_rom_r\r
+               rjmp pro_read_command\r
+               rjmp pro_write_scratchpad\r
+               rjmp pro_read_scratchpad\r
+               rjmp pro_programm_page\r
+               rjmp pro_recall_flash\r
+\r
+pro_read_rom_command:\r
+               ldi mode,OWM_SLEEP\r
+               cpi rwbyte,0xCC\r
+               brne pro_rcc_1\r
+               ldi mode,OWM_READ_COMMAND\r
+               rjmp pro_out_bitp1\r
+pro_rcc_1:\r
+               cpi rwbyte,0xF0 ;Searchrom\r
+               brne pro_rcc_2\r
+               ldi XL,low(sowid)  ;init sram pointer\r
+               ldi XH,high(sowid)\r
+               ld srbyte,X+\r
+               ldi bytep,0\r
+               rjmp pro_serchrom_next_bit\r
+pro_rcc_2:\r
+               cpi rwbyte,0x55 ;Matchrom\r
+               brne pro_rcc_3\r
+//             rcall pro_owidinit\r
+               ldi XL,low(sowid)  ;init sram pointer\r
+               ldi XH,high(sowid)\r
+               ldi mode,OWM_MATCH_ROM\r
+               rjmp pro_out_bytep0\r
+\r
+pro_rcc_3:\r
+               ret\r
+\r
+pro_match_rom:         \r
+               ld temp,X+\r
+               cp temp,rwbyte\r
+               breq pro_match_rom_next\r
+               ldi mode,OWM_SLEEP\r
+               ret\r
+pro_match_rom_next:                                    \r
+               cpi XL,LOW(SRAM_START+8);####################\r
+               breq pro_match_rom_found\r
+               rjmp pro_out_bitp1\r
+pro_match_rom_found:\r
+           ldi mode,OWM_READ_COMMAND\r
+               rjmp pro_out_bitp1\r
+\r
+pro_read_command:\r
+               ldi mode,OWM_SLEEP\r
+               cpi rwbyte,0x0F ;; Write to Scratchpad\r
+               brne pro_rc_1\r
+               ldi mode,OWM_WRITE_SCRATCHPAD\r
+               ldi XL,low(scratchpad)  ;init sram pointer\r
+               ldi XH,high(scratchpad)\r
+               rjmp pro_out_bytep0\r
+pro_rc_1:\r
+               cpi rwbyte,0xAA\r
+               brne pro_rc_2\r
+               ldi mode,OWM_READ_SCRATCHPAD  ;;Read from Scratchpad\r
+               ldi XL,low(scratchpad)  ;init sram pointer\r
+               ldi XH,high(scratchpad)\r
+               inc smode\r
+               ld rwbyte,X+\r
+               rjmp pro_out_bytep0\r
+\r
+pro_rc_2:\r
+               cpi rwbyte,0xB8\r
+               brne pro_rc_3\r
+               ldi mode,OWM_RECALL_FLASH  ;; copy Flash page in Scratchpad\r
+               ldi XL,low(scratchpad)  ;init sram pointer\r
+               ldi XH,high(scratchpad)\r
+               rjmp pro_out_bytep0\r
+pro_rc_3:\r
+               cpi rwbyte,0x55 ; copy Scratchpad to Flash\r
+               brne pro_rc_4\r
+               ldi mode,OWM_SLEEP\r
+               rjmp pro_programm_page\r
+               \r
+pro_rc_4:\r
+               cpi rwbyte,0x89 ; Reset Device /Boot (new) Firmware\r
+               brne pro_rc_5\r
+               jmp jreset              \r
+pro_rc_5:\r
+               cpi rwbyte,0x8B ; Clear the OWID saved in EEPROM / one ID1\r
+               brne pro_rc_6   \r
+               ldi temp,7\r
+pro_rc_5a:\r
+               ldi XL,low(E2END)\r
+               ldi XH,high(E2END)\r
+               sub XL,temp\r
+               out EEARH,XH\r
+               out EEARL,XL\r
+               ldi temp, (0<<EEPM1)|(0<<EEPM0)\r
+               out EECR, temp\r
+               ldi temp,0xFF\r
+               out EEDR, temp\r
+               sbi EECR, EEMPE\r
+               sbi EECR, EEPE\r
+               ret\r
+\r
+\r
+pro_rc_6:\r
+               cpi rwbyte,0x8C ; Clear the OWID saved in EEPROM / one ID2\r
+               brne pro_rc_7\r
+               ldi temp,7+8\r
+               rjmp pro_rc_5a\r
+\r
+pro_rc_7:\r
+               ret\r
+\r
+pro_write_scratchpad:\r
+               st X+,rwbyte\r
+               cpi XL,138 ;#####################################\r
+               brlo pro_write_scratchpad_next\r
+               ldi mode,OWM_SLEEP\r
+               ret             \r
+pro_write_scratchpad_next:\r
+               ldi bitp,1\r
+               ret\r
+\r
+pro_read_scratchpad:\r
+               cpi XL,8+130 ;###################################\r
+               brlo pro_read_scratchpad_next\r
+               ldi mode,OWM_SLEEP\r
+               clr smode\r
+               ret\r
+pro_read_scratchpad_next:\r
+               ld rwbyte,X+\r
+               rjmp pro_out_bitp1\r
+\r
+\r
+pro_programm_page:\r
+.equ PAGESIZEB = 128 ; Not correct deglaration in inc file of ATMEGA328PB  PAGESIZE*2;PAGESIZEB is page size in BYTES, not words\r
+// .org SMALLBOOTSTART\r
+write_page:\r
+               ;transfer data from RAM to Flash page buffer\r
+               ldi bytep, PAGESIZEB ;init loop variable\r
+               ldi YL,low(scratchpad)  ;init sram pointer\r
+               ldi YH,high(scratchpad)\r
+               ld ZL,Y+\r
+               ld ZH,Y+\r
+               ;page erase\r
+               ldi spmcrval,(1<<PGERS) | (1<<SPMEN)\r
+               rcall do_spm\r
+               ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)\r
+               rcall do_spm\r
+wrloop:\r
+               ld r0, Y+\r
+               ld r1, Y+\r
+               ldi spmcrval, (1<<SPMEN)\r
+               rcall do_spm\r
+               adiw ZH:ZL, 2\r
+               subi bytep, 2;use subi for PAGESIZEB<=256\r
+               brne wrloop\r
+               ;execute page write\r
+               subi ZL, low(PAGESIZEB) ;restore pointer\r
+               sbci ZH, high(PAGESIZEB) ;not required for PAGESIZEB<=256\r
+               ldi spmcrval, (1<<PGWRT) + (1<<SPMEN)\r
+               rcall do_spm\r
+               ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)\r
+               rcall do_spm\r
+               ;read back and check, optional\r
+               ldi bytep, PAGESIZEB\r
+               subi YL, low(PAGESIZEB) ;restore pointer\r
+               sbci YH, high(PAGESIZEB)\r
+rdloop:\r
+               lpm r0, Z+\r
+               ld r1, Y+\r
+               cpse r0, r1\r
+               rjmp error\r
+               subi bytep, 2;use subi for PAGESIZEB<=256\r
+               brne rdloop\r
+               ;return\r
+               ret\r
+do_spm:\r
+                ;input: spmcrval determines SPM action\r
+               ;disable interrupts if enabled, store status\r
+               in temp2, SREG\r
+               cli\r
+               ;check for previous SPM complete\r
+wait:\r
+               in temp, SPMCSR\r
+               sbrc temp, SPMEN\r
+               rjmp wait\r
+               ;SPM timed sequence\r
+               out SPMCSR, spmcrval\r
+               spm\r
+               ;restore SREG (to enable interrupts if originally enabled)\r
+               out SREG, temp2\r
+               ret\r
+\r
+error:\r
+\r
+\r
+               ret\r
+\r
+pro_recall_flash:\r
+               st X+,rwbyte\r
+               ;inc bytep\r
+               cpi XL,low(SRAM_START+8+2) ;##############################################\r
+               brlo pro_out_bitp1;pro_recall_flash_next\r
+               lds ZL,scratchpad\r
+               lds ZH,scratchpad+1\r
+pro_recall_flash_cl:\r
+               lpm temp,Z+\r
+               st X+,temp\r
+               cpi XL,low(SRAM_START+8+66) ;############################################\r
+               brne pro_recall_flash_cl\r
+               ldi mode,OWM_SLEEP\r
+               ret\r
+\r
+pro_out_read_command:\r
+               ldi mode,OWM_READ_COMMAND\r
+pro_out_bytep0:\r
+               ldi bytep,0\r
+pro_out_bitp1:\r
+               ldi bitp,1\r
+               ret             \r
+\r
+\r
+\r
+pro_serchrom_next_bit:\r
+               mov rwbyte,srbyte\r
+               mov temp2,rwbyte\r
+               com rwbyte\r
+               ror temp2  ;first bit in C\r
+               rol rwbyte ;C in first bit \r
+               inc smode\r
+               ldi bitp,0x40\r
+               ldi mode,OWM_SEARCH_ROM_R  ;next mod Resive\r
+               ret\r
+\r
+\r
+pro_search_rom_s:\r
+               clr temp2\r
+               lsr srbyte ;shift in C lowest bit\r
+               ror temp2  ; shift in temp2 as highest bit\r
+               andi rwbyte,0x80  ;  clear other bits\r
+               eor temp2,rwbyte\r
+               breq pro_search_rom_s_goon\r
+               ldi mode,OWM_SLEEP\r
+               ret\r
+pro_search_rom_s_goon:\r
+               inc bytep\r
+               mov temp2,bytep\r
+               andi temp2,0x07\r
+               brne pro_serchrom_next_bit ;prepare next bit\r
+               mov temp2,bytep\r
+               andi temp2,0x40 ;;end\r
+               brne pro_search_rom_found\r
+               ;read next byte\r
+               ld srbyte,X+\r
+               rjmp pro_serchrom_next_bit\r
+\r
+pro_search_rom_found:\r
+               ldi mode,OWM_READ_COMMAND\r
+               rjmp pro_out_bytep0\r
+\r
+pro_search_rom_r:\r
+               clr smode\r
+               ldi mode,OWM_SEARCH_ROM_S\r
+               ldi bitp,0  ;go to searchrom_s after bit get\r
+               ret\r
+\r
+pro_owid: .DB 0xA3, 0xAA, 0x57, 0xAA, 0x57, 0xAA, 0x57, 0x8A\r
+\r
+\r
+\r
+\r
+\r
+wait_time:\r
+               out TCNT0,zero\r
+wait_time1:\r
+               in temp,TCNT0\r
+               cp temp,param\r
+               brlo wait_time1\r
+               ret\r
+\r
+\r
+.DSEG\r
+sowid: .BYTE 8\r
+scratchpad: .BYTE 130
\ No newline at end of file