Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[PIC32MX440][DMA] Dziwne zachowanie DMA

Jado_one 19 Mar 2012 20:08 1631 2
  • #1 19 Mar 2012 20:08
    Jado_one
    Poziom 22  

    Witam,

    Przysiadłem do DMA na PIC32 i od kilku dni walczę o jego poprawne działanie.
    Zachowanie jest dziwne - o ile przesłanie pojedynczego bloku (który w tym przypadku składa się z 3 transakcji DMA po 172 bajty - razem 516 * dwa kanały) wydaje się działać poprawnie, to przy większej ilości przesłań dochodzi do jakiegoś rozprogramowania DMA, które zaczyna siać samodzielnie transmisją.
    DMA obsługuje SPI - jeden kanał odbiór, drugi nadawanie (nadaje tylko 0xFF).
    Nie mogę jakoś uchwycić problemu - może ktoś miał podobny przypadek i naprowadzi na rozwiązanie?

    DMA ma obsługiwać pobranie sektora danych z karty SD.
    Obsługa tego za pomocą tradycyjnego SPI - na przerwaniach działa bez zarzutu.
    Podmieniam tylko ten fragment kodu, odpowiedzialny za przesłanie sektora.
    Kilkadziesiąt odczytów jest ok - potem mu coś "odbija".

    Tak to wygląda na analizatorze:
    [PIC32MX440][DMA] Dziwne zachowanie DMA

    Natomiast tak wygląda to przy tradycyjnym (i poprawnym) SPI(32bit):
    [PIC32MX440][DMA] Dziwne zachowanie DMA

    W razie czego mogę dodać kod obsługi DMA (ale jest dość długi).

    To DMA jest trochę wredne, bo jednorazowo można przesłać tylko 256 bajtów, więc dla 516, musiałem zrobić 3 transakcje obsługiwane w przerwaniu od DMA, które składa to razem w 516 bajtów.

    Trochę mi brakuje pomysłów na dalsze postępowanie - oprócz jednego: przesłać tak w pętli z 500 bloków transmisji, żeby zobaczyć czy się też wysypie (samoistnie) czy sypie się tylko przy współpracy z kartą SD.

    Any ideas?

    Dodano po 2 [godziny] 6 [minuty]:

    Zrobiłem test o którym wyżej - 1000 x 516b transmisji przechodzi bez problemu....
    A zatem konfiguracja DMA wydaje się w porządku....

    Samo DMA wydaje się dość czułe na zakłócenia - inicjacja transakcji gdy trwa jeszcze poprzednia transakcja prowadzi do jego "zgłupienia".

    Ale ja mam zrobione zabezpieczenie przed wywołaniem w trakcie...a i tak się coś sypie w programie...

    Pozostaje więc dalej szukać - może przerwania? A zwłaszcza wylączanie i właczanie przerwania od SPI przed i po transakcji DMA......

    0 2
  • #2 20 Mar 2012 21:19
    Jado_one
    Poziom 22  

    Mojej walki ciąg dalszy..
    Bestia jest uparta, ale ja też ...:-)

    Doszedłem do tego, że zawieszenie następuje w momencie zmiany klastra....
    Po długich pomiarach i analizach okazało się, że następuje błędny odczyt sektora FAT (conajmniej), a liczba otrzymana po obliczeniach mająca być numerem następnego klastra to jakiś kosmos, który powoduje, że karta zawiesza dalszą komunikację wskutek podania błędnego, nieistniejącego adresu....I komunikacja z SPI zamiera....

    Co ciekawe pierwsze odczyty sektorów (poprzez DMA już) wydają się być poprawne.
    Zarówno MBR jak i BootSector maja poprawne sygnatury, odczytuje się też RootDirectory, a także poprawnie wyszukują się pliki po nazwach.
    Ich startowy numer sektora też jest poprawny.... Co powoduje że później pojawia się błąd w transmisji?
    Próbowałem np. wyłączać moduł DMA po skończonej transmisji, a włączać go przed rozpoczęciem następnej (czyli teoretycznie resetować moduł) ale nic to nie pomaga....

    Teraz chyba pozostaje ręczne odczytanie sektor po sektorze pierwszego klastra i porównanie tradycyjnej transmisji przez SPI z tą poprzez DMA, żeby wyłapać moment błędnego odczytu....

    Nie zdziwię się jednak, jak wszystko będzie OK, a błąd będzie występować tylko przy pełnym puszczeniu wszystkich elementów programu.....


    Qrcze - od lat nie pamiętam, żebym tak walczył z problemem....

    0
  • #3 21 Mar 2012 13:44
    Jado_one
    Poziom 22  

    No udało się! :-)

    Kolejne zagęszczanie obszaru poszukiwań doprowadziło mnie do stwierdzenia, że coś powoduje błędny odczyt sektora poprzez kanał DMA.
    Raz dobry, a raz zły....

    W końcu znalazłem błąd - tak banalny, że..... :-)

    W systemie są dwa bufory odbiorcze po 516 bajtów, tak żeby procedura odtwarzająca dźwięk mogła opróżniać jeden, a w tym czasie napełniany odczytem z karty jest drugi bufor....
    Do tego są dwie flagi wskazujące z którego aktualnie bufora się czyta i który w danej chwili jest napełniany...
    Nazwy tych bitów są do siebie dość podobne - różnica 3 literek (przedrostek).
    No i użyłem niewłaściwego z nich w procedurze odczytu przez DMA....
    Oko po prostu nie rejestrowało tej różnicy.

    Przy okazji poszukiwań "przetrzepałem" wszystkie związane z tym procedury, odchudziłem i zoptymalizowałem - więc może to się trochę przydało.
    No i miło jest teraz patrzeć jak podczas odczytu sektora obciążenie pętli głównej nie zmienia się ani jotę :-)

    .

    0