Spis treści

AVR JTAG

Wstęp

Pliki do ściągnięcia można znaleźć na końcu tekstu. Poprawiłem błąd związany ze źle wykrywanym napięciem oraz zrzut ekranu z programu Pony Prog. Dorzuciłem zrzut całego firmware, etap programowania powinien być teraz szybszy.

Podobny interfejs jest opisany w Elektronice Praktycznej numer 6 z 2004 roku (płytka w 7/2004). Na stronie Elektroniki Praktycznej można za parę złotych (przez SMS) ściągnąć ten artykuł. Płytka drukowana jest dwustronna.

Pewnego dnia dowiedziałem się że można samemu zbudować interfejs JTAG dla procesora AVR. Zacząłem szukać w sieci, ale to co znalazłem, to były skrawki informacji i jeden kompletny projekt, który miał wszystko w jednym (JTAG + programator). Doszedłem do wniosku, że lepiej samemu zrobić wszystko od początku, niż całkowicie polegać na projektach z sieci. To co tutaj zamieszczam jest kompilacją tego co można znaleźć w sieci i nocie aplikacyjnej, którą kiedyś opublikował Atmel. Nie wiem, czy jest jeszcze dostępna na stronie Atmela.

Niemal wszystko, dotyczące JTAG dla AVR, jest opisane we wspomnianej wcześniej nocie. Nota zawiera kompletny schemat interfejsu JTAG dla procesora AVR. Oryginalny projekt firmy Atmel jest dość złożony: zawiera zabezpieczenia przeciw przepięciowe, umożliwia współpracę z układami działającymi na bardzo niskich napięciach - wszystko to, w zastosowaniach amatorskich, nie jest, zwykle, potrzebne. Tak się składa, że sam interfejs może być znacznie prostszy.

Jak działa JTAG i co to jest? JTAG to standard umożliwiający zaglądnięcie, co się dzieje w środku układu scalonego - w tym przypadku - procesora AVR. Co jest fajne, układy posiadające interfejs JTAG można łączyć szeregowo, przez co można obserwować pracę wielu układów jednocześnie. Wymaga to jednak odpowiedniej konfiguracji od strony sterownika, tutaj - komputera. AVR JTAG (lub JTAG ICE) zawiera pewne rozszerzenie, które umożliwia programowanie wewnętrznych pamięci - więc możemy stosować go jako programator. Komunikacja na drodze komputer → AVR JTAG odbywa się za pomocą interfejsu szeregowego RS-232, a AVR JTAG → debugowany układ za pomocą 10 żyłowego kabla (aktywnych sygnałów jest mniej). Na poniższym obrazku można to zobaczyć

Komunikacja pomiędzy poszczególnymi elementami systemu

Budowa

Schemat ideowy znajduje się poniżej:

Schemat ideowy interfejsu JTAG dla AVR

Wszystkim zajmuje się procesor ATMega16, oryginalnie, w nocie Atmela, jest to inny procesor, ale ATMega16 jest nowszy i sprawuje się równie dobrze. Widać również układ MAX232, który dostosowuje poziomy napięć do standardu RS-232. Uwaga! Możliwe jest tam wstawienie układu MAX2323, w ten sposób układ będzie mógł działać przy napięciu 3,3 V - być może konieczna będzie zmiana wartości niektórych kondensatorów (C3, C4, C5, C6), oraz podłączenie kondensatora C5 do masy (a nie do VCC). Sam układ MAX2323 kosztuje naście złotych, można dostać tanią wersję innego producenta, jednak należy sprawdzić konfigurację układu i wartości kondensatorów - wartości i sposób podłączenia mogą się różnić. Jeśli robisz wersję na 3,3 V nie zapomnij o odpowiedniej wersji procesora (patrz dokumentacja do ATMega16). Reszta to rezystory, kondensatory i 2 diody. Jest też jeden jumper, którego rola zostanie opisana później, standardowo powinny być zwarte, za pomocą zworki, piny 2 i 3.

Poniżej znajduje się opis złącza między AVR JTAG a układem debugującym. Układ docelowy - ten, który chcemy debugować łączymy 10 żyłową taśmą zakończoną złączką 2 razy 5 pinów (IDC10).

Opis złącza JTAG

PinNazwaWejście/wyjścieOpis
1TCKWyjścieTest Clock, sygnał zegarowy z JTAG ICE do urządzenia docelowego
2GND-Masa
3TDOWejścieTest Data Output, sygnał danych z urządzenia docelowego do JTAG ICE
4VTREFWejściePoziom napięcia logiki układu docelowego
5TMSWyjścieTest Mode Select, sygnał wyboru trybu z JTAG ICE do układu docelowego
6NSRSTWejście/wyjścieWyjście typu open collector z JTAG ICE do układu docelowego, jest to również wejście, aby móc wykryć reset wykonany w urządzeniu docelowym
7VSUPPWejścieNapięcie zasilające JTAG ICE. Ta linia jest odcinana, jeśli jest podłączony zewnętrzny zasilacz (patrz schemat)
8NTRSTWyjście/NCNie podłączone, zarezerwowane dla innych urządzeń JTAG (reset portu JTAG)
9TDIWyjścieTest Data Input, sygnał danych z JTAG ICE do urządzenia docelowego
10GND-Masa

Jak zrobić - krok po kroku

Musimy zrobić pytkę (wszystkie rzeczy do ściągnięcia są na końcu tekstu), polutować wszystko. Płytka ma rozmiar 100 mm na 46 mm. Układy najlepiej wstawiać w podstawki (szczególnie ATMega16). Upewnijmy się, że nie ma żadnych zwarć oraz elementy mają poprawne wartości. Ach, IC2 musi być MAX232A, można wtedy zastosować kondensatory 0,1 μF; oczywiście można wstawić też zwykły MAX232 lub odpowiednik, ale trzeba pamiętać o odpowiednich wartościach kondensatorów. W razie pomyłki raczej nie stanie się nic złego, bo nie bardzo ma się co popsuć - układ ma proste zabezpieczenie przeciw podłączeniu zasilania o niewłaściwej polaryzacji - dioda D1.

Metoda szybka (nowa)

Trzeba zaprogramować procesor, w zewnętrznym programatorze (możliwe jest też programowanie za pomocą przejściówki JTAG-ISP), plikiem firmware ściągniętym z działającego, wcześniej zaprogramowanego JTAGa; należy ustawić bity fuse tak jak dla metody wolnej. JTAG powinien działać natychmiast, w razie problemów radzę przeczytać cały opis dla metody wolnej.

Metoda wolna (stara)

Teraz pora na zaprogramowanie procesora - robi się to dwuetapowo:

1. Pierwszy etap to zaprogramowanie procesora bootloaderem, który potem posłuży do załadowania programu właściwego, odpowiadającego za działanie JTAG AVR. Więcej o samym bootloaderze poniżej tabelki. Trzeba też pamiętać o odpowiednim zaprogramowaniu fuse-bitów, lock-bitów nie trzeba programować. Aby zaprogramować bootloader musimy posiadać jakikolwiek zewnętrzny programator, ja polecam schemat zamieszczony na stronie PonyProg: schemat, do samego programowania użyłem PonyProga. Możliwe jest też użycie przejściówki JTAG-ISP (JTAG ma sygnały potrzebne do programowania) jednak praktycznie tego nie sprawdzałem. Poniżej obrazek, który bit zaprogramować (zrzut z PonyProga) oraz tabelka z objaśnieniem:

Ustawienie bitów w PonyProg

Ustawienia bitów fuse bits:

OznaczenieWartośćWyjaśnienie
OCDEN1Wyłączenie On Chip Debug, jeżeli włączone może zużywać więcej prądu w trybach uśpienia, ze względu na stale działające podukłady systemu rozprowadzania sygnałów zegarowych
JTAGEN1JTAG tutaj nieużywany
SPIEN0Konieczny podczas szeregowego programowania (nie można go od programować w trybie SPI)
CKOPT1Wartość wynika z użycia kwarcu 7,3728 MHz, patrz dokumentacja do ATMega16
EESAVE1Zawartość EEPROMU nie musi być zachowywana między programowaniami - więc wyłączone
BOOTSZ10Wielkość bootloadera ustawiona na 1024 słów, czyli 2048 bajtów (szczegóły w dokumentacji)
BOOTSZ00Wielkość bootloadera ustawiona na 1024 słów, czyli 2048 bajtów (szczegóły w dokumentacji)
BOOTRST0Po resecie skacz do bootloadera
BODLEVEL1Poziom Brown Out Detector - wykrywanie zaniku zasilania - tutaj nie używane więc nie ustawione
BODEN1Brown Out Detector - wykrywanie zaniku zasilania - nie używane więc nie ustawione
SUT11Start Up Time - tutaj bez większego znaczenia - ustawione na 65 ms SUT0 1 Start Up Time - tutaj bez większego znaczenia - ustawione na 65 ms
CKSEL31Wartość wynika z zastosowania kwarcu 7,3728 MHz
CKSEL21Wartość wynika z zastosowania kwarcu 7,3728 MHz
CKSEL11Wartość wynika z zastosowania kwarcu 7,3728 MHz
CKSEL01Wartość wynika z zastosowania kwarcu 7,3728 MHz

Bootloader jest zgodny z protokołem avrboot, skompilowałem go korzystając z tego projektu. Działa to tak, że tuż po włączeniu procesora uruchamiany jest program programatora, który czeka na rozkazy wysyłane przez port szeregowy (prędkość 19200, 8N1). Ważne: zworka na jumperze JP1 musi być w pozycji 1-2, tylko wtedy bootloader przechodzi w tryb programowania - inaczej (pozycja 2-3) uruchamiany jest program zawarty w procesorze. Jeśli używamy kabla USB-RS232 najlepiej jest ustawić numer portu COM między 1 a 4, robi się to w ustawieniach zaawansowanych danego portu komunikacyjnego w Menedżerze Urządzeń. O ile tutaj nie ma to znaczenia to potem AvrProg może narzekać że nie odnalazł urządzenia. Komunikację można sprawdzić korzystając z terminala podłączonego do portu szeregowego i wysłać znak S lub V. Jako terminala można użyć darmowego programu Termite. Poniżej widać efekt, białe tło oznacza wysyłany znak:

Okno terminala połączonego z avrboot. Białe tło oznacza wysyłany znak

Okno programu Termite połączonego z avrboot

Poniższy diagram powinien pomóc w zrozumieniu jak działa komunikacja z JTAGiem:

Droga sygnału RXD i TXD

2. Bootloader mamy już zaprogramowany, pamiętajmy o zworce (pozycja 1-2). Teraz trzeba załadować program sterujący. Uruchamiamy AVRStudio. Przykłady są podane dla wersji 4.0, podobnie jest w wersji 3.5. Jeśli używasz kabla USB-RS232 być może będzie konieczne przestawienie numeru portu między 1 a 4. Z menu Tools wybieramy AVR Prog:

Uruchomienie AVR Prog

Uruchamianie AVR Prog z pakietu AVR Studio Pojawi się okno AVR Prog, pamiętajmy - przed, nasz interfejs musi być włączony i podłączony kablem szeregowym z komputerem oraz zworka w pozycji 1-2, inaczej pojawi się komunikat, że nie został wykryty żaden interfejs. Oto okno AVR Prog (pojawi się jeśli wszystko jest OK):

Okno AVR Prog

Okno programu AVR Prog Klikamy Browse i lokalizujemy plik upgrade.ebn, w standardowej instalacji jest to: C:\Program Files\Atmel\AVR Tools\JTAGICE\Upgrade.ebn. Tutaj jest cała magia - ten plik to zaszyfrowana zawartość programu interfejsu JTAG, AVR Studio zajmie się już programowaniem, my o nic się nie martwimy i wciskamy Program (w sekcji Flash). Gotowe. Na koniec przestawiamy zworkę w pozycję 2-3 tak, aby bootloader już się nie uruchamiał. Bezpośrednio po włączeniu powinna zapalić dioda sygnalizująca komunikację JTAG (ta druga oprócz diody power).

Krótki test

Aby przetestować interfejs zbudowałem prosty układ z procesorem ATMega16 - ten ma już interfejs JTAG, bo na przykład ATMega8 nie ma JTAG. Fabrycznie procesor jest dostarczony z zaprogramowanym bitem JTAGEN, jednak ja dla pewności zaprogramowałem go wraz z bitem OCDEN (myślę, że ten etap nie jest konieczny). Oto schemat układu testowego:

Schemat układu testowego

Linie sygnałowe TCK, TDO, TMS, TDI łączymy z odpowiednimi nóżkami układu, NSRST łączymy z resetem procesora, oraz łączymy VCC do VTREF. Układ testowy łączymy z płytką interfejsu JTAG za pomocą kabla 10 żyłowego. U mnie zadziałało prawie od razu - zapomniałem jedynie podłączyć napięcia do VTREF, po korekcie AVR Studio przestało narzekać, że napięcie nie jest podłączone. A oto jak sprawdzić interfejs: wybieramy Tools → Program AVR → Connect:

Krok pierwszy, wybieramy odpowiednią pozycję menu

Pojawi się okno wyboru programatora, z którego wybieramy JTAG ICE oraz port, do którego jest podłączony nasz interfejs:

Krok drugi, wybieramy programator JTAG ICE

Jeśli wszystko działa poprawnie pojawi się okno programatora:

Krok trzeci, JTAG gotowy do pracy

Jedyne, co mi nie pasowało, to źle wykryte napięcie VTREF, powinno być 5 V, jednak program wykrywa 6,2 V. Nie wpływa to jednak na pracę całego układu. Schemat i płytka zawierają już dzielnik napięcia toteż napięcie powinno być już poprawnie wykrywane, przekreślenie dotyczy starej wersji schematu i płytki.

Działanie sprawdziłem pod Linuksem przy pomocy programu avarice oraz avr-insight - bez problemu udało się zaprogramować i obserwować działanie testowego układu z procesorem ATMega16.

Złożony interfejs JTAG AVR (obrazek przedstawia starszą wersję bez dzielnika napięcia)

Linki i pliki do pobrania

Komentarze

Proszę pamiętać że, po czasie, mogę usunąć niektóre komentarze jeśli nie wnoszą one niczego nowego.