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.

Wszystko o ARM (LPCxxxx) i programowaniu w asm i C.

atom1477 04 Paź 2009 00:31 15970 141
  • #61 04 Paź 2009 00:31
    atom1477
    Poziom 43  

    Mam też TD035STEB1 (320x240 kolorowy TFT). Nowy. Takie idą do Palmtowów Acerów N30 czy jakichś takich. 120zł kosztował.
    I mam też sx21v001-z4 (640x480 kolorowy ale STN). Nowy. Kupiony w ARTRONICu. 180zł.
    Czyli 500zł Cię to nie wyniesie ;p
    Najlepiej chyba będzie z jakiegoś starego laptopa wyjąć. Myślę że na allegro za kilkadziesiąt zł kupisz. Ale nie wiem do czego Ci to potrzebne, więc nie wiem czy Az taki duży (gabarytowo) Ci potrzeba.

    PS. A żebyś wiedział. LQ084V3DG01 kosztowały gdzież z 500zł :(

  • Pomocny post
    #62 04 Paź 2009 00:33
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Z tego powodu na takich płytkach najlepiej dać jakieś goldpiny, a dopiero do nich przyczepiać odpowiednią przejściówkę ze stosownym gniazdkiem [;

    4\/3!!

  • #63 04 Paź 2009 01:17
    atom1477
    Poziom 43  

    Wiem. Tylko że ja już robię finalną wersję do urządzenia.
    Jedyne co nas ratuje to to, że te wyświetlacze TSEBxxxx i ten z ARTRONICa (a mam 2) też bym chciał wykorzystać, więc może po prostu zaprojektuję sobie (i Tobie) jeszcze jedna wersję płytek drukowanych.
    Może chętnych było by jeszcze więcej.

    PS. Pierwszą wersję miałem na GoldPinach (jeszcze z AVR + CPLD + SRAM). Niedługo wyślę fotkę jak wyglądało podłączenie LCD to może zmienisz zdanie co do GioldPinów ;p

    Po za tym. AVR radził sobie z generowaniem obrazu na żywo w ciągu może 200ms.
    Wysyłanie gotowych danych to nawet 50ms (pierwsza wersja generowała, druga wysyłała gotowe, wygenerowane wcześniej na kompie a pobierane z karty SD dane).
    Czyli ARM dopiero co ledwo to przegonił. Jedyna różnica jest taka, że nad AVRem siedziałem z miesiąc (nad samym kodem do grafiki) i powstało z 10000 linijek w assemblerze.
    Przy ARMie mam nogi na stole, a nad samą grafiką siedziałem może 15 minut (nad uruchomieniem ARMa więcej, ale nad AVRem kilka lat temu też siedziałem więc to pomijam). I nie ma nic w assemblerze (to co zapodałem w assemblerze na forum ostatecznie nie trafiło do programu).

  • Pomocny post
    #64 04 Paź 2009 09:42
    Freddie Chopin
    Specjalista - Mikrokontrolery

    atom1477 napisał:
    Jedyne co nas ratuje to to, że te wyświetlacze TSEBxxxx i ten z ARTRONICa (a mam 2) też bym chciał wykorzystać, więc może po prostu zaprojektuję sobie (i Tobie) jeszcze jedna wersję płytek drukowanych.
    Może chętnych było by jeszcze więcej.

    Pewnie by było, ale wtedy jak zrobisz błędy to masz przerąbane u większej ilości osób <:

    4\/3!!

  • #65 04 Paź 2009 10:20
    atom1477
    Poziom 43  

    No ale dam to do oceny na forum przecież ;p

    EDIT.
    Dodam jeszcze, że niedługo zamieszczę projekt Plasma dla LPC2478. Dla potomnych, bo efekt fajny ;p
    W ogóle ilość przykładowych kodów pod coś innego niż Keil na ARMy jest na tym forum mizerna. Więc jak ja nie umieszczę, to w ogóle nie będzie ;p

  • Pomocny post
    #66 05 Paź 2009 01:14
    94075
    Użytkownik usunął konto  
  • #67 10 Paź 2009 22:24
    atom1477
    Poziom 43  

    No właśnie.
    Od samego początku się nad tym zastanawiałem (w poprzednim User Manualu tego nie napisali).
    Więc kolejny raz większe dzięki :D
    I kolejny raz drutowanie :D

    EDIT.
    Ja pierniczę, jaki wstyd.
    Linia BA1 była zwarta do VCC. A sterownik chyba jakoś nietypowo steruje pamięcią, bo przełącza banki już zaraz po przewinięciu się adresu kolumn (myślałem że idą Kolumny:Wiersze:Banki, a wychodzi że Kolumny:Banki:Wiersze).
    Czyli co 256B miałem krzaki. A spodziewałem się że uszkodzenie linii od banków da mi błędy dopiero na adresach po pierwszych 2MB.
    Teraz wszystko śmiga aż miło.
    Ciekawe co u zbigel-a. Nie odzywa się coś.


    EDIT2.
    Obiecany projekt "Plasma".

  • Pomocny post
    #68 19 Paź 2009 07:42
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Podepnę się trochę:

    czy przy użyciu dostępnych w TME pamięci K4S641632K (16b) można łatwo osiągnąć szerokość szyny 32b po prostu podłączając adresy tych pamięci do tych samych pinów, a linie danych zgodnie z logiką - jednej pamięci do D0 - D15, a drugiej do D16 - D31? Czy może lepiej nie kombinować i szarpnąć się na droższe SDRAM o szerokości 32b?

    Czy, zgodnie z logiką, podłączenie pamięci o szerokości 32b poprawi wydajność aplikacji, czy może gdzieś tam wewnętrznie kontroler w LPC2478 jest tak naprawdę 16bitowy i odczyt 32bitów to dwa odczyty po 16?

    4\/3!!

  • Pomocny post
    #69 19 Paź 2009 13:49
    arrevalk
    Poziom 25  

    @Freddie Chopin
    Ad1. Takie rozwiązanie jest z powodzeniem stosowane na płytkach ewaluacyjnych Atmela *-ek dla procesorów AT91SAM926X jak i innych podobnych konstrukcjach. A że schematy są ogólnie dostępne to można podejżeć rozwiązanie.

    Ad2. To raczej pytanie do datasheeta albo pomocy technicznej NXP. Przyznam się że nie miałem okazji do zabawy z tymi procesorami.

  • #70 19 Paź 2009 18:48
    atom1477
    Poziom 43  

    1. Oczywiście że można i ja tak zamierzam zrobić. Zresztą tak jest na schemacie płytki z Olimexu.
    Widziałem i inne płytki i nikt nie stosował rozwiązania z jedną pamięcią 32b. Zawsze wstawiali 2 16-to bitowe (ale tylko do płytki z Olimexu udało mi się załatwić schemat).
    Oczywiście linie DQMN0 i DQMN1 do pamięci nr. 1, a DQMN2 i DQMN3 do pamięci nr. 2.

    2. ARM (to znaczy EMC w układzie LPC2478) domyślnie czyta po 32b i tak na prawdę to kombinuje dopiero wtedy gdy ma pamięć inną niż 32b ;p
    Przepustowość oczywiście wzrośnie (dwukrotnie).
    Na stronie NXP był nawet jakiś arkusz kalkulacyjny pozwalający wyznaczyć przepustowość przy danej szerokości szyny, danej częstotliwości taktowania i danych czasach dostępu do pamięci.
    Liczył też wymaganą przepustowość pamięci dla poprawnego odświeżania danego wyświetlacza LCD.
    Niestety nie mogę teraz znaleźć. Jak zresztą niczego innego na stronie NXP ;p
    Mogę wrzócić to jako załącznik jak chcecie, bo mam to gdzieś na kompie.

  • #71 03 Lis 2009 19:52
    atom1477
    Poziom 43  

    A jak uruchomić przerwanie FIQ?
    Na początku zmieniłem atrybut (jak się później okazało nie zmienia to niczego w programie (porównałem pliki BIN)):

    Code:

    static void t0isr(void) __attribute__ ((interrupt("FIQ")));


    Później zmiana w rejestrze VIC:
    Code:

    VICIntSelect = 0x00000010;    //t0isr = FIQ


    I na tym zakończyłem zmiany, ale jak się okazało kod nie działał.
    No to luk do tablicy wektorów, i widzę że FIQ jest zadeklarowane jako stała funkcja. Czyli adres nie jest pobierany z żadnego rejestru ale jest podany na tacy.

    Chodzi mi o to:
    Code:

    // FIQ (fast interrupt)
    void FIQ_Handler(void) __attribute__ ((interrupt("FIQ"), weak, alias("__Default_Handler")));

    ...
    ...

    void (* const vectors[])(void) __attribute__ ((section(".vectors"))) = {
          (void (*)(void))0xe59ff018,         // "Reset" vector
          (void (*)(void))0xe59ff018,         // "Undefined instruction" vector
          (void (*)(void))0xe59ff018,         // "Software interrupt (SWI)" vector
          (void (*)(void))0xe59ff018,         // "Prefetch Abort (instruction fetch memory abort)" vector
          (void (*)(void))0xe59ff018,         // "Data Abort (data access memory abort)" vector
          (void (*)(void))0,               // Reserved vector (code signature)
          (void (*)(void))0xe51ff120,         // "IRQ" vector
          (void (*)(void))0xe59ff010,         // "FIQ (fast interrupt)" vector
          Reset_Handler,                  // Reset
          Undefined_Handler,               // Undefined instruction
          SWI_Handler,                  // Software interrupt (SWI)
          Prefetch_Abort_Handler,            // Prefetch Abort (instruction fetch memory abort)
          Data_Abort_Handler,               // Data Abort (data access memory abort)
          FIQ_Handler                     // FIQ (fast interrupt)
    };


    No więc zmieniłem moje przerwanie na:
    Code:

    void FIQ_Handler(void) __attribute__ ((interrupt("FIQ"), weak, alias("__Default_Handler")))
    {
    ...
    ...
    }


    Ale teraz to nawet skompilować się nie chce.
    Więc jak uruchomić to przerwanie FIQ?

  • Pomocny post
    #72 03 Lis 2009 22:38
    Freddie Chopin
    Specjalista - Mikrokontrolery

    bo przerwanie powinieneś zmienić na

    void FIQ_Handler(void) __attribute__ ((interrupt("FIQ")));
    void FIQ_Handler(void)
    { ... }

    gdyż reszta parametrów jest potrzebna aby NIEUŻYWANE przerwania były przypisane do domyślnego. Pozatym potrzebna jest też konfiguracja danego źródła jako FIQ w module VIC.

    4\/3!!

  • #73 03 Lis 2009 22:45
    atom1477
    Poziom 43  

    Freddie Chopin napisał:
    bo przerwanie powinieneś zmienić na

    void FIQ_Handler(void) __attribute__ ((interrupt("FIQ")));
    void FIQ_Handler(void)
    { ... }

    gdyż reszta parametrów jest potrzebna aby NIEUŻYWANE przerwania były przypisane do domyślnego.

    Znaczy się "t0isr" na "FIQ_Handler"?


    Freddie Chopin napisał:
    Pozatym potrzebna jest też konfiguracja danego źródła jako FIQ w module VIC.

    No ale nie robi tego linia:
    Code:

    VICIntSelect = 0x00000010;    //t0isr = FIQ

    ?

    Na "pocieszenie" dodam że to nie wszystko. Jutro będę męczył zagnieżdzanie przerwań (Ten temat: https://www.elektroda.pl/rtvforum/topic1269062.html oczywiście widziałem. Ale nie, nic nie rozumiem :D).

  • Pomocny post
    #74 03 Lis 2009 22:58
    Freddie Chopin
    Specjalista - Mikrokontrolery

    atom1477 napisał:
    Znaczy się "t0isr" na "FIQ_Handler"?

    tak

    Cytat:
    No ale nie robi tego linia:
    Code:

    VICIntSelect = 0x00000010;    //t0isr = FIQ

    ?

    Pewnie robi, nie pamiętam <:

    4\/3!!

  • #75 03 Lis 2009 23:24
    atom1477
    Poziom 43  

    Freddie Chopin napisał:
    atom1477 napisał:
    Znaczy się "t0isr" na "FIQ_Handler"?

    tak

    Acha. Bo wcześniej w ogóle wywalałem deklarację funkcji, uznając że jest ona w pliku z wektorami.
    Zmieniałem tylko nazwę w samej funkcji, ale deklaracji nie zmieniałem tylko ją całkowicie wywalałem :D
    Czy działa sprawdzę jutro, bo teraz już nie mam dostępu do płytki.


    Więc pytanie o priorytety przerwań:
    Po co w LPC2000 są rejestry ustalające priorytety przerwań, skoro bez Wrappera zagnieżdżającego przerwania zagnieżdżania przerwań i tak nie będzie?

    I pytanie o Wrapper:
    On po prosu sprawdza któro przerwanie zostało wywołane i maskuje wszystkie przerwania o niższym priorytecie (bez globalnego blokowania przerwań)?
    Wtedy wystąpienie przerwania o większym priorytecie przerwie poprzednie przerwanie.
    O niższym nie zostanie zauważone, aż to o wyższym któro się właśnie wykonuje się nie zakończy i nie zostanie usunięte maskowanie?
    (pomijam zachowywanie adresów powrotu)
    Generalnie chodzi mi o to czy Wrapper normalnie sprzętowo blokuje przerwania o niższym priorytecie, czy też może są one zgłaszane i przerywają przerwanie o wyższym priorytecie, ale na krótko, tylko na czas w którym Wrapper sprawdzi że trzeba je zablokować?
    I druga sprawa: Czy Wrapper jest uniwersalny, czy trzeba pisać osobny dla każdego modelu przerwań?

  • #76 04 Lis 2009 19:09
    atom1477
    Poziom 43  

    Ok. Działa.
    W User Manulalu znalazłem informację że rejestr VICVectAddr ma być zapisywany pod koniec przerwania IRQ. Nie pisze wyraźnie że w przerwaniu FIQ nie, ale to jeszcze o niczym nie przesądza.
    Sprawdziłem obydwa przypadki (zapis i brak zapisu) i efekt jest taki sam. Działa.
    Więc nie wiem co z tym zrobić.
    Jakieś sugestie?

  • Pomocny post
    #77 04 Lis 2009 19:11
    94075
    Użytkownik usunął konto  
  • #78 04 Lis 2009 19:21
    atom1477
    Poziom 43  

    Dzięki.
    Ale co ciekawe program działał mimo tego. A mam jeszcze jedno zwykłe przerwanie któro wykonuje się około 50ms a częstotliwością 10Hz.
    To FIQ wykonuje się mnie więcej co 23us (co daje 44100Hz) i trwa kilkadziesiąt cykli.
    Czyli kilka tysięcy razy podczas wykonywania się przerwania IRQ wywoływane jest przerwanie FIQ i zapisuje mi rejestr VICVectAddr.
    A w nocie pisze że zapis do tego rejestru kiedy indziej niż pod koniec obsługi przerwania może mieć nieprzewidywalne skutki.
    Czyli w pewnym sensie w moim przypadku ten rejestr właśnie jest zapisywany wtedy kiedy nie powinien a program mimo to działa.

  • Pomocny post
    #79 04 Lis 2009 19:29
    94075
    Użytkownik usunął konto  
  • #80 04 Lis 2009 20:00
    atom1477
    Poziom 43  

    albertb napisał:
    Natomiast spotkałem się z nieprzewidywalnym skutkiem, w sytuacji odwrotnej, kiedy taki wpis nie był wykonywany w startupie lub w komendach debugera. Procesor restartowany JTAGIEM w czasie obsługi przerwania nie działał poprawnie - nie pamiętam w tej chwili czy sypał abortem czy wisiał.

    Albert


    A po co dokonywać takiego spisu w Startupie albo podczas debugowania?

    Dodano po 8 [minuty]:

    Niestety dwa przerwania to dla mnie za mało.
    Wygląda na to że muszę mieć z 6.
    I wymagane jest zagnieżdżanie.
    Więc ponawiam pytanie: czy Wrapper jest uniwersalny i jeden Wrapper obsłuży ile przerwań zechcę i w dowolnej konfiguracji priorytetów, czy też trzeba go napisać specjalnie do konkretnego modelu przerwań?

  • Pomocny post
    #81 04 Lis 2009 20:13
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Jak ktoś ma odpowiedzieć, skoro nie wiemy o czym piszesz, bo nikt chyba nie spotkał się z oficjalnym i "jedynym słusznym" kodem wrappera przerwań... Uniwersalny wrapper będzie uniwersalny, nieuniwersalny nie będzie uniwersalny. Na pewno priorytety nie mają nic do rzeczy, bo nimi nie zajmuje się twój kod, tylko sprzęt (VIC), który albo zgłosi przerwanie jeśli jego priorytet jest wyższy, albo go nie zgłosi.

    4\/3!!

  • Pomocny post
    #82 04 Lis 2009 20:18
    94075
    Użytkownik usunął konto  
  • #83 04 Lis 2009 20:52
    atom1477
    Poziom 43  

    albertb napisał:

    atom1477 napisał:

    I wymagane jest zagnieżdżanie.

    A przed tym zawsze trzy razy sprawdzam, czy nie da się inaczej.
    Albert

    Niestety sprawdziłem i nie da rady tego prosto zrobić bez tych 6-ciu przerwań.
    Na okrągło musi chodzić zapis na SD a do tego około 10 razy na sekundę być generowana nowa ramka do wyświetlenia na LCD. Obie rzeczy w programie głównym nie pójdą, bo nie mam jak wingerować w bibliotekę do FAT.
    Jak już wywołam procedurę zapisu pliku na SD to nic z tym nie zrobię. Mam kilka sekund „zawiechy”.
    Czyli odświeżanie LCD musi być na przerwaniu (A wcale długo to nie schodzi. Ze 20ms na jedną ramkę).
    Do tego mam aktywne 4 UARTy i muszą one zgłaszać przerwania, bo inaczej pogubię dane. 20ms zwłoki to za dużo. UARTy muszą mieć wyższy priorytet od „odświeżacza” LCD.
    A na koniec generowanie dźwięku. To ma mieć maxymalnie wysoki priorytet. Ale to rozwiązałem (rozwiązaliśmy :D) FIQ-iem. Dzięki FIQ-owi przy okazji mam też najmniejszy możliwy do uzyskania JITTER.


    Freddie Chopin napisał:
    Jak ktoś ma odpowiedzieć, skoro nie wiemy o czym piszesz, bo nikt chyba nie spotkał się z oficjalnym i "jedynym słusznym" kodem wrappera przerwań... Uniwersalny wrapper będzie uniwersalny, nieuniwersalny nie będzie uniwersalny.

    Domyśliłem się że WRAPPERy mogą być różne. Ale jest aż taka rozpiętość?
    Chodzi mi o to czy ten uniwersalny Wrapper nie będzie za bardzo spowalniał przerwań jeżeli wykorzystam tylko 6 przerwań (a Wrapper będzie na maxa uniwersalny i przystosowany do obsłużenia wszystkich możliwych przerwań)?


    Freddie Chopin napisał:
    Na pewno priorytety nie mają nic do rzeczy, bo nimi nie zajmuje się twój kod, tylko sprzęt (VIC), który albo zgłosi przerwanie jeśli jego priorytet jest wyższy, albo go nie zgłosi.

    Acha! Chyba zaczynam rozumieć. Czyli Wrapper nie musi niczego blokować bo przerwania o niższym priorytecie same zostaną zablokowane (sprzętowo)?
    Wrapper dba tylko o zachowywanie adresów powrotu, tak?

  • Pomocny post
    #84 04 Lis 2009 20:58
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Tak - wrapper tylko zachowuje co trzeba i zmienia tryb, a potem wywołuje obsługę przerwania.

    http://www.embedded.com/design/opensource/201500001

    Tu masz opis uniwersalnego wrappera, tyle że dla Atmela, więc będzie lekko inne pobieranie adresu rzeczywistego przerwania.

    4\/3!!

  • Pomocny post
    #85 04 Lis 2009 21:25
    94075
    Użytkownik usunął konto  
  • #86 04 Lis 2009 21:42
    atom1477
    Poziom 43  

    albertb napisał:
    20ms w przerwaniu to wiecznść. Ale w opisywanej sytuacji na pewno nie zagnieżdzałbym przerwań, a przepisał kod obsługi LCD. Uarty mają FIFO, więc aż tak krytyczne czasowo nie są.

    Albert


    Spodziewałem się takiej opinii.
    Ale jak nie przerwanie to tylko wielowątkowość mi zostaje (a przynajmniej ja nie widzę innego rozwiązania).
    Zresztą, nie takie rzeczy w przerwaniach robiłem :D
    Bo nie uznaję krótkich przerwań. Krótka obsługa przerwania dla samego bycia krótką dla mnie nie ma sensu. Nauczyłem się tak pisać programy że program główny najczęściej nic krytycznego nie robi. Więc jak jakieś przerwanie zajmie mi 99% czasu procesora to mi to nie przeszkadza.

    A o co chodzi z tym przepisaniem obsługi LCD?

    Niestety bufory UARTów mi nie wystarczają, bo prędkość przesyłania danych jest duża.

    Chciałem jeszcze dać jeden Timer który by odświeżał kawałek LCD i odczytywał wszystkie UARTy. Czyli zamiast 5-ciu przerwań miał bym tylko jedno (+ to jedno od dźwięku, ale jego nie liczę bo to FIQ). Ale zabawy przy tym sporo.


    Freddie Chopin napisał:
    Tak - wrapper tylko zachowuje co trzeba i zmienia tryb, a potem wywołuje obsługę przerwania.

    http://www.embedded.com/design/opensource/201500001
    Tu masz opis uniwersalnego wrappera, tyle że dla Atmela, więc będzie lekko inne pobieranie adresu rzeczywistego przerwania.

    4\/3!!

    Widziałem już to. Był do tego link w tym temacie o zagnieżdżaniu przerwań w Keil-u.
    Nie wiedziałem co dokładnie ma robić Wrapper więc jeszcze tego nie przetestowałem.
    Ale jeżeli już wiem że Wrappera nie obchodzi jakie to przerwania i jakie mają priorytety, to po prostu to sprawdzę.
    Ale jak już to nie to, ale przykład z noty AN10381 od NXP.
    Zawsze to bardziej gotowcowy gotowiec :D

  • Pomocny post
    #87 05 Lis 2009 13:45
    94075
    Użytkownik usunął konto  
  • #88 05 Lis 2009 14:03
    atom1477
    Poziom 43  

    To wyjście pośrednie niestety nic mi nie da, bo to operuje na całych blokach.
    A tak jak mówiłem u mnie jest zapis na kartę SD i trwa on bardzo długo. A musiał bym to zaimplementować jako jeden blok i ten protothreating nie mógł by przerwać jego wykonywania.
    Rozbijanie roboty na małe kawałki też mi nie pasuje, bo komplikuje to program strasznie, a do tego spowolni mi jego działanie.
    Muszę powiedzieć że na takim czymś (zagnieżdżonych przerwaniach) całkiem dobrze działała poprzednia wersja urządzania, na AVR.
    Pozatym na AVR zrobiłem nawet pełną wielowątkowość :D Ale nie przydała się (bo było duże zużycie stosu). Na ARMie było by o wiele lepiej bo tutaj mam niewiarygodnie dużo SRAMu a jeszcze więcej SDRAMu.

    Więc na razie zostanę przy zagnieżdżonych przerwaniach.
    Pozatym to mam wprawę w dłubaniu. Więc chyba nie będzie źle.
    A niedługo pewnie zrobię sobie wielowątkowość na ARMa :D (tylko muszę się jeszcze doszkolić w budowie rdzenia).
    W każdym razie dzięki za pomoc.


    Freddie Chopin napisał:
    http://www.embedded.com/design/opensource/201500001

    Tu masz opis uniwersalnego wrappera, tyle że dla Atmela, więc będzie lekko inne pobieranie adresu rzeczywistego przerwania.

    A to przypadkiem nie jest na ARMv7?

  • Pomocny post
    #89 08 Lis 2009 14:05
    94075
    Użytkownik usunął konto  
  • #90 08 Lis 2009 15:08
    atom1477
    Poziom 43  

    albertb napisał:
    Co do tych "całych bloków" to się mylisz.
    I myślę, że to najprostszy sposób na dojście do wielowątkowości.
    Bez szkolenia z budowy rdzenia ;-)


    W takim razie kompletnie nie rozumiem jak to działa. Jak można przełączyć wątki w połowie bloku jak blok mógł odłożyć coś na stos?