Bootloader dla ATMEGA8

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 24 sie 2007, 8:27

Gdyby tam nie było komnetarzy, to nawet nie próbowałbym tego rozszyfrowac :smile:
Komentarze opisują tylko poszczególne instrukcje, i "nazwy" podprogramów.

[ Dodano: 2007-08-24, 13:59 ]
Mam troche pytań. Czy kazda linia kończy się znakiem CR (13)? Tak wynika z instrukcji CPI t, 13 podprogramu _receive_hex_line_char. I podobna sprawa z z instrukcją TST R_size w podprogramie _read_record_size. Sprawdza czy przekonwertowany znak ma wartośc 0. czyli zero będzie dla znaku 00 w ASCII. O co tu chodzi? Następna rzecz, nie jestem pewnien, czy instrukcja SPM posługuje się znakami ASCII czy bajtami? Bo nie moge się dopatrzec w programie czy gdzies jest ST zapisujaca przekonwertowany znak ASCII na bajt. SPM czyta cała linię, czy nie? Bo tu wygląda to tak jakby były czytane tylko dwa rejesrty R0, R1. No więc jak to jest z tym rozkazem, bo nie można zapisac mniejszej ilości danych niz strona?

ZbeeGin

Post autor: ZbeeGin » 24 sie 2007, 16:56

Tak. Każda linia w pliku HEX kończy się znakami {CR} i {LF}.

Instrukcja TST wykonuje iloraz logiczny rejestru - sam ze sobą - podanego jako parametr. Chodzi tylko o ustawienie znaczników w rejestrze SREG a zwłaszcza flagi Z. Później można użyć BRNE, BREQ...

SPM posługuje się słowami, zatem dwie pary znaków z pliku HEX muszą zostać przekonwerterowana na słowo. A słowo które ma zaspisać SPM musi się znaleźć w parze R0:R1. Adres gdzie ma trafić dane słowo zawarty jest w rejestrze Z (czyli para rejestrów tworząca ten wirtualny rejestr).

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 26 sie 2007, 12:33

Rozpracowałem mniej więcej ten kod i nie widze błedów. Podejrzewam tylko że cos jest nie tak przy inicjacji UARTU. Ale dałem sobie z tym spokój. Oryginalny bascomowy "boot" zajmuje tylko 20bajtów więcej i działa... no prawie. Na terminalu wszystko jest w porządku, za to w pamięci flash juz nie :( Cos tam na pewno zapisuje i procek juz nie rusza. Wygląda na to że w trakcie zapisu danych z bufora do flash'a pojawiają się przekłamania, albo adres jest błędny.

ZbeeGin

Post autor: ZbeeGin » 26 sie 2007, 12:45

A zabezpieczyłeś kod bootloadera przez Lock Bits?

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 26 sie 2007, 18:01

Mam ustawione tak jak na zdjąciu, czyli SPM ma dostęp bez ograniczeń (jak wyczytałem z dokumentacji). Ale reset ustawiony jest na zero więc jeśli wpisze tam jakiś program to powinien on działac. Podczas transmisji bootloader raczej się nie nadpisuje, bo by juz nie wysyłał pytajników. W dokumentacji atmega8 jest fragment bootloadera (bez procedur transmisji), i wygląda bardzo podobnie do tego z bascoma. Jeszcze sie temu dokładnie nie przyjrzałem.
Załączniki
lockBits.JPG

Awatar użytkownika
Tranzystor
Użytkownik
Posty: 889
Rejestracja: 28 sie 2005, 19:19
Lokalizacja: Świętochłowice
Kontakt:

Post autor: Tranzystor » 27 sie 2007, 7:14

A ustawiłeś odpowiednią wielkość bootloadera :?: Znajduje się ona w Fusebits High. Niżej masz przykład.
Załączniki
boot_m8.jpg
Bootloader_size_m8

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 27 sie 2007, 8:34

Tak oczywiście:) W twoim przykładzie jest akurat 2kB, mnie wystarczy 256B. A robiłes cos kiedyś z bootloaderem?

Awatar użytkownika
Tranzystor
Użytkownik
Posty: 889
Rejestracja: 28 sie 2005, 19:19
Lokalizacja: Świętochłowice
Kontakt:

Post autor: Tranzystor » 27 sie 2007, 9:33

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

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 27 sie 2007, 13:05

Zerknij na poprzednia stronę:) A mógłbyś pokazac ten działający na atmege162? Raczej nie powinno byc większych różnic.

Awatar użytkownika
Tranzystor
Użytkownik
Posty: 889
Rejestracja: 28 sie 2005, 19:19
Lokalizacja: Świętochłowice
Kontakt:

Post autor: Tranzystor » 27 sie 2007, 13:34

Aro pisze:Zerknij na poprzednia stronę:) A mógłbyś pokazac ten działający na atmege162? Raczej nie powinno byc większych różnic.
W tej chwili nie posiadam go... Jest na innym komputerze. Byłem na stronie wcześniejszej i ten bootloader troche okrojony jest. Mi się wydaje, że gdybyś ustawił wewnętrzny RC na 8MHz to by wszystko śmigało, wydaje mi się, że zbyt duże są błędy przy 1MHz. Spróbuj odpalić ten bootloader co Ci dałem, zmień jeszcze ten RC na 8MHz i powiedz czy działa czy nie... Kiedyś jak się uczyłem BASCOMa to wrzuciłem go do procka i wszystko działało.

Pozdrawiam

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 27 sie 2007, 13:52

Dałem na 8MHz i chodzi tak samo, czyli źle. Musze jeszcze rozpracowac ten bascomowy (oryginalny) bootloader, on jest najbliżej poprawnego działania.
Taki banalny programik, a sprawia tyle kłopotu...

Awatar użytkownika
Tranzystor
Użytkownik
Posty: 889
Rejestracja: 28 sie 2005, 19:19
Lokalizacja: Świętochłowice
Kontakt:

Post autor: Tranzystor » 27 sie 2007, 18:50

No to już nie wiem, ja bym jeszcze podłączył zewnętrzny kwarc, ale to raczej nie będzie miało zbyt dużego znaczenia. Nie wiem czemu, ale mi działał bootloader.

Pozdrawiam

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 27 sie 2007, 20:07

Jest gorzej:( Bascomowy boot robi dziwne rzeczy. Przy wpiswaniu krótkiego programu (16lini) bootloader skasował 4 pierwsze linie. Reszta programu została nienaruszona. Przy dłuzszym programie sprawa jest bardziej skomplikowana. Fragment mapy pamięci flash(u dołu) i pliku hex (góra) widac na printscreen'ie. Juz nie mam pojęcia jak sie za to zabrac. Na dodatek program Marcina Wiązani ustawia inne bity w rejestrze SPMCR przy _enable_page. Teraz nie wiem któremu programowi ufac. Choc poprawny wydaje się bascomowy boot, przypomina ten z karty katalogowej atmegi. Co robic???
Załączniki
mapyHex.JPG

Awatar użytkownika
Tranzystor
Użytkownik
Posty: 889
Rejestracja: 28 sie 2005, 19:19
Lokalizacja: Świętochłowice
Kontakt:

Post autor: Tranzystor » 28 sie 2007, 7:04

No to trzeba byłoby przejść na metodę prób i błędów. Zobacz jeszcze może ten bootloader z noty katalogowej, ja niestety w tej chwili nie posiadam niestety żadnej ATmega8 a tym bardziej z podłączeniem RS232, tak bym sprawdził wszystkie booty po kolei i powiedział, który działa. Pewnie działały by mi wszystkie :neutral: Jaką wersję masz BASCOM AVR :?: Może zmiana na nowszą lub starszą coś pomoże, lecz wydaje mi się że to nic nie da.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 23 gru 2009, 22:43

to ja odświeżę ten dość satry topik. rozgryźliście temat? potrzebuję bootloadera na atmega8. powiedzcie że coś macie.

ODPOWIEDZ