;------------------------------------------------------------- .include "m88def.inc" ;------------------------------------------------------------- .def acc = r16 .def temp = r17 .def temp2 = r18 .def spm_cmd = r19 .def spm_wait = r20 .def ee_temp = r21 .def delay_reg_1 = r22 .def delay_reg_2 = r23 .def delay_reg_3 = r24 ;------------------------------------------------------------- .equ LED_PORT = PORTD .equ LED_DIR = LED_PORT - 1 .equ LED = 4 ;------------------------------------------------------------- .equ RWW_PAGES = 96 .equ PAGE_SIZE = PAGESIZE << 1 ;------------------------------------------------------------- .equ SW_MAJ_VER = 0 .equ SW_MIN_VER = 8 ;------------------------------------------------------------- ; ; SEGMENT KODU ; ;------------------------------------------------------------- .cseg .org 0 prog: rcall SigLED_toggle ldi acc,250 rcall Delay_ms rjmp prog .org 0x0C00 Bootloader_start: ldi acc,LOW(RAMEND) out SPL,acc ldi acc,HIGH(RAMEND) out SPH,acc ; PORTS INIT ldi acc,0xFF out LED_DIR,acc ldi acc,0xFF out LED_PORT,acc ; UART init ldi temp,high(38) ; 19200 bps (x% err at 12MHz) ldi temp2,low(38) sts UBRR0H,temp sts UBRR0L,temp2 ldi temp,(1 << UCSZ00 | 1 << UCSZ01) sts UCSR0C,temp ldi temp,(1 << RXEN0 | 1 << TXEN0) sts UCSR0B,temp ;------------------------------------------------------------- Main: ldi temp,30 main_loop: ldi acc,100 rcall Delay_ms rcall SigLED_toggle dec temp breq main_prog_in lds temp2,UCSR0A sbrs temp2,RXC0 rjmp main_loop lds acc,UDR0 cpi acc,'b' breq boot main_prog_in: rcall SigLED_off ; UART off (pins) clr temp sts UCSR0B,temp main_prog: rjmp 0 main_prog_in_q: rcall RS232_send_char rjmp main_prog_in ;------------------------------------------------------------- ; bootloader main boot: rcall SigLED_on ldi acc,'b' rcall RS232_send_char boot_loop: rcall RS232_receive_char cpi acc,'q' breq main_prog_in_q cpi acc,'e' breq boot_erase_chip cpi acc,'r' breq boot_read cpi acc,'w' breq boot_write cpi acc,'v' breq boot_version_go cpi acc,'i' breq boot_identify_go ldi acc,'?' rcall RS232_send_char rjmp boot_loop boot_version_go: rjmp boot_version boot_identify_go: rjmp boot_identify ; bootloader functions ;---------- boot_erase_chip: rcall RS232_send_char clr zl clr zh clr acc clr temp ldi temp2,PAGE_SIZE boot_erase_chip_loop: ldi spm_cmd,(1 << PGERS | 1 << SELFPRGEN) rcall spm_do add zl,temp2 adc zh,temp inc acc cpi acc,RWW_PAGES brne boot_erase_chip_loop ldi spm_cmd,(1 << RWWSRE | 1 << SELFPRGEN) rcall spm_do ldi acc,'d' rcall RS232_send_char rjmp boot_loop ;---------- boot_read: rcall RS232_send_char rcall RS232_receive_char cpi acc,'f' brne boot_read_ee rcall RS232_send_char clr zl clr zh boot_read_loop: lpm acc,z+ rcall RS232_send_char cpi zh,high((RWW_STOP_ADDR + 1) << 1) brne boot_read_loop cpi zl,low((RWW_STOP_ADDR + 1) << 1) brne boot_read_loop rjmp boot_loop boot_read_ee: cpi acc,'e' brne boot_loop rcall RS232_send_char clr xl clr xh boot_read_ee_loop: rcall AVR_EE_read rcall RS232_send_char adiw x,1 cpi xh,high(EEPROMEND + 1) brne boot_read_ee_loop cpi xl,low(EEPROMEND + 1) brne boot_read_ee_loop rjmp boot_loop ;---------- boot_write: rcall RS232_send_char rcall RS232_receive_char cpi acc,'f' brne boot_write_ee rcall RS232_send_char rcall RS232_receive_char mov yh,acc rcall RS232_receive_char mov yl,acc clr zl clr zh boot_write_flash_loop_1: mov xl,zl mov xh,zh ldi temp2,PAGESIZE boot_write_flash_loop_2: rcall RS232_receive_char rcall RS232_send_char mov r0,acc rcall RS232_receive_char rcall RS232_send_char mov r1,acc ldi spm_cmd,(1 << SELFPRGEN) rcall spm_do adiw z,2 cp zh,yh brlo boot_write_flash_no_end cp zl,yl brsh boot_write_flash_end boot_write_flash_no_end: dec temp2 brne boot_write_flash_loop_2 boot_write_flash_end: push zl push zh mov zl,xl mov zh,xh ldi spm_cmd,(1 << PGWRT | 1 << SELFPRGEN) rcall spm_do pop zh pop zl cp zh,yh brlo boot_write_flash_loop_1 cp zl,yl brlo boot_write_flash_loop_1 ldi spm_cmd,(1 << RWWSRE | 1 << SELFPRGEN) rcall spm_do ldi acc,'d' rcall RS232_send_char boot_loop_go: rjmp boot_loop boot_write_ee: cpi acc,'e' brne boot_loop_go rcall RS232_send_char clr xl clr xh boot_write_ee_loop: rcall RS232_receive_char rcall AVR_EE_write adiw x,1 cpi xh,high(EEPROMEND + 1) brne boot_write_ee_loop cpi xl,low(EEPROMEND + 1) brne boot_write_ee_loop ldi acc,'d' rcall RS232_send_char rjmp boot_loop ;---------- boot_version: ldi acc,SW_MAJ_VER rcall RS232_send_char ldi acc,SW_MIN_VER rcall RS232_send_char rjmp boot_loop ;---------- boot_identify: ldi zl,low(boot_id << 1) ldi zh,high(boot_id << 1) rcall RS232_print rjmp boot_loop ;-------------------- ; other functions spm_do: in spm_wait,SPMCSR sbrc spm_wait,SELFPRGEN rjmp spm_do spm_do_wait_ee: sbic EECR,EEPE rjmp spm_do_wait_ee out SPMCSR,spm_cmd spm ret ;-------------------- ; ; zapis i odczyt z EEPROM ; ; adres w x, dana w acc ; AVR_EE_write: sbic EECR,EEPE rjmp AVR_EE_write ldi ee_temp,(0 << EEPM1) | (0 << EEPM0) out EECR,ee_temp out EEARL,xl out EEARH,xh out EEDR,acc sbi EECR,EEMPE sbi EECR,EEPE ret AVR_EE_read: sbic EECR,EEPE rjmp AVR_EE_read out EEARL,xl out EEARH,xh sbi EECR,EERE in acc,EEDR ret ;------------------------------------------------------------- ; wysłanie znaku na rs232 RS232_send_char: push temp rs_send_char_loop: lds temp,UCSR0A sbrs temp,UDRE0 rjmp rs_send_char_loop sts UDR0,acc pop temp ret ;------------------------------------------------------------- ; wysłanie znaku na rs232 RS232_receive_char: push temp rs_receive_char_loop: lds temp,UCSR0A sbrs temp,RXC0 rjmp rs_receive_char_loop lds acc,UDR0 pop temp ret ;------------------------------------------------------------- ; wysłanie ciągu na rs232 RS232_print: push acc rs_print_loop: lpm acc,z+ tst acc breq rs_print_end rcall RS232_send_char rjmp rs_print_loop rs_print_end: pop acc ret ;------------------------------------------------------------- Delay_ms: mov delay_reg_1,acc L: ldi delay_reg_2,15 L0: ldi delay_reg_3,200 L1: nop dec delay_reg_3 brne L1 dec delay_reg_2 brne L0 dec delay_reg_1 brne L ret ;------------------------------------------------------------- ; sygnalizacja LED SigLED_toggle: sbic LED_PORT,LED rjmp on sbi LED_PORT,LED rjmp finito on: cbi LED_PORT,LED finito: ret SigLED_on: cbi LED_PORT,LED ret SigLED_off: sbi LED_PORT,LED ret ;------------------------------------------------------------- ; dane boot_id: .db "jAVRboot",0