logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Protokół PDI w układach Xmega

manekinen 07 Lis 2011 15:52 2766 8
  • #1 10112721
    manekinen
    Poziom 29  
    Witajcie.

    Próbuję rozgryźć protokół PDI, tzn dobrać się do układu Xmega innym prockiem.

    Stanąłem na samym początku, nie mogę w ogóle włączyć trybu PDI.

    Zacytuję tutaj DS od Xmega16A4:

    enabling napisał:
    The PDI Physical must be enabled before it can be used. This is done by first forcing the PDI_DATA line high for a period longer than the equivalent external reset minimum pulse width (refer to device data sheet for external reset pulse width data). This will disable the RESET functionality of the Reset pin, if not already disabled by the fuse settings.

    In the next step of the enabling procedure the PDI_DATA line must be kept high for 16 PDI_CLK cycles (16 positive edges detected). The first PDI_CLK cycle must start no later than 100uS after the RESET functionality of the Reset pin was disabled. If this does not occur in time the RESET functionality of the Reset pin is automatically enabled again and the enabling procedure must start over again.

    After this the PDI is enabled and ready to receive instructions. The enable sequence is shown in Figure 29-3 on page 346.
    Protokół PDI w układach Xmega

    The RESET pin is sampled when the PDI interface is enabled. The RESET register is then set according to the state of the RESET pin, preventing the device from running code after the reset functionality of this pin is disabled.

    The PDI_DATA pin has an internal pull-down resistor.


    disabling napisał:
    If the clock frequency on the PDI_CLK is lower than approximately 10 kHz, this is regarding as inactivity on the clock line. This will then automatically disable the PDI. If not disabled by fuse, the RESET function on the Reset (PDI_CLK) pin is automatically enabled again. If the time-out occurs during the PDI enabling sequence, the whole sequence must be started from the beginning.

    This also means that the minimum programming frequency is approximately 10 kHz.


    Ok, a więc na początku muszę podciągnąć linię DATA do VCC na okres dłuższy niż minimalny wymagany czas trwania impulsu linii RESET. Nota mówi, że typowo jest to 90ns a maksymalnie 1000ns. Ok, podciągam tą linię na 1us w górę, a następnie gdy już zwykła funkcja resetu jest wyłączona(?), włączam zegar > 10kHz. Ponieważ minimalna prędkość programowania to 10kHz, i poniżej tej wartości PDI zostanie wyłączone.

    Sytuacja jest taka że układ się resetuje, ale nie z powodu wejścia w tryb PDI. Zwyczajnie, od stanu niskiego na RESET. Ponieważ gdy skończę wysyłać zegar z niskim stanem końcowym to układ nie budzi się, a gdy z wysokim to wstaje.

    Napisano, że mam zacząć wysyłać zegar nie później jak 100us po tym jak funkcja resetu zostanie wyłączona. CZYLI KIEDY? Skąd mam wiedzieć kiedy ona zostaje wyłączona, skoro czas potrzebny na reset (czyli linia DATA w górze) podano od 90 do 1000ns? Próbowałem różnych czasów na chybił trafił ale nic to nie daje :(
  • #2 10112837
    kriss68
    Poziom 20  
    Cytat:
    In the next step of the enabling procedure the PDI_DATA line must be kept high for 16 PDI_CLK cycles (16 positive edges detected).
    A zastosowałeś się do tego?
  • #3 10112854
    manekinen
    Poziom 29  
    PDI_DATA jest cały czas w górze, w ogóle jej nie ruszam. Jednak z pierwszym zboczem opadającym na RESET, układ się zwyczajnie resetuje - czyli funkcjonalność resetu jako resetu nie została wyłączona.
  • #4 10112877
    kriss68
    Poziom 20  
    Jesteś pewien, że przy pierwszym zboczu się resetuje? Spróbuj poczekać jakieś 20us po podciągnięciu PDI_DATA potem puścić te 16 cykli i ściągnij do 0 PDI_DATA. I nie wiem czy pin reset nie powinien być na 0 lub 1 w trakcie włączania PDI
  • #5 10112938
    manekinen
    Poziom 29  
    Hmm czy przy pierwszym to nie jestem pewien - ale na pewno resetuje się od stanu niskiego na reset a nie od wejścia w PDI. Z tego co wyczytałem, wynika że układ nie powinien się zresetować dopóki nie wpiszemy wartości 0x59 do rejestru "reset".

    Dałem 20us, i na końcu zwolniłem PDI_DATA (ten pin ma wewnętrzny pulldown). No i bez efektu.

    Pin RESET podczas podania 1 na PDI_DATA może być w górze lub w dole - obojętne - sugeruje się załączonym obrazkiem z sekwencją włączania PDI. Ale u mnie jest w górze tak że układ pracuje.

    Poniżej inicjacja PDI programatora w którym to działa jak złotko, i wg tego badana xmega normalnie się inicjuje w PDI.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    U siebie robię praktycznie to samo tylko że w uproszczony sposób. Niestety mam jednokanałowy oscyloskop/rejestrator i nie mogę porównać zależności czasowych pomiędzy liniami CLK a DATA.

    Nie próbowałem jeszcze słać danych bo nie pasuje mi to że reset wciąż działa jako reset, w DS nie napisali nic czy układ się resetuje na krótką chwilę czy co. Zaraz zmontuję jakąś ramkę danych i spróbuję wpisać te 0x59 aby układ pozostał w stanie resetu...
  • #6 10112955
    kriss68
    Poziom 20  
    A skąd masz pewność, ze układ się resetuje? W jaki sposób to sprawdzasz? Poza tym przeczysz sam sobie
    Cytat:
    ...wynika że układ nie powinien się zresetować dopóki nie wpiszemy wartości 0x59 do rejestru "reset".
    A potem piszesz
    Cytat:
    Zaraz zmontuję jakąś ramkę danych i spróbuję wpisać te 0x59 aby układ pozostał w stanie resetu...
    Tak trochę nie wiem o co Ci chodzi :) Zrób PDI_DATA = 1 potem czekasz 20us zaczynasz słać zegar i puszczasz PDI_DATA. Może tajemnica kryję się w funkcji XPROGTarget_SendIdle();?
  • #7 10113559
    manekinen
    Poziom 29  
    kriss68 napisał:
    A skąd masz pewność, ze układ się resetuje? W jaki sposób to sprawdzasz?

    Układ zmienia stan na porcie co 100ms więc widać każdy jego reset.

    kriss68 napisał:
    Poza tym przeczysz sam sobie

    Chodzi mi o to że nie wiem czy ten reset układu jest wywołany pinem reset czy wejściem w PDI.

    kriss68 napisał:
    Zrób PDI_DATA = 1 potem czekasz 20us zaczynasz słać zegar i puszczasz PDI_DATA


    Ciągle tak robię :)

    kriss68 napisał:
    Może tajemnica kryję się w funkcji XPROGTarget_SendIdle();?

    Hmm no i to jest tylko te 16 pustych taktów, tutaj akurat 24 bo wolą skorzystać z gotowej funkcji zamiast bazgrać kolejną.

    I teraz ciąg dalszy kodu tego programatora:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Czyli po tej inicjacji którą wkleiłem wyżej, wysyłane są od razu:
    komenda STCS = 0xC0
    rejestr "reset" = 0x01
    wartość dla rejestru = 0x59

    Robię to samo u siebie, wg tego:
    Protokół PDI w układach Xmega

    Niestety nie mam wolnego sprzętowego uarta więc robię to całkowicie softowo. Skleiłem dwa przebiegi (rejestrowane osobno bo mam jeden kanał) więc może nie wygląda to za ładnie ale widać dokładnie jaki bit na którym takcie leci. Sonda na nogach Xmegi, góra to zegar a dół do dane:
    Protokół PDI w układach Xmega
    Na moje oko jest ok. Napierw linia DATA jest w górze, czekam te 20us, ślę 16 cykli zegara, ściągam DATA w dół, i zaczynają się dane. Najpierw bit startu 0, potem bajt danych słany od najmłodszego bitu, bit parzystości, i dwa bity stopu 1.

    Jednak układ nie pozostaje w stanie resetu. Jeśli podniosę zegar w górę to układ wstaje, tak jak by pin reset nadal działał jako reset a przecież nie powinien. Pewnie robię gdzieś masakrycznie durny błąd jak to bywa... :(
  • #8 10113850
    michalko12
    Specjalista - Mikrokontrolery
    Te min 10kHz ma być cały czas aktywne w trakcie całego okresu programowania, a linią danych synchronizujesz się do tego zegara. Masz tak zrobione?
  • #9 10118411
    manekinen
    Poziom 29  
    michalko12 napisał:
    Te min 10kHz ma być cały czas aktywne w trakcie całego okresu programowania, a linią danych synchronizujesz się do tego zegara. Masz tak zrobione?

    Jeśli pytasz o to czy transmisja jest zsynchronizowana, to jak najbardziej, co potwierdza powyższy oscylogram. Zegar nie jest jednak jednostały bo jest to zrobione "na kolanie", a z tego co wyczytałem to programator generuje zegar i napisano jedynie że nie może spaść poniżej 10kHz ale nic o czasach trwania/zmiany stanów nic tam nie ma.

    Ale już się sprawa wyjaśniła. Szkoda że tak strasznie ubogo opisali ten protokół, człowiek musi sam się z tym męczyć...

    Trochę źle interpretowałem na początku dane które trzeba wysyłać...

    Kolejno:
    0xC1 - oznacza komendę STCS i jednocześnie wybór rejestru "1" czyli "reset"
    0x59 - wartość do wpisania w rejestr "reset" aby utrzymać układ w stanie resetu, na początku to nie działało, ale o tym dalej...
    0xC2 - komenda STCS i wybór rejestru kontrolnego "2" czyli "ctrl"
    0x07 - tutaj ustawiamy sobie ilość pustych bitów wysyłanych od procka po przełączeniu go w tryb nadawania, tak aby przygotować programator na odbiór danych. 07 oznacza 0 bitów.
    0xE0 - komenda KEY do wpisania klucza dla pamięci NVM aby uzyskać do niej dostęp
    0x1289AB45CDD888FF - klucz NVM, bajty należy słać od końca
    0x80 - komenda LDCS i wybór rejestru "0" czyli "status"

    W tej chwili następuje przełączenie kontrolera PDI w tryb nadawania, i odbieramy zawartość rejestru statusu. Włączony bit 1 (0x02) oznacza że interfejs NVM został prawidłowo włączony. Taką też odpowiedź udało mi się odebrać.

    I DOPIERO po wysłaniu tej całości i DOPIERO po odczytaniu statusu, procek pozostaje w stanie resetu pomimo wyłączenia zegara dla PDI (i tym samym PDI) - i właśnie tak to miało działać.

    Także pierwsza zagadka rozwikłana :)
REKLAMA