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

[Nokia 6100][SAM3S][LCD][C] LCD Nokia 6100 - koncepcje drivera dla 32-bit MCU

23 Mar 2013 23:05 1653 2
  • Poziom 18  
    Jak wielu z was, jestem szczęśliwym posiadaczem LCD od Nokii 6100 :D, z tym że nigdy go jeszcze nie używałem. Tak właściwie nigdy nie używałem żadnego wyświetlacza graficznego, więc obsługę tego traktuję jako wprawkę (chociaż wiem, że większe wyświetlacze mają raczej interfejs równoległy i steruje się nimi np. przy pomocy interfejsu EBI w MCU, a ten wyświetlacz ma sterowanie szeregowe po SPI).

    Chcę do niego zaprojektować PCB, nie chcę kupować gotowców, np. KamodTFT2 od Kamami. Zanim przejdę do opisu drivera mam pytanko hardware'owe. Chodzi o to, że sterownik PCF8833 lub ten od Epsona dają możliwość odczytu pewnych danych statusowych oraz temperatury wyświetlacza. Natomiast na wszystkich znalezionych przeze mnie w sieci "pinologiach" złącza od wyświetlacza nie ma linii MISO. Znalazłem np. coś takiego:
    1 - VDD
    2 - RESET
    3 - DATA (MOSI)
    4 - SCK
    5 - CS
    6 - VLCD
    7 - NC
    8 - GND
    9 - LED_BL-
    10 - LED_BL+

    Czy to możliwe, że na pinie 7 jest właśnie MISO, tylko nie jest uwzględnione w rozpiskach, bo zazwyczaj nikomu nie zależy na odczycie informacji z LCD?
    Czy ktoś z was sprawdzał, czy z tego LCD MISO jest wyprowadzone na złącze?

    A teraz w kwestii drivera. Chcę napisać w miarę uniwersalny driver dla MCU 32-bit (nie musi to być Cortex, chociaż uruchamiał będę właśnie na Cortexie). Chcę, żeby był łatwo portowalny na inne architektury. Sam będę to uruchamiał na płytce SAM3-P256 Olimexu (MCU to SAM3S4B). Dopiero się wdrażam w programowanie ARM'ów (wcześniej programowałem tylko ośmiobitowce) dlatego napisanie tego drivera traktuję jako wprawkę w ich programowaniu. Nie będę startował od zera, wzoruję się na słynnym :D driverze Jamesa P. Lyncha:
    Nokia 6100 LCD Display Driver

    Driver z tego pdfa był pisany dla AT91SAM7 i przeróbka na SAM3S4B to banał, bo SPI w SAM7 i SAM3 są bardzo podobne.
    Dobra, do rzeczy po przydługim wstępie. Driver Lyncha jest oparty o polling, co jest sporym ograniczeniem, gdy program MCU ma robić jeszcze wiele innych rzeczy w głównej pętli i niekoniecznie chce czekać na zakończenie wyświetlania LCD (co musi trwać, nawet mimo tego, że ten LCD można napędzać SPI taktowanym zegarem 6 MHz). Taki driver jest dla mnie niedopuszczalny, tzn. obsługę opartą o polling można zostawić do prostych aplikacji, ale częściej będzie potrzebne coś szybszego, co przede wszystkim nie marnuje czasu CPU na czekanie w pętli (to takie nieeleganckie :D). Dlatego też chcę zrobić driver, którzy będzie wykorzystywał co najmniej przerwania a jeszcze lepiej DMA.

    Mam 3 koncepcje i odwołuję się tu do wszystkich, którzy mają doświadczenie w pisaniu prostych interfejsów graficznych lub animacji na takie małe wyświetlacze, aby wypunktowali mi wszystkie błędy koncepcji, realizacji itp. oraz abyście podzielili się swoimi sposobami na tego typu rzeczy.

    Koncepcja I - Menu + FIFO + ISR (przydatna do wyświetlania menu czy innych zegarków, kiedy zawartość ekranu zmienia się stosunkowo rzadko)
    - ekran nie jest regularnie czyszczony i odświeżany, zapisy dokonywane są tylko wtedy, gdy trzeba wyświetlić coś nowego (przejście z jednego poziomu menu do drugiego, zmiana wyświetlanej temperatury, czasu itp.)
    - funkcje rysujące nie wpisują danych bezpośrednio do SPI, tylko do kolejki FIFO (element kolejki to po prostu gołe dane do wysłania do LCD, więc potem przy wysyłaniu do SPI wciąż jest wykorzystywane to, że PCF8833 automatycznie inkrementuje adres piksela przy wypełnianiu obszaru);
    - przy rysowaniu program wie, co jest wyświetlone w jakim obszarze, więc wie też które piksele musi sobie przed wyświetlaniem nowych danych wyczyścić;
    - przerwania od SPI opróżniają FIFO; tutaj widzę problem, gdy kolejka jest pusta - po zapisie do FIFO trzeba jakoś wyzwolić wysyłanie pierwszego bajtu:
    - w przerwaniu od niezależnego timera
    - każda z funkcji rysujących najpierw sprawdza, czy FIFO jest puste; jeśli tak, to po wykonaniu rysowania funkcja wyzwala wysłanie pierwszego bajtu (ten wariant wydaje mi się przekombinowany).

    Cechy takiego podejścia:
    - w głównej pętli programu (mówie o aplikacjach, które nie działają pod kontrolą RTOSa) nie ma długiego oczekiwania na wysyłanie danych po SPI (w związku z tym nie ma zależności czasu wykonywania funkcji rysujących od częstotliwości zegara SPI) - cykle CPU nie są marnowane
    - nie ma cyklicznego wysyłania pełnej zawartości ekranu, ilość danych jest b. ograniczona, w szczególności gdy użytkownik nie zmienia poziomu menu, do wyświetlacza nic nie jest wysyłane
    - wadą koncepcji jest konieczność wchodzenia w przerwania od SPI - sporo czasu wymaganego na obsługę,
    - inna wada to konieczność trzymania kolejki FIFO - "footprint" drivera jest większy;

    Koncepcja II - Menu + bufor danych + DMA (przydatna do wyświetlania menu czy innych zegarków)
    - ekran nie jest regularnie czyszczony i odświeżany, zapisy dokonywane są tylko wtedy, gdy trzeba wyświetlić coś nowego (przejście z jednego poziomu menu do drugiego itp.)
    - funkcje rysujące nie wpisują danych bezpośrednio do SPI, tylko do bufora danych;
    - przy rysowaniu program wie, co jest wyświetlone w jakim obszarze, więc wie też które piksele musi sobie przed wyświetleniem nowych danych wyczyścić;
    - po częściowym lub pełnym wypełnieniu bufora funkcja rysująca inicjalizuje transakcję DMA;
    - każda kolejna funkcja rysująca musi niestety poczekać na koniec poprzedniej transakcji zanim zapisze coś do bufora (czy coś tu przeoczyłem? da się to jakoś inaczej zrealizować?)

    Ta koncepcja niby ma zaletę polegającą na uniknięciu przerwań, bo wszystko załatwia DMA, ale z kolei pojawia się polling innego rodzaj - oczekiwanie na zakończenie poprzedniej transakcji DMA. Bez sensu. No chyba, że czegoś nie widzę.

    Koncepcja III - Menu lub Animacje + bufor pełnej klatki + odświeżanie + DMA (nadaje się do wyświetlania czegokolwiek)
    - ekran jest regularnie czyszczony i odświeżany; częstotliwość ustawiana #define'em na miarę możliwości sprzętu,
    - funkcje rysujące nadpisują piksele w buforze klatki - tylko w wymaganym obszarze,
    - funkcja rysująca np. fonty wciąż musi czyścić obszar całej powierzchni znaku,
    - funkcja rysująca po zakończeniu działań nie musi nic wyzwalać,
    - niezależny wątek (np. wyzwalany cyklicznie przez timer) inicjalizuje transakcję DMA dla całego obszaru wyświetlacza; DMA wypełnia piksel po pikselu cały ekran; oczywiście może i będzie się tak zdarzać, że odświeżanie zbiegnie się w czasie ze zmianą zawartości ekranu, ale chyba nie ma sensu definiowanie okien czasowych typu "zezwalanie na zmianę zawartości", "zezwalanie na odświeżanie"; być może przejścia (zwłaszcza dla małych częstotliwości odświeżania) byłyby ładniejsze, ale byłoby więcej zachodu;

    Co do bufora pełnej klatki:
    - wyświetlacz 132x132, 12 bitów na piksel -> 132 * 132 * 1,5 = 26136 B = 25,5 KB. Trochę dużo, ale w SAM3S4B da radę bez konieczności dopięcia zewnętrznego RAMu.

    Co myślicie o takich podejściach? Czy są tu jakieś drastyczne błędy koncepcyjne?
    Jak wy realizujecie takie wyświetlanie i na jakim sprzęcie i ile fps jesteście w stanie wyciągnąć?
  • PCBway
  • Użytkownik usunął konto  
  • PCBway
  • Poziom 18  
    Jest tak jak mówisz.
    W międzyczasie obejrzałem ten schemat:
    MOD-LCD6610

    Samo oznaczenie sugeruje, że linia danych jest dwukierunkowa, poza tym widać, że jest rozpięta, z odpowiednią separacją, na MOSI i MISO.
    Poza tym sprawdziłem notę sterownika PCF8833 i tam jest wszystko pięknie napisane o komunikacji szeregowej, w której SDIN i SDOUT są wyprowadzone na wspólny pin. Cofam swoje pytanie o linię MISO :D.