Tak robiłem, ATMEGA162 i działał. Wiesz co ja proponuję zrobić bootloadera według książki Marcina Wiązani.
Kod: Zaznacz cały
$regfile = "m8def.dat"
$crystal = 8000000
Const Ramend_lo = $5f
Const Ramend_hi = $04
Const Pagesize = 32
!.def Tmp_reg = R16
!.def Hex_reg = R17
!.def Ser_reg = R18
!.def SPM_reg = R19
!.def Rec_size = R20
!.def Chk_sum = R21
Config Pinb.1 = Output
S1 Alias Pinb.1
Set Portb.1
Do
If S1 = 0 Then
Waitms 25
If S1 = 0 Then
JMP $F80
End If
End If
Loop
End
$boot = $f7f
NOP
Disable Interrupts
_bootloader_start:
LDI Tmp_reg, Ramend_hi
!OUT SPH, Tmp_reg
LDI Tmp_reg, Ramend_lo
!OUT SPL, Tmp_reg
LDI Tmp_reg, $00
!OUT UCSRA, Tmp_reg
LDI Tmp_reg, $18
!OUT UCSRB, Tmp_reg
LDI Tmp_reg, $86
!OUT UCSRC, Tmp_reg
LDI Tmp_reg, $00
!OUT UBRRH , Tmp_reg
LDI Tmp_reg, 25
!OUT UBRRL , Tmp_reg
CLT
_send_boot_msg:
LDI Ser_reg, Asc("B")
RCALL _send_ser
_read_lines:
RCALL _receive_hex_line
_parse_line:
LDI XH, $01
LDI XL, $00
CLR Chk_sum
_read_header:
LD Tmp_reg, X+
CPI Tmp_reg, Asc(":")
BREQ _header_ok
_header_err:
LDI Ser_reg , Asc( "!")
RCALL _send_ser
_header_ok:
_header_record_size:
RCALL _char_to_byte
MOV Rec_size, Hex_reg
TST Rec_size
BRNE _read_address
!SET
RJMP _write_current_page
_read_address:
RCALL _char_to_byte
MOV ZH, Hex_reg
RCALL _char_to_byte
MOV ZL, Hex_reg
_read_record_type:
RCALL _char_to_byte
_read_data_pairs:
RCALL _char_to_byte
MOV R0, Hex_reg
RCALL _char_to_byte
MOV R1, Hex_reg
_store_word:
LDI Spm_reg, 1
RCALL _exec_spm
_check_byte_count:
SUBI Rec_size, 2
BREQ _read_checksum
SUBI ZL, $FE
RJMP _read_data_pairs
_read_checksum:
RCALL _char_to_byte
BREQ _checksum_ok
_checksum_err:
LDI Ser_reg, Asc("!")
RCALL _send_ser
_checksum_ok:
_chk_page_full:
MOV Tmp_reg, ZL
ANDI Tmp_reg, ((Pagesize - 1)*2)
CPI Tmp_reg, ((Pagesize - 1)*2)
BRNE _read_lines
_write_current_page:
_erase_page:
LDI Spm_reg, 3
RCALL _exec_spm
_write_page:
ANDI ZL, $C0
LDI Spm_reg, 5
RCALL _exec_spm
_enable_page:
RCALL _wait_spm
LDI Spm_reg, 11
RCALL _exec_spm
_check_end_of_file:
BRTC _read_lines
_exit_bootloader:
JMP $0000
_send_ser:
SBIS UCSRA, UDRE
RJMP _send_ser
!OUT UDR, ser_reg
RET
_receive_hex_line:
LDI XH, $01
LDI XL, $00
LDI Ser_reg, Asc("?")
RCALL _send_ser
_receive_hex_line_char:
SBIS UCSRA, RXC
RJMP _receive_hex_line_char
IN Tmp_reg, UDR
MOV Ser_reg, Tmp_reg
RCALL _send_ser
CPI Tmp_reg, 13
BREQ _receive_hex_line_end
ST X+, Tmp_reg
RJMP _receive_hex_line_char
_receive_hex_line_end:
RET
_char_to_byte:
LD Hex_reg, X+
SUBI Hex_reg, $41
BRCC _char_to_byte1
SUBI Hex_reg, $F9
_char_to_byte1:
SUBI Hex_reg, $F6
LSL Hex_reg
LSL Hex_reg
LSL Hex_reg
LSL Hex_reg
LD Tmp_reg, X+
SUBI Tmp_reg , $41
BRCC _char_to_byte2
SUBI Tmp_reg, $F9
_char_to_byte2:
SUBI Tmp_reg, $F6
ADD Hex_reg, Tmp_reg
ADD Chk_sum, Hex_reg
RET
_exec_spm:
!OUT SPMCR, Spm_reg
SPM
_wait_spm:
IN Spm_reg, SPMCR
SBRC Spm_reg, SPMEN
RJMP _wait_spm
RET
Bootloader zajmuje jedynie 128 słów i powinien od razu działać. Prędkość transmisji danych to 19200 bodów.
Pozdrawiam