Code:
' Bootloader angepasst
' Taste S2 und S3 liegen hier auf PG1 und PG2
'_______________________________________________________________________________
'Bootloader
'Standard Intel hex file can be sent
':10 0000 00 0C 94 2400189500001895000018950000 25
':00 0000 01 FF
' size , address,record type, data, checksum
'anderes Beispiel-File
' .-- Size (im Beispiel: 10=16 Stellen / 0A=10 Stellen)
' ' .-- Adresse
' ' ' .--Record type
' ' ' ' .-- Data
' ' ' ' ' .--Checksum
' ' ' ' ' '
' ' ' ' 0 1 2 3 4 5 6 7 8 9 A B C D E F
':10 0000 00 0C944600189500001895000018950000 03
':10 0010 00 18950000189500001895000018950000 2C
':10 0020 00 18950000189500001895000018950000 1C
'...
':10 0240 00 0f920024facf426f6f742d5465737420 9f
':10 0250 00 2E2E2E2E2E2E00004765687420212121 7F
':0A 0260 00 21202020202020200000 93
':00 0000 01 FF
'The same baudrate is used as the main program is using
'but we can change it here when we like. Just unremark the next line and/or change it
'But take in mind that the bootloader sender must use the same baud rate !!!
'#if M128boot = 1
$asm
$boot = $fe00
Ldi R24,$FF ; hardware stack pointer
!Out SPL,R24
Ldi R24,$10
!Out SPH,R24
'no interrupts are allowed during bootloader programming
Disable Interrupts
Ldi _temp1,&B00011000 ; enable TX and RX
!Out UCR,_temp1
Ldi r24,6
Sts $95,r24
$end Asm
Baud = 19200
$asm
lds r24,$63 ; port g einlesen / PING = $63
andi r24,&B00000110 ; g1 und g2 ausfiltern / S2+S3 Taste
cpi r24,0 ; port hat das richtige bitmuster ?
breq Bootloaderbasic ; ja
jmp $0000 ; start the normal program
' Programmteil vom MCS-electronic
Bootloaderbasic:
'jmp $0000 ; start the normal program
clr r18 ; word counter for written data
clr r22 ; page counter LSB
clr r23 ; page counter MSB
_read_lines:
rcall _rec_line ; get line into SRAM pointed by X
ldi r26,$01 ; point to start of line
ldi r27,$01
ld r24,x+ ; get char in r24
rcall _hex2number ; convert result in r17
ld r24,x+
rcall _hex2number2 ; convert second char , r17 holds the number of hex pairs to get
mov r19,r17 ; number of entries
! sub r16,r17 ; checksum
tst r19
brne _readnext ; not the end record
rjmp _write_last_page ; final line so write the last page
_readnext:
ldi r25,3
_docheck:
ld r24,x+ ; get char in r24
rcall _hex2number ; convert result in r17
ld r24,x+
rcall _hex2number2 ; convert second char , r17 holds the data
!sub r16,r17
dec r25
brne _docheck
' adiw xl,6 ; point to first pair
_readnextpair:
ld r24,x+ ; get char in r24
rcall _hex2number ; convert result in r17
ld r24,x+
rcall _hex2number2 ; convert second char , r17 holds the data
mov r0,r17 ; save in r0
! sub r16,r17 ; checksum
dec r19 ; adjust pair data counter
ld r24,x+ ; get char in r24
rcall _hex2number ; convert result in r17
ld r24,x+
rcall _hex2number2 ; convert second char , r17 holds the data
mov r1,r17 ; save data
! sub r16,r17 ; checksum
rcall _write_page ; write into page buffer
cpi r18,128 ; page is 256 bytes is 128 words
breq _writeit ; write page since it is full
_lbl1:
dec r19 ; adjust data pair
brne _readnextpair ; more data
' ----------------checksum checkining ---------------
ld r24,x+ ; get char in r24
rcall _hex2number ; convert result in r17
ld r24,x+
rcall _hex2number2 ; convert second char , r17 holds the data
cp r16,r17 ; checksum ok?
breq _checkok ; yes
_lbl2:
sbis usr,5
rjmp _lbl2
ldi r24, asc("!") ; load !
!out udr,r24 ; show ! so we know there is an error
' note that you only get an indication something wend wrong,there is no error recovery !!!
_checkok:
rjmp _read_lines ; next line
_writeit:
rcall _erase_page ; erase next page
rcall _save_page ; save page
Rjmp _lbl1 ; continue
_write_last_page:
rcall _erase_page
rcall _save_page ; save last page
_exit_page:
jmp $0000 ; exit needs a reset
' get 1 byte from serial port and store in R24
_recbyte:
Sbis USR, 7 ; Wait for character
rjmp _recbyte
in r24, UDR ; get byte
Ret
'get one line from the serial port and store in location pointed by X
_rec_line:
ldi r26,$00 ; point to first location in SRAM
ldi r27,$01
clr r16
_rec_line5:
sbis usr,5
rjmp _rec_line5
ldi r24, 63 ; ?
!out udr,r24 ; show ? so we know we can send next line
_rec_line1:
rcall _recbyte ; get byte
cpi r24,13 ; enter?
breq _rec_line2 ; yes ready
st x+,r24 ; no so store in sram buffer
rjmp _rec_line1 ; next byte
_rec_line2:
clr r24 ; string terminator
st x,r24
ret
' convert HEX byte in r24 into bin value , on exit byte in r17
_hex2number:
clr r17
_hex2number4:
Subi R24,65 ; subtract 65
Brcc _hex2number3 ; in case carry was cleared
Subi R24,249 ; not
_hex2number3:
Subi R24,246
Add R17,R24 ; add to accu
ret
';called for the second byte
_hex2number2:
Lsl R17 ; shift data
Lsl R17
Lsl R17
Lsl R17
rjmp _hex2number4 ; handle the conversion
_enable_page:
rcall _wait_spm
ldi r24,17 ; reenable page
sts {Spmcsr} , R24
spm
nop
nop
ret
'rjmp _wait_spm
'page address in z7-z13
_erase_page:
' rcall _wait_spm
mov r31,r22 ; page address z8-z15
! out rampz,r23 ; bit 9 of pageaddress goes into Z16
clr r30
ldi r24,3 ; page erase command
sts {Spmcsr} , R24
spm
nop
nop
rcall _wait_spm
' rcall _enable_page
ret
_write_page:
'rcall _wait_spm
mov r31,r22 ; page address z8-z15
! out rampz,r23 ; bit 9 of page address goes into Z16(bit 0 of rampz)
mov r30,r18 ; word address buffer counter
lsl r30
ldi r24,1 ; buffer fill
sts {Spmcsr} , R24
spm
nop
nop
rcall _wait_spm
inc r18 ; next word address
ret
_save_page:
'z0-z6 must be 0
'z7-z13 is the page address
'r0 and r1 are ignored
' rcall _wait_spm
mov r31,r22 ; LSB of page counter
! out rampz,r23 ; bit nine goes into bit 0 of rampz
clr r30
ldi r24,5 ; write page
sts {Spmcsr} , R24
spm
nop
nop
rcall _wait_spm
rcall _enable_page
clr r18 ; page word address counter
subi r22,-1 ; increment page counter
sbci r23,255
ret
_wait_spm:
LDS R25,{Spmcsr}
SBRC R25,0
RJMP _WAIT_SPM ; Wait for SPMEN flag cleared
RET
$end Asm
'#endif
[/code]
Lesezeichen