Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

LPC1769 - UART TX przez DMA (FreeRTOS)

Freddie Chopin 28 Jun 2012 01:24 1931 3
  • #1
    Freddie Chopin
    MCUs specialist
    Witam!

    Walka jest ostra, ale z każdą chwilą tracę nadzieję [;

    Problem pierwszy:
    W każdym miejscu (choćby biblioteki od NXP) kanał DMA włączany jest przez
    LPC_GPDMACHx->DMACCConfig |= GPDMACHx_DMACCConfig_E;
    na końcu, a u mnie tak po prostu zupełnie nie działa... Musi być "=", zamiast "|=" i wtedy w miarę działa.

    Ustawienie DMA jest następujące:

    Code: C
    Log in, to see the code


    Bonusowy problem jest tego typu, że np zgłaszane jest tylko co drugie przerwanie, chyba że przed ostatnim zapisem (bit E) dodam niewielkie opóźnienie (które oczywiście nie rozwiązuje problemu głównego)...

    Ktoś w ogóle wie o co chodzi?

    Problem drugi:
    Przypuszczalnie powiązany jakoś z tym pierwszym. Jeśli przed konfiguracją kanału DMA dam oczekiwanie na semafor, który jest "dawany" w przerwaniu od zakończenia transmisji, to... przestaje się wywoływać przerwanie od DMA, a więc przez UART idzie tylko pierwszy blok, a potem cisza...

    Pełny kod tego przypadku wygląda tak:

    Code: C
    Log in, to see the code


    Co więcej, jeśli chciałbym zrobić prymitywną synchronizację za pomocą flagi volatile, to też przestają działać przerwania od DMA (cała reszta programu chodzi).

    EDIT: przy synchronizacji flagą jakimś sposobem gubione jest pierwsze przerwanie, więc jeśli za pierwszym razem nie czekam na flagę, to potem już idzie, tyle że się trochę UART sypie - po 14tu znakach wysyłane są dwa zera...

    Jakieś pomysły co robię źle?

    4\/3!!
    Kamery 3D Time of Flight - zastosowania w przemyśle. Darmowe szkolenie 16.12.2021r. g. 10.00 Zarejestruj się
  • Helpful post
    #2
    tymon_x
    Level 30  
    Freddie Chopin wrote:
    Co więcej, jeśli chciałbym zrobić prymitywną synchronizację za pomocą flagi volatile, to też przestają działać przerwania od DMA (cała reszta programu chodzi).

    EDIT: przy synchronizacji flagą jakimś sposobem gubione jest pierwsze przerwanie, więc jeśli za pierwszym razem nie czekam na flagę, to potem już idzie, tyle że się trochę UART sypie - po 14tu znakach wysyłane są dwa zera...

    Jakieś pomysły co robię źle?

    Ten sam mikrokontroler (LPC1768/9).

    Widzę, że nie tylko ja ten problem ostatnio mam. Mi czasem po ponownym zaprogramowaniu raz działa DMA, raz latchuje się na stałe. Widać w debugerze, że licznik adresu rośnie i zdarzy się, że nie załapuje na enable.

    1. Działa jak należy i śmiga jak rakieta.
    2. Raz wyślę i nie ustawia enable ani przerwania i nie wiadomo o co chodzi.

    W obu przypadkach licznik dochodzi do poprawnej wartości 'ilości wysłanych bajtów'.

    Tak wyszło po jednodniowym bawieniu się z DMA i wysyłaniem. Na pewno też coś źle zrobiłem, ale nie wgryzłem się ten problem jeszcze i zostawiłem na pewniejszych przerwaniach. Ale tego tak nie zostawię, zwrócę się z tym w ten weekend, może mnie olśni po przerwie.

    PS.
    Dokumentacja NXP od LPC są biedne i jak dla mnie nieścisłe w wielu miejscach. Zdecydowanie od ST, bardziej klarują o co im chodzi. Ale to opinia subiektywna.
  • #3
    Freddie Chopin
    MCUs specialist
    Po uproszczeniu przypadku z którym mam problem i oddzieleniu go od RTOSa udało mi się znaleźć rozwiązanie (; Ale najpierw kilka obserwacji, które mogą się przydać na przyszłość

    Code: C
    Log in, to see the code


    Kilka obserwacji:
    - zakomentowanie ustawianie bitu E przez sumę logiczną nie działa, choć powinno, natomiast ustawienie przez wywalenie całej poprzedniej zawartości rejestru działa, choć wg mnie nie powinno...
    - przy pierwszym wejściu do przerwania od DMA zmienna flag ma wartość 2, to znaczy, że jedno przerwanie się "zgubiło", potem flag ma już zawsze wartość 1,
    - po linii
    LPC_GPDMA->DMACConfig = GPDMA_DMACConfig_E; // enable DMA controller
    zapalają się bity od UART0 TX i UART1 TX w rejestrze DMACSoftBReq, tzn. że żądania są wysyłane poprawnie.

    Więcej obserwacji już nie ma, bo właśnie w tym momencie znalazłem błąd w swoim kodzie:
    LPC_GPDMACH7->DMACCConfig = GPDMACHx_DMACCConfig_SrcPeripheral_UART0_TX_MAT0_0 | // select UART0
    a przecież UART nie jest ŹRÓDŁEM tylko CELEM dla DMA. Po zmianie na:
    LPC_GPDMACH7->DMACCConfig = GPDMACHx_DMACCConfig_DestPeripheral_UART0_TX_MAT0_0 | // select UART0
    Wszystko śmiga jak naleźy.

    Tak to jest jak jest zbyt późno. Swoją drogą działanie z niepoprawnym kodem jest co najmniej ciekawe...

    4\/3!!
  • #4
    gaskoin
    Level 38  
    Pamiętam jak dondu uruchomił DMA w trybie mem2mem w trybie circular, który wg noty jest zabroniony a działał :?

    tymon_x wrote:

    PS.
    Dokumentacja NXP od LPC są biedne i jak dla mnie nieścisłe w wielu miejscach. Zdecydowanie od ST, bardziej klarują o co im chodzi. Ale to opinia subiektywna.


    To nie tylko Twoje wrażenie. Najbardziej mi przypadły do gustu noty z Freescale, ST, TI i energymicro